From: "J. Bruce Fields" <bfields@redhat.com>
To: linux-nfs@vger.kernel.org
To: linux-nfs@vger.kernel.org
Cc: "J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 22/25] nfsd4: hash deleg stateid's like any other
Date: Wed, 14 Sep 2011 07:45:18 -0400 [thread overview]
Message-ID: <1316000721-3289-23-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <1316000721-3289-1-git-send-email-bfields@redhat.com>
It's simpler to look up delegation stateid's in the same hash table as
any other stateid.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
fs/nfsd/nfs4state.c | 112 +++++++++++++++++++++------------------------------
fs/nfsd/state.h | 5 ++
2 files changed, 51 insertions(+), 66 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 581a5d0..24685a0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -60,8 +60,6 @@ static u64 current_sessionid = 1;
#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
/* forward declarations */
-static struct nfs4_delegation * search_for_delegation(stateid_t *stid);
-static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
/* Locking: */
@@ -256,10 +254,12 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
get_nfs4_file(fp);
dp->dl_file = fp;
dp->dl_type = type;
+ dp->dl_stid.sc_type = NFS4_DELEG_STID;
dp->dl_stid.sc_stateid.si_boot = boot_time;
dp->dl_stid.sc_stateid.si_stateownerid = current_delegid++;
dp->dl_stid.sc_stateid.si_fileid = 0;
dp->dl_stid.sc_stateid.si_generation = 1;
+ hash_stid(&dp->dl_stid);
fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle);
dp->dl_time = 0;
atomic_set(&dp->dl_count, 1);
@@ -292,6 +292,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
static void
unhash_delegation(struct nfs4_delegation *dp)
{
+ list_del_init(&dp->dl_stid.sc_hash);
list_del_init(&dp->dl_perclnt);
spin_lock(&recall_lock);
list_del_init(&dp->dl_perfile);
@@ -1077,7 +1078,7 @@ same_stateid(stateid_t *id_one, stateid_t *id_two)
return id_one->si_fileid == id_two->si_fileid;
}
-static struct nfs4_ol_stateid *find_stateid(stateid_t *t)
+static struct nfs4_stid *find_stateid(stateid_t *t)
{
struct nfs4_stid *s;
unsigned int hashval;
@@ -1085,22 +1086,42 @@ static struct nfs4_ol_stateid *find_stateid(stateid_t *t)
hashval = stateid_hashval(t->si_stateownerid, t->si_fileid);
list_for_each_entry(s, &stateid_hashtbl[hashval], sc_hash)
if (same_stateid(&s->sc_stateid, t))
- return openlockstateid(s);
+ return s;
return NULL;
}
-static struct nfs4_ol_stateid *find_stateid_by_type(stateid_t *t, char typemask)
+static struct nfs4_ol_stateid *find_ol_stateid(stateid_t *t)
{
- struct nfs4_ol_stateid *s;
+ struct nfs4_stid *s;
+
+ s = find_stateid(t);
+ if (!s)
+ return NULL;
+ return openlockstateid(s);
+}
+
+static struct nfs4_stid *find_stateid_by_type(stateid_t *t, char typemask)
+{
+ struct nfs4_stid *s;
s = find_stateid(t);
if (!s)
return NULL;
- if (typemask & s->st_stid.sc_type)
+ if (typemask & s->sc_type)
return s;
return NULL;
}
+static struct nfs4_ol_stateid *find_ol_stateid_by_type(stateid_t *t, char typemask)
+{
+ struct nfs4_stid *s;
+
+ s = find_stateid_by_type(t, typemask);
+ if (!s)
+ return NULL;
+ return openlockstateid(s);
+}
+
static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
struct svc_rqst *rqstp, nfs4_verifier *verf)
{
@@ -2573,26 +2594,21 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
return nfs_ok;
}
-static struct nfs4_delegation *
-find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
+static int share_access_to_flags(u32 share_access)
{
- struct nfs4_delegation *dp;
+ share_access &= ~NFS4_SHARE_WANT_MASK;
- spin_lock(&recall_lock);
- list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
- if (dp->dl_stid.sc_stateid.si_stateownerid == stid->si_stateownerid) {
- spin_unlock(&recall_lock);
- return dp;
- }
- spin_unlock(&recall_lock);
- return NULL;
+ return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
}
-static int share_access_to_flags(u32 share_access)
+static struct nfs4_delegation *find_deleg_stateid(stateid_t *s)
{
- share_access &= ~NFS4_SHARE_WANT_MASK;
+ struct nfs4_stid *ret;
- return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
+ ret = find_stateid_by_type(s, NFS4_DELEG_STID);
+ if (!ret)
+ return NULL;
+ return delegstateid(ret);
}
static __be32
@@ -2602,7 +2618,7 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
int flags;
__be32 status = nfserr_bad_stateid;
- *dp = find_delegation_file(fp, &open->op_delegate_stateid);
+ *dp = find_deleg_stateid(&open->op_delegate_stateid);
if (*dp == NULL)
goto out;
flags = share_access_to_flags(open->op_share_access);
@@ -3252,7 +3268,7 @@ __be32 nfs4_validate_stateid(stateid_t *stateid, bool has_session)
goto out;
status = nfserr_expired;
- stp = find_stateid(stateid);
+ stp = find_ol_stateid(stateid);
if (!stp)
goto out;
status = nfserr_bad_stateid;
@@ -3301,7 +3317,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
*/
status = nfserr_expired;
if (is_delegation_stateid(stateid)) {
- dp = find_delegation_stateid(ino, stateid);
+ dp = find_deleg_stateid(stateid);
if (!dp)
goto out;
status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
@@ -3316,7 +3332,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
BUG_ON(!*filpp);
}
} else { /* open or lock stateid */
- stp = find_stateid(stateid);
+ stp = find_ol_stateid(stateid);
if (!stp)
goto out;
status = nfserr_bad_stateid;
@@ -3348,9 +3364,10 @@ out:
static __be32
nfsd4_free_delegation_stateid(stateid_t *stateid)
{
- struct nfs4_delegation *dp = search_for_delegation(stateid);
+ struct nfs4_delegation *dp = find_deleg_stateid(stateid);
if (dp)
return nfserr_locks_held;
+
return nfserr_bad_stateid;
}
@@ -3391,7 +3408,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
}
- stp = find_stateid(stateid);
+ stp = find_ol_stateid(stateid);
if (!stp) {
ret = nfserr_bad_stateid;
goto out;
@@ -3460,7 +3477,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
status = nfs4_nospecial_stateid_checks(stateid);
if (status)
return status;
- *stpp = find_stateid_by_type(stateid, typemask);
+ *stpp = find_ol_stateid_by_type(stateid, typemask);
if (*stpp == NULL)
return nfserr_expired;
cstate->replay_owner = (*stpp)->st_stateowner;
@@ -3672,7 +3689,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (!is_delegation_stateid(stateid))
goto out;
status = nfserr_expired;
- dp = find_delegation_stateid(inode, stateid);
+ dp = find_deleg_stateid(stateid);
if (!dp)
goto out;
status = check_stateid_generation(stateid, &dp->dl_stid.sc_stateid, nfsd4_has_session(cstate));
@@ -3733,43 +3750,6 @@ lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
-static struct nfs4_delegation *
-search_for_delegation(stateid_t *stid)
-{
- struct nfs4_file *fp;
- struct nfs4_delegation *dp;
- struct list_head *pos;
- int i;
-
- for (i = 0; i < FILE_HASH_SIZE; i++) {
- list_for_each_entry(fp, &file_hashtbl[i], fi_hash) {
- list_for_each(pos, &fp->fi_delegations) {
- dp = list_entry(pos, struct nfs4_delegation, dl_perfile);
- if (same_stateid(&dp->dl_stid.sc_stateid, stid))
- return dp;
- }
- }
- }
- return NULL;
-}
-
-static struct nfs4_delegation *
-find_delegation_stateid(struct inode *ino, stateid_t *stid)
-{
- struct nfs4_file *fp;
- struct nfs4_delegation *dl;
-
- dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__,
- STATEID_VAL(stid));
-
- fp = find_file(ino);
- if (!fp)
- return NULL;
- dl = find_delegation_file(fp, stid);
- put_nfs4_file(fp);
- return dl;
-}
-
/*
* TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
* we can't properly handle lock requests that go beyond the (2^63 - 1)-th
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index e3ff7c9..12c1424 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -113,6 +113,11 @@ struct nfs4_cb_conn {
struct svc_xprt *cb_xprt; /* minorversion 1 only */
};
+static inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
+{
+ return container_of(s, struct nfs4_delegation, dl_stid);
+}
+
/* Maximum number of slots per session. 160 is useful for long haul TCP */
#define NFSD_MAX_SLOTS_PER_SESSION 160
/* Maximum number of operations per session compound */
--
1.7.4.1
next prev parent reply other threads:[~2011-09-14 11:45 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-14 11:44 [PATCH 00/25] nfsd4 state cleanup J. Bruce Fields
2011-09-14 11:44 ` [PATCH 01/25] nfsd4: centralize handling of replay owners J. Bruce Fields
2011-09-14 11:44 ` [PATCH 02/25] nfsd4: cleanup seqid op stateowner usage J. Bruce Fields
2011-09-14 11:44 ` [PATCH 03/25] nfsd4: extend state lock over seqid replay logic J. Bruce Fields
2011-09-27 16:55 ` Bryan Schumaker
2011-09-28 1:40 ` J. Bruce Fields
2011-09-28 1:49 ` J. Bruce Fields
2011-09-28 13:18 ` Bryan Schumaker
2011-09-28 13:44 ` J. Bruce Fields
2011-09-14 11:45 ` [PATCH 04/25] nfsd4: eliminate impossible open replay case J. Bruce Fields
2011-09-14 11:45 ` [PATCH 05/25] nfsd4: drop most stateowner refcounting J. Bruce Fields
2011-09-14 11:45 ` [PATCH 06/25] nfsd4: eliminate unused lt_stateowner J. Bruce Fields
2011-09-14 11:45 ` [PATCH 07/25] nfsd4: share common seqid checks J. Bruce Fields
2011-09-14 11:45 ` [PATCH 08/25] nfsd4: simplify check_open logic J. Bruce Fields
2011-09-14 11:45 ` [PATCH 09/25] nfsd4: move double-confirm test to open_confirm J. Bruce Fields
2011-09-14 11:45 ` [PATCH 10/25] nfsd4: move CLOSE_STATE special case to caller J. Bruce Fields
2011-09-14 11:45 ` [PATCH 11/25] nfsd4: split stateowners into open and lockowners J. Bruce Fields
2011-09-14 11:45 ` [PATCH 12/25] nfsd4: split out some free_generic_stateid code J. Bruce Fields
2011-09-14 11:45 ` [PATCH 13/25] nfsd4: rearrange to avoid a forward reference J. Bruce Fields
2011-09-14 11:45 ` [PATCH 14/25] nfsd4: split up find_stateid J. Bruce Fields
2011-09-14 11:45 ` [PATCH 15/25] nfsd4: split preprocess_seqid, cleanup J. Bruce Fields
2011-09-14 11:45 ` [PATCH 16/25] nfsd4: pass around typemask instead of flags J. Bruce Fields
2011-09-14 11:45 ` [PATCH 17/25] nfsd4: rename init_stateid J. Bruce Fields
2011-09-14 11:45 ` [PATCH 18/25] nfsd4: remove redundant stateid initialization J. Bruce Fields
2011-09-14 11:45 ` [PATCH 19/25] nfsd4: move some of nfs4_stateid into a separate structure J. Bruce Fields
2011-09-14 11:45 ` [PATCH 20/25] nfsd4: add common dl_stid field to delegation J. Bruce Fields
2011-09-14 11:45 ` [PATCH 21/25] nfsd4: share common stid-hashing helper function J. Bruce Fields
2011-09-14 11:45 ` J. Bruce Fields [this message]
2011-09-14 11:45 ` [PATCH 23/25] nfsd4: fix test_stateid for delegation stateid's J. Bruce Fields
2011-09-14 11:45 ` [PATCH 24/25] nfsd4: use deleg changes to cleanup preprocess_stateid_op J. Bruce Fields
2011-09-14 11:45 ` [PATCH 25/25] nfsd4: better stateid hashing J. Bruce Fields
2011-09-19 13:14 ` [PATCH 00/25] nfsd4 state cleanup J. Bruce Fields
2011-09-19 13:15 ` [PATCH 1/5] nfsd4: replace oo_confirmed by flag bit J. Bruce Fields
2011-09-19 13:15 ` [PATCH 2/5] nfsd4: match close replays on stateid, not open owner id J. Bruce Fields
2011-09-19 13:15 ` [PATCH 3/5] nfsd4: simplify free_stateid J. Bruce Fields
2011-09-19 13:15 ` [PATCH 4/5] nfsd4: construct stateid from clientid and counter J. Bruce Fields
2011-09-27 16:10 ` Bryan Schumaker
2011-09-28 15:49 ` J. Bruce Fields
2011-10-03 14:43 ` Benny Halevy
2011-10-03 14:57 ` J. Bruce Fields
2011-10-03 15:13 ` Benny Halevy
2011-10-03 15:38 ` J. Bruce Fields
2011-10-04 15:52 ` Benny Halevy
2011-10-04 16:02 ` J. Bruce Fields
2011-09-19 13:15 ` [PATCH 5/5] nfsd4: hash closed stateid's like any other J. Bruce Fields
2011-09-26 22:36 ` [PATCH 00/25] nfsd4 state cleanup J. Bruce Fields
2011-09-26 22:44 ` J. Bruce Fields
2011-09-26 22:37 ` J. Bruce Fields
2011-09-26 22:39 ` [PATCH 1/4] nfsd4: move client * to nfs4_stateid, add init_stid helper J. Bruce Fields
2011-09-26 22:39 ` [PATCH 2/4] nfsd4: use idr for stateid's J. Bruce Fields
2011-09-26 22:39 ` [PATCH 3/4] nfsd4: assume test_stateid always has session J. Bruce Fields
2011-09-26 22:39 ` [PATCH 4/4] nfsd4: look up stateid's per clientid J. Bruce Fields
2011-11-08 22:57 ` [PATCH 00/25] nfsd4 state cleanup J. Bruce Fields
2011-11-08 22:59 ` [PATCH 1/3] nfsd4: hash lockowners to simplify RELEASE_LOCKOWNER J. Bruce Fields
2011-11-08 22:59 ` [PATCH 2/3] nfsd4: share open and lock owner hash tables J. Bruce Fields
2011-11-08 22:59 ` [PATCH 3/3] nfsd4: add a separate (lockowner, inode) lookup J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1316000721-3289-23-git-send-email-bfields@redhat.com \
--to=bfields@redhat.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.