aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2005-01-04 05:51:07 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:51:07 -0800
commit95402a16ada69cfd8180961a33540e8edfb63f05 (patch)
tree8ba22f6e33478a7e48e724abc2a3a63eaba4b072 /fs
parent0fe1a2eabab2d0fc1fb5c69326f6d809b194f28b (diff)
downloadhistory-95402a16ada69cfd8180961a33540e8edfb63f05.tar.gz
[PATCH] knfsd: helper functions for deciding to grant a delegation.
Signed-off-by: Andy Adamson <andros@citi.umich.edu> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4state.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 29f52bd05ef196..313acf87731983 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1504,6 +1504,43 @@ out:
}
static int
+nfs4_deleg_conflict(u32 share, u32 dtype)
+{
+ return (((share & NFS4_SHARE_ACCESS_WRITE) &&
+ dtype == NFS4_OPEN_DELEGATE_READ) ||
+ ((share & NFS4_SHARE_ACCESS_READ) &&
+ dtype == NFS4_OPEN_DELEGATE_WRITE));
+}
+
+#define DONT_DELEGATE 8
+
+/*
+ * nfs4_check_deleg_recall()
+ *
+ * Test any delegation that is currently within an incompleted recalled
+ * state, and return NFSERR_DELAY for conflicting open share.
+ * flag is set to DONT_DELEGATE for shares that match the deleg type.
+ */
+static int
+nfs4_check_deleg_recall(struct nfs4_file *fp, struct nfsd4_open *op, int *flag)
+{
+ struct nfs4_delegation *dp;
+ int status = 0;
+
+ list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
+ dprintk("NFSD: found delegation %p with dl_state %d\n",
+ dp, atomic_read(&dp->dl_state));
+ if (atomic_read(&dp->dl_state) == NFS4_RECALL_IN_PROGRESS) {
+ if(nfs4_deleg_conflict(op->op_share_access, dp->dl_type))
+ status = nfserr_jukebox;
+ else
+ *flag = DONT_DELEGATE;
+ }
+ }
+ return status;
+}
+
+static int
nfs4_check_open(struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open, struct nfs4_stateid **stpp)
{
struct nfs4_stateid *local;