Commit 99c41515 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: clean up nfs4_open_delegation

The nfs4_open_delegation logic is unecessarily baroque.

Also stop pretending we support write delegations in several places.

Some day we will support write delegations, but when that happens adding
back in these flag parameters will be the easy part.  For now they're
just confusing.
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 9a0590ae
...@@ -364,19 +364,12 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) ...@@ -364,19 +364,12 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
} }
static struct nfs4_delegation * static struct nfs4_delegation *
alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh)
{ {
struct nfs4_delegation *dp; struct nfs4_delegation *dp;
struct nfs4_file *fp = stp->st_file; struct nfs4_file *fp = stp->st_file;
dprintk("NFSD alloc_init_deleg\n"); dprintk("NFSD alloc_init_deleg\n");
/*
* Major work on the lease subsystem (for example, to support
* calbacks on stat) will be required before we can support
* write delegations properly.
*/
if (type != NFS4_OPEN_DELEGATE_READ)
return NULL;
if (fp->fi_had_conflict) if (fp->fi_had_conflict)
return NULL; return NULL;
if (num_delegations > max_delegations) if (num_delegations > max_delegations)
...@@ -397,7 +390,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv ...@@ -397,7 +390,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
INIT_LIST_HEAD(&dp->dl_recall_lru); INIT_LIST_HEAD(&dp->dl_recall_lru);
get_nfs4_file(fp); get_nfs4_file(fp);
dp->dl_file = fp; dp->dl_file = fp;
dp->dl_type = type; dp->dl_type = NFS4_OPEN_DELEGATE_READ;
fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
dp->dl_time = 0; dp->dl_time = 0;
atomic_set(&dp->dl_count, 1); atomic_set(&dp->dl_count, 1);
...@@ -3020,13 +3013,13 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f ...@@ -3020,13 +3013,13 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f
return fl; return fl;
} }
static int nfs4_setlease(struct nfs4_delegation *dp, int flag) static int nfs4_setlease(struct nfs4_delegation *dp)
{ {
struct nfs4_file *fp = dp->dl_file; struct nfs4_file *fp = dp->dl_file;
struct file_lock *fl; struct file_lock *fl;
int status; int status;
fl = nfs4_alloc_init_lease(dp, flag); fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
if (!fl) if (!fl)
return -ENOMEM; return -ENOMEM;
fl->fl_file = find_readable_file(fp); fl->fl_file = find_readable_file(fp);
...@@ -3044,12 +3037,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag) ...@@ -3044,12 +3037,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
return 0; return 0;
} }
static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) static int nfs4_set_delegation(struct nfs4_delegation *dp)
{ {
struct nfs4_file *fp = dp->dl_file; struct nfs4_file *fp = dp->dl_file;
if (!fp->fi_lease) if (!fp->fi_lease)
return nfs4_setlease(dp, flag); return nfs4_setlease(dp);
spin_lock(&recall_lock); spin_lock(&recall_lock);
if (fp->fi_had_conflict) { if (fp->fi_had_conflict) {
spin_unlock(&recall_lock); spin_unlock(&recall_lock);
...@@ -3085,6 +3078,9 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status) ...@@ -3085,6 +3078,9 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
/* /*
* Attempt to hand out a delegation. * Attempt to hand out a delegation.
*
* Note we don't support write delegations, and won't until the vfs has
* proper support for them.
*/ */
static void static void
nfs4_open_delegation(struct net *net, struct svc_fh *fh, nfs4_open_delegation(struct net *net, struct svc_fh *fh,
...@@ -3093,26 +3089,26 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh, ...@@ -3093,26 +3089,26 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
struct nfs4_delegation *dp; struct nfs4_delegation *dp;
struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
int cb_up; int cb_up;
int status = 0, flag = 0; int status = 0;
cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
flag = NFS4_OPEN_DELEGATE_NONE;
open->op_recall = 0; open->op_recall = 0;
switch (open->op_claim_type) { switch (open->op_claim_type) {
case NFS4_OPEN_CLAIM_PREVIOUS: case NFS4_OPEN_CLAIM_PREVIOUS:
if (!cb_up) if (!cb_up)
open->op_recall = 1; open->op_recall = 1;
flag = open->op_delegate_type; if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
if (flag == NFS4_OPEN_DELEGATE_NONE) goto out_no_deleg;
goto out;
break; break;
case NFS4_OPEN_CLAIM_NULL: case NFS4_OPEN_CLAIM_NULL:
/* Let's not give out any delegations till everyone's /*
* had the chance to reclaim theirs.... */ * Let's not give out any delegations till everyone's
* had the chance to reclaim theirs....
*/
if (locks_in_grace(net)) if (locks_in_grace(net))
goto out; goto out_no_deleg;
if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
goto out; goto out_no_deleg;
/* /*
* Also, if the file was opened for write or * Also, if the file was opened for write or
* create, there's a good chance the client's * create, there's a good chance the client's
...@@ -3121,20 +3117,17 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh, ...@@ -3121,20 +3117,17 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
* write delegations): * write delegations):
*/ */
if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
flag = NFS4_OPEN_DELEGATE_WRITE; goto out_no_deleg;
else if (open->op_create == NFS4_OPEN_CREATE) if (open->op_create == NFS4_OPEN_CREATE)
flag = NFS4_OPEN_DELEGATE_WRITE; goto out_no_deleg;
else
flag = NFS4_OPEN_DELEGATE_READ;
break; break;
default: default:
goto out; goto out_no_deleg;
} }
dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh);
dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
if (dp == NULL) if (dp == NULL)
goto out_no_deleg; goto out_no_deleg;
status = nfs4_set_delegation(dp, flag); status = nfs4_set_delegation(dp);
if (status) if (status)
goto out_free; goto out_free;
...@@ -3142,9 +3135,13 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh, ...@@ -3142,9 +3135,13 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
STATEID_VAL(&dp->dl_stid.sc_stateid)); STATEID_VAL(&dp->dl_stid.sc_stateid));
out: open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
open->op_delegate_type = flag; return;
if (flag == NFS4_OPEN_DELEGATE_NONE) { out_free:
unhash_stid(&dp->dl_stid);
nfs4_put_delegation(dp);
out_no_deleg:
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS && if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
dprintk("NFSD: WARNING: refusing delegation reclaim\n"); dprintk("NFSD: WARNING: refusing delegation reclaim\n");
...@@ -3152,14 +3149,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh, ...@@ -3152,14 +3149,7 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
/* 4.1 client asking for a delegation? */ /* 4.1 client asking for a delegation? */
if (open->op_deleg_want) if (open->op_deleg_want)
nfsd4_open_deleg_none_ext(open, status); nfsd4_open_deleg_none_ext(open, status);
}
return; return;
out_free:
unhash_stid(&dp->dl_stid);
nfs4_put_delegation(dp);
out_no_deleg:
flag = NFS4_OPEN_DELEGATE_NONE;
goto out;
} }
static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment