public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] NFSv4 - do not accept an incompatible delegation.
@ 2015-06-22  7:53 NeilBrown
  2015-06-22 11:41 ` Trond Myklebust
  0 siblings, 1 reply; 7+ messages in thread
From: NeilBrown @ 2015-06-22  7:53 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Linux NFS Mailing List


Hi,
 this is my proposed solution to the problem I outlined in
   NFSv4 state management issue - Linux disagrees with Netapp.
 I haven't tested it yet (no direct access to the Netapp), but
 I'll try to get some testing done.  RFC for now.

NeilBrown


When opening a file, nfs _nfs4_do_open() will return any
incompatible delegation, meaning if the delegation held for
that file does not give all the permissions required, it is
returned.
This is because various places assume that the current delegation
provides all necessary access.

However when a delegation is received, it is not validated in the
same way so it is possible to, for example, hold a read-only
delegation while the file is open write-only.
When that delegation is recalled, the NFS client will try to
reclaim the write-only open, and that will fail.

So when considering a new delegation, reject it if it is incompatible
with any open.

Signed-off-by: NeilBrown <neilb@suse.de>
URL: https://bugzilla.suse.com/show_bug.cgi?id=934203

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 029d688..92cecd3 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -377,6 +377,25 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 				old_delegation, clp);
 		if (freeme == NULL)
 			goto out;
+	} else {
+		/* Don't accept an incompatible delegation */
+		int incompatible = 0;
+		struct nfs_inode *nfsi = NFS_I(inode);
+		struct nfs4_state *state;
+
+		spin_lock(&inode->i_lock);
+		list_for_each_entry(state, &nfsi->open_states, inode_states) {
+			if ((state->state & delegation->type) != state->state) {
+				incompatible = 1;
+				break;
+			}
+		}
+		spin_unlock(&inode->i_lock);
+		if (incompatible) {
+			freeme = delegation;
+			delegation = NULL;
+			goto out;
+		}
 	}
 	list_add_tail_rcu(&delegation->super_list, &server->delegations);
 	rcu_assign_pointer(nfsi->delegation, delegation);
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-06-29  4:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-22  7:53 [PATCH/RFC] NFSv4 - do not accept an incompatible delegation NeilBrown
2015-06-22 11:41 ` Trond Myklebust
2015-06-22 21:04   ` NeilBrown
2015-06-22 21:34     ` Trond Myklebust
2015-06-23  1:07       ` NeilBrown
2015-06-23  1:16         ` Trond Myklebust
2015-06-29  4:24           ` NeilBrown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox