[sheepdog] [PATCH v3 09/12] sheep/nfs: implement read/write nfs operation

Liu Yuan namei.unix at gmail.com
Wed Jan 29 09:26:23 CET 2014


Now we support more bash command such as cp, mv, echo, cat ...

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 include/util.h      |  8 +++++
 sheep/Makefile.am   |  5 +++
 sheep/nfs/fs.c      | 41 +++++++++++++++++++++++++
 sheep/nfs/fs.h      |  2 ++
 sheep/nfs/nfs.c     | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 sheep/nfs/nfs.h     |  2 ++
 sheep/nfs/nfsd.c    |  3 ++
 sheep/trace/trace.h |  8 -----
 8 files changed, 146 insertions(+), 10 deletions(-)

diff --git a/include/util.h b/include/util.h
index 4b4fa27..9545270 100644
--- a/include/util.h
+++ b/include/util.h
@@ -523,4 +523,12 @@ static inline long __must_check IS_ERR_OR_NULL(const void *ptr)
 	return !ptr || IS_ERR_VALUE((unsigned long)ptr);
 }
 
+static inline uint64_t clock_get_time(void)
+{
+	struct timespec ts;
+
+	clock_gettime(CLOCK_REALTIME, &ts);
+	return (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
+}
+
 #endif
diff --git a/sheep/Makefile.am b/sheep/Makefile.am
index df3b626..406a4ec 100644
--- a/sheep/Makefile.am
+++ b/sheep/Makefile.am
@@ -55,6 +55,11 @@ endif
 
 sheep_LDADD	  	= ../lib/libsheepdog.a -lpthread -lm\
 			  $(libcpg_LIBS) $(libcfg_LIBS) $(libacrd_LIBS) $(LIBS)
+
+if BUILD_NFS
+sheep_LDADD		+= -lrt
+endif
+
 sheep_DEPENDENCIES	= ../lib/libsheepdog.a
 
 
diff --git a/sheep/nfs/fs.c b/sheep/nfs/fs.c
index acf58f1..a0a6691 100644
--- a/sheep/nfs/fs.c
+++ b/sheep/nfs/fs.c
@@ -337,3 +337,44 @@ int fs_create_file(uint64_t pino, struct inode *new, const char *name)
 	free(inode);
 	return ret;
 }
+
+/* TODO: support extent */
+int64_t fs_read(struct inode *inode, void *buffer, uint64_t count,
+		uint64_t offset)
+{
+	uint8_t *start = inode->data + offset;
+	int64_t done = count;
+
+	if (offset >= inode->size || count == 0)
+		return 0;
+
+	if (offset + count > inode->size)
+		done = inode->size - offset;
+
+	memcpy(buffer, start, done);
+
+	return done;
+}
+
+int64_t fs_write(struct inode *inode, void *buffer, uint64_t count,
+		 uint64_t offset)
+{
+	uint8_t *start = inode->data + offset;
+	int64_t done = count;
+	int ret;
+
+	if (count == 0)
+		return 0;
+
+	memcpy(start, buffer, done);
+
+	/* TODO: lock inode */
+	if ((offset + done) > inode->size)
+		inode->size = offset + done;
+
+	inode->mtime = time(NULL);
+	ret = fs_write_inode_full(inode);
+	if (ret != SD_RES_SUCCESS)
+		done = -1;
+	return done;
+}
diff --git a/sheep/nfs/fs.h b/sheep/nfs/fs.h
index 5d6b308..eaecb7c 100644
--- a/sheep/nfs/fs.h
+++ b/sheep/nfs/fs.h
@@ -66,5 +66,7 @@ int fs_read_dir(struct inode *inode, uint64_t offset,
 		void *data);
 struct dentry *fs_lookup_dir(struct inode *inode, const char *name);
 int fs_create_file(uint64_t pino, struct inode *new, const char *name);
+int64_t fs_read(struct inode *inode, void *buffer, uint64_t count, uint64_t);
+int64_t fs_write(struct inode *inode, void *buffer, uint64_t count, uint64_t);
 
 #endif
diff --git a/sheep/nfs/nfs.c b/sheep/nfs/nfs.c
index 16dcfe8..b9b55f6 100644
--- a/sheep/nfs/nfs.c
+++ b/sheep/nfs/nfs.c
@@ -250,14 +250,97 @@ void *nfs3_readlink(struct svc_req *req, struct nfs_arg *argp)
 	return NULL;
 }
 
+static char nfs_read_buffer[RPCSVC_MAXPAYLOAD];
+
 void *nfs3_read(struct svc_req *req, struct nfs_arg *argp)
 {
-	return NULL;
+	static READ3res result;
+	READ3args *arg = &argp->read;
+	struct svc_fh *fh = get_svc_fh(argp);
+	uint64_t offset = arg->offset, count = arg->count;
+	struct post_op_attr *poa =
+		&result.READ3res_u.resok.file_attributes;
+	struct fattr3 *post = &poa->post_op_attr_u.attributes;
+	struct inode *inode;
+	int ret;
+
+	sd_debug("%"PRIx64"count %"PRIu64" offset %"PRIu64, fh->ino,
+		 count, offset);
+
+	inode = fs_read_inode_full(fh->ino);
+	if (IS_ERR(inode)) {
+		switch (PTR_ERR(inode)) {
+		case SD_RES_NO_OBJ:
+			result.status = NFS3ERR_NOENT;
+			goto out;
+		default:
+			result.status = NFS3ERR_IO;
+			goto out;
+		}
+	}
+
+	ret = fs_read(inode, nfs_read_buffer, count, offset);
+	if (ret < 0) {
+		result.status = NFS3ERR_IO;
+		goto out_free;
+	}
+	result.status = NFS3_OK;
+	result.READ3res_u.resok.count = ret;
+	result.READ3res_u.resok.eof = ret < count;
+	result.READ3res_u.resok.data.data_val = nfs_read_buffer;
+	result.READ3res_u.resok.data.data_len = ret;
+	poa->attributes_follow = true;
+	update_post_attr(inode, post);
+out_free:
+	free(inode);
+out:
+	return &result;
 }
 
 void *nfs3_write(struct svc_req *req, struct nfs_arg *argp)
 {
-	return NULL;
+	static WRITE3res result;
+	WRITE3args *arg = &argp->write;
+	struct svc_fh *fh = get_svc_fh(argp);
+	uint64_t offset = arg->offset, count = arg->count;
+	struct post_op_attr *poa =
+		&result.WRITE3res_u.resok.file_wcc.after;
+	struct fattr3 *post = &poa->post_op_attr_u.attributes;
+	struct inode *inode;
+	int64_t done;
+	void *buffer = arg->data.data_val;
+
+	sd_debug("%"PRIx64" count %"PRIu64" offset %"PRIu64" stable %d",
+		 fh->ino, count, offset, arg->stable);
+
+	inode = fs_read_inode_full(fh->ino);
+	if (IS_ERR(inode)) {
+		switch (PTR_ERR(inode)) {
+		case SD_RES_NO_OBJ:
+			result.status = NFS3ERR_NOENT;
+			goto out;
+		default:
+			result.status = NFS3ERR_IO;
+			goto out;
+		}
+	}
+
+	done = fs_write(inode, buffer, count, offset);
+	if (done < 0) {
+		result.status = NFS3ERR_IO;
+		goto out_free;
+	}
+	result.status = NFS3_OK;
+	result.WRITE3res_u.resok.count = done;
+	result.WRITE3res_u.resok.committed = FILE_SYNC;
+	memcpy(&result.WRITE3res_u.resok.verf, &nfs_boot_time,
+	       sizeof(nfs_boot_time));
+	poa->attributes_follow = true;
+	update_post_attr(inode, post);
+out_free:
+	free(inode);
+out:
+	return &result;
 }
 
 /* FIXME: support GUARDED and EXCLUSIVE */
diff --git a/sheep/nfs/nfs.h b/sheep/nfs/nfs.h
index f3f8288..8cbad09 100644
--- a/sheep/nfs/nfs.h
+++ b/sheep/nfs/nfs.h
@@ -1234,6 +1234,8 @@ struct svc_fh {
 	uint64_t ino;
 };
 
+uint64_t nfs_boot_time;
+
 #include "fs.h"
 
 #endif /* !_NFS_H */
diff --git a/sheep/nfs/nfsd.c b/sheep/nfs/nfsd.c
index 31b3375..8ac8625 100644
--- a/sheep/nfs/nfsd.c
+++ b/sheep/nfs/nfsd.c
@@ -194,6 +194,8 @@ out:
 	pthread_exit(NULL);
 }
 
+uint64_t nfs_boot_time;
+
 int nfs_init(const char *options)
 {
 	pthread_t t;
@@ -205,6 +207,7 @@ int nfs_init(const char *options)
 		return -1;
 	}
 
+	nfs_boot_time = clock_get_time();
 	return 0;
 }
 
diff --git a/sheep/trace/trace.h b/sheep/trace/trace.h
index ea72733..ed75d06 100644
--- a/sheep/trace/trace.h
+++ b/sheep/trace/trace.h
@@ -63,13 +63,5 @@ regist_ ##tracer(void)				\
 	regist_tracer(&tracer);			\
 }
 
-static inline uint64_t clock_get_time(void)
-{
-	struct timespec ts;
-
-	clock_gettime(CLOCK_REALTIME, &ts);
-	return (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
-}
-
 #endif /* __ASSEMBLY__ */
 #endif
-- 
1.8.1.2




More information about the sheepdog mailing list