Patch "staging/lustre/llite: Close atomic_open race with several openers" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
staging/lustre/llite: Close atomic_open race with several openers
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
staging-lustre-llite-close-atomic_open-race-with-several-openers.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
99f1c013194e64d4b67d5d318148303b0e1585e1Mon Sep 17 00:00:00 2001
From: Oleg Drokin <[email protected]>
Date: Thu, 14 Jul 2016 23:40:21 -0400
Subject: staging/lustre/llite: Close atomic_open race with several openers
From: Oleg Drokin <[email protected]>
commit 99f1c013194e64d4b67d5d318148303b0e1585e1 upstream.
Right now, if it's an open of a negative dentry, a race is possible with several openers who all try to instantiate/rehash the same dentry and would hit a BUG_ON in d_add.
But in fact if we got a negative dentry in atomic_open, that means we just revalidated it so no point in talking to MDS at all, just return ENOENT and make the race go away completely.
--- drivers/staging/lustre/lustre/llite/namei.c | 43 +++++++++++++++------------- 1 file changed, 24 insertions(+), 19 deletions(-)
drivers/staging/lustre/lustre/llite/namei.c +24 -19
@@ -391,6 +391,7 @@ static int ll_lookup_it_finish(struct ptstruct inode *inode =NULL ;__u64 bits =0 ;int rc =0 ; +struct dentry *alias;/* NB 1 request reference will be taken away by ll_intent_lock() * when I return
@@ -415,26 +416,12 @@ static int ll_lookup_it_finish(struct pt*/ } -/* Only hash *de if it is unhashed (new dentry). -* Atoimc_open may passing hashed dentries for open. -*/ -if (d_unhashed (*de)) { -struct dentry *alias; - - alias =ll_splice_alias (inode, *de); -if (IS_ERR (alias)) { - rc =PTR_ERR (alias); - goto out; - } - *de = alias; - }else if (!it_disposition (it,DISP_LOOKUP_NEG ) && - !it_disposition (it,DISP_OPEN_CREATE )) { -/* With DISP_OPEN_CREATE dentry will be -* instantiated in ll_create_it. -*/ -LASSERT (!d_inode (*de)); -d_instantiate (*de, inode); + alias =ll_splice_alias (inode, *de); +if (IS_ERR (alias)) { + rc =PTR_ERR (alias); + goto out; } + *de = alias;if (!it_disposition (it,DISP_LOOKUP_NEG )) {/* we have lookup look - unhide dentry */
@@ -590,6 +577,24 @@ static int ll_atomic_open(struct inode * dentry,PFID (ll_inode2fid (dir)), dir, file, open_flags, mode, *opened); +/* Only negative dentries enter here */ +LASSERT (!d_inode (dentry)); + +if (!d_in_lookup (dentry)) { +/* A valid negative dentry that just passed revalidation, +* there's little point to try and open it server-side, +* even though there's a minuscle chance it might succeed. +* Either way it's a valid race to just return -ENOENT here. +*/ +if (!(open_flags &O_CREAT )) +return -ENOENT ; + +/* Otherwise we just unhash it to be rehashed afresh via +* lookup if necessary +*/ +d_drop (dentry); + } + it =kzalloc (sizeof (*it),GFP_NOFS );if (!it)return -ENOMEM ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/sunrpc-fix-infinite-looping-in-rpc_clnt_iterate_for_each_xprt.patch queue-4.7/staging-lustre-llite-close-atomic_open-race-with-several-openers.patch