diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-25 15:37:29 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-25 15:37:29 -0400 |
commit | ed1e6211a0a134ff23592c6f057af982ad5dab52 (patch) | |
tree | b3485dbf3c041e40ab485b8307fb53f7154330c6 /fs/nfs/delegation.c | |
parent | 73ca1001ed6881b476e8252adcd0eede1ea368ea (diff) |
NFSv4: Don't use the delegation->inode in nfs_mark_return_delegation()
nfs_mark_return_delegation() is usually called without any locking, and
so it is not safe to dereference delegation->inode. Since the inode is
only used to discover the nfs_client anyway, it makes more sense to
have the callers pass a valid pointer to the nfs_server as a parameter.
Reported-by: Ian Kent <raven@themaw.net>
Cc: stable@kernel.org
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index dd25c2aec375..321a66bc3846 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -398,12 +398,11 @@ int nfs_inode_return_delegation(struct inode *inode) | |||
398 | return err; | 398 | return err; |
399 | } | 399 | } |
400 | 400 | ||
401 | static void nfs_mark_return_delegation(struct nfs_delegation *delegation) | 401 | static void nfs_mark_return_delegation(struct nfs_server *server, |
402 | struct nfs_delegation *delegation) | ||
402 | { | 403 | { |
403 | struct nfs_client *clp = NFS_SERVER(delegation->inode)->nfs_client; | ||
404 | |||
405 | set_bit(NFS_DELEGATION_RETURN, &delegation->flags); | 404 | set_bit(NFS_DELEGATION_RETURN, &delegation->flags); |
406 | set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); | 405 | set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state); |
407 | } | 406 | } |
408 | 407 | ||
409 | /** | 408 | /** |
@@ -441,7 +440,7 @@ static void nfs_mark_return_all_delegation_types(struct nfs_server *server, | |||
441 | if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) | 440 | if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) |
442 | continue; | 441 | continue; |
443 | if (delegation->type & flags) | 442 | if (delegation->type & flags) |
444 | nfs_mark_return_delegation(delegation); | 443 | nfs_mark_return_delegation(server, delegation); |
445 | } | 444 | } |
446 | } | 445 | } |
447 | 446 | ||
@@ -508,7 +507,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server) | |||
508 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 507 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
509 | if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) | 508 | if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) |
510 | continue; | 509 | continue; |
511 | nfs_mark_return_delegation(delegation); | 510 | nfs_mark_return_delegation(server, delegation); |
512 | } | 511 | } |
513 | } | 512 | } |
514 | 513 | ||
@@ -539,7 +538,8 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp) | |||
539 | int nfs_async_inode_return_delegation(struct inode *inode, | 538 | int nfs_async_inode_return_delegation(struct inode *inode, |
540 | const nfs4_stateid *stateid) | 539 | const nfs4_stateid *stateid) |
541 | { | 540 | { |
542 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | 541 | struct nfs_server *server = NFS_SERVER(inode); |
542 | struct nfs_client *clp = server->nfs_client; | ||
543 | struct nfs_delegation *delegation; | 543 | struct nfs_delegation *delegation; |
544 | 544 | ||
545 | rcu_read_lock(); | 545 | rcu_read_lock(); |
@@ -549,7 +549,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, | |||
549 | rcu_read_unlock(); | 549 | rcu_read_unlock(); |
550 | return -ENOENT; | 550 | return -ENOENT; |
551 | } | 551 | } |
552 | nfs_mark_return_delegation(delegation); | 552 | nfs_mark_return_delegation(server, delegation); |
553 | rcu_read_unlock(); | 553 | rcu_read_unlock(); |
554 | 554 | ||
555 | nfs_delegation_run_state_manager(clp); | 555 | nfs_delegation_run_state_manager(clp); |