patch "staging/lustre/llite: Close atomic_open race with several openers" added to staging-linus
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 my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
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
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
@@ -388,6 +388,7 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request,struct 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
@@ -412,26 +413,12 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request,*/ } -/* 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 */
@@ -587,6 +574,24 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, 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 ;
Signature · 1 line
2.9.3