aboutsummaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2015-09-14 14:21:39 -0700
committerKevin Hilman <khilman@linaro.org>2015-09-14 14:21:39 -0700
commitf249a14dd1b6b341e7b5e29b64c0edae6e13b7f5 (patch)
treee5b53c75e42b5ac0d9b8feac65ce4b7a1b2a17bd /fs/nfsd/nfs4state.c
parent48cf795880b441a6c59cd840d0475fac7fdffd87 (diff)
parent0c5c1f1a4f991ee015da85cce6d2d9f9c9380b4f (diff)
Merge tag 'v4.1.7' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into linux-linaro-lsk-v4.1lsk-v4.1-15.09
This is the 4.1.7 stable release * tag 'v4.1.7' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable: (165 commits) Linux 4.1.7 ARM: 8405/1: VDSO: fix regression with toolchains lacking ld.bfd executable x86/idle: Restore trace_cpu_idle to mwait_idle() calls x86/apic: Fix fallout from x2apic cleanup x86/xen: make CONFIG_XEN depend on CONFIG_X86_LOCAL_APIC arm64: perf: fix unassigned cpu_pmu->plat_device when probing PMU PPIs arm64: KVM: Fix host crash when injecting a fault into a 32bit guest fnic: Use the local variable instead of I/O flag to acquire io_req_lock in fnic_queuecommand() to avoid deadloack Add factory recertified Crucial M500s to blacklist can: pcan_usb: don't provide CAN FD bittimings by non-FD adapters SCSI: Fix NULL pointer dereference in runtime PM genirq: Introduce irq_chip_set_type_parent() helper genirq: Don't return ENOSYS in irq_chip_retrigger_hierarchy ARM: OMAP: wakeupgen: Restore the irq_set_type() mechanism irqchip/crossbar: Restore set_wake functionality irqchip/crossbar: Restore the mask on suspend behaviour irqchip/crossbar: Restore the irq_set_type() mechanism 9p: ensure err is initialized to 0 in p9_client_read/write drm/i915: Avoid TP3 on CHV drm/i915: remove HBR2 from chv supported list ...
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c101
1 files changed, 54 insertions, 47 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 039f9c8a95e8..6e13504f736e 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4397,9 +4397,9 @@ laundromat_main(struct work_struct *laundry)
queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
}
-static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
+static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stid *stp)
{
- if (!fh_match(&fhp->fh_handle, &stp->st_stid.sc_file->fi_fhandle))
+ if (!fh_match(&fhp->fh_handle, &stp->sc_file->fi_fhandle))
return nfserr_bad_stateid;
return nfs_ok;
}
@@ -4574,20 +4574,48 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
return nfs_ok;
}
+static struct file *
+nfs4_find_file(struct nfs4_stid *s, int flags)
+{
+ switch (s->sc_type) {
+ case NFS4_DELEG_STID:
+ if (WARN_ON_ONCE(!s->sc_file->fi_deleg_file))
+ return NULL;
+ return get_file(s->sc_file->fi_deleg_file);
+ case NFS4_OPEN_STID:
+ case NFS4_LOCK_STID:
+ if (flags & RD_STATE)
+ return find_readable_file(s->sc_file);
+ else
+ return find_writeable_file(s->sc_file);
+ break;
+ }
+
+ return NULL;
+}
+
+static __be32
+nfs4_check_olstateid(struct svc_fh *fhp, struct nfs4_ol_stateid *ols, int flags)
+{
+ __be32 status;
+
+ status = nfsd4_check_openowner_confirmed(ols);
+ if (status)
+ return status;
+ return nfs4_check_openmode(ols, flags);
+}
+
/*
-* Checks for stateid operations
-*/
+ * Checks for stateid operations
+ */
__be32
nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
stateid_t *stateid, int flags, struct file **filpp)
{
- struct nfs4_stid *s;
- struct nfs4_ol_stateid *stp = NULL;
- struct nfs4_delegation *dp = NULL;
- struct svc_fh *current_fh = &cstate->current_fh;
- struct inode *ino = d_inode(current_fh->fh_dentry);
+ struct svc_fh *fhp = &cstate->current_fh;
+ struct inode *ino = d_inode(fhp->fh_dentry);
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- struct file *file = NULL;
+ struct nfs4_stid *s;
__be32 status;
if (filpp)
@@ -4597,60 +4625,39 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
return nfserr_grace;
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
- return check_special_stateids(net, current_fh, stateid, flags);
+ return check_special_stateids(net, fhp, stateid, flags);
status = nfsd4_lookup_stateid(cstate, stateid,
NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
&s, nn);
if (status)
return status;
- status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
+ status = check_stateid_generation(stateid, &s->sc_stateid,
+ nfsd4_has_session(cstate));
if (status)
goto out;
+
switch (s->sc_type) {
case NFS4_DELEG_STID:
- dp = delegstateid(s);
- status = nfs4_check_delegmode(dp, flags);
- if (status)
- goto out;
- if (filpp) {
- file = dp->dl_stid.sc_file->fi_deleg_file;
- if (!file) {
- WARN_ON_ONCE(1);
- status = nfserr_serverfault;
- goto out;
- }
- get_file(file);
- }
+ status = nfs4_check_delegmode(delegstateid(s), flags);
break;
case NFS4_OPEN_STID:
case NFS4_LOCK_STID:
- stp = openlockstateid(s);
- status = nfs4_check_fh(current_fh, stp);
- if (status)
- goto out;
- status = nfsd4_check_openowner_confirmed(stp);
- if (status)
- goto out;
- status = nfs4_check_openmode(stp, flags);
- if (status)
- goto out;
- if (filpp) {
- struct nfs4_file *fp = stp->st_stid.sc_file;
-
- if (flags & RD_STATE)
- file = find_readable_file(fp);
- else
- file = find_writeable_file(fp);
- }
+ status = nfs4_check_olstateid(fhp, openlockstateid(s), flags);
break;
default:
status = nfserr_bad_stateid;
+ break;
+ }
+ if (status)
goto out;
+ status = nfs4_check_fh(fhp, s);
+
+ if (!status && filpp) {
+ *filpp = nfs4_find_file(s, flags);
+ if (!*filpp)
+ status = nfserr_serverfault;
}
- status = nfs_ok;
- if (file)
- *filpp = file;
out:
nfs4_put_stid(s);
return status;
@@ -4754,7 +4761,7 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
if (status)
return status;
- return nfs4_check_fh(current_fh, stp);
+ return nfs4_check_fh(current_fh, &stp->st_stid);
}
/*