static struct list_head file_hashtbl[FILE_HASH_SIZE];
static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
-static inline void nfs4_file_get_access(struct nfs4_file *fp, int oflag)
+static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
{
BUG_ON(!(fp->fi_fds[oflag] || fp->fi_fds[O_RDWR]));
atomic_inc(&fp->fi_access[oflag]);
}
-static inline void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
+static void nfs4_file_get_access(struct nfs4_file *fp, int oflag)
+{
+ if (oflag == O_RDWR) {
+ __nfs4_file_get_access(fp, O_RDONLY);
+ __nfs4_file_get_access(fp, O_WRONLY);
+ } else
+ __nfs4_file_get_access(fp, oflag);
+}
+
+static void nfs4_file_put_fd(struct nfs4_file *fp, int oflag)
{
if (fp->fi_fds[oflag]) {
fput(fp->fi_fds[oflag]);
}
}
-static inline void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
+static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
{
if (atomic_dec_and_test(&fp->fi_access[oflag])) {
nfs4_file_put_fd(fp, O_RDWR);
}
}
+static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
+{
+ if (oflag == O_RDWR) {
+ __nfs4_file_put_access(fp, O_RDONLY);
+ __nfs4_file_put_access(fp, O_WRONLY);
+ } else
+ __nfs4_file_put_access(fp, oflag);
+}
+
static struct nfs4_delegation *
alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type)
{
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)
{
- u32 op_share_access, new_access;
+ u32 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
+ bool new_access;
__be32 status;
- set_access(&new_access, stp->st_access_bmap);
- new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK;
-
+ new_access = !test_bit(op_share_access, &stp->st_access_bmap);
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)
return status;
}
return status;
}
/* 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(open->op_share_deny, &stp->st_deny_bmap);
*filpp = find_readable_file(stp->st_file);
else
*filpp = find_writeable_file(stp->st_file);
- BUG_ON(!*filpp); /* assured by check_openmode */
}
}
status = nfs_ok;
nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
{
struct nfs4_stateowner *sop;
- unsigned int hval;
if (fl->fl_lmops == &nfsd_posix_mng_ops) {
sop = (struct nfs4_stateowner *) fl->fl_owner;
- hval = lockownerid_hashval(sop->so_id);
kref_get(&sop->so_ref);
deny->ld_sop = sop;
deny->ld_clientid = sop->so_client->cl_clientid;
struct nfs4_stateowner *open_sop = NULL;
struct nfs4_stateowner *lock_sop = NULL;
struct nfs4_stateid *lock_stp;
- struct file *filp;
+ struct nfs4_file *fp;
+ struct file *filp = NULL;
struct file_lock file_lock;
struct file_lock conflock;
__be32 status = 0;
* lock stateid.
*/
struct nfs4_stateid *open_stp = NULL;
- struct nfs4_file *fp;
status = nfserr_stale_clientid;
if (!nfsd4_has_session(cstate) &&
if (status)
goto out;
lock_sop = lock->lk_replay_owner;
+ fp = lock_stp->st_file;
}
/* lock->lk_replay_owner and lock_stp have been created or found */
switch (lock->lk_type) {
case NFS4_READ_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;
cmd = F_SETLK;
break;
case NFS4_WRITE_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;
cmd = F_SETLK;
break;