From: Trond Myklebust <trondmy@gmail.com> To: linux-nfs@vger.kernel.org Subject: [PATCH 11/19] pnfs: Add LAYOUTGET to OPEN of an existing file Date: Wed, 30 May 2018 14:05:45 -0400 Message-ID: <20180530180553.38769-12-trond.myklebust@hammerspace.com> (raw) In-Reply-To: <20180530180553.38769-11-trond.myklebust@hammerspace.com> From: Fred Isaman <fred.isaman@gmail.com> Signed-off-by: Fred Isaman <fred.isaman@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- fs/nfs/pnfs.c | 90 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 17 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index a0a2484c3aed..258b68110277 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -921,9 +921,9 @@ pnfs_find_server(struct inode *inode, struct nfs_open_context *ctx) { struct nfs_server *server; - if (inode) + if (inode) { server = NFS_SERVER(inode); - else { + } else { struct dentry *parent_dir = dget_parent(ctx->dentry); server = NFS_SERVER(parent_dir->d_inode); dput(parent_dir); @@ -1686,6 +1686,22 @@ static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo) wake_up_bit(bitlock, NFS_LAYOUT_FIRST_LAYOUTGET); } +static void _add_to_server_list(struct pnfs_layout_hdr *lo, + struct nfs_server *server) +{ + if (list_empty(&lo->plh_layouts)) { + struct nfs_client *clp = server->nfs_client; + + /* The lo must be on the clp list if there is any + * chance of a CB_LAYOUTRECALL(FILE) coming in. + */ + spin_lock(&clp->cl_lock); + if (list_empty(&lo->plh_layouts)) + list_add_tail(&lo->plh_layouts, &server->layouts); + spin_unlock(&clp->cl_lock); + } +} + /* * Layout segment is retreived from the server if not cached. * The appropriate layout segment is referenced and returned to the caller. @@ -1836,15 +1852,7 @@ pnfs_update_layout(struct inode *ino, atomic_inc(&lo->plh_outstanding); spin_unlock(&ino->i_lock); - if (list_empty(&lo->plh_layouts)) { - /* The lo must be on the clp list if there is any - * chance of a CB_LAYOUTRECALL(FILE) coming in. - */ - spin_lock(&clp->cl_lock); - if (list_empty(&lo->plh_layouts)) - list_add_tail(&lo->plh_layouts, &server->layouts); - spin_unlock(&clp->cl_lock); - } + _add_to_server_list(lo, server); pg_offset = arg.offset & ~PAGE_MASK; if (pg_offset) { @@ -1943,12 +1951,62 @@ pnfs_sanity_check_layout_range(struct pnfs_layout_range *range) return true; } +static struct pnfs_layout_hdr * +_pnfs_grab_empty_layout(struct inode *ino, struct nfs_open_context *ctx) +{ + struct pnfs_layout_hdr *lo; + + spin_lock(&ino->i_lock); + lo = pnfs_find_alloc_layout(ino, ctx, GFP_KERNEL); + if (!lo) + goto out_unlock; + if (!test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags)) + goto out_unlock; + if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) + goto out_unlock; + if (pnfs_layoutgets_blocked(lo)) + goto out_unlock; + if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags)) + goto out_unlock; + atomic_inc(&lo->plh_outstanding); + spin_unlock(&ino->i_lock); + _add_to_server_list(lo, NFS_SERVER(ino)); + return lo; + +out_unlock: + spin_unlock(&ino->i_lock); + pnfs_put_layout_hdr(lo); + return NULL; +} + extern const nfs4_stateid current_stateid; static void _lgopen_prepare_attached(struct nfs4_opendata *data, struct nfs_open_context *ctx) { - /* STUB */ + struct inode *ino = data->dentry->d_inode; + struct pnfs_layout_range rng = { + .iomode = (data->o_arg.fmode & FMODE_WRITE) ? + IOMODE_RW: IOMODE_READ, + .offset = 0, + .length = NFS4_MAX_UINT64, + }; + struct nfs4_layoutget *lgp; + struct pnfs_layout_hdr *lo; + + lo = _pnfs_grab_empty_layout(ino, ctx); + if (!lo) + return; + lgp = pnfs_alloc_init_layoutget_args(ino, ctx, ¤t_stateid, + &rng, GFP_KERNEL); + if (!lgp) { + pnfs_clear_first_layoutget(lo); + pnfs_put_layout_hdr(lo); + return; + } + data->lgp = lgp; + data->o_arg.lg_args = &lgp->args; + data->o_res.lg_res = &lgp->res; } static void _lgopen_prepare_floating(struct nfs4_opendata *data, @@ -1996,11 +2054,9 @@ void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp, if (!lgp || lgp->res.layoutp->len == 0) return; if (!lgp->args.inode) { - /* Need to grab lo */ - spin_lock(&ino->i_lock); - lo = pnfs_find_alloc_layout(ino, ctx, GFP_KERNEL); - atomic_inc(&lo->plh_outstanding); - spin_unlock(&ino->i_lock); + lo = _pnfs_grab_empty_layout(ino, ctx); + if (!lo) + return; lgp->args.inode = ino; } else lo = NFS_I(lgp->args.inode)->layout; -- 2.17.0
next prev parent reply index Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-30 18:05 [PATCH 00/19] Layoutget on OPEN Trond Myklebust 2018-05-30 18:05 ` [PATCH 01/19] pnfs: Remove redundant assignment from nfs4_proc_layoutget() Trond Myklebust 2018-05-30 18:05 ` [PATCH 02/19] pnfs: Store return value of decode_layoutget for later processing Trond Myklebust 2018-05-30 18:05 ` [PATCH 03/19] NFS4: move ctx into nfs4_run_open_task Trond Myklebust 2018-05-30 18:05 ` [PATCH 04/19] pnfs: Add layout driver flag PNFS_LAYOUTGET_ON_OPEN Trond Myklebust 2018-05-30 18:05 ` [PATCH 05/19] pnfs: refactor send_layoutget Trond Myklebust 2018-05-30 18:05 ` [PATCH 06/19] pnfs: move allocations out of nfs4_proc_layoutget Trond Myklebust 2018-05-30 18:05 ` [PATCH 07/19] pnfs: Add conditional encode/decode of LAYOUTGET within OPEN compound Trond Myklebust 2018-05-30 18:05 ` [PATCH 08/19] pnfs: Move nfs4_opendata into nfs4_fs.h Trond Myklebust 2018-05-30 18:05 ` [PATCH 09/19] pnfs: Change pnfs_alloc_init_layoutget_args call signature Trond Myklebust 2018-05-30 18:05 ` [PATCH 10/19] pnfs: Add LAYOUTGET to OPEN of a new file Trond Myklebust 2018-05-30 18:05 ` Trond Myklebust [this message] 2018-05-30 18:05 ` [PATCH 12/19] pnfs: Stop attempting LAYOUTGET on OPEN on failure Trond Myklebust 2018-05-30 18:05 ` [PATCH 13/19] pnfs: Add barrier to prevent lgopen using LAYOUTGET during recall Trond Myklebust 2018-05-30 18:05 ` [PATCH 14/19] pnfs: Fix manipulation of NFS_LAYOUT_FIRST_LAYOUTGET Trond Myklebust 2018-05-30 18:05 ` [PATCH 15/19] NFSv4/pnfs: Ensure pnfs_parse_lgopen() won't try to parse uninitialised data Trond Myklebust 2018-05-30 18:05 ` [PATCH 16/19] NFSv4/pnfs: Don't switch off layoutget-on-open for transient errors Trond Myklebust 2018-05-30 18:05 ` [PATCH 17/19] pNFS: Don't send LAYOUTGET on OPEN for read, if we already have cached data Trond Myklebust 2018-05-30 18:05 ` [PATCH 18/19] pnfs: Don't call commit on failed layoutget-on-open Trond Myklebust 2018-05-30 18:05 ` [PATCH 19/19] pnfs: Don't release the sequence slot until we've processed layoutget on open Trond Myklebust 2018-05-30 20:10 ` [PATCH 04/19] pnfs: Add layout driver flag PNFS_LAYOUTGET_ON_OPEN Olga Kornievskaia 2018-05-31 12:40 ` Trond Myklebust 2019-09-06 20:17 ` Olga Kornievskaia 2018-05-30 18:25 ` [PATCH 00/19] Layoutget on OPEN Olga Kornievskaia 2018-05-30 18:36 ` Trond Myklebust 2018-05-30 18:37 ` Olga Kornievskaia 2018-05-30 19:27 ` Olga Kornievskaia 2018-05-30 19:29 ` Olga Kornievskaia 2018-05-30 19:47 ` Olga Kornievskaia 2018-05-30 22:33 ` Trond Myklebust 2018-05-31 18:59 ` J. Bruce Fields 2018-06-01 0:28 ` Trond Myklebust
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180530180553.38769-12-trond.myklebust@hammerspace.com \ --to=trondmy@gmail.com \ --cc=linux-nfs@vger.kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Linux-NFS Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \ linux-nfs@vger.kernel.org public-inbox-index linux-nfs Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs AGPL code for this site: git clone https://public-inbox.org/public-inbox.git