Commit 2547d1d2 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-2.6.36' of git://linux-nfs.org/~bfields/linux

* 'for-2.6.36' of git://linux-nfs.org/~bfields/linux:
  nfsd: fix NULL dereference in nfsd_statfs()
  nfsd4: fix downgrade/lock logic
  nfsd4: typo fix in find_any_file
  nfsd4: bad BUG() in preprocess_stateid_op
parents 7be0d4f9 f6360efb
...@@ -2450,14 +2450,13 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, ...@@ -2450,14 +2450,13 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
static __be32 static __be32
nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
{ {
u32 op_share_access, new_access; u32 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
bool new_access;
__be32 status; __be32 status;
set_access(&new_access, stp->st_access_bmap); new_access = !test_bit(op_share_access, &stp->st_access_bmap);
new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK;
if (new_access) { if (new_access) {
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, new_access); status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access);
if (status) if (status)
return status; return status;
} }
...@@ -2470,7 +2469,6 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c ...@@ -2470,7 +2469,6 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
return status; return status;
} }
/* remember the open */ /* remember the open */
op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
__set_bit(op_share_access, &stp->st_access_bmap); __set_bit(op_share_access, &stp->st_access_bmap);
__set_bit(open->op_share_deny, &stp->st_deny_bmap); __set_bit(open->op_share_deny, &stp->st_deny_bmap);
...@@ -2983,7 +2981,6 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, ...@@ -2983,7 +2981,6 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
*filpp = find_readable_file(stp->st_file); *filpp = find_readable_file(stp->st_file);
else else
*filpp = find_writeable_file(stp->st_file); *filpp = find_writeable_file(stp->st_file);
BUG_ON(!*filpp); /* assured by check_openmode */
} }
} }
status = nfs_ok; status = nfs_ok;
...@@ -3561,7 +3558,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3561,7 +3558,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfs4_stateowner *open_sop = NULL; struct nfs4_stateowner *open_sop = NULL;
struct nfs4_stateowner *lock_sop = NULL; struct nfs4_stateowner *lock_sop = NULL;
struct nfs4_stateid *lock_stp; struct nfs4_stateid *lock_stp;
struct file *filp; struct nfs4_file *fp;
struct file *filp = NULL;
struct file_lock file_lock; struct file_lock file_lock;
struct file_lock conflock; struct file_lock conflock;
__be32 status = 0; __be32 status = 0;
...@@ -3591,7 +3589,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3591,7 +3589,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
* lock stateid. * lock stateid.
*/ */
struct nfs4_stateid *open_stp = NULL; struct nfs4_stateid *open_stp = NULL;
struct nfs4_file *fp;
status = nfserr_stale_clientid; status = nfserr_stale_clientid;
if (!nfsd4_has_session(cstate) && if (!nfsd4_has_session(cstate) &&
...@@ -3634,6 +3631,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3634,6 +3631,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status) if (status)
goto out; goto out;
lock_sop = lock->lk_replay_owner; lock_sop = lock->lk_replay_owner;
fp = lock_stp->st_file;
} }
/* lock->lk_replay_owner and lock_stp have been created or found */ /* lock->lk_replay_owner and lock_stp have been created or found */
...@@ -3648,13 +3646,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -3648,13 +3646,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
switch (lock->lk_type) { switch (lock->lk_type) {
case NFS4_READ_LT: case NFS4_READ_LT:
case NFS4_READW_LT: case NFS4_READW_LT:
filp = find_readable_file(lock_stp->st_file); if (find_readable_file(lock_stp->st_file)) {
nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ);
filp = find_readable_file(lock_stp->st_file);
}
file_lock.fl_type = F_RDLCK; file_lock.fl_type = F_RDLCK;
cmd = F_SETLK; cmd = F_SETLK;
break; break;
case NFS4_WRITE_LT: case NFS4_WRITE_LT:
case NFS4_WRITEW_LT: case NFS4_WRITEW_LT:
filp = find_writeable_file(lock_stp->st_file); if (find_writeable_file(lock_stp->st_file)) {
nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE);
filp = find_writeable_file(lock_stp->st_file);
}
file_lock.fl_type = F_WRLCK; file_lock.fl_type = F_WRLCK;
cmd = F_SETLK; cmd = F_SETLK;
break; break;
......
...@@ -363,23 +363,23 @@ struct nfs4_file { ...@@ -363,23 +363,23 @@ struct nfs4_file {
* at all? */ * at all? */
static inline struct file *find_writeable_file(struct nfs4_file *f) static inline struct file *find_writeable_file(struct nfs4_file *f)
{ {
if (f->fi_fds[O_RDWR]) if (f->fi_fds[O_WRONLY])
return f->fi_fds[O_RDWR]; return f->fi_fds[O_WRONLY];
return f->fi_fds[O_WRONLY]; return f->fi_fds[O_RDWR];
} }
static inline struct file *find_readable_file(struct nfs4_file *f) static inline struct file *find_readable_file(struct nfs4_file *f)
{ {
if (f->fi_fds[O_RDWR]) if (f->fi_fds[O_RDONLY])
return f->fi_fds[O_RDWR]; return f->fi_fds[O_RDONLY];
return f->fi_fds[O_RDONLY]; return f->fi_fds[O_RDWR];
} }
static inline struct file *find_any_file(struct nfs4_file *f) static inline struct file *find_any_file(struct nfs4_file *f)
{ {
if (f->fi_fds[O_RDWR]) if (f->fi_fds[O_RDWR])
return f->fi_fds[O_RDWR]; return f->fi_fds[O_RDWR];
else if (f->fi_fds[O_RDWR]) else if (f->fi_fds[O_WRONLY])
return f->fi_fds[O_WRONLY]; return f->fi_fds[O_WRONLY];
else else
return f->fi_fds[O_RDONLY]; return f->fi_fds[O_RDONLY];
......
...@@ -2033,15 +2033,17 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, ...@@ -2033,15 +2033,17 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
__be32 __be32
nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
{ {
struct path path = {
.mnt = fhp->fh_export->ex_path.mnt,
.dentry = fhp->fh_dentry,
};
__be32 err; __be32 err;
err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
if (!err && vfs_statfs(&path, stat)) if (!err) {
err = nfserr_io; struct path path = {
.mnt = fhp->fh_export->ex_path.mnt,
.dentry = fhp->fh_dentry,
};
if (vfs_statfs(&path, stat))
err = nfserr_io;
}
return err; return err;
} }
......
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