From: Michael Vrable Date: Wed, 6 Jan 2010 18:50:57 +0000 (-0800) Subject: Mostly-working NFS rename support. X-Git-Url: https://git.vrable.net/?a=commitdiff_plain;h=4bef26446b9100f63ac3c953b7f96f1966673980;p=bluesky.git Mostly-working NFS rename support. --- diff --git a/bluesky/dir.c b/bluesky/dir.c index f279eb6..cd4ee1d 100644 --- a/bluesky/dir.c +++ b/bluesky/dir.c @@ -186,6 +186,8 @@ gboolean bluesky_rename(BlueSkyInode *dir1, gchar *name1, if (d1 == NULL) return FALSE; + uint64_t inum = d1->inum; + /* Check that this rename does not cause a directory to be moved into one * of its descendants, as that would create a loop of directories * disconnected from the root. */ @@ -196,8 +198,14 @@ gboolean bluesky_rename(BlueSkyInode *dir1, gchar *name1, return FALSE; bluesky_directory_remove(dir2, name2); + + // TODO: Drop inode reference } + bluesky_directory_remove(dir1, name1); + bluesky_directory_insert(dir2, name2, inum); + + return TRUE; } /* Dump the contents of a directory to stdout. Debugging only. */ diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 70c9a60..0ba7f56 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -609,8 +609,37 @@ rename3res * nfsproc3_rename_3_svc(rename3args *argp, struct svc_req *rqstp) { static rename3res result; + wcc_data *wcc1 = &result.rename3res_u.res.fromdir_wcc; + wcc_data *wcc2 = &result.rename3res_u.res.todir_wcc; + memset(wcc1, 0, sizeof(*wcc1)); + memset(wcc2, 0, sizeof(*wcc2)); - result.status = NFS3ERR_NOTSUPP; + BlueSkyInode *dir1 = lookup_fh(&argp->from.dir); + if (dir1 == NULL) { + result.status = NFS3ERR_STALE; + return &result; + } + encode_pre_wcc(wcc1, dir1); + + BlueSkyInode *dir2 = lookup_fh(&argp->to.dir); + if (dir2 == NULL) { + result.status = NFS3ERR_STALE; + return &result; + } + encode_pre_wcc(wcc2, dir1); + + gboolean status = bluesky_rename(dir1, argp->from.name, + dir2, argp->to.name, + TRUE, TRUE); + + wcc1->after.present = TRUE; + encode_fattr3(&wcc1->after.post_op_attr_u.attributes, dir1); + wcc2->after.present = TRUE; + encode_fattr3(&wcc2->after.post_op_attr_u.attributes, dir2); + if (status) + result.status = NFS3_OK; + else + result.status = NFS3ERR_PERM; return &result; }