From: "J. Bruce Fields" <bfields@redhat.com>
To: linux-nfs@vger.kernel.org
Cc: "J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 4/5] nfsd4: construct stateid from clientid and counter
Date: Mon, 19 Sep 2011 09:15:42 -0400 [thread overview]
Message-ID: <1316438143-1057-4-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <20110919131415.GB32498@fieldses.org>
Including the full clientid in the on-the-wire stateid allows more
reliable detection of bad vs. expired stateid's, simplifies code, and
ensures we won't reuse the opaque part of the stateid (as we currently
do when the same openowner closes and reopens the same file).
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
fs/nfsd/nfs4state.c | 58 +++++++++++---------------------------------------
fs/nfsd/state.h | 18 ++++-----------
2 files changed, 18 insertions(+), 58 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index fdd03f6..922f47d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -49,9 +49,7 @@
time_t nfsd4_lease = 90; /* default lease time */
time_t nfsd4_grace = 90;
static time_t boot_time;
-static u32 current_ownerid = 1;
-static u32 current_fileid = 1;
-static u32 current_delegid = 1;
+static u32 current_stateid = 1;
static stateid_t zerostateid; /* bits all 0 */
static stateid_t onestateid; /* bits all 1 */
static u64 current_sessionid = 1;
@@ -136,11 +134,6 @@ unsigned int max_delegations;
#define OPEN_OWNER_HASH_SIZE (1 << OPEN_OWNER_HASH_BITS)
#define OPEN_OWNER_HASH_MASK (OPEN_OWNER_HASH_SIZE - 1)
-static unsigned int open_ownerid_hashval(const u32 id)
-{
- return id & OPEN_OWNER_HASH_MASK;
-}
-
static unsigned int open_ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
{
unsigned int ret;
@@ -150,7 +143,6 @@ static unsigned int open_ownerstr_hashval(u32 clientid, struct xdr_netobj *owner
return ret & OPEN_OWNER_HASH_MASK;
}
-static struct list_head open_ownerid_hashtbl[OPEN_OWNER_HASH_SIZE];
static struct list_head open_ownerstr_hashtbl[OPEN_OWNER_HASH_SIZE];
/* hash table for nfs4_file */
@@ -255,9 +247,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
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_opaque.so_clid = clp->cl_clientid;
+ dp->dl_stid.sc_stateid.si_opaque.so_id = current_stateid++;
dp->dl_stid.sc_stateid.si_generation = 1;
hash_stid(&dp->dl_stid);
fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle);
@@ -457,7 +448,6 @@ static void unhash_lockowner(struct nfs4_lockowner *lo)
{
struct nfs4_ol_stateid *stp;
- list_del(&lo->lo_owner.so_idhash);
list_del(&lo->lo_owner.so_strhash);
list_del(&lo->lo_perstateid);
while (!list_empty(&lo->lo_owner.so_stateids)) {
@@ -502,7 +492,6 @@ static void unhash_openowner(struct nfs4_openowner *oo)
{
struct nfs4_ol_stateid *stp;
- list_del(&oo->oo_owner.so_idhash);
list_del(&oo->oo_owner.so_strhash);
list_del(&oo->oo_perclient);
while (!list_empty(&oo->oo_owner.so_stateids)) {
@@ -1081,9 +1070,8 @@ static void gen_confirm(struct nfs4_client *clp)
static int
same_stateid(stateid_t *id_one, stateid_t *id_two)
{
- if (id_one->si_stateownerid != id_two->si_stateownerid)
- return 0;
- return id_one->si_fileid == id_two->si_fileid;
+ return 0 == memcmp(&id_one->si_opaque, &id_two->si_opaque,
+ sizeof(stateid_opaque_t));
}
static struct nfs4_stid *find_stateid(stateid_t *t)
@@ -2198,7 +2186,6 @@ alloc_init_file(struct inode *ino)
INIT_LIST_HEAD(&fp->fi_stateids);
INIT_LIST_HEAD(&fp->fi_delegations);
fp->fi_inode = igrab(ino);
- fp->fi_id = current_fileid++;
fp->fi_had_conflict = false;
fp->fi_lease = NULL;
memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
@@ -2295,7 +2282,6 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj
sop->so_owner.len = owner->len;
INIT_LIST_HEAD(&sop->so_stateids);
- sop->so_id = current_ownerid++;
sop->so_client = clp;
init_nfs4_replay(&sop->so_replay);
return sop;
@@ -2303,10 +2289,6 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj
static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
{
- unsigned int idhashval;
-
- idhashval = open_ownerid_hashval(oo->oo_owner.so_id);
- list_add(&oo->oo_owner.so_idhash, &open_ownerid_hashtbl[idhashval]);
list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]);
list_add(&oo->oo_perclient, &clp->cl_openowners);
}
@@ -2331,6 +2313,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
static inline void
init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
struct nfs4_openowner *oo = open->op_openowner;
+ struct nfs4_client *clp = oo->oo_owner.so_client;
INIT_LIST_HEAD(&stp->st_lockowners);
list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
@@ -2339,9 +2322,8 @@ init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, struct nfsd
stp->st_stateowner = &oo->oo_owner;
get_nfs4_file(fp);
stp->st_file = fp;
- stp->st_stid.sc_stateid.si_boot = boot_time;
- stp->st_stid.sc_stateid.si_stateownerid = oo->oo_owner.so_id;
- stp->st_stid.sc_stateid.si_fileid = fp->fi_id;
+ stp->st_stid.sc_stateid.si_opaque.so_clid = clp->cl_clientid;
+ stp->st_stid.sc_stateid.si_opaque.so_id = current_stateid++;
/* note will be incremented before first return to client: */
stp->st_stid.sc_stateid.si_generation = 0;
hash_stid(&stp->st_stid);
@@ -3095,8 +3077,6 @@ nfs4_laundromat(void)
test_val = u;
break;
}
- dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
- oo->oo_owner.so_id);
release_openowner(oo);
}
if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
@@ -3141,7 +3121,7 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *stp)
static int
STALE_STATEID(stateid_t *stateid)
{
- if (stateid->si_boot == boot_time)
+ if (stateid->si_opaque.so_clid.cl_boot == boot_time)
return 0;
dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
STATEID_VAL(stateid));
@@ -3710,11 +3690,6 @@ last_byte_offset(u64 start, u64 len)
return end > start ? end - 1: NFS4_MAX_UINT64;
}
-static unsigned int lockownerid_hashval(u32 id)
-{
- return id & LOCK_HASH_MASK;
-}
-
static inline unsigned int
lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
struct xdr_netobj *ownername)
@@ -3724,7 +3699,6 @@ lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
& LOCK_HASH_MASK;
}
-static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
/*
@@ -3795,10 +3769,6 @@ find_lockowner_str(struct inode *inode, clientid_t *clid,
static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp)
{
- unsigned int idhashval;
-
- idhashval = lockownerid_hashval(lo->lo_owner.so_id);
- list_add(&lo->lo_owner.so_idhash, &lock_ownerid_hashtbl[idhashval]);
list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]);
list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
}
@@ -3831,6 +3801,7 @@ static struct nfs4_ol_stateid *
alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_ol_stateid *open_stp)
{
struct nfs4_ol_stateid *stp;
+ struct nfs4_client *clp = lo->lo_owner.so_client;
stp = nfs4_alloc_stateid();
if (stp == NULL)
@@ -3841,9 +3812,8 @@ alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct
stp->st_stid.sc_type = NFS4_LOCK_STID;
get_nfs4_file(fp);
stp->st_file = fp;
- stp->st_stid.sc_stateid.si_boot = boot_time;
- stp->st_stid.sc_stateid.si_stateownerid = lo->lo_owner.so_id;
- stp->st_stid.sc_stateid.si_fileid = fp->fi_id;
+ stp->st_stid.sc_stateid.si_opaque.so_clid = clp->cl_clientid;
+ stp->st_stid.sc_stateid.si_opaque.so_id = current_stateid++;
/* note will be incremented before first return to client: */
stp->st_stid.sc_stateid.si_generation = 0;
hash_stid(&stp->st_stid);
@@ -4252,7 +4222,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
* data structures. */
INIT_LIST_HEAD(&matches);
for (i = 0; i < LOCK_HASH_SIZE; i++) {
- list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) {
+ list_for_each_entry(sop, &lock_ownerstr_hashtbl[i], so_strhash) {
if (!same_owner_str(sop, owner, clid))
continue;
list_for_each_entry(stp, &sop->so_stateids,
@@ -4398,12 +4368,10 @@ nfs4_state_init(void)
}
for (i = 0; i < OPEN_OWNER_HASH_SIZE; i++) {
INIT_LIST_HEAD(&open_ownerstr_hashtbl[i]);
- INIT_LIST_HEAD(&open_ownerid_hashtbl[i]);
}
for (i = 0; i < STATEID_HASH_SIZE; i++)
INIT_LIST_HEAD(&stateid_hashtbl[i]);
for (i = 0; i < LOCK_HASH_SIZE; i++) {
- INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
}
memset(&onestateid, ~0, sizeof(stateid_t));
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index e807abb..d6aec4f 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -45,24 +45,20 @@ typedef struct {
} clientid_t;
typedef struct {
- u32 so_boot;
- u32 so_stateownerid;
- u32 so_fileid;
+ clientid_t so_clid;
+ u32 so_id;
} stateid_opaque_t;
typedef struct {
u32 si_generation;
stateid_opaque_t si_opaque;
} stateid_t;
-#define si_boot si_opaque.so_boot
-#define si_stateownerid si_opaque.so_stateownerid
-#define si_fileid si_opaque.so_fileid
#define STATEID_FMT "(%08x/%08x/%08x/%08x)"
#define STATEID_VAL(s) \
- (s)->si_boot, \
- (s)->si_stateownerid, \
- (s)->si_fileid, \
+ (s)->si_opaque.so_clid.cl_boot, \
+ (s)->si_opaque.so_clid.cl_id, \
+ (s)->si_opaque.so_id, \
(s)->si_generation
struct nfsd4_callback {
@@ -353,11 +349,9 @@ struct nfs4_replay {
*/
struct nfs4_stateowner {
- struct list_head so_idhash; /* hash by so_id */
struct list_head so_strhash; /* hash by op_name */
struct list_head so_stateids;
int so_is_open_owner; /* 1=openowner,0=lockowner */
- u32 so_id;
struct nfs4_client * so_client;
/* after increment in ENCODE_SEQID_OP_TAIL, represents the next
* sequence id expected from the client: */
@@ -415,8 +409,6 @@ struct nfs4_file {
struct file_lock *fi_lease;
atomic_t fi_delegees;
struct inode *fi_inode;
- u32 fi_id; /* used with stateowner->so_id
- * for stateid_hashtbl hash */
bool fi_had_conflict;
};
--
1.7.4.1
next prev parent reply other threads:[~2011-09-19 13:15 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 ` [PATCH 22/25] nfsd4: hash deleg stateid's like any other J. Bruce Fields
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 ` J. Bruce Fields [this message]
2011-09-27 16:10 ` [PATCH 4/5] nfsd4: construct stateid from clientid and counter 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=1316438143-1057-4-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).