Commit f9c00c3a authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

nfsd: Do not let nfs4_file pin the struct inode

Remove the fi_inode field in struct nfs4_file in order to remove the
possibility of struct nfs4_file pinning the inode when it does not have
any open state.

The only place we still need to get to an inode is in check_for_locks,
so change it to use find_any_file and use the inode from any that it
finds. If it doesn't find one, then just assume there aren't any.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent b07c54a4
...@@ -70,7 +70,7 @@ static u64 current_sessionid = 1; ...@@ -70,7 +70,7 @@ static u64 current_sessionid = 1;
#define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t))) #define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t)))
/* forward declarations */ /* forward declarations */
static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner); static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner);
/* Locking: */ /* Locking: */
...@@ -259,7 +259,6 @@ put_nfs4_file(struct nfs4_file *fi) ...@@ -259,7 +259,6 @@ put_nfs4_file(struct nfs4_file *fi)
if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
hlist_del(&fi->fi_hash); hlist_del(&fi->fi_hash);
spin_unlock(&state_lock); spin_unlock(&state_lock);
iput(fi->fi_inode);
nfsd4_free_file(fi); nfsd4_free_file(fi);
} }
} }
...@@ -2845,8 +2844,7 @@ static struct nfs4_file *nfsd4_alloc_file(void) ...@@ -2845,8 +2844,7 @@ static struct nfs4_file *nfsd4_alloc_file(void)
} }
/* OPEN Share state helper functions */ /* OPEN Share state helper functions */
static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino, static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh)
struct knfsd_fh *fh)
{ {
unsigned int hashval = file_hashval(fh); unsigned int hashval = file_hashval(fh);
...@@ -2856,8 +2854,6 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino, ...@@ -2856,8 +2854,6 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino,
spin_lock_init(&fp->fi_lock); spin_lock_init(&fp->fi_lock);
INIT_LIST_HEAD(&fp->fi_stateids); INIT_LIST_HEAD(&fp->fi_stateids);
INIT_LIST_HEAD(&fp->fi_delegations); INIT_LIST_HEAD(&fp->fi_delegations);
ihold(ino);
fp->fi_inode = ino;
fh_copy_shallow(&fp->fi_fhandle, fh); fh_copy_shallow(&fp->fi_fhandle, fh);
fp->fi_had_conflict = false; fp->fi_had_conflict = false;
fp->fi_lease = NULL; fp->fi_lease = NULL;
...@@ -3063,14 +3059,14 @@ find_file(struct knfsd_fh *fh) ...@@ -3063,14 +3059,14 @@ find_file(struct knfsd_fh *fh)
} }
static struct nfs4_file * static struct nfs4_file *
find_or_add_file(struct inode *ino, struct nfs4_file *new, struct knfsd_fh *fh) find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh)
{ {
struct nfs4_file *fp; struct nfs4_file *fp;
spin_lock(&state_lock); spin_lock(&state_lock);
fp = find_file_locked(fh); fp = find_file_locked(fh);
if (fp == NULL) { if (fp == NULL) {
nfsd4_init_file(new, ino, fh); nfsd4_init_file(new, fh);
fp = new; fp = new;
} }
spin_unlock(&state_lock); spin_unlock(&state_lock);
...@@ -3714,7 +3710,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf ...@@ -3714,7 +3710,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
struct nfsd4_compoundres *resp = rqstp->rq_resp; struct nfsd4_compoundres *resp = rqstp->rq_resp;
struct nfs4_client *cl = open->op_openowner->oo_owner.so_client; struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
struct nfs4_file *fp = NULL; struct nfs4_file *fp = NULL;
struct inode *ino = current_fh->fh_dentry->d_inode;
struct nfs4_ol_stateid *stp = NULL; struct nfs4_ol_stateid *stp = NULL;
struct nfs4_delegation *dp = NULL; struct nfs4_delegation *dp = NULL;
__be32 status; __be32 status;
...@@ -3724,7 +3719,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf ...@@ -3724,7 +3719,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
* and check for delegations in the process of being recalled. * and check for delegations in the process of being recalled.
* If not found, create the nfs4_file struct * If not found, create the nfs4_file struct
*/ */
fp = find_or_add_file(ino, open->op_file, &current_fh->fh_handle); fp = find_or_add_file(open->op_file, &current_fh->fh_handle);
if (fp != open->op_file) { if (fp != open->op_file) {
status = nfs4_check_deleg(cl, open, &dp); status = nfs4_check_deleg(cl, open, &dp);
if (status) if (status)
...@@ -4663,7 +4658,9 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str ...@@ -4663,7 +4658,9 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
} }
static struct nfs4_ol_stateid * static struct nfs4_ol_stateid *
alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_ol_stateid *open_stp) alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp,
struct inode *inode,
struct nfs4_ol_stateid *open_stp)
{ {
struct nfs4_ol_stateid *stp; struct nfs4_ol_stateid *stp;
struct nfs4_client *clp = lo->lo_owner.so_client; struct nfs4_client *clp = lo->lo_owner.so_client;
...@@ -4723,6 +4720,7 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s ...@@ -4723,6 +4720,7 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s
struct nfs4_file *fi = ost->st_file; struct nfs4_file *fi = ost->st_file;
struct nfs4_openowner *oo = openowner(ost->st_stateowner); struct nfs4_openowner *oo = openowner(ost->st_stateowner);
struct nfs4_client *cl = oo->oo_owner.so_client; struct nfs4_client *cl = oo->oo_owner.so_client;
struct inode *inode = cstate->current_fh.fh_dentry->d_inode;
struct nfs4_lockowner *lo; struct nfs4_lockowner *lo;
unsigned int strhashval; unsigned int strhashval;
struct nfsd_net *nn = net_generic(cl->net, nfsd_net_id); struct nfsd_net *nn = net_generic(cl->net, nfsd_net_id);
...@@ -4743,7 +4741,7 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s ...@@ -4743,7 +4741,7 @@ static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, s
*lst = find_lock_stateid(lo, fi); *lst = find_lock_stateid(lo, fi);
if (*lst == NULL) { if (*lst == NULL) {
*lst = alloc_init_lock_stateid(lo, fi, ost); *lst = alloc_init_lock_stateid(lo, fi, inode, ost);
if (*lst == NULL) { if (*lst == NULL) {
release_lockowner_if_empty(lo); release_lockowner_if_empty(lo);
return nfserr_jukebox; return nfserr_jukebox;
...@@ -5092,25 +5090,34 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -5092,25 +5090,34 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
/* /*
* returns * returns
* 1: locks held by lockowner * true: locks held by lockowner
* 0: no locks held by lockowner * false: no locks held by lockowner
*/ */
static int static bool
check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner) check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
{ {
struct file_lock **flpp; struct file_lock **flpp;
struct inode *inode = filp->fi_inode; int status = false;
int status = 0; struct file *filp = find_any_file(fp);
struct inode *inode;
if (!filp) {
/* Any valid lock stateid should have some sort of access */
WARN_ON_ONCE(1);
return status;
}
inode = file_inode(filp);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
if ((*flpp)->fl_owner == (fl_owner_t)lowner) { if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
status = 1; status = true;
goto out; break;
} }
} }
out:
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
fput(filp);
return status; return status;
} }
......
...@@ -397,7 +397,6 @@ struct nfs4_file { ...@@ -397,7 +397,6 @@ struct nfs4_file {
struct file_lock *fi_lease; struct file_lock *fi_lease;
atomic_t fi_delegees; atomic_t fi_delegees;
struct knfsd_fh fi_fhandle; struct knfsd_fh fi_fhandle;
struct inode *fi_inode;
bool fi_had_conflict; bool fi_had_conflict;
}; };
......
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