diff --git a/nfs-service.c b/nfs-service.c index 0caede3..9b15b58 100644 --- a/nfs-service.c +++ b/nfs-service.c @@ -2,7 +2,7 @@ #include #include "nfs-service.h" -static void fill_example_fsattr(struct fattr3 *attr) +static void fill_example_rootdir_fsattr(struct fattr3 *attr) { struct timespec now; clock_gettime(CLOCK_REALTIME, &now); @@ -22,6 +22,26 @@ static void fill_example_fsattr(struct fattr3 *attr) attr->ctime = attr->atime; } +static void fill_example_testfile_fsattr(struct fattr3 *attr) +{ + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + attr->type = NF3REG; + attr->mode = 0644; + attr->nlink = 1; + attr->uid = 0; + attr->gid = 0; + attr->size = strlen("Hello, world!")+1; + attr->used = strlen("Hello, world!")+1; + attr->rdev = (specdata3){ 0, 0 }; + attr->fsid = 1; + attr->fileid = 2; + attr->atime.seconds = now.tv_sec; + attr->atime.nseconds = now.tv_nsec; + attr->mtime = attr->atime; + attr->ctime = attr->atime; +} + static int nfs3_null_proc(struct rpc_context *rpc, struct rpc_msg *call) { rpc_send_reply(rpc, call, NULL, (zdrproc_t)zdr_void, 0); @@ -41,7 +61,7 @@ static int nfs3_getattr_proc(struct rpc_context *rpc, struct rpc_msg *call) { // Fill info reply.status = NFS3_OK; - fill_example_fsattr(&reply.GETATTR3res_u.resok.obj_attributes); + fill_example_rootdir_fsattr(&reply.GETATTR3res_u.resok.obj_attributes); } rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_GETATTR3res, sizeof(GETATTR3res)); return 0; @@ -51,7 +71,8 @@ static int nfs3_setattr_proc(struct rpc_context *rpc, struct rpc_msg *call) { SETATTR3args *args = call->body.cbody.args; SETATTR3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_SETATTR3res, sizeof(SETATTR3res)); return 0; } @@ -78,7 +99,8 @@ static int nfs3_readlink_proc(struct rpc_context *rpc, struct rpc_msg *call) { READLINK3args *args = call->body.cbody.args; READLINK3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_READLINK3res, sizeof(READLINK3res)); return 0; } @@ -96,7 +118,8 @@ static int nfs3_write_proc(struct rpc_context *rpc, struct rpc_msg *call) { WRITE3args *args = call->body.cbody.args; WRITE3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res)); return 0; } @@ -105,7 +128,8 @@ static int nfs3_create_proc(struct rpc_context *rpc, struct rpc_msg *call) { CREATE3args *args = call->body.cbody.args; CREATE3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_CREATE3res, sizeof(CREATE3res)); return 0; } @@ -114,7 +138,8 @@ static int nfs3_mkdir_proc(struct rpc_context *rpc, struct rpc_msg *call) { MKDIR3args *args = call->body.cbody.args; MKDIR3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_MKDIR3res, sizeof(MKDIR3res)); return 0; } @@ -123,7 +148,8 @@ static int nfs3_symlink_proc(struct rpc_context *rpc, struct rpc_msg *call) { SYMLINK3args *args = call->body.cbody.args; SYMLINK3res reply; - + // Not supported yet + reply.status = NFS3ERR_NOTSUPP; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_SYMLINK3res, sizeof(SYMLINK3res)); return 0; } @@ -167,8 +193,8 @@ static int nfs3_rename_proc(struct rpc_context *rpc, struct rpc_msg *call) static int nfs3_link_proc(struct rpc_context *rpc, struct rpc_msg *call) { LINK3args *args = call->body.cbody.args; - LINK3res reply; - + // We don't support hard links + LINK3res reply = { NFS3ERR_NOTSUPP }; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_LINK3res, sizeof(LINK3res)); return 0; } @@ -177,7 +203,18 @@ static int nfs3_readdir_proc(struct rpc_context *rpc, struct rpc_msg *call) { READDIR3args *args = call->body.cbody.args; READDIR3res reply; - + // Example: return 1 entry + struct entry3 entries[1] = { { + .fileid = 2, + .name = "testfile", + .cookie = 0, + .nextentry = NULL, + } }; + reply.status = NFS3_OK; + reply.READDIR3res_u.resok.dir_attributes.attributes_follow = FALSE; + *(uint64_t*)(reply.READDIR3res_u.resok.cookieverf) = 1; // continuation cookie + reply.READDIR3res_u.resok.reply.entries = entries; + reply.READDIR3res_u.resok.reply.eof = TRUE; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_READDIR3res, sizeof(READDIR3res)); return 0; } @@ -186,16 +223,44 @@ static int nfs3_readdirplus_proc(struct rpc_context *rpc, struct rpc_msg *call) { READDIRPLUS3args *args = call->body.cbody.args; READDIRPLUS3res reply; - + // Example: return 1 entry (but this time with attributes) + struct entryplus3 entries[1] = { { + .fileid = 2, + .name = "testfile", + .cookie = 0, + .name_attributes = { + .attributes_follow = TRUE, + }, + .name_handle = { + .handle_follows = FALSE, + }, + .nextentry = NULL, + } }; + fill_example_testfile_fsattr(&entries[0].name_attributes.post_op_attr_u.attributes); + reply.status = NFS3_OK; + reply.READDIRPLUS3res_u.resok.dir_attributes.attributes_follow = FALSE; + *(uint64_t*)(reply.READDIRPLUS3res_u.resok.cookieverf) = 1; // continuation cookie + reply.READDIRPLUS3res_u.resok.reply.entries = entries; + reply.READDIRPLUS3res_u.resok.reply.eof = TRUE; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_READDIRPLUS3res, sizeof(READDIRPLUS3res)); return 0; } +// Get file system statistics static int nfs3_fsstat_proc(struct rpc_context *rpc, struct rpc_msg *call) { FSSTAT3args *args = call->body.cbody.args; FSSTAT3res reply; - + reply.status = NFS3_OK; + reply.FSSTAT3res_u.resok.obj_attributes.attributes_follow = TRUE; + fill_example_rootdir_fsattr(&reply.FSSTAT3res_u.resok.obj_attributes.post_op_attr_u.attributes); + reply.FSSTAT3res_u.resok.tbytes = 4096; // total bytes + reply.FSSTAT3res_u.resok.fbytes = 4096; // free bytes + reply.FSSTAT3res_u.resok.abytes = 4096; // available bytes + reply.FSSTAT3res_u.resok.tfiles = 1 << 31; // total files + reply.FSSTAT3res_u.resok.ffiles = 1 << 31; // free files + reply.FSSTAT3res_u.resok.afiles = 1 << 31; // available files + reply.FSSTAT3res_u.resok.invarsec = 0; rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_FSSTAT3res, sizeof(FSSTAT3res)); return 0; } @@ -214,7 +279,7 @@ static int nfs3_fsinfo_proc(struct rpc_context *rpc, struct rpc_msg *call) // Fill info reply.status = NFS3_OK; reply.FSINFO3res_u.resok.obj_attributes.attributes_follow = TRUE; - fill_example_fsattr(&reply.FSINFO3res_u.resok.obj_attributes.post_op_attr_u.attributes); + fill_example_rootdir_fsattr(&reply.FSINFO3res_u.resok.obj_attributes.post_op_attr_u.attributes); reply.FSINFO3res_u.resok.rtmax = 128*1024*1024; reply.FSINFO3res_u.resok.rtpref = 128*1024*1024; reply.FSINFO3res_u.resok.rtmult = 4096; @@ -259,8 +324,8 @@ static int nfs3_pathconf_proc(struct rpc_context *rpc, struct rpc_msg *call) static int nfs3_commit_proc(struct rpc_context *rpc, struct rpc_msg *call) { COMMIT3args *args = call->body.cbody.args; - COMMIT3res reply; - + COMMIT3res reply = { 0 }; + // Just pretend we did fsync :-) rpc_send_reply(rpc, call, &reply, (zdrproc_t)zdr_COMMIT3res, sizeof(COMMIT3res)); return 0; }