walters / rpms / nfs-utils

Forked from rpms/nfs-utils 6 years ago
Clone
944e52b
commit dfa1f714caaed32ebe64ae9c4f8678e6c56bce5d
944e52b
Author: Dan Muntz <dmuntz@netapp.com>
944e52b
Date:   Tue May 6 16:45:09 2008 -0700
944e52b
944e52b
    Add read/write-through-MDS for spNFS
944e52b
    
944e52b
    Signed-off-by: Dan Muntz <dmuntz@netapp.com>
944e52b
944e52b
diff --git a/utils/spnfsd/nfsd4_spnfs.h b/utils/spnfsd/nfsd4_spnfs.h
944e52b
index 6516ab3..fc6bd9a 100644
944e52b
--- a/utils/spnfsd/nfsd4_spnfs.h
944e52b
+++ b/utils/spnfsd/nfsd4_spnfs.h
944e52b
@@ -55,9 +55,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
944e52b
 #define SPNFS_TYPE_CREATE		0x09
944e52b
 #define SPNFS_TYPE_REMOVE		0x0a
944e52b
 #define SPNFS_TYPE_COMMIT		0x0b
944e52b
+#define SPNFS_TYPE_READ			0x0c
944e52b
+#define SPNFS_TYPE_WRITE		0x0d
944e52b
 
944e52b
 #define	SPNFS_MAX_DEVICES		1
944e52b
 #define	SPNFS_MAX_DATA_SERVERS		2
944e52b
+#define SPNFS_MAX_IO			2048
944e52b
 
944e52b
 /* layout */
944e52b
 struct spnfs_msg_layoutget_args {
944e52b
@@ -198,6 +201,30 @@ struct spnfs_msg_commit_res {
944e52b
 };
944e52b
 */
944e52b
 
944e52b
+/* read */
944e52b
+struct spnfs_msg_read_args {
944e52b
+	unsigned long inode;
944e52b
+	loff_t offset;
944e52b
+	unsigned long len;
944e52b
+};
944e52b
+
944e52b
+struct spnfs_msg_read_res {
944e52b
+	int status;
944e52b
+	char data[SPNFS_MAX_IO];
944e52b
+};
944e52b
+
944e52b
+/* write */
944e52b
+struct spnfs_msg_write_args {
944e52b
+	unsigned long inode;
944e52b
+	loff_t offset;
944e52b
+	unsigned long len;
944e52b
+	char data[SPNFS_MAX_IO];
944e52b
+};
944e52b
+
944e52b
+struct spnfs_msg_write_res {
944e52b
+	int status;
944e52b
+};
944e52b
+
944e52b
 /* bundle args and responses */
944e52b
 union spnfs_msg_args {
944e52b
 	struct spnfs_msg_layoutget_args		layoutget_args;
944e52b
@@ -217,6 +244,8 @@ union spnfs_msg_args {
944e52b
 /*
944e52b
 	struct spnfs_msg_commit_args		commit_args;
944e52b
 */
944e52b
+	struct spnfs_msg_read_args		read_args;
944e52b
+	struct spnfs_msg_write_args		write_args;
944e52b
 };
944e52b
 
944e52b
 union spnfs_msg_res {
944e52b
@@ -237,6 +266,8 @@ union spnfs_msg_res {
944e52b
 /*
944e52b
 	struct spnfs_msg_commit_res		commit_res;
944e52b
 */
944e52b
+	struct spnfs_msg_read_res		read_res;
944e52b
+	struct spnfs_msg_write_res		write_res;
944e52b
 };
944e52b
 
944e52b
 /* a spnfs message, args and response */
944e52b
@@ -268,7 +299,9 @@ int spnfs_getdeviceinfo(struct super_block *, struct pnfs_devinfo_arg *);
944e52b
 int spnfs_setattr(void);
944e52b
 int spnfs_open(struct inode *, void *);
944e52b
 int spnfs_get_state(struct inode *, void *, void *);
944e52b
-int spnfs_remove(unsigned long ino);
944e52b
+int spnfs_remove(unsigned long);
944e52b
+int spnfs_read(unsigned long, loff_t, unsigned long *, int, struct svc_rqst *);
944e52b
+int spnfs_write(unsigned long, loff_t, size_t, int, struct svc_rqst *);
944e52b
 
944e52b
 int nfsd_spnfs_new(void);
944e52b
 void nfsd_spnfs_delete(void);
944e52b
diff --git a/utils/spnfsd/spnfsd.c b/utils/spnfsd/spnfsd.c
944e52b
index f7bae84..fc9113d 100644
944e52b
--- a/utils/spnfsd/spnfsd.c
944e52b
+++ b/utils/spnfsd/spnfsd.c
944e52b
@@ -40,6 +40,8 @@
944e52b
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
944e52b
  */
944e52b
 
944e52b
+#define _LARGEFILE64_SOURCE
944e52b
+#define _FILE_OFFSET_BITS 64
944e52b
 #include <sys/types.h>
944e52b
 #include <sys/time.h>
944e52b
 #include <sys/poll.h>
944e52b
@@ -340,6 +342,12 @@ spnfs_msg_handler(struct spnfs_client *scp, struct spnfs_msg *im)
944e52b
 	case SPNFS_TYPE_COMMIT:
944e52b
 		err = spnfsd_commit(im);
944e52b
 		break;
944e52b
+	case SPNFS_TYPE_READ:
944e52b
+		err = spnfsd_read(im);
944e52b
+		break;
944e52b
+	case SPNFS_TYPE_WRITE:
944e52b
+		err = spnfsd_write(im);
944e52b
+		break;
944e52b
 	default:
944e52b
 		spnfsd_warnx("spnfs_msg_handler: Invalid msg type (%d) in message",
944e52b
 			     im->im_type);
944e52b
diff --git a/utils/spnfsd/spnfsd.h b/utils/spnfsd/spnfsd.h
944e52b
index e8527e7..e05c272 100644
944e52b
--- a/utils/spnfsd/spnfsd.h
944e52b
+++ b/utils/spnfsd/spnfsd.h
944e52b
@@ -65,4 +65,6 @@ int spnfsd_close(struct spnfs_msg *);
944e52b
 int spnfsd_create(struct spnfs_msg *);
944e52b
 int spnfsd_remove(struct spnfs_msg *);
944e52b
 int spnfsd_commit(struct spnfs_msg *);
944e52b
+int spnfsd_read(struct spnfs_msg *);
944e52b
+int spnfsd_write(struct spnfs_msg *);
944e52b
 int spnfsd_getfh(char *, unsigned char *, unsigned int *);
944e52b
diff --git a/utils/spnfsd/spnfsd_ops.c b/utils/spnfsd/spnfsd_ops.c
944e52b
index e3adadd..5099c00 100644
944e52b
--- a/utils/spnfsd/spnfsd_ops.c
944e52b
+++ b/utils/spnfsd/spnfsd_ops.c
944e52b
@@ -20,6 +20,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
944e52b
 
944e52b
 ******************************************************************************/
944e52b
 
944e52b
+#define _LARGEFILE64_SOURCE
944e52b
+#define _FILE_OFFSET_BITS 64
944e52b
 #include "nfsd4_spnfs.h"
944e52b
 #include "spnfsd.h"
944e52b
 #include "nfs/nfs.h"
944e52b
@@ -265,6 +267,130 @@ spnfsd_remove(struct spnfs_msg *im)
944e52b
 int
944e52b
 spnfsd_commit(struct spnfs_msg *im)
944e52b
 {
944e52b
+	im->im_status = SPNFS_STATUS_SUCCESS;
944e52b
+	return 0;
944e52b
+}
944e52b
+
944e52b
+int
944e52b
+min (unsigned int x, unsigned int y)
944e52b
+{
944e52b
+	if (x
944e52b
+}
944e52b
+
944e52b
+/* DMXXX: for read and write, there's an issue with partially completed i/o */
944e52b
+int
944e52b
+spnfsd_read(struct spnfs_msg *im)
944e52b
+{
944e52b
+	unsigned long inode = im->im_args.read_args.inode;
944e52b
+	loff_t offset = im->im_args.read_args.offset;
944e52b
+	unsigned long len = im->im_args.read_args.len;
944e52b
+	int ds, iolen;
944e52b
+	loff_t soffset;
944e52b
+	int bufoffset = 0;
944e52b
+	char fullpath[1024]; /* DMXXX */
944e52b
+	int fd, err;
944e52b
+	int completed = 0;
944e52b
+
944e52b
+	im->im_status = SPNFS_STATUS_SUCCESS;
944e52b
+	im->im_res.read_res.status = 0;
944e52b
+	if (len > SPNFS_MAX_IO) {
944e52b
+		im->im_res.read_res.status = -1;
944e52b
+		return 0;
944e52b
+	}
944e52b
+	while (len > 0) {
944e52b
+		ds = (offset / stripesize) % num_ds;
944e52b
+		if (densestriping == 0)
944e52b
+			soffset = offset;
944e52b
+		else
944e52b
+			soffset = (offset / num_ds) + (offset % stripesize);
944e52b
+		iolen = min(len, stripesize - (offset % stripesize));
944e52b
+
944e52b
+		sprintf(fullpath, "%s/%s/%ld", dsmountdir,
944e52b
+			dataservers[ds].ds_ip, inode);
944e52b
+		fd = open(fullpath, O_RDONLY);
944e52b
+		if (fd < 0) {
944e52b
+			perror(fullpath);
944e52b
+			im->im_res.read_res.status = -errno;
944e52b
+			return 0; /* DMXXX */
944e52b
+		}
944e52b
+		/* DM: add some error checking */
944e52b
+		lseek64(fd, offset, SEEK_SET);
944e52b
+		err = read(fd,
944e52b
+			(void *)(im->im_res.read_res.data+bufoffset), iolen);
944e52b
+		close(fd);
944e52b
+		if (err < 0) {
944e52b
+			perror("read");
944e52b
+			im->im_res.read_res.status = -errno;
944e52b
+			return 0; /* DMXXX */
944e52b
+		}
944e52b
+
944e52b
+		if (err == 0)
944e52b
+			break;
944e52b
+		iolen = err; /* number of bytes read */
944e52b
+		completed += iolen;
944e52b
+		len -= iolen;
944e52b
+		offset += iolen;
944e52b
+		bufoffset += iolen;
944e52b
+	}
944e52b
+	im->im_res.read_res.status = completed;
944e52b
+
944e52b
+	return 0;
944e52b
+}
944e52b
+
944e52b
+int
944e52b
+spnfsd_write(struct spnfs_msg *im)
944e52b
+{
944e52b
+	unsigned long inode = im->im_args.write_args.inode;
944e52b
+	loff_t offset = im->im_args.write_args.offset;
944e52b
+	size_t len = im->im_args.write_args.len;
944e52b
+	char *wbuf = im->im_args.write_args.data;
944e52b
+	int ds, iolen;
944e52b
+	loff_t soffset;
944e52b
+	int bufoffset = 0;
944e52b
+	char fullpath[1024]; /* DMXXX */
944e52b
+	int fd, err;
944e52b
+	int completed = 0;
944e52b
+
944e52b
+	im->im_status = SPNFS_STATUS_SUCCESS;
944e52b
+	im->im_res.write_res.status = 0;
944e52b
+	if (len > SPNFS_MAX_IO) {
944e52b
+		printf("write length > SPNFS_MAX_IO\n");
944e52b
+		im->im_res.write_res.status = -1;
944e52b
+		return 0;
944e52b
+	}
944e52b
+	while (len > 0) {
944e52b
+		ds = (offset / stripesize) % num_ds;
944e52b
+		if (densestriping == 0)
944e52b
+			soffset = offset;
944e52b
+		else
944e52b
+			soffset = (offset / num_ds) + (offset % stripesize);
944e52b
+		iolen = min(len, stripesize - (offset % stripesize));
944e52b
+
944e52b
+		sprintf(fullpath, "%s/%s/%ld", dsmountdir,
944e52b
+			dataservers[ds].ds_ip, inode);
944e52b
+		fd = open(fullpath, O_WRONLY);
944e52b
+		if (fd < 0) {
944e52b
+			perror(fullpath);
944e52b
+			im->im_res.write_res.status = -errno;
944e52b
+			return 0; /* DMXXX */
944e52b
+		}
944e52b
+		/* DM: add some error checking */
944e52b
+		lseek64(fd, offset, SEEK_SET);
944e52b
+		err = write(fd, (void *)(wbuf+bufoffset), iolen);
944e52b
+		close(fd);
944e52b
+		if (err < 0) {
944e52b
+			perror("write");
944e52b
+			im->im_res.write_res.status = -errno;
944e52b
+			return 0; /* DMXXX */
944e52b
+		}
944e52b
+
944e52b
+		iolen = err; /* number of bytes read */
944e52b
+		completed += iolen;
944e52b
+		len -= iolen;
944e52b
+		offset += iolen;
944e52b
+		bufoffset += iolen;
944e52b
+	}
944e52b
+	im->im_res.write_res.status = completed;
944e52b
 	return 0;
944e52b
 }
944e52b