[sheepdog] [PATCH 09/12] sheep/nfs: implement read/write nfs operation
Liu Yuan
namei.unix at gmail.com
Tue Jan 28 21:19:09 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/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 -----
7 files changed, 141 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/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