Mostly-working NFS rename support.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Wed, 6 Jan 2010 18:50:57 +0000 (10:50 -0800)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Wed, 6 Jan 2010 18:50:57 +0000 (10:50 -0800)
bluesky/dir.c
nfs3/nfs3.c

index f279eb6..cd4ee1d 100644 (file)
@@ -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. */
index 70c9a60..0ba7f56 100644 (file)
@@ -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;
 }