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. */
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. */
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;
}