aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2005-01-04 05:51:20 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:51:20 -0800
commita0e7d577db9c490289c8de7ab0ef19a00c328cf8 (patch)
treee059a716e89f3e785f583e5ce392d6e2d9937b82 /fs
parent95402a16ada69cfd8180961a33540e8edfb63f05 (diff)
downloadhistory-a0e7d577db9c490289c8de7ab0ef19a00c328cf8.tar.gz
[PATCH] knfsd: attempt to hand out 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.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 313acf87731983..facbe9976dadd4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1642,6 +1642,65 @@ nfs4_set_claim_prev(struct nfsd4_open *open, int *status)
}
/*
+ * Attempt to hand out a delegation.
+ */
+static void
+nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp, int *flag)
+{
+ struct nfs4_delegation *dp;
+ struct nfs4_stateowner *sop = stp->st_stateowner;
+ struct nfs4_callback *cb = &sop->so_client->cl_callback;
+ struct file_lock fl, *flp = &fl;
+ int status;
+
+ if (*flag == DONT_DELEGATE) {
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ return;
+ }
+
+ /* set flag */
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
+ || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
+ return;
+
+ if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
+ *flag = NFS4_OPEN_DELEGATE_READ;
+
+ else if (!(open->op_share_access & NFS4_SHARE_ACCESS_READ))
+ *flag = NFS4_OPEN_DELEGATE_WRITE;
+
+ if (!(dp = alloc_init_deleg(sop->so_client, stp->st_file, fh, *flag)))
+ return;
+ locks_init_lock(&fl);
+ fl.fl_lmops = &nfsd_lease_mng_ops;
+ fl.fl_flags = FL_LEASE;
+ fl.fl_end = OFFSET_MAX;
+ fl.fl_owner = (fl_owner_t)dp;
+ fl.fl_file = stp->st_vfs_file;
+ fl.fl_pid = current->tgid;
+
+ if ((status = setlease(stp->st_vfs_file,
+ *flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) {
+ dprintk("NFSD: setlease failed [%d], no delegation\n", status);
+ list_del(&dp->dl_del_perfile);
+ list_del(&dp->dl_del_perclnt);
+ kfree(dp);
+ free_delegation++;
+ *flag = NFS4_OPEN_DELEGATE_NONE;
+ return;
+ }
+
+ memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid));
+
+ dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n",
+ dp->dl_stateid.si_boot,
+ dp->dl_stateid.si_stateownerid,
+ dp->dl_stateid.si_fileid,
+ dp->dl_stateid.si_generation);
+}
+
+/*
* called with nfs4_lock_state() held.
*/
int