aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-07-30 23:33:59 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-09-07 09:45:49 -0400
commitfe0750e5c43189adb6e6fc59837af7d5a588f413 (patch)
tree88c5afe7a955f1e55e305639a4d6031237542b8d /fs/nfsd/nfs4state.c
parentf4dee24cca98739a4190a00fa014cd1b7e2581a4 (diff)
nfsd4: split stateowners into open and lockowners
The stateowner has some fields that only make sense for openowners, and some that only make sense for lockowners, and I find it a lot clearer if those are separated out. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c367
1 files changed, 186 insertions, 181 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index eb11626babc6..567130dccda0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -63,7 +63,7 @@ static u64 current_sessionid = 1;
63static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 63static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
64static struct nfs4_delegation * search_for_delegation(stateid_t *stid); 64static struct nfs4_delegation * search_for_delegation(stateid_t *stid);
65static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); 65static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
66static int check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner); 66static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
67 67
68/* Locking: */ 68/* Locking: */
69 69
@@ -77,7 +77,8 @@ static DEFINE_MUTEX(client_mutex);
77 */ 77 */
78static DEFINE_SPINLOCK(recall_lock); 78static DEFINE_SPINLOCK(recall_lock);
79 79
80static struct kmem_cache *stateowner_slab = NULL; 80static struct kmem_cache *openowner_slab = NULL;
81static struct kmem_cache *lockowner_slab = NULL;
81static struct kmem_cache *file_slab = NULL; 82static struct kmem_cache *file_slab = NULL;
82static struct kmem_cache *stateid_slab = NULL; 83static struct kmem_cache *stateid_slab = NULL;
83static struct kmem_cache *deleg_slab = NULL; 84static struct kmem_cache *deleg_slab = NULL;
@@ -432,41 +433,39 @@ static void release_lock_stateid(struct nfs4_stateid *stp)
432 unhash_generic_stateid(stp); 433 unhash_generic_stateid(stp);
433 file = find_any_file(stp->st_file); 434 file = find_any_file(stp->st_file);
434 if (file) 435 if (file)
435 locks_remove_posix(file, (fl_owner_t)stp->st_stateowner); 436 locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner));
436 free_generic_stateid(stp); 437 free_generic_stateid(stp);
437} 438}
438 439
439static void unhash_lockowner(struct nfs4_stateowner *sop) 440static void unhash_lockowner(struct nfs4_lockowner *lo)
440{ 441{
441 struct nfs4_stateid *stp; 442 struct nfs4_stateid *stp;
442 443
443 list_del(&sop->so_idhash); 444 list_del(&lo->lo_owner.so_idhash);
444 list_del(&sop->so_strhash); 445 list_del(&lo->lo_owner.so_strhash);
445 list_del(&sop->so_perstateid); 446 list_del(&lo->lo_perstateid);
446 while (!list_empty(&sop->so_stateids)) { 447 while (!list_empty(&lo->lo_owner.so_stateids)) {
447 stp = list_first_entry(&sop->so_stateids, 448 stp = list_first_entry(&lo->lo_owner.so_stateids,
448 struct nfs4_stateid, st_perstateowner); 449 struct nfs4_stateid, st_perstateowner);
449 release_lock_stateid(stp); 450 release_lock_stateid(stp);
450 } 451 }
451} 452}
452 453
453static void release_lockowner(struct nfs4_stateowner *sop) 454static void release_lockowner(struct nfs4_lockowner *lo)
454{ 455{
455 unhash_lockowner(sop); 456 unhash_lockowner(lo);
456 nfs4_free_stateowner(sop); 457 nfs4_free_lockowner(lo);
457} 458}
458 459
459static void 460static void
460release_stateid_lockowners(struct nfs4_stateid *open_stp) 461release_stateid_lockowners(struct nfs4_stateid *open_stp)
461{ 462{
462 struct nfs4_stateowner *lock_sop; 463 struct nfs4_lockowner *lo;
463 464
464 while (!list_empty(&open_stp->st_lockowners)) { 465 while (!list_empty(&open_stp->st_lockowners)) {
465 lock_sop = list_entry(open_stp->st_lockowners.next, 466 lo = list_entry(open_stp->st_lockowners.next,
466 struct nfs4_stateowner, so_perstateid); 467 struct nfs4_lockowner, lo_perstateid);
467 /* list_del(&open_stp->st_lockowners); */ 468 release_lockowner(lo);
468 BUG_ON(lock_sop->so_is_open_owner);
469 release_lockowner(lock_sop);
470 } 469 }
471} 470}
472 471
@@ -477,26 +476,25 @@ static void release_open_stateid(struct nfs4_stateid *stp)
477 free_generic_stateid(stp); 476 free_generic_stateid(stp);
478} 477}
479 478
480static void unhash_openowner(struct nfs4_stateowner *sop) 479static void unhash_openowner(struct nfs4_openowner *oo)
481{ 480{
482 struct nfs4_stateid *stp; 481 struct nfs4_stateid *stp;
483 482
484 list_del(&sop->so_idhash); 483 list_del(&oo->oo_owner.so_idhash);
485 list_del(&sop->so_strhash); 484 list_del(&oo->oo_owner.so_strhash);
486 list_del(&sop->so_perclient); 485 list_del(&oo->oo_perclient);
487 list_del(&sop->so_perstateid); /* XXX: necessary? */ 486 while (!list_empty(&oo->oo_owner.so_stateids)) {
488 while (!list_empty(&sop->so_stateids)) { 487 stp = list_first_entry(&oo->oo_owner.so_stateids,
489 stp = list_first_entry(&sop->so_stateids,
490 struct nfs4_stateid, st_perstateowner); 488 struct nfs4_stateid, st_perstateowner);
491 release_open_stateid(stp); 489 release_open_stateid(stp);
492 } 490 }
493} 491}
494 492
495static void release_openowner(struct nfs4_stateowner *sop) 493static void release_openowner(struct nfs4_openowner *oo)
496{ 494{
497 unhash_openowner(sop); 495 unhash_openowner(oo);
498 list_del(&sop->so_close_lru); 496 list_del(&oo->oo_close_lru);
499 nfs4_free_stateowner(sop); 497 nfs4_free_openowner(oo);
500} 498}
501 499
502#define SESSION_HASH_SIZE 512 500#define SESSION_HASH_SIZE 512
@@ -961,7 +959,7 @@ unhash_client_locked(struct nfs4_client *clp)
961static void 959static void
962expire_client(struct nfs4_client *clp) 960expire_client(struct nfs4_client *clp)
963{ 961{
964 struct nfs4_stateowner *sop; 962 struct nfs4_openowner *oo;
965 struct nfs4_delegation *dp; 963 struct nfs4_delegation *dp;
966 struct list_head reaplist; 964 struct list_head reaplist;
967 965
@@ -979,8 +977,8 @@ expire_client(struct nfs4_client *clp)
979 unhash_delegation(dp); 977 unhash_delegation(dp);
980 } 978 }
981 while (!list_empty(&clp->cl_openowners)) { 979 while (!list_empty(&clp->cl_openowners)) {
982 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient); 980 oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
983 release_openowner(sop); 981 release_openowner(oo);
984 } 982 }
985 nfsd4_shutdown_callback(clp); 983 nfsd4_shutdown_callback(clp);
986 if (clp->cl_cb_conn.cb_xprt) 984 if (clp->cl_cb_conn.cb_xprt)
@@ -2173,7 +2171,8 @@ nfsd4_free_slab(struct kmem_cache **slab)
2173void 2171void
2174nfsd4_free_slabs(void) 2172nfsd4_free_slabs(void)
2175{ 2173{
2176 nfsd4_free_slab(&stateowner_slab); 2174 nfsd4_free_slab(&openowner_slab);
2175 nfsd4_free_slab(&lockowner_slab);
2177 nfsd4_free_slab(&file_slab); 2176 nfsd4_free_slab(&file_slab);
2178 nfsd4_free_slab(&stateid_slab); 2177 nfsd4_free_slab(&stateid_slab);
2179 nfsd4_free_slab(&deleg_slab); 2178 nfsd4_free_slab(&deleg_slab);
@@ -2182,9 +2181,13 @@ nfsd4_free_slabs(void)
2182static int 2181static int
2183nfsd4_init_slabs(void) 2182nfsd4_init_slabs(void)
2184{ 2183{
2185 stateowner_slab = kmem_cache_create("nfsd4_stateowners", 2184 openowner_slab = kmem_cache_create("nfsd4_openowners",
2186 sizeof(struct nfs4_stateowner), 0, 0, NULL); 2185 sizeof(struct nfs4_openowner), 0, 0, NULL);
2187 if (stateowner_slab == NULL) 2186 if (openowner_slab == NULL)
2187 goto out_nomem;
2188 lockowner_slab = kmem_cache_create("nfsd4_lockowners",
2189 sizeof(struct nfs4_openowner), 0, 0, NULL);
2190 if (lockowner_slab == NULL)
2188 goto out_nomem; 2191 goto out_nomem;
2189 file_slab = kmem_cache_create("nfsd4_files", 2192 file_slab = kmem_cache_create("nfsd4_files",
2190 sizeof(struct nfs4_file), 0, 0, NULL); 2193 sizeof(struct nfs4_file), 0, 0, NULL);
@@ -2205,11 +2208,16 @@ out_nomem:
2205 return -ENOMEM; 2208 return -ENOMEM;
2206} 2209}
2207 2210
2208void 2211void nfs4_free_openowner(struct nfs4_openowner *oo)
2209nfs4_free_stateowner(struct nfs4_stateowner *sop) 2212{
2213 kfree(oo->oo_owner.so_owner.data);
2214 kmem_cache_free(openowner_slab, oo);
2215}
2216
2217void nfs4_free_lockowner(struct nfs4_lockowner *lo)
2210{ 2218{
2211 kfree(sop->so_owner.data); 2219 kfree(lo->lo_owner.so_owner.data);
2212 kmem_cache_free(stateowner_slab, sop); 2220 kmem_cache_free(lockowner_slab, lo);
2213} 2221}
2214 2222
2215static void init_nfs4_replay(struct nfs4_replay *rp) 2223static void init_nfs4_replay(struct nfs4_replay *rp)
@@ -2219,74 +2227,72 @@ static void init_nfs4_replay(struct nfs4_replay *rp)
2219 rp->rp_buf = rp->rp_ibuf; 2227 rp->rp_buf = rp->rp_ibuf;
2220} 2228}
2221 2229
2222static inline struct nfs4_stateowner *alloc_stateowner(struct xdr_netobj *owner, struct nfs4_client *clp) 2230static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj *owner, struct nfs4_client *clp)
2223{ 2231{
2224 struct nfs4_stateowner *sop; 2232 struct nfs4_stateowner *sop;
2225 2233
2226 sop = kmem_cache_alloc(stateowner_slab, GFP_KERNEL); 2234 sop = kmem_cache_alloc(slab, GFP_KERNEL);
2227 if (!sop) 2235 if (!sop)
2228 return NULL; 2236 return NULL;
2229 2237
2230 sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL); 2238 sop->so_owner.data = kmemdup(owner->data, owner->len, GFP_KERNEL);
2231 if (!sop->so_owner.data) { 2239 if (!sop->so_owner.data) {
2232 kmem_cache_free(stateowner_slab, sop); 2240 kmem_cache_free(slab, sop);
2233 return NULL; 2241 return NULL;
2234 } 2242 }
2235 sop->so_owner.len = owner->len; 2243 sop->so_owner.len = owner->len;
2236 2244
2237 INIT_LIST_HEAD(&sop->so_perclient);
2238 INIT_LIST_HEAD(&sop->so_stateids); 2245 INIT_LIST_HEAD(&sop->so_stateids);
2239 INIT_LIST_HEAD(&sop->so_perstateid);
2240 INIT_LIST_HEAD(&sop->so_close_lru);
2241 sop->so_id = current_ownerid++; 2246 sop->so_id = current_ownerid++;
2242 sop->so_time = 0;
2243 sop->so_client = clp; 2247 sop->so_client = clp;
2244 init_nfs4_replay(&sop->so_replay); 2248 init_nfs4_replay(&sop->so_replay);
2245 return sop; 2249 return sop;
2246} 2250}
2247 2251
2248static void hash_openowner(struct nfs4_stateowner *sop, struct nfs4_client *clp, unsigned int strhashval) 2252static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
2249{ 2253{
2250 unsigned int idhashval; 2254 unsigned int idhashval;
2251 2255
2252 idhashval = open_ownerid_hashval(sop->so_id); 2256 idhashval = open_ownerid_hashval(oo->oo_owner.so_id);
2253 list_add(&sop->so_idhash, &open_ownerid_hashtbl[idhashval]); 2257 list_add(&oo->oo_owner.so_idhash, &open_ownerid_hashtbl[idhashval]);
2254 list_add(&sop->so_strhash, &open_ownerstr_hashtbl[strhashval]); 2258 list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]);
2255 list_add(&sop->so_perclient, &clp->cl_openowners); 2259 list_add(&oo->oo_perclient, &clp->cl_openowners);
2256} 2260}
2257 2261
2258static struct nfs4_stateowner * 2262static struct nfs4_openowner *
2259alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { 2263alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) {
2260 struct nfs4_stateowner *sop; 2264 struct nfs4_openowner *oo;
2261 2265
2262 sop = alloc_stateowner(&open->op_owner, clp); 2266 oo = alloc_stateowner(openowner_slab, &open->op_owner, clp);
2263 if (!sop) 2267 if (!oo)
2264 return NULL; 2268 return NULL;
2265 sop->so_is_open_owner = 1; 2269 oo->oo_owner.so_is_open_owner = 1;
2266 sop->so_seqid = open->op_seqid; 2270 oo->oo_owner.so_seqid = open->op_seqid;
2267 sop->so_confirmed = 0; 2271 oo->oo_confirmed = 0;
2268 hash_openowner(sop, clp, strhashval); 2272 oo->oo_time = 0;
2269 return sop; 2273 INIT_LIST_HEAD(&oo->oo_close_lru);
2274 hash_openowner(oo, clp, strhashval);
2275 return oo;
2270} 2276}
2271 2277
2272static inline void 2278static inline void
2273init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) { 2279init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
2274 struct nfs4_stateowner *sop = open->op_stateowner; 2280 struct nfs4_openowner *oo = open->op_openowner;
2275 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 2281 unsigned int hashval = stateid_hashval(oo->oo_owner.so_id, fp->fi_id);
2276 2282
2277 INIT_LIST_HEAD(&stp->st_hash); 2283 INIT_LIST_HEAD(&stp->st_hash);
2278 INIT_LIST_HEAD(&stp->st_perstateowner); 2284 INIT_LIST_HEAD(&stp->st_perstateowner);
2279 INIT_LIST_HEAD(&stp->st_lockowners); 2285 INIT_LIST_HEAD(&stp->st_lockowners);
2280 INIT_LIST_HEAD(&stp->st_perfile); 2286 INIT_LIST_HEAD(&stp->st_perfile);
2281 list_add(&stp->st_hash, &stateid_hashtbl[hashval]); 2287 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
2282 list_add(&stp->st_perstateowner, &sop->so_stateids); 2288 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
2283 list_add(&stp->st_perfile, &fp->fi_stateids); 2289 list_add(&stp->st_perfile, &fp->fi_stateids);
2284 stp->st_type = NFS4_OPEN_STID; 2290 stp->st_type = NFS4_OPEN_STID;
2285 stp->st_stateowner = sop; 2291 stp->st_stateowner = &oo->oo_owner;
2286 get_nfs4_file(fp); 2292 get_nfs4_file(fp);
2287 stp->st_file = fp; 2293 stp->st_file = fp;
2288 stp->st_stateid.si_boot = boot_time; 2294 stp->st_stateid.si_boot = boot_time;
2289 stp->st_stateid.si_stateownerid = sop->so_id; 2295 stp->st_stateid.si_stateownerid = oo->oo_owner.so_id;
2290 stp->st_stateid.si_fileid = fp->fi_id; 2296 stp->st_stateid.si_fileid = fp->fi_id;
2291 /* note will be incremented before first return to client: */ 2297 /* note will be incremented before first return to client: */
2292 stp->st_stateid.si_generation = 0; 2298 stp->st_stateid.si_generation = 0;
@@ -2299,12 +2305,12 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
2299} 2305}
2300 2306
2301static void 2307static void
2302move_to_close_lru(struct nfs4_stateowner *sop) 2308move_to_close_lru(struct nfs4_openowner *oo)
2303{ 2309{
2304 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); 2310 dprintk("NFSD: move_to_close_lru nfs4_openowner %p\n", oo);
2305 2311
2306 list_move_tail(&sop->so_close_lru, &close_lru); 2312 list_move_tail(&oo->oo_close_lru, &close_lru);
2307 sop->so_time = get_seconds(); 2313 oo->oo_time = get_seconds();
2308} 2314}
2309 2315
2310static int 2316static int
@@ -2316,14 +2322,14 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
2316 (sop->so_client->cl_clientid.cl_id == clid->cl_id); 2322 (sop->so_client->cl_clientid.cl_id == clid->cl_id);
2317} 2323}
2318 2324
2319static struct nfs4_stateowner * 2325static struct nfs4_openowner *
2320find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open) 2326find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
2321{ 2327{
2322 struct nfs4_stateowner *so = NULL; 2328 struct nfs4_stateowner *so = NULL;
2323 2329
2324 list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) { 2330 list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) {
2325 if (same_owner_str(so, &open->op_owner, &open->op_clientid)) 2331 if (same_owner_str(so, &open->op_owner, &open->op_clientid))
2326 return so; 2332 return container_of(so, struct nfs4_openowner, oo_owner);
2327 } 2333 }
2328 return NULL; 2334 return NULL;
2329} 2335}
@@ -2474,7 +2480,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2474 clientid_t *clientid = &open->op_clientid; 2480 clientid_t *clientid = &open->op_clientid;
2475 struct nfs4_client *clp = NULL; 2481 struct nfs4_client *clp = NULL;
2476 unsigned int strhashval; 2482 unsigned int strhashval;
2477 struct nfs4_stateowner *sop = NULL; 2483 struct nfs4_openowner *oo = NULL;
2478 __be32 status; 2484 __be32 status;
2479 2485
2480 if (!check_name(open->op_owner)) 2486 if (!check_name(open->op_owner))
@@ -2484,34 +2490,34 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
2484 return nfserr_stale_clientid; 2490 return nfserr_stale_clientid;
2485 2491
2486 strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner); 2492 strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner);
2487 sop = find_openstateowner_str(strhashval, open); 2493 oo = find_openstateowner_str(strhashval, open);
2488 open->op_stateowner = sop; 2494 open->op_openowner = oo;
2489 if (!sop) { 2495 if (!oo) {
2490 /* Make sure the client's lease hasn't expired. */ 2496 /* Make sure the client's lease hasn't expired. */
2491 clp = find_confirmed_client(clientid); 2497 clp = find_confirmed_client(clientid);
2492 if (clp == NULL) 2498 if (clp == NULL)
2493 return nfserr_expired; 2499 return nfserr_expired;
2494 goto renew; 2500 goto renew;
2495 } 2501 }
2496 if (!sop->so_confirmed) { 2502 if (!oo->oo_confirmed) {
2497 /* Replace unconfirmed owners without checking for replay. */ 2503 /* Replace unconfirmed owners without checking for replay. */
2498 clp = sop->so_client; 2504 clp = oo->oo_owner.so_client;
2499 release_openowner(sop); 2505 release_openowner(oo);
2500 open->op_stateowner = NULL; 2506 open->op_openowner = NULL;
2501 goto renew; 2507 goto renew;
2502 } 2508 }
2503 status = nfsd4_check_seqid(cstate, sop, open->op_seqid); 2509 status = nfsd4_check_seqid(cstate, &oo->oo_owner, open->op_seqid);
2504 if (status) 2510 if (status)
2505 return status; 2511 return status;
2506renew: 2512renew:
2507 if (open->op_stateowner == NULL) { 2513 if (open->op_openowner == NULL) {
2508 sop = alloc_init_open_stateowner(strhashval, clp, open); 2514 oo = alloc_init_open_stateowner(strhashval, clp, open);
2509 if (sop == NULL) 2515 if (oo == NULL)
2510 return nfserr_jukebox; 2516 return nfserr_jukebox;
2511 open->op_stateowner = sop; 2517 open->op_openowner = oo;
2512 } 2518 }
2513 list_del_init(&sop->so_close_lru); 2519 list_del_init(&oo->oo_close_lru);
2514 renew_client(sop->so_client); 2520 renew_client(oo->oo_owner.so_client);
2515 return nfs_ok; 2521 return nfs_ok;
2516} 2522}
2517 2523
@@ -2565,7 +2571,7 @@ out:
2565 return nfs_ok; 2571 return nfs_ok;
2566 if (status) 2572 if (status)
2567 return status; 2573 return status;
2568 open->op_stateowner->so_confirmed = 1; 2574 open->op_openowner->oo_confirmed = 1;
2569 return nfs_ok; 2575 return nfs_ok;
2570} 2576}
2571 2577
@@ -2573,14 +2579,14 @@ static __be32
2573nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) 2579nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
2574{ 2580{
2575 struct nfs4_stateid *local; 2581 struct nfs4_stateid *local;
2576 struct nfs4_stateowner *sop = open->op_stateowner; 2582 struct nfs4_openowner *oo = open->op_openowner;
2577 2583
2578 list_for_each_entry(local, &fp->fi_stateids, st_perfile) { 2584 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
2579 /* ignore lock owners */ 2585 /* ignore lock owners */
2580 if (local->st_stateowner->so_is_open_owner == 0) 2586 if (local->st_stateowner->so_is_open_owner == 0)
2581 continue; 2587 continue;
2582 /* remember if we have seen this open owner */ 2588 /* remember if we have seen this open owner */
2583 if (local->st_stateowner == sop) 2589 if (local->st_stateowner == &oo->oo_owner)
2584 *stpp = local; 2590 *stpp = local;
2585 /* check for conflicting share reservations */ 2591 /* check for conflicting share reservations */
2586 if (!test_share(local, open)) 2592 if (!test_share(local, open))
@@ -2698,8 +2704,8 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2698static void 2704static void
2699nfs4_set_claim_prev(struct nfsd4_open *open) 2705nfs4_set_claim_prev(struct nfsd4_open *open)
2700{ 2706{
2701 open->op_stateowner->so_confirmed = 1; 2707 open->op_openowner->oo_confirmed = 1;
2702 open->op_stateowner->so_client->cl_firststate = 1; 2708 open->op_openowner->oo_owner.so_client->cl_firststate = 1;
2703} 2709}
2704 2710
2705/* Should we give out recallable state?: */ 2711/* Should we give out recallable state?: */
@@ -2782,11 +2788,11 @@ static void
2782nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp) 2788nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_stateid *stp)
2783{ 2789{
2784 struct nfs4_delegation *dp; 2790 struct nfs4_delegation *dp;
2785 struct nfs4_stateowner *sop = stp->st_stateowner; 2791 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
2786 int cb_up; 2792 int cb_up;
2787 int status, flag = 0; 2793 int status, flag = 0;
2788 2794
2789 cb_up = nfsd4_cb_channel_good(sop->so_client); 2795 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
2790 flag = NFS4_OPEN_DELEGATE_NONE; 2796 flag = NFS4_OPEN_DELEGATE_NONE;
2791 open->op_recall = 0; 2797 open->op_recall = 0;
2792 switch (open->op_claim_type) { 2798 switch (open->op_claim_type) {
@@ -2802,7 +2808,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2802 * had the chance to reclaim theirs.... */ 2808 * had the chance to reclaim theirs.... */
2803 if (locks_in_grace()) 2809 if (locks_in_grace())
2804 goto out; 2810 goto out;
2805 if (!cb_up || !sop->so_confirmed) 2811 if (!cb_up || !oo->oo_confirmed)
2806 goto out; 2812 goto out;
2807 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 2813 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
2808 flag = NFS4_OPEN_DELEGATE_WRITE; 2814 flag = NFS4_OPEN_DELEGATE_WRITE;
@@ -2813,7 +2819,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
2813 goto out; 2819 goto out;
2814 } 2820 }
2815 2821
2816 dp = alloc_init_deleg(sop->so_client, stp, fh, flag); 2822 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
2817 if (dp == NULL) 2823 if (dp == NULL)
2818 goto out_no_deleg; 2824 goto out_no_deleg;
2819 status = nfs4_set_delegation(dp, flag); 2825 status = nfs4_set_delegation(dp, flag);
@@ -2901,7 +2907,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2901 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); 2907 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
2902 2908
2903 if (nfsd4_has_session(&resp->cstate)) 2909 if (nfsd4_has_session(&resp->cstate))
2904 open->op_stateowner->so_confirmed = 1; 2910 open->op_openowner->oo_confirmed = 1;
2905 2911
2906 /* 2912 /*
2907 * Attempt to hand out a delegation. No error return, because the 2913 * Attempt to hand out a delegation. No error return, because the
@@ -2922,7 +2928,7 @@ out:
2922 * To finish the open response, we just need to set the rflags. 2928 * To finish the open response, we just need to set the rflags.
2923 */ 2929 */
2924 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; 2930 open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
2925 if (!open->op_stateowner->so_confirmed && 2931 if (!open->op_openowner->oo_confirmed &&
2926 !nfsd4_has_session(&resp->cstate)) 2932 !nfsd4_has_session(&resp->cstate))
2927 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; 2933 open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
2928 2934
@@ -2981,7 +2987,7 @@ static time_t
2981nfs4_laundromat(void) 2987nfs4_laundromat(void)
2982{ 2988{
2983 struct nfs4_client *clp; 2989 struct nfs4_client *clp;
2984 struct nfs4_stateowner *sop; 2990 struct nfs4_openowner *oo;
2985 struct nfs4_delegation *dp; 2991 struct nfs4_delegation *dp;
2986 struct list_head *pos, *next, reaplist; 2992 struct list_head *pos, *next, reaplist;
2987 time_t cutoff = get_seconds() - nfsd4_lease; 2993 time_t cutoff = get_seconds() - nfsd4_lease;
@@ -3038,16 +3044,16 @@ nfs4_laundromat(void)
3038 } 3044 }
3039 test_val = nfsd4_lease; 3045 test_val = nfsd4_lease;
3040 list_for_each_safe(pos, next, &close_lru) { 3046 list_for_each_safe(pos, next, &close_lru) {
3041 sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); 3047 oo = container_of(pos, struct nfs4_openowner, oo_close_lru);
3042 if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { 3048 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) {
3043 u = sop->so_time - cutoff; 3049 u = oo->oo_time - cutoff;
3044 if (test_val > u) 3050 if (test_val > u)
3045 test_val = u; 3051 test_val = u;
3046 break; 3052 break;
3047 } 3053 }
3048 dprintk("NFSD: purging unused open stateowner (so_id %d)\n", 3054 dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
3049 sop->so_id); 3055 oo->oo_owner.so_id);
3050 release_openowner(sop); 3056 release_openowner(oo);
3051 } 3057 }
3052 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) 3058 if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
3053 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; 3059 clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
@@ -3069,13 +3075,12 @@ laundromat_main(struct work_struct *not_used)
3069 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 3075 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
3070} 3076}
3071 3077
3072static struct nfs4_stateowner * 3078static struct nfs4_openowner * search_close_lru(u32 st_id)
3073search_close_lru(u32 st_id)
3074{ 3079{
3075 struct nfs4_stateowner *local; 3080 struct nfs4_openowner *local;
3076 3081
3077 list_for_each_entry(local, &close_lru, so_close_lru) { 3082 list_for_each_entry(local, &close_lru, oo_close_lru) {
3078 if (local->so_id == st_id) 3083 if (local->oo_owner.so_id == st_id)
3079 return local; 3084 return local;
3080 } 3085 }
3081 return NULL; 3086 return NULL;
@@ -3209,7 +3214,8 @@ __be32 nfs4_validate_stateid(stateid_t *stateid, bool has_session)
3209 goto out; 3214 goto out;
3210 status = nfserr_bad_stateid; 3215 status = nfserr_bad_stateid;
3211 3216
3212 if (!stp->st_stateowner->so_confirmed) 3217 if (stp->st_stateowner->so_is_open_owner
3218 && !openowner(stp->st_stateowner)->oo_confirmed)
3213 goto out; 3219 goto out;
3214 3220
3215 status = check_stateid_generation(stateid, &stp->st_stateid, has_session); 3221 status = check_stateid_generation(stateid, &stp->st_stateid, has_session);
@@ -3274,7 +3280,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
3274 status = nfserr_bad_stateid; 3280 status = nfserr_bad_stateid;
3275 if (nfs4_check_fh(current_fh, stp)) 3281 if (nfs4_check_fh(current_fh, stp))
3276 goto out; 3282 goto out;
3277 if (!stp->st_stateowner->so_confirmed) 3283 if (stp->st_stateowner->so_is_open_owner
3284 && !openowner(stp->st_stateowner)->oo_confirmed)
3278 goto out; 3285 goto out;
3279 status = check_stateid_generation(stateid, &stp->st_stateid, 3286 status = check_stateid_generation(stateid, &stp->st_stateid,
3280 nfsd4_has_session(cstate)); 3287 nfsd4_has_session(cstate));
@@ -3308,7 +3315,7 @@ nfsd4_free_delegation_stateid(stateid_t *stateid)
3308static __be32 3315static __be32
3309nfsd4_free_lock_stateid(struct nfs4_stateid *stp) 3316nfsd4_free_lock_stateid(struct nfs4_stateid *stp)
3310{ 3317{
3311 if (check_for_locks(stp->st_file, stp->st_stateowner)) 3318 if (check_for_locks(stp->st_file, lockowner(stp->st_stateowner)))
3312 return nfserr_locks_held; 3319 return nfserr_locks_held;
3313 release_lock_stateid(stp); 3320 release_lock_stateid(stp);
3314 return nfs_ok; 3321 return nfs_ok;
@@ -3417,7 +3424,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
3417 if (status) 3424 if (status)
3418 return status; 3425 return status;
3419 3426
3420 if (!sop->so_confirmed && !(flags & CONFIRM)) { 3427 if (sop->so_is_open_owner && !openowner(sop)->oo_confirmed
3428 && !(flags & CONFIRM)) {
3421 dprintk("NFSD: preprocess_seqid_op: stateowner not" 3429 dprintk("NFSD: preprocess_seqid_op: stateowner not"
3422 " confirmed yet!\n"); 3430 " confirmed yet!\n");
3423 return nfserr_bad_stateid; 3431 return nfserr_bad_stateid;
@@ -3434,7 +3442,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3434 struct nfsd4_open_confirm *oc) 3442 struct nfsd4_open_confirm *oc)
3435{ 3443{
3436 __be32 status; 3444 __be32 status;
3437 struct nfs4_stateowner *sop; 3445 struct nfs4_openowner *oo;
3438 struct nfs4_stateid *stp; 3446 struct nfs4_stateid *stp;
3439 3447
3440 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", 3448 dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
@@ -3452,17 +3460,17 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3452 CONFIRM | OPEN_STATE, &stp); 3460 CONFIRM | OPEN_STATE, &stp);
3453 if (status) 3461 if (status)
3454 goto out; 3462 goto out;
3455 sop = stp->st_stateowner; 3463 oo = openowner(stp->st_stateowner);
3456 status = nfserr_bad_stateid; 3464 status = nfserr_bad_stateid;
3457 if (sop->so_confirmed) 3465 if (oo->oo_confirmed)
3458 goto out; 3466 goto out;
3459 sop->so_confirmed = 1; 3467 oo->oo_confirmed = 1;
3460 update_stateid(&stp->st_stateid); 3468 update_stateid(&stp->st_stateid);
3461 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); 3469 memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t));
3462 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 3470 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
3463 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); 3471 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid));
3464 3472
3465 nfsd4_create_clid_dir(sop->so_client); 3473 nfsd4_create_clid_dir(oo->oo_owner.so_client);
3466 status = nfs_ok; 3474 status = nfs_ok;
3467out: 3475out:
3468 if (!cstate->replay_owner) 3476 if (!cstate->replay_owner)
@@ -3513,7 +3521,6 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3513 &od->od_stateid, OPEN_STATE, &stp); 3521 &od->od_stateid, OPEN_STATE, &stp);
3514 if (status) 3522 if (status)
3515 goto out; 3523 goto out;
3516
3517 status = nfserr_inval; 3524 status = nfserr_inval;
3518 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3525 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) {
3519 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3526 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n",
@@ -3546,8 +3553,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3546 struct nfsd4_close *close) 3553 struct nfsd4_close *close)
3547{ 3554{
3548 __be32 status; 3555 __be32 status;
3556 struct nfs4_openowner *oo;
3549 struct nfs4_stateid *stp; 3557 struct nfs4_stateid *stp;
3550 struct nfs4_stateowner *so;
3551 3558
3552 dprintk("NFSD: nfsd4_close on file %.*s\n", 3559 dprintk("NFSD: nfsd4_close on file %.*s\n",
3553 (int)cstate->current_fh.fh_dentry->d_name.len, 3560 (int)cstate->current_fh.fh_dentry->d_name.len,
@@ -3563,19 +3570,19 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3563 * Also, we should make sure this isn't just the result of 3570 * Also, we should make sure this isn't just the result of
3564 * a replayed close: 3571 * a replayed close:
3565 */ 3572 */
3566 so = search_close_lru(close->cl_stateid.si_stateownerid); 3573 oo = search_close_lru(close->cl_stateid.si_stateownerid);
3567 /* It's not stale; let's assume it's expired: */ 3574 /* It's not stale; let's assume it's expired: */
3568 if (so == NULL) 3575 if (oo == NULL)
3569 goto out; 3576 goto out;
3570 cstate->replay_owner = so; 3577 cstate->replay_owner = &oo->oo_owner;
3571 status = nfsd4_check_seqid(cstate, so, close->cl_seqid); 3578 status = nfsd4_check_seqid(cstate, &oo->oo_owner, close->cl_seqid);
3572 if (status) 3579 if (status)
3573 goto out; 3580 goto out;
3574 status = nfserr_bad_seqid; 3581 status = nfserr_bad_seqid;
3575 } 3582 }
3576 if (status) 3583 if (status)
3577 goto out; 3584 goto out;
3578 so = stp->st_stateowner; 3585 oo = openowner(stp->st_stateowner);
3579 status = nfs_ok; 3586 status = nfs_ok;
3580 update_stateid(&stp->st_stateid); 3587 update_stateid(&stp->st_stateid);
3581 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); 3588 memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
@@ -3587,8 +3594,8 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3587 * released by the laundromat service after the lease period 3594 * released by the laundromat service after the lease period
3588 * to enable us to handle CLOSE replay 3595 * to enable us to handle CLOSE replay
3589 */ 3596 */
3590 if (list_empty(&so->so_stateids)) 3597 if (list_empty(&oo->oo_owner.so_stateids))
3591 move_to_close_lru(so); 3598 move_to_close_lru(oo);
3592out: 3599out:
3593 if (!cstate->replay_owner) 3600 if (!cstate->replay_owner)
3594 nfs4_unlock_state(); 3601 nfs4_unlock_state();
@@ -3768,17 +3775,17 @@ static const struct lock_manager_operations nfsd_posix_mng_ops = {
3768static inline void 3775static inline void
3769nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny) 3776nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
3770{ 3777{
3771 struct nfs4_stateowner *sop; 3778 struct nfs4_lockowner *lo;
3772 3779
3773 if (fl->fl_lmops == &nfsd_posix_mng_ops) { 3780 if (fl->fl_lmops == &nfsd_posix_mng_ops) {
3774 sop = (struct nfs4_stateowner *) fl->fl_owner; 3781 lo = (struct nfs4_lockowner *) fl->fl_owner;
3775 deny->ld_owner.data = kmemdup(sop->so_owner.data, 3782 deny->ld_owner.data = kmemdup(lo->lo_owner.so_owner.data,
3776 sop->so_owner.len, GFP_KERNEL); 3783 lo->lo_owner.so_owner.len, GFP_KERNEL);
3777 if (!deny->ld_owner.data) 3784 if (!deny->ld_owner.data)
3778 /* We just don't care that much */ 3785 /* We just don't care that much */
3779 goto nevermind; 3786 goto nevermind;
3780 deny->ld_owner.len = sop->so_owner.len; 3787 deny->ld_owner.len = lo->lo_owner.so_owner.len;
3781 deny->ld_clientid = sop->so_client->cl_clientid; 3788 deny->ld_clientid = lo->lo_owner.so_client->cl_clientid;
3782 } else { 3789 } else {
3783nevermind: 3790nevermind:
3784 deny->ld_owner.len = 0; 3791 deny->ld_owner.len = 0;
@@ -3795,8 +3802,8 @@ nevermind:
3795 deny->ld_type = NFS4_WRITE_LT; 3802 deny->ld_type = NFS4_WRITE_LT;
3796} 3803}
3797 3804
3798static struct nfs4_stateowner * 3805static struct nfs4_lockowner *
3799find_lockstateowner_str(struct inode *inode, clientid_t *clid, 3806find_lockowner_str(struct inode *inode, clientid_t *clid,
3800 struct xdr_netobj *owner) 3807 struct xdr_netobj *owner)
3801{ 3808{
3802 unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); 3809 unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner);
@@ -3804,19 +3811,19 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
3804 3811
3805 list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { 3812 list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
3806 if (same_owner_str(op, owner, clid)) 3813 if (same_owner_str(op, owner, clid))
3807 return op; 3814 return lockowner(op);
3808 } 3815 }
3809 return NULL; 3816 return NULL;
3810} 3817}
3811 3818
3812static void hash_lockowner(struct nfs4_stateowner *sop, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp) 3819static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp)
3813{ 3820{
3814 unsigned int idhashval; 3821 unsigned int idhashval;
3815 3822
3816 idhashval = lockownerid_hashval(sop->so_id); 3823 idhashval = lockownerid_hashval(lo->lo_owner.so_id);
3817 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]); 3824 list_add(&lo->lo_owner.so_idhash, &lock_ownerid_hashtbl[idhashval]);
3818 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]); 3825 list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]);
3819 list_add(&sop->so_perstateid, &open_stp->st_lockowners); 3826 list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
3820} 3827}
3821 3828
3822/* 3829/*
@@ -3827,28 +3834,27 @@ static void hash_lockowner(struct nfs4_stateowner *sop, unsigned int strhashval,
3827 * strhashval = lock_ownerstr_hashval 3834 * strhashval = lock_ownerstr_hashval
3828 */ 3835 */
3829 3836
3830static struct nfs4_stateowner * 3837static struct nfs4_lockowner *
3831alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) { 3838alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfs4_stateid *open_stp, struct nfsd4_lock *lock) {
3832 struct nfs4_stateowner *sop; 3839 struct nfs4_lockowner *lo;
3833 3840
3834 sop = alloc_stateowner(&lock->lk_new_owner, clp); 3841 lo = alloc_stateowner(lockowner_slab, &lock->lk_new_owner, clp);
3835 if (!sop) 3842 if (!lo)
3836 return NULL; 3843 return NULL;
3837 INIT_LIST_HEAD(&sop->so_stateids); 3844 INIT_LIST_HEAD(&lo->lo_owner.so_stateids);
3838 sop->so_is_open_owner = 0; 3845 lo->lo_owner.so_is_open_owner = 0;
3839 /* It is the openowner seqid that will be incremented in encode in the 3846 /* It is the openowner seqid that will be incremented in encode in the
3840 * case of new lockowners; so increment the lock seqid manually: */ 3847 * case of new lockowners; so increment the lock seqid manually: */
3841 sop->so_seqid = lock->lk_new_lock_seqid + 1; 3848 lo->lo_owner.so_seqid = lock->lk_new_lock_seqid + 1;
3842 sop->so_confirmed = 1; 3849 hash_lockowner(lo, strhashval, clp, open_stp);
3843 hash_lockowner(sop, strhashval, clp, open_stp); 3850 return lo;
3844 return sop;
3845} 3851}
3846 3852
3847static struct nfs4_stateid * 3853static struct nfs4_stateid *
3848alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp) 3854alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
3849{ 3855{
3850 struct nfs4_stateid *stp; 3856 struct nfs4_stateid *stp;
3851 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 3857 unsigned int hashval = stateid_hashval(lo->lo_owner.so_id, fp->fi_id);
3852 3858
3853 stp = nfs4_alloc_stateid(); 3859 stp = nfs4_alloc_stateid();
3854 if (stp == NULL) 3860 if (stp == NULL)
@@ -3859,13 +3865,13 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
3859 INIT_LIST_HEAD(&stp->st_lockowners); /* not used */ 3865 INIT_LIST_HEAD(&stp->st_lockowners); /* not used */
3860 list_add(&stp->st_hash, &stateid_hashtbl[hashval]); 3866 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
3861 list_add(&stp->st_perfile, &fp->fi_stateids); 3867 list_add(&stp->st_perfile, &fp->fi_stateids);
3862 list_add(&stp->st_perstateowner, &sop->so_stateids); 3868 list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
3863 stp->st_stateowner = sop; 3869 stp->st_stateowner = &lo->lo_owner;
3864 stp->st_type = NFS4_LOCK_STID; 3870 stp->st_type = NFS4_LOCK_STID;
3865 get_nfs4_file(fp); 3871 get_nfs4_file(fp);
3866 stp->st_file = fp; 3872 stp->st_file = fp;
3867 stp->st_stateid.si_boot = boot_time; 3873 stp->st_stateid.si_boot = boot_time;
3868 stp->st_stateid.si_stateownerid = sop->so_id; 3874 stp->st_stateid.si_stateownerid = lo->lo_owner.so_id;
3869 stp->st_stateid.si_fileid = fp->fi_id; 3875 stp->st_stateid.si_fileid = fp->fi_id;
3870 /* note will be incremented before first return to client: */ 3876 /* note will be incremented before first return to client: */
3871 stp->st_stateid.si_generation = 0; 3877 stp->st_stateid.si_generation = 0;
@@ -3902,8 +3908,8 @@ __be32
3902nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 3908nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3903 struct nfsd4_lock *lock) 3909 struct nfsd4_lock *lock)
3904{ 3910{
3905 struct nfs4_stateowner *open_sop = NULL; 3911 struct nfs4_openowner *open_sop = NULL;
3906 struct nfs4_stateowner *lock_sop = NULL; 3912 struct nfs4_lockowner *lock_sop = NULL;
3907 struct nfs4_stateid *lock_stp; 3913 struct nfs4_stateid *lock_stp;
3908 struct nfs4_file *fp; 3914 struct nfs4_file *fp;
3909 struct file *filp = NULL; 3915 struct file *filp = NULL;
@@ -3949,23 +3955,23 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3949 OPEN_STATE, &open_stp); 3955 OPEN_STATE, &open_stp);
3950 if (status) 3956 if (status)
3951 goto out; 3957 goto out;
3958 open_sop = openowner(open_stp->st_stateowner);
3952 status = nfserr_bad_stateid; 3959 status = nfserr_bad_stateid;
3953 open_sop = open_stp->st_stateowner;
3954 if (!nfsd4_has_session(cstate) && 3960 if (!nfsd4_has_session(cstate) &&
3955 !same_clid(&open_sop->so_client->cl_clientid, 3961 !same_clid(&open_sop->oo_owner.so_client->cl_clientid,
3956 &lock->v.new.clientid)) 3962 &lock->v.new.clientid))
3957 goto out; 3963 goto out;
3958 /* create lockowner and lock stateid */ 3964 /* create lockowner and lock stateid */
3959 fp = open_stp->st_file; 3965 fp = open_stp->st_file;
3960 strhashval = lock_ownerstr_hashval(fp->fi_inode, 3966 strhashval = lock_ownerstr_hashval(fp->fi_inode,
3961 open_sop->so_client->cl_clientid.cl_id, 3967 open_sop->oo_owner.so_client->cl_clientid.cl_id,
3962 &lock->v.new.owner); 3968 &lock->v.new.owner);
3963 /* XXX: Do we need to check for duplicate stateowners on 3969 /* XXX: Do we need to check for duplicate stateowners on
3964 * the same file, or should they just be allowed (and 3970 * the same file, or should they just be allowed (and
3965 * create new stateids)? */ 3971 * create new stateids)? */
3966 status = nfserr_jukebox; 3972 status = nfserr_jukebox;
3967 lock_sop = alloc_init_lock_stateowner(strhashval, 3973 lock_sop = alloc_init_lock_stateowner(strhashval,
3968 open_sop->so_client, open_stp, lock); 3974 open_sop->oo_owner.so_client, open_stp, lock);
3969 if (lock_sop == NULL) 3975 if (lock_sop == NULL)
3970 goto out; 3976 goto out;
3971 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); 3977 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
@@ -3974,12 +3980,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3974 } else { 3980 } else {
3975 /* lock (lock owner + lock stateid) already exists */ 3981 /* lock (lock owner + lock stateid) already exists */
3976 status = nfs4_preprocess_seqid_op(cstate, 3982 status = nfs4_preprocess_seqid_op(cstate,
3977 lock->lk_old_lock_seqid, 3983 lock->lk_old_lock_seqid,
3978 &lock->lk_old_lock_stateid, 3984 &lock->lk_old_lock_stateid,
3979 LOCK_STATE, &lock_stp); 3985 LOCK_STATE, &lock_stp);
3980 if (status) 3986 if (status)
3981 goto out; 3987 goto out;
3982 lock_sop = lock_stp->st_stateowner; 3988 lock_sop = lockowner(lock_stp->st_stateowner);
3983 fp = lock_stp->st_file; 3989 fp = lock_stp->st_file;
3984 } 3990 }
3985 /* lock_sop and lock_stp have been created or found */ 3991 /* lock_sop and lock_stp have been created or found */
@@ -4092,7 +4098,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4092{ 4098{
4093 struct inode *inode; 4099 struct inode *inode;
4094 struct file_lock file_lock; 4100 struct file_lock file_lock;
4095 struct nfs4_stateowner *so; 4101 struct nfs4_lockowner *lo;
4096 int error; 4102 int error;
4097 __be32 status; 4103 __be32 status;
4098 4104
@@ -4128,10 +4134,9 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4128 goto out; 4134 goto out;
4129 } 4135 }
4130 4136
4131 so = find_lockstateowner_str(inode, 4137 lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner);
4132 &lockt->lt_clientid, &lockt->lt_owner); 4138 if (lo)
4133 if (so) 4139 file_lock.fl_owner = (fl_owner_t)lo;
4134 file_lock.fl_owner = (fl_owner_t)so;
4135 file_lock.fl_pid = current->tgid; 4140 file_lock.fl_pid = current->tgid;
4136 file_lock.fl_flags = FL_POSIX; 4141 file_lock.fl_flags = FL_POSIX;
4137 4142
@@ -4186,7 +4191,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4186 BUG_ON(!filp); 4191 BUG_ON(!filp);
4187 locks_init_lock(&file_lock); 4192 locks_init_lock(&file_lock);
4188 file_lock.fl_type = F_UNLCK; 4193 file_lock.fl_type = F_UNLCK;
4189 file_lock.fl_owner = (fl_owner_t) stp->st_stateowner; 4194 file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4190 file_lock.fl_pid = current->tgid; 4195 file_lock.fl_pid = current->tgid;
4191 file_lock.fl_file = filp; 4196 file_lock.fl_file = filp;
4192 file_lock.fl_flags = FL_POSIX; 4197 file_lock.fl_flags = FL_POSIX;
@@ -4225,7 +4230,7 @@ out_nfserr:
4225 * 0: no locks held by lockowner 4230 * 0: no locks held by lockowner
4226 */ 4231 */
4227static int 4232static int
4228check_for_locks(struct nfs4_file *filp, struct nfs4_stateowner *lowner) 4233check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4229{ 4234{
4230 struct file_lock **flpp; 4235 struct file_lock **flpp;
4231 struct inode *inode = filp->fi_inode; 4236 struct inode *inode = filp->fi_inode;
@@ -4250,6 +4255,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4250{ 4255{
4251 clientid_t *clid = &rlockowner->rl_clientid; 4256 clientid_t *clid = &rlockowner->rl_clientid;
4252 struct nfs4_stateowner *sop; 4257 struct nfs4_stateowner *sop;
4258 struct nfs4_lockowner *lo;
4253 struct nfs4_stateid *stp; 4259 struct nfs4_stateid *stp;
4254 struct xdr_netobj *owner = &rlockowner->rl_owner; 4260 struct xdr_netobj *owner = &rlockowner->rl_owner;
4255 struct list_head matches; 4261 struct list_head matches;
@@ -4279,11 +4285,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4279 continue; 4285 continue;
4280 list_for_each_entry(stp, &sop->so_stateids, 4286 list_for_each_entry(stp, &sop->so_stateids,
4281 st_perstateowner) { 4287 st_perstateowner) {
4282 if (check_for_locks(stp->st_file, sop)) 4288 lo = lockowner(sop);
4289 if (check_for_locks(stp->st_file, lo))
4283 goto out; 4290 goto out;
4284 /* Note: so_perclient unused for lockowners, 4291 list_add(&lo->lo_list, &matches);
4285 * so it's OK to fool with here. */
4286 list_add(&sop->so_perclient, &matches);
4287 } 4292 }
4288 } 4293 }
4289 } 4294 }
@@ -4292,12 +4297,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
4292 * have been checked. */ 4297 * have been checked. */
4293 status = nfs_ok; 4298 status = nfs_ok;
4294 while (!list_empty(&matches)) { 4299 while (!list_empty(&matches)) {
4295 sop = list_entry(matches.next, struct nfs4_stateowner, 4300 lo = list_entry(matches.next, struct nfs4_lockowner,
4296 so_perclient); 4301 lo_list);
4297 /* unhash_stateowner deletes so_perclient only 4302 /* unhash_stateowner deletes so_perclient only
4298 * for openowners. */ 4303 * for openowners. */
4299 list_del(&sop->so_perclient); 4304 list_del(&lo->lo_list);
4300 release_lockowner(sop); 4305 release_lockowner(lo);
4301 } 4306 }
4302out: 4307out:
4303 nfs4_unlock_state(); 4308 nfs4_unlock_state();