From: Michael Vrable Date: Mon, 28 Dec 2009 01:13:45 +0000 (-0800) Subject: NFS link operation. X-Git-Url: https://git.vrable.net/?a=commitdiff_plain;h=afd70a13376f68a96339efcad957c8b41791e707;p=bluesky.git NFS link operation. --- diff --git a/nfs3/nfs3.c b/nfs3/nfs3.c index 2c0d150..3f8a8d2 100644 --- a/nfs3/nfs3.c +++ b/nfs3/nfs3.c @@ -542,8 +542,54 @@ link3res * nfsproc3_link_3_svc(link3args *argp, struct svc_req *rqstp) { static link3res result; + struct wcc_data wcc; + memset(&wcc, 0, sizeof(wcc)); - result.status = NFS3ERR_NOTSUPP; + BlueSkyInode *inode = lookup_fh(&argp->file); + if (inode == NULL) { + result.status = NFS3ERR_STALE; + result.link3res_u.res.linkdir_wcc = wcc; + return &result; + } + + BlueSkyInode *dir = lookup_fh(&argp->link.dir); + if (dir == NULL) { + result.status = NFS3ERR_STALE; + result.link3res_u.res.linkdir_wcc = wcc; + return &result; + } + + encode_pre_wcc(&wcc, dir); + if (dir->type != BLUESKY_DIRECTORY) { + result.status = NFS3ERR_NOTDIR; + result.link3res_u.res.linkdir_wcc = wcc; + return &result; + } + + if (!validate_filename(argp->link.name) + || strcmp(argp->link.name, ".") == 0 + || strcmp(argp->link.name, "..") == 0 + || bluesky_directory_lookup(dir, argp->link.name) != 0) + { + result.status = NFS3ERR_EXIST; + result.link3res_u.res.linkdir_wcc = wcc; + return &result; + } + + if (!bluesky_directory_insert(dir, argp->link.name, inode->inum)) { + result.status = NFS3ERR_EXIST; + result.link3res_u.res.linkdir_wcc = wcc; + return &result; + } + inode->nlink++; + bluesky_inode_update_ctime(inode, 0); + + result.status = NFS3_OK; + wcc.after.present = TRUE; + encode_fattr3(&wcc.after.post_op_attr_u.attributes, dir); + result.link3res_u.res.file_attributes.present = TRUE; + encode_fattr3(&result.link3res_u.res.file_attributes.post_op_attr_u.attributes, inode); + result.link3res_u.res.linkdir_wcc = wcc; return &result; }