X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=nfs3%2Fnfs3.c;h=2895e5b9d96ebd29b0bf0ad9c0dabcf794277042;hb=25ddfddd324493ee87cc3770245104420b35fd75;hp=72ec9cb7a26173e6a0732a428a901d0c0af99597;hpb=50c08ba526a6638e8e3c4eec0503365a2c110a85;p=bluesky.git diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 72ec9cb..2895e5b 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -243,10 +243,14 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) async_rpc_send_reply(req, &result); return; } + + result.lookup3res_u.resok.dir_attributes.present = TRUE; + encode_fattr3(&result.lookup3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir); + g_mutex_unlock(dir->lock); + BlueSkyInode *inode = bluesky_get_inode(fs, inum); if (inode == NULL) { result.status = NFS3ERR_NOENT; - g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); return; } @@ -254,8 +258,6 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) schedule_inode_unref(req, inode); result.status = NFS3_OK; - result.lookup3res_u.resok.dir_attributes.present = TRUE; - encode_fattr3(&result.lookup3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir); result.lookup3res_u.resok.obj_attributes.present = TRUE; encode_fattr3(&result.lookup3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode); @@ -265,7 +267,6 @@ void nfsproc3_lookup_3_svc(diropargs3 *argp, RPCRequest *req) result.lookup3res_u.resok.object.data.data_val = (char *)&fh_bytes; g_mutex_unlock(inode->lock); - g_mutex_unlock(dir->lock); async_rpc_send_reply(req, &result); } @@ -937,12 +938,32 @@ void nfsproc3_readdirplus_3_svc(readdirplus3args *argp, RPCRequest *req) uint64_t fh_bytes[MAX_READDIR_DIRENTS]; int count = 0; - /* TODO: Handle dircount, maxcount arguments from client. */ - + GSequenceIter *i; BlueSkyDirent start = {NULL, NULL, argp->cookie, 0}; - GSequenceIter *i = g_sequence_search(dir->dirents, &start, - bluesky_dirent_compare, NULL); + /* Perform a prefetch pass on inodes: for all the inodes we think we will + * return information about, try to load each one but don't wait. This + * should let multiple inodes be fetched in parallel, instead of + * sequentially in the loop that follows. */ + i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL); + while (count < MAX_READDIR_DIRENTS + && !g_sequence_iter_is_end(i) + && dircount <= argp->dircount + && dircount + attrcount <= argp->maxcount) + { + BlueSkyDirent *d = g_sequence_get(i); + BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); + if (inode != NULL) + bluesky_inode_unref(inode); + dircount += 24 + ((strlen(d->name) + 3) & ~3); + attrcount += 88 + 8 + 8; + i = g_sequence_iter_next(i); + } + + i = g_sequence_search(dir->dirents, &start, bluesky_dirent_compare, NULL); + count = 0; + dircount = 88 + 16; + attrcount = 0; while (count < MAX_READDIR_DIRENTS && !g_sequence_iter_is_end(i)) { BlueSkyDirent *d = g_sequence_get(i); BlueSkyInode *inode = bluesky_get_inode(fs, d->inum); @@ -1074,5 +1095,22 @@ void nfsproc3_commit_3_svc(commit3args *argp, RPCRequest *req) result.status = NFS3ERR_NOTSUPP; + BlueSkyInode *inode = lookup_fh(req, &argp->file); + if (inode == NULL) { + result.status = NFS3ERR_STALE; + async_rpc_send_reply(req, &result); + return; + } + + g_mutex_lock(inode->lock); + encode_pre_wcc(&result.commit3res_u.resok.file_wcc, inode); + + bluesky_inode_do_sync(inode); + + result.commit3res_u.resok.file_wcc.after.present = TRUE; + encode_fattr3(&result.commit3res_u.resok.file_wcc.after.post_op_attr_u.attributes, inode); + + g_mutex_unlock(inode->lock); + async_rpc_send_reply(req, &result); }