Loading fs/nfs/callback_proc.c +12 −7 Original line number Diff line number Diff line Loading @@ -112,7 +112,8 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, * TODO: keep track of all layouts (and delegations) in a hash table * hashed by filehandle. */ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh) static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh, nfs4_stateid *stateid) { struct nfs_server *server; struct inode *ino; Loading @@ -120,17 +121,19 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { list_for_each_entry(lo, &server->layouts, plh_layouts) { if (!nfs4_stateid_match_other(&lo->plh_stateid, stateid)) continue; if (nfs_compare_fh(fh, &NFS_I(lo->plh_inode)->fh)) continue; ino = igrab(lo->plh_inode); if (!ino) continue; break; spin_lock(&ino->i_lock); /* Is this layout in the process of being freed? */ if (NFS_I(ino)->layout != lo) { spin_unlock(&ino->i_lock); iput(ino); continue; break; } pnfs_get_layout_hdr(lo); spin_unlock(&ino->i_lock); Loading @@ -141,13 +144,14 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, return NULL; } static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh) static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh, nfs4_stateid *stateid) { struct pnfs_layout_hdr *lo; spin_lock(&clp->cl_lock); rcu_read_lock(); lo = get_layout_by_fh_locked(clp, fh); lo = get_layout_by_fh_locked(clp, fh, stateid); rcu_read_unlock(); spin_unlock(&clp->cl_lock); Loading @@ -162,9 +166,9 @@ static u32 initiate_file_draining(struct nfs_client *clp, u32 rv = NFS4ERR_NOMATCHING_LAYOUT; LIST_HEAD(free_me_list); lo = get_layout_by_fh(clp, &args->cbl_fh); lo = get_layout_by_fh(clp, &args->cbl_fh, &args->cbl_stateid); if (!lo) return NFS4ERR_NOMATCHING_LAYOUT; goto out; ino = lo->plh_inode; spin_lock(&ino->i_lock); Loading @@ -179,6 +183,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_free_lseg_list(&free_me_list); pnfs_put_layout_hdr(lo); iput(ino); out: return rv; } Loading fs/nfs/dir.c +49 −6 Original line number Diff line number Diff line Loading @@ -69,21 +69,28 @@ const struct address_space_operations nfs_dir_aops = { static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred) { struct nfs_inode *nfsi = NFS_I(dir); struct nfs_open_dir_context *ctx; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (ctx != NULL) { ctx->duped = 0; ctx->attr_gencount = NFS_I(dir)->attr_gencount; ctx->attr_gencount = nfsi->attr_gencount; ctx->dir_cookie = 0; ctx->dup_cookie = 0; ctx->cred = get_rpccred(cred); spin_lock(&dir->i_lock); list_add(&ctx->list, &nfsi->open_files); spin_unlock(&dir->i_lock); return ctx; } return ERR_PTR(-ENOMEM); } static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx) static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx) { spin_lock(&dir->i_lock); list_del(&ctx->list); spin_unlock(&dir->i_lock); put_rpccred(ctx->cred); kfree(ctx); } Loading Loading @@ -126,7 +133,7 @@ nfs_opendir(struct inode *inode, struct file *filp) static int nfs_closedir(struct inode *inode, struct file *filp) { put_nfs_open_dir_context(filp->private_data); put_nfs_open_dir_context(filp->f_path.dentry->d_inode, filp->private_data); return 0; } Loading Loading @@ -437,6 +444,22 @@ void nfs_advise_use_readdirplus(struct inode *dir) set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags); } /* * This function is mainly for use by nfs_getattr(). * * If this is an 'ls -l', we want to force use of readdirplus. * Do this by checking if there is an active file descriptor * and calling nfs_advise_use_readdirplus, then forcing a * cache flush. */ void nfs_force_use_readdirplus(struct inode *dir) { if (!list_empty(&NFS_I(dir)->open_files)) { nfs_advise_use_readdirplus(dir); nfs_zap_mapping(dir, dir->i_mapping); } } static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { Loading Loading @@ -815,6 +838,17 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc) goto out; } static bool nfs_dir_mapping_need_revalidate(struct inode *dir) { struct nfs_inode *nfsi = NFS_I(dir); if (nfs_attribute_cache_expired(dir)) return true; if (nfsi->cache_validity & NFS_INO_INVALID_DATA) return true; return false; } /* The file offset position represents the dirent entry number. A last cookie cache takes care of the common case of reading the whole directory. Loading Loading @@ -847,7 +881,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0; nfs_block_sillyrename(dentry); if (ctx->pos == 0 || nfs_attribute_cache_expired(inode)) if (ctx->pos == 0 || nfs_dir_mapping_need_revalidate(inode)) res = nfs_revalidate_mapping(inode, file->f_mapping); if (res < 0) goto out; Loading Loading @@ -1906,6 +1940,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct dentry *dentry = NULL, *rehash = NULL; struct rpc_task *task; int error = -EBUSY; dfprintk(VFS, "NFS: rename(%pd2 -> %pd2, ct=%d)\n", Loading Loading @@ -1953,8 +1988,16 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_inode != NULL) NFS_PROTO(new_inode)->return_delegation(new_inode); error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL); if (IS_ERR(task)) { error = PTR_ERR(task); goto out; } error = rpc_wait_for_completion_task(task); if (error == 0) error = task->tk_status; rpc_put_task(task); nfs_mark_for_revalidate(old_inode); out: if (rehash) Loading fs/nfs/inode.c +27 −7 Original line number Diff line number Diff line Loading @@ -588,6 +588,25 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) } EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); static void nfs_request_parent_use_readdirplus(struct dentry *dentry) { struct dentry *parent; parent = dget_parent(dentry); nfs_force_use_readdirplus(parent->d_inode); dput(parent); } static bool nfs_need_revalidate_inode(struct inode *inode) { if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) return true; if (nfs_attribute_cache_expired(inode)) return true; return false; } int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; Loading Loading @@ -616,10 +635,13 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) need_atime = 0; if (need_atime) err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); else err = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (need_atime || nfs_need_revalidate_inode(inode)) { struct nfs_server *server = NFS_SERVER(inode); if (server->caps & NFS_CAP_READDIRPLUS) nfs_request_parent_use_readdirplus(dentry); err = __nfs_revalidate_inode(server, inode); } if (!err) { generic_fillattr(inode, stat); stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); Loading Loading @@ -961,9 +983,7 @@ int nfs_attribute_cache_expired(struct inode *inode) */ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) { if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) && !nfs_attribute_cache_expired(inode)) if (!nfs_need_revalidate_inode(inode)) return NFS_STALE(inode) ? -ESTALE : 0; return __nfs_revalidate_inode(server, inode); } Loading fs/nfs/internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,7 @@ extern struct nfs_client *nfs_init_client(struct nfs_client *clp, const char *ip_addr); /* dir.c */ extern void nfs_force_use_readdirplus(struct inode *dir); extern unsigned long nfs_access_cache_count(struct shrinker *shrink, struct shrink_control *sc); extern unsigned long nfs_access_cache_scan(struct shrinker *shrink, Loading Loading @@ -474,6 +475,13 @@ extern int nfs_migrate_page(struct address_space *, #define nfs_migrate_page NULL #endif /* unlink.c */ extern struct rpc_task * nfs_async_rename(struct inode *old_dir, struct inode *new_dir, struct dentry *old_dentry, struct dentry *new_dentry, void (*complete)(struct rpc_task *, struct nfs_renamedata *)); extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); /* direct.c */ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, struct nfs_direct_req *dreq); Loading fs/nfs/nfs3proc.c +0 −36 Original line number Diff line number Diff line Loading @@ -477,41 +477,6 @@ nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir, return 1; } static int nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *new_dir, struct qstr *new_name) { struct nfs_renameargs arg = { .old_dir = NFS_FH(old_dir), .old_name = old_name, .new_dir = NFS_FH(new_dir), .new_name = new_name, }; struct nfs_renameres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; int status = -ENOMEM; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); res.old_fattr = nfs_alloc_fattr(); res.new_fattr = nfs_alloc_fattr(); if (res.old_fattr == NULL || res.new_fattr == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); nfs_post_op_update_inode(old_dir, res.old_fattr); nfs_post_op_update_inode(new_dir, res.new_fattr); out: nfs_free_fattr(res.old_fattr); nfs_free_fattr(res.new_fattr); dprintk("NFS reply rename: %d\n", status); return status; } static int nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { Loading Loading @@ -967,7 +932,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .unlink_setup = nfs3_proc_unlink_setup, .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare, .unlink_done = nfs3_proc_unlink_done, .rename = nfs3_proc_rename, .rename_setup = nfs3_proc_rename_setup, .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare, .rename_done = nfs3_proc_rename_done, Loading Loading
fs/nfs/callback_proc.c +12 −7 Original line number Diff line number Diff line Loading @@ -112,7 +112,8 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, * TODO: keep track of all layouts (and delegations) in a hash table * hashed by filehandle. */ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh) static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh, nfs4_stateid *stateid) { struct nfs_server *server; struct inode *ino; Loading @@ -120,17 +121,19 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { list_for_each_entry(lo, &server->layouts, plh_layouts) { if (!nfs4_stateid_match_other(&lo->plh_stateid, stateid)) continue; if (nfs_compare_fh(fh, &NFS_I(lo->plh_inode)->fh)) continue; ino = igrab(lo->plh_inode); if (!ino) continue; break; spin_lock(&ino->i_lock); /* Is this layout in the process of being freed? */ if (NFS_I(ino)->layout != lo) { spin_unlock(&ino->i_lock); iput(ino); continue; break; } pnfs_get_layout_hdr(lo); spin_unlock(&ino->i_lock); Loading @@ -141,13 +144,14 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, return NULL; } static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh) static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh, nfs4_stateid *stateid) { struct pnfs_layout_hdr *lo; spin_lock(&clp->cl_lock); rcu_read_lock(); lo = get_layout_by_fh_locked(clp, fh); lo = get_layout_by_fh_locked(clp, fh, stateid); rcu_read_unlock(); spin_unlock(&clp->cl_lock); Loading @@ -162,9 +166,9 @@ static u32 initiate_file_draining(struct nfs_client *clp, u32 rv = NFS4ERR_NOMATCHING_LAYOUT; LIST_HEAD(free_me_list); lo = get_layout_by_fh(clp, &args->cbl_fh); lo = get_layout_by_fh(clp, &args->cbl_fh, &args->cbl_stateid); if (!lo) return NFS4ERR_NOMATCHING_LAYOUT; goto out; ino = lo->plh_inode; spin_lock(&ino->i_lock); Loading @@ -179,6 +183,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_free_lseg_list(&free_me_list); pnfs_put_layout_hdr(lo); iput(ino); out: return rv; } Loading
fs/nfs/dir.c +49 −6 Original line number Diff line number Diff line Loading @@ -69,21 +69,28 @@ const struct address_space_operations nfs_dir_aops = { static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred) { struct nfs_inode *nfsi = NFS_I(dir); struct nfs_open_dir_context *ctx; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (ctx != NULL) { ctx->duped = 0; ctx->attr_gencount = NFS_I(dir)->attr_gencount; ctx->attr_gencount = nfsi->attr_gencount; ctx->dir_cookie = 0; ctx->dup_cookie = 0; ctx->cred = get_rpccred(cred); spin_lock(&dir->i_lock); list_add(&ctx->list, &nfsi->open_files); spin_unlock(&dir->i_lock); return ctx; } return ERR_PTR(-ENOMEM); } static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx) static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx) { spin_lock(&dir->i_lock); list_del(&ctx->list); spin_unlock(&dir->i_lock); put_rpccred(ctx->cred); kfree(ctx); } Loading Loading @@ -126,7 +133,7 @@ nfs_opendir(struct inode *inode, struct file *filp) static int nfs_closedir(struct inode *inode, struct file *filp) { put_nfs_open_dir_context(filp->private_data); put_nfs_open_dir_context(filp->f_path.dentry->d_inode, filp->private_data); return 0; } Loading Loading @@ -437,6 +444,22 @@ void nfs_advise_use_readdirplus(struct inode *dir) set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags); } /* * This function is mainly for use by nfs_getattr(). * * If this is an 'ls -l', we want to force use of readdirplus. * Do this by checking if there is an active file descriptor * and calling nfs_advise_use_readdirplus, then forcing a * cache flush. */ void nfs_force_use_readdirplus(struct inode *dir) { if (!list_empty(&NFS_I(dir)->open_files)) { nfs_advise_use_readdirplus(dir); nfs_zap_mapping(dir, dir->i_mapping); } } static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { Loading Loading @@ -815,6 +838,17 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc) goto out; } static bool nfs_dir_mapping_need_revalidate(struct inode *dir) { struct nfs_inode *nfsi = NFS_I(dir); if (nfs_attribute_cache_expired(dir)) return true; if (nfsi->cache_validity & NFS_INO_INVALID_DATA) return true; return false; } /* The file offset position represents the dirent entry number. A last cookie cache takes care of the common case of reading the whole directory. Loading Loading @@ -847,7 +881,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0; nfs_block_sillyrename(dentry); if (ctx->pos == 0 || nfs_attribute_cache_expired(inode)) if (ctx->pos == 0 || nfs_dir_mapping_need_revalidate(inode)) res = nfs_revalidate_mapping(inode, file->f_mapping); if (res < 0) goto out; Loading Loading @@ -1906,6 +1940,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct dentry *dentry = NULL, *rehash = NULL; struct rpc_task *task; int error = -EBUSY; dfprintk(VFS, "NFS: rename(%pd2 -> %pd2, ct=%d)\n", Loading Loading @@ -1953,8 +1988,16 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_inode != NULL) NFS_PROTO(new_inode)->return_delegation(new_inode); error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL); if (IS_ERR(task)) { error = PTR_ERR(task); goto out; } error = rpc_wait_for_completion_task(task); if (error == 0) error = task->tk_status; rpc_put_task(task); nfs_mark_for_revalidate(old_inode); out: if (rehash) Loading
fs/nfs/inode.c +27 −7 Original line number Diff line number Diff line Loading @@ -588,6 +588,25 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) } EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); static void nfs_request_parent_use_readdirplus(struct dentry *dentry) { struct dentry *parent; parent = dget_parent(dentry); nfs_force_use_readdirplus(parent->d_inode); dput(parent); } static bool nfs_need_revalidate_inode(struct inode *inode) { if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) return true; if (nfs_attribute_cache_expired(inode)) return true; return false; } int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; Loading Loading @@ -616,10 +635,13 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) need_atime = 0; if (need_atime) err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); else err = nfs_revalidate_inode(NFS_SERVER(inode), inode); if (need_atime || nfs_need_revalidate_inode(inode)) { struct nfs_server *server = NFS_SERVER(inode); if (server->caps & NFS_CAP_READDIRPLUS) nfs_request_parent_use_readdirplus(dentry); err = __nfs_revalidate_inode(server, inode); } if (!err) { generic_fillattr(inode, stat); stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); Loading Loading @@ -961,9 +983,7 @@ int nfs_attribute_cache_expired(struct inode *inode) */ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) { if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) && !nfs_attribute_cache_expired(inode)) if (!nfs_need_revalidate_inode(inode)) return NFS_STALE(inode) ? -ESTALE : 0; return __nfs_revalidate_inode(server, inode); } Loading
fs/nfs/internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,7 @@ extern struct nfs_client *nfs_init_client(struct nfs_client *clp, const char *ip_addr); /* dir.c */ extern void nfs_force_use_readdirplus(struct inode *dir); extern unsigned long nfs_access_cache_count(struct shrinker *shrink, struct shrink_control *sc); extern unsigned long nfs_access_cache_scan(struct shrinker *shrink, Loading Loading @@ -474,6 +475,13 @@ extern int nfs_migrate_page(struct address_space *, #define nfs_migrate_page NULL #endif /* unlink.c */ extern struct rpc_task * nfs_async_rename(struct inode *old_dir, struct inode *new_dir, struct dentry *old_dentry, struct dentry *new_dentry, void (*complete)(struct rpc_task *, struct nfs_renamedata *)); extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); /* direct.c */ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, struct nfs_direct_req *dreq); Loading
fs/nfs/nfs3proc.c +0 −36 Original line number Diff line number Diff line Loading @@ -477,41 +477,6 @@ nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir, return 1; } static int nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *new_dir, struct qstr *new_name) { struct nfs_renameargs arg = { .old_dir = NFS_FH(old_dir), .old_name = old_name, .new_dir = NFS_FH(new_dir), .new_name = new_name, }; struct nfs_renameres res; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], .rpc_argp = &arg, .rpc_resp = &res, }; int status = -ENOMEM; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); res.old_fattr = nfs_alloc_fattr(); res.new_fattr = nfs_alloc_fattr(); if (res.old_fattr == NULL || res.new_fattr == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); nfs_post_op_update_inode(old_dir, res.old_fattr); nfs_post_op_update_inode(new_dir, res.new_fattr); out: nfs_free_fattr(res.old_fattr); nfs_free_fattr(res.new_fattr); dprintk("NFS reply rename: %d\n", status); return status; } static int nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) { Loading Loading @@ -967,7 +932,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .unlink_setup = nfs3_proc_unlink_setup, .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare, .unlink_done = nfs3_proc_unlink_done, .rename = nfs3_proc_rename, .rename_setup = nfs3_proc_rename_setup, .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare, .rename_done = nfs3_proc_rename_done, Loading