the nfs4_file can be found via the layout stateid. Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxxxxxx> --- fs/nfsd/nfs4pnfsd.c | 64 ++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/fs/nfsd/nfs4pnfsd.c b/fs/nfsd/nfs4pnfsd.c index 52fd2d1..474c183 100644 --- a/fs/nfsd/nfs4pnfsd.c +++ b/fs/nfsd/nfs4pnfsd.c @@ -259,7 +259,7 @@ struct sbid_tracker { * Returns zero and the layout state in *lsp, or error. */ static __be32 -nfs4_process_layout_stateid(struct nfs4_client *clp, struct nfs4_file *fp, +nfs4_process_layout_stateid(struct nfs4_client *clp, stateid_t *stateid, unsigned char typemask, struct nfs4_layout_state **lsp) { @@ -267,8 +267,8 @@ struct sbid_tracker { __be32 status; struct nfs4_stid *stid; - dprintk("--> %s clp %p fp %p operation stateid=" STATEID_FMT "\n", - __func__, clp, fp, STATEID_VAL(stateid)); + dprintk("--> %s clp %p operation stateid=" STATEID_FMT "\n", + __func__, clp, STATEID_VAL(stateid)); nfs4_assert_state_locked(); status = nfsd4_lookup_stateid(stateid, typemask, &stid, true, @@ -295,10 +295,7 @@ struct sbid_tracker { dprintk("%s: layout stateid=" STATEID_FMT " ref=%d\n", __func__, STATEID_VAL(&ls->ls_stid.sc_stateid), atomic_read(&ls->ls_ref.refcount)); - if (lsp) - *lsp = ls; - else - put_layout_state(ls); + *lsp = ls; out: dprintk("<-- %s status %d\n", __func__, htonl(status)); @@ -920,30 +917,31 @@ struct super_block * { struct inode *ino = current_fh->fh_dentry->d_inode; struct super_block *sb = ino->i_sb; - struct nfs4_file *fp = NULL; struct nfs4_client *clp; + struct nfs4_layout_state *ls = NULL; __be32 nfserr = NFS4_OK; int status = 0; lcp->res.lc_size_chg = 0; nfs4_lock_state(); - fp = find_file(ino); clp = find_confirmed_client((clientid_t *)&lcp->lc_clientid, true, net_generic(SVC_NET(rqstp), nfsd_net_id)); - if (!fp || !clp) { + if (!clp) { nfserr = nfserr_inval; nfs4_unlock_state(); goto out; } - nfserr = nfs4_process_layout_stateid(clp, fp, &lcp->lc_sid, - NFS4_LAYOUT_STID, NULL); + nfserr = nfs4_process_layout_stateid(clp, &lcp->lc_sid, + NFS4_LAYOUT_STID, &ls); nfs4_unlock_state(); if (nfserr) goto out; if (sb->s_pnfs_op->layout_commit) { + struct nfs4_file *fp = ls->ls_file; + nfs4_file_lo_lock(fp); status = sb->s_pnfs_op->layout_commit(ino, &lcp->args, &lcp->res); nfs4_file_lo_unlock(fp); @@ -980,8 +978,11 @@ struct super_block * } out: - if (fp) - put_nfs4_file(fp); + if (ls) { + nfs4_lock_state(); + put_layout_state(ls); + nfs4_unlock_state(); + } return cpu_to_be32(nfserr); } @@ -1255,26 +1256,15 @@ int nfs4_pnfs_return_layout(struct svc_rqst *rqstp, goto out_unlock; if (lrp->args.lr_return_type == RETURN_FILE) { - fp = find_file(ino); - if (!fp) { - dprintk("%s: RETURN_FILE: no nfs4_file for ino %p:%lu\n", - __func__, ino, ino ? ino->i_ino : 0L); - /* If we had a layout on the file the nfs4_file would - * be referenced and we should have found it. Since we - * don't then it means all layouts were ROC and at this - * point we returned all of them on file close. - */ - goto out_unlock; - } - /* Check the stateid */ dprintk("%s PROCESS LO_STATEID inode %p\n", __func__, ino); - status = nfs4_process_layout_stateid(clp, fp, + status = nfs4_process_layout_stateid(clp, (stateid_t *)&lrp->args.lr_sid, NFS4_LAYOUT_STID, &ls); nfs4_unlock_state(); if (status) goto out; + fp = ls->ls_file; layouts_found = pnfs_return_file_layouts(lrp, ls, 0, &lo_destroy_list); } else { @@ -1283,20 +1273,14 @@ int nfs4_pnfs_return_layout(struct svc_rqst *rqstp, 0, &lo_destroy_list); } - dprintk("pNFS %s: clp %p fp %p layout_type 0x%x iomode %d " + dprintk("pNFS %s: clp %p fp %p ino %lu layout_type 0x%x iomode %d " "return_type %d fsid 0x%llx offset %llu length %llu: " "layouts_found %d\n", - __func__, clp, fp, lrp->args.lr_seg.layout_type, + __func__, clp, fp, ino->i_ino, lrp->args.lr_seg.layout_type, lrp->args.lr_seg.iomode, lrp->args.lr_return_type, ex_fsid, lrp->args.lr_seg.offset, lrp->args.lr_seg.length, layouts_found); - nfs4_lock_state(); - if (ls) - put_layout_state(ls); - destroy_layout_list(&lo_destroy_list); - nfs4_unlock_state(); - /* update layoutrecalls * note: for RETURN_{FSID,ALL}, fp may be NULL */ @@ -1316,10 +1300,14 @@ int nfs4_pnfs_return_layout(struct svc_rqst *rqstp, layoutrecall_list_done_put(&lo_destroy_list); -out: - if (fp) - put_nfs4_file(fp); + /* put_layout_state here as we need to keep a reference on ls_file */ + nfs4_lock_state(); + if (ls) + put_layout_state(ls); + destroy_layout_list(&lo_destroy_list); + nfs4_unlock_state(); +out: dprintk("pNFS %s: exit status %d\n", __func__, status); return status; out_unlock: -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html