diff mbox

[v3,24/25] sunrpc: Change how dentry's d_lock field is accessed

Message ID 1372883132-23410-1-git-send-email-Waiman.Long@hp.com
State Not Applicable, archived
Delegated to: David Miller
Headers show

Commit Message

Waiman Long July 3, 2013, 8:25 p.m. UTC
Because of the changes made in dcache.h header file, files that
use the d_lock field of the dentry structure need to be changed
accordingly. All the d_lock's spin_lock() and spin_unlock() calls
are replaced by the corresponding d_lock() and d_unlock() calls.
There is no change in logic and everything should just work.

Signed-off-by: Waiman Long <Waiman.Long@hp.com>
---
 net/sunrpc/rpc_pipe.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

Comments

Al Viro July 4, 2013, 4:20 a.m. UTC | #1
On Wed, Jul 03, 2013 at 04:25:32PM -0400, Waiman Long wrote:
> There is no change in logic and everything should just work.

> -		spin_lock(&file->f_path.dentry->d_lock);
> +		d_lock(file->f_path.dentry);
>  		if (!d_unhashed(file->f_path.dentry))
>  			clnt = RPC_I(inode)->private;
>  		if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {
> -			spin_unlock(&file->f_path.dentry->d_lock);
> +			d_unlock(file->f_path.dentry);

Could somebody explain WTF is being protected here?  It's not ->private -
that gets set (and, more importantly, cleared) without ->d_lock in sight.
Trond, that seems to be your code from about three years ago (introduced
in "SUNRPC: Fix a race in rpc_info_open").  What's going on there?
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Trond Myklebust July 8, 2013, 4:53 p.m. UTC | #2
On Thu, 2013-07-04 at 05:20 +0100, Al Viro wrote:
> On Wed, Jul 03, 2013 at 04:25:32PM -0400, Waiman Long wrote:

> > There is no change in logic and everything should just work.

> 

> > -		spin_lock(&file->f_path.dentry->d_lock);

> > +		d_lock(file->f_path.dentry);

> >  		if (!d_unhashed(file->f_path.dentry))

> >  			clnt = RPC_I(inode)->private;

> >  		if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {

> > -			spin_unlock(&file->f_path.dentry->d_lock);

> > +			d_unlock(file->f_path.dentry);

> 

> Could somebody explain WTF is being protected here?  It's not ->private -

> that gets set (and, more importantly, cleared) without ->d_lock in sight.

> Trond, that seems to be your code from about three years ago (introduced

> in "SUNRPC: Fix a race in rpc_info_open").  What's going on there?


AFAICR we're using the fact that the dentry will remain hashed until
we're in the process of freeing up the rpc_client. By testing that the
dentry is hashed under the dentry->d_lock, we are assured that the
non-NULL 'clnt' is still pointing to a valid rpc_client, and that it is
safe to access clnt->cl_count.

-- 
Trond Myklebust
Linux NFS client maintainer

NetApp
Trond.Myklebust@netapp.com
www.netapp.com
diff mbox

Patch

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e7ce4b3..58bc128 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -427,14 +427,14 @@  rpc_info_open(struct inode *inode, struct file *file)
 	if (!ret) {
 		struct seq_file *m = file->private_data;
 
-		spin_lock(&file->f_path.dentry->d_lock);
+		d_lock(file->f_path.dentry);
 		if (!d_unhashed(file->f_path.dentry))
 			clnt = RPC_I(inode)->private;
 		if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) {
-			spin_unlock(&file->f_path.dentry->d_lock);
+			d_unlock(file->f_path.dentry);
 			m->private = clnt;
 		} else {
-			spin_unlock(&file->f_path.dentry->d_lock);
+			d_unlock(file->f_path.dentry);
 			single_release(inode, file);
 			ret = -EINVAL;
 		}