Commit 902773e5 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] knfsd: nfsdv4 byte range locking - prepatation

From: "William A.(Andy) Adamson" <andros@citi.umich.edu>

This renames some structures and functions that can be used for
byte-range locking as well as for the exiting open share locks, and does
some cleanup.
parent b8ba293d
...@@ -355,7 +355,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read ...@@ -355,7 +355,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
if (read->rd_offset >= OFFSET_MAX) if (read->rd_offset >= OFFSET_MAX)
return nfserr_inval; return nfserr_inval;
nfsd4_lock_state(); nfs4_lock_state();
status = nfs_ok; status = nfs_ok;
/* For stateid -1, we don't check share reservations. */ /* For stateid -1, we don't check share reservations. */
if (ONE_STATEID(&read->rd_stateid)) { if (ONE_STATEID(&read->rd_stateid)) {
...@@ -388,7 +388,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read ...@@ -388,7 +388,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
} }
status = nfs_ok; status = nfs_ok;
out: out:
nfsd4_unlock_state(); nfs4_unlock_state();
read->rd_rqstp = rqstp; read->rd_rqstp = rqstp;
read->rd_fhp = current_fh; read->rd_fhp = current_fh;
return status; return status;
...@@ -464,7 +464,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se ...@@ -464,7 +464,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
return status; return status;
} }
nfsd4_lock_state(); nfs4_lock_state();
if ((status = nfs4_preprocess_stateid_op(current_fh, if ((status = nfs4_preprocess_stateid_op(current_fh,
&setattr->sa_stateid, &setattr->sa_stateid,
CHECK_FH, &stp))) { CHECK_FH, &stp))) {
...@@ -476,11 +476,11 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se ...@@ -476,11 +476,11 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
dprintk("NFSD: nfsd4_setattr: not opened for write!\n"); dprintk("NFSD: nfsd4_setattr: not opened for write!\n");
goto out; goto out;
} }
nfsd4_unlock_state(); nfs4_unlock_state();
} }
return (nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0)); return (nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0));
out: out:
nfsd4_unlock_state(); nfs4_unlock_state();
return status; return status;
} }
...@@ -497,7 +497,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ ...@@ -497,7 +497,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
if (write->wr_offset >= OFFSET_MAX) if (write->wr_offset >= OFFSET_MAX)
return nfserr_inval; return nfserr_inval;
nfsd4_lock_state(); nfs4_lock_state();
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
dprintk("NFSD: nfsd4_write: zero stateid...\n"); dprintk("NFSD: nfsd4_write: zero stateid...\n");
if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_WRITE))) { if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_WRITE))) {
...@@ -519,7 +519,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ ...@@ -519,7 +519,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
} }
zero_stateid: zero_stateid:
nfsd4_unlock_state(); nfs4_unlock_state();
write->wr_bytes_written = write->wr_buflen; write->wr_bytes_written = write->wr_buflen;
write->wr_how_written = write->wr_stable_how; write->wr_how_written = write->wr_stable_how;
p = (u32 *)write->wr_verifier; p = (u32 *)write->wr_verifier;
...@@ -530,7 +530,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ ...@@ -530,7 +530,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
write->wr_vec, write->wr_vlen, write->wr_buflen, write->wr_vec, write->wr_vlen, write->wr_buflen,
&write->wr_how_written)); &write->wr_how_written));
out: out:
nfsd4_unlock_state(); nfs4_unlock_state();
return status; return status;
} }
......
...@@ -80,13 +80,13 @@ u32 vfsclose = 0; ...@@ -80,13 +80,13 @@ u32 vfsclose = 0;
static struct semaphore client_sema; static struct semaphore client_sema;
void void
nfsd4_lock_state(void) nfs4_lock_state(void)
{ {
down(&client_sema); down(&client_sema);
} }
void void
nfsd4_unlock_state(void) nfs4_unlock_state(void)
{ {
up(&client_sema); up(&client_sema);
} }
...@@ -386,7 +386,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) ...@@ -386,7 +386,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
strhashval = clientstr_hashval(clname.data, clname.len); strhashval = clientstr_hashval(clname.data, clname.len);
conf = NULL; conf = NULL;
down(&client_sema); nfs4_lock_state();
list_for_each_safe(pos, next, &conf_str_hashtbl[strhashval]) { list_for_each_safe(pos, next, &conf_str_hashtbl[strhashval]) {
clp = list_entry(pos, struct nfs4_client, cl_strhash); clp = list_entry(pos, struct nfs4_client, cl_strhash);
if (!cmp_name(&clp->cl_name, &clname)) if (!cmp_name(&clp->cl_name, &clname))
...@@ -525,7 +525,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) ...@@ -525,7 +525,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
printk(KERN_INFO "NFSD: this client will not receive delegations\n"); printk(KERN_INFO "NFSD: this client will not receive delegations\n");
status = nfs_ok; status = nfs_ok;
out: out:
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
...@@ -557,7 +557,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi ...@@ -557,7 +557,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
*/ */
idhashval = clientid_hashval(clid->cl_id); idhashval = clientid_hashval(clid->cl_id);
down(&client_sema); nfs4_lock_state();
list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) { list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
clp = list_entry(pos, struct nfs4_client, cl_idhash); clp = list_entry(pos, struct nfs4_client, cl_idhash);
if (!cmp_clid(&clp->cl_clientid, clid)) if (!cmp_clid(&clp->cl_clientid, clid))
...@@ -657,7 +657,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi ...@@ -657,7 +657,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
goto out; goto out;
out: out:
/* XXX if status == nfs_ok, probe callback path */ /* XXX if status == nfs_ok, probe callback path */
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
...@@ -683,17 +683,17 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; ...@@ -683,17 +683,17 @@ static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
#define FILE_HASH_SIZE (1 << FILE_HASH_BITS) #define FILE_HASH_SIZE (1 << FILE_HASH_BITS)
#define FILE_HASH_MASK (FILE_HASH_SIZE - 1) #define FILE_HASH_MASK (FILE_HASH_SIZE - 1)
/* hash table for (open)nfs4_stateid */ /* hash table for (open)nfs4_stateid */
#define OPENSTATEID_HASH_BITS 10 #define STATEID_HASH_BITS 10
#define OPENSTATEID_HASH_SIZE (1 << OPENSTATEID_HASH_BITS) #define STATEID_HASH_SIZE (1 << STATEID_HASH_BITS)
#define OPENSTATEID_HASH_MASK (OPENSTATEID_HASH_SIZE - 1) #define STATEID_HASH_MASK (STATEID_HASH_SIZE - 1)
#define file_hashval(x) \ #define file_hashval(x) \
hash_ptr(x, FILE_HASH_BITS) hash_ptr(x, FILE_HASH_BITS)
#define openstateid_hashval(owner_id, file_id) \ #define stateid_hashval(owner_id, file_id) \
(((owner_id) + (file_id)) & OPENSTATEID_HASH_MASK) (((owner_id) + (file_id)) & STATEID_HASH_MASK)
static struct list_head file_hashtbl[FILE_HASH_SIZE]; static struct list_head file_hashtbl[FILE_HASH_SIZE];
static struct list_head openstateid_hashtbl[OPENSTATEID_HASH_SIZE]; static struct list_head stateid_hashtbl[STATEID_HASH_SIZE];
/* OPEN Share state helper functions */ /* OPEN Share state helper functions */
static inline struct nfs4_file * static inline struct nfs4_file *
...@@ -768,7 +768,7 @@ alloc_init_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct n ...@@ -768,7 +768,7 @@ alloc_init_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct n
INIT_LIST_HEAD(&sop->so_idhash); INIT_LIST_HEAD(&sop->so_idhash);
INIT_LIST_HEAD(&sop->so_strhash); INIT_LIST_HEAD(&sop->so_strhash);
INIT_LIST_HEAD(&sop->so_perclient); INIT_LIST_HEAD(&sop->so_perclient);
INIT_LIST_HEAD(&sop->so_peropenstate); INIT_LIST_HEAD(&sop->so_perfilestate);
list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]); list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]); list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
list_add(&sop->so_perclient, &clp->cl_perclient); list_add(&sop->so_perclient, &clp->cl_perclient);
...@@ -794,9 +794,9 @@ release_stateowner(struct nfs4_stateowner *sop) ...@@ -794,9 +794,9 @@ release_stateowner(struct nfs4_stateowner *sop)
list_del_init(&sop->so_strhash); list_del_init(&sop->so_strhash);
list_del_init(&sop->so_perclient); list_del_init(&sop->so_perclient);
del_perclient++; del_perclient++;
while (!list_empty(&sop->so_peropenstate)) { while (!list_empty(&sop->so_perfilestate)) {
stp = list_entry(sop->so_peropenstate.next, stp = list_entry(sop->so_perfilestate.next,
struct nfs4_stateid, st_peropenstate); struct nfs4_stateid, st_perfilestate);
release_stateid(stp); release_stateid(stp);
} }
free_stateowner(sop); free_stateowner(sop);
...@@ -804,13 +804,13 @@ release_stateowner(struct nfs4_stateowner *sop) ...@@ -804,13 +804,13 @@ release_stateowner(struct nfs4_stateowner *sop)
static inline void static inline void
init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) { init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
unsigned int hashval = openstateid_hashval(sop->so_id, fp->fi_id); unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
INIT_LIST_HEAD(&stp->st_hash); INIT_LIST_HEAD(&stp->st_hash);
INIT_LIST_HEAD(&stp->st_peropenstate); INIT_LIST_HEAD(&stp->st_perfilestate);
INIT_LIST_HEAD(&stp->st_perfile); INIT_LIST_HEAD(&stp->st_perfile);
list_add(&stp->st_hash, &openstateid_hashtbl[hashval]); list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
list_add(&stp->st_peropenstate, &sop->so_peropenstate); list_add(&stp->st_perfilestate, &sop->so_perfilestate);
list_add_perfile++; list_add_perfile++;
list_add(&stp->st_perfile, &fp->fi_perfile); list_add(&stp->st_perfile, &fp->fi_perfile);
stp->st_stateowner = sop; stp->st_stateowner = sop;
...@@ -829,7 +829,7 @@ release_stateid(struct nfs4_stateid *stp) { ...@@ -829,7 +829,7 @@ release_stateid(struct nfs4_stateid *stp) {
list_del_init(&stp->st_hash); list_del_init(&stp->st_hash);
list_del_perfile++; list_del_perfile++;
list_del_init(&stp->st_perfile); list_del_init(&stp->st_perfile);
list_del_init(&stp->st_peropenstate); list_del_init(&stp->st_perfilestate);
if(stp->st_vfs_set) { if(stp->st_vfs_set) {
nfsd_close(&stp->st_vfs_file); nfsd_close(&stp->st_vfs_file);
vfsclose++; vfsclose++;
...@@ -864,7 +864,7 @@ release_open_state(struct nfs4_stateid *stp, struct nfsd4_close *cl) ...@@ -864,7 +864,7 @@ release_open_state(struct nfs4_stateid *stp, struct nfsd4_close *cl)
* released by the laundromat service after the lease period * released by the laundromat service after the lease period
* to enable us to handle CLOSE replay * to enable us to handle CLOSE replay
*/ */
if (sop->so_confirmed && list_empty(&sop->so_peropenstate)) { if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) {
release_stateowner(sop); release_stateowner(sop);
cl->cl_stateowner = NULL; cl->cl_stateowner = NULL;
} }
...@@ -883,7 +883,7 @@ cmp_owner_str(struct nfs4_stateowner *sop, struct nfsd4_open *open) { ...@@ -883,7 +883,7 @@ cmp_owner_str(struct nfs4_stateowner *sop, struct nfsd4_open *open) {
/* search ownerstr_hashtbl[] for owner */ /* search ownerstr_hashtbl[] for owner */
static int static int
find_stateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) { find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) {
struct list_head *pos, *next; struct list_head *pos, *next;
struct nfs4_stateowner *local = NULL; struct nfs4_stateowner *local = NULL;
...@@ -1020,9 +1020,9 @@ nfsd4_process_open1(struct nfsd4_open *open) ...@@ -1020,9 +1020,9 @@ nfsd4_process_open1(struct nfsd4_open *open)
if (STALE_CLIENTID(&open->op_clientid)) if (STALE_CLIENTID(&open->op_clientid))
goto out; goto out;
down(&client_sema); /* XXX need finer grained locking */ nfs4_lock_state();
strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
if (find_stateowner_str(strhashval, open, &sop)) { if (find_openstateowner_str(strhashval, open, &sop)) {
open->op_stateowner = sop; open->op_stateowner = sop;
/* check for replay */ /* check for replay */
if (open->op_seqid == sop->so_seqid){ if (open->op_seqid == sop->so_seqid){
...@@ -1078,7 +1078,7 @@ nfsd4_process_open1(struct nfsd4_open *open) ...@@ -1078,7 +1078,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
renew: renew:
renew_client(sop->so_client); renew_client(sop->so_client);
out: out:
up(&client_sema); /*XXX need finer grained locking */ nfs4_unlock_state();
return status; return status;
} }
...@@ -1100,7 +1100,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf ...@@ -1100,7 +1100,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
ino = current_fh->fh_dentry->d_inode; ino = current_fh->fh_dentry->d_inode;
down(&client_sema); /*XXX need finer grained locking */ nfs4_lock_state();
fi_hashval = file_hashval(ino); fi_hashval = file_hashval(ino);
if (find_file(fi_hashval, ino, &fp)) { if (find_file(fi_hashval, ino, &fp)) {
/* Search for conflicting share reservations */ /* Search for conflicting share reservations */
...@@ -1186,7 +1186,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf ...@@ -1186,7 +1186,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
if (!open->op_stateowner->so_confirmed) if (!open->op_stateowner->so_confirmed)
open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
up(&client_sema); /*XXX need finer grained locking */ nfs4_unlock_state();
return status; return status;
out_free: out_free:
kfree(stp); kfree(stp);
...@@ -1204,7 +1204,7 @@ nfsd4_renew(clientid_t *clid) ...@@ -1204,7 +1204,7 @@ nfsd4_renew(clientid_t *clid)
unsigned int idhashval; unsigned int idhashval;
int status; int status;
down(&client_sema); nfs4_lock_state();
printk("process_renew(%08x/%08x): starting\n", printk("process_renew(%08x/%08x): starting\n",
clid->cl_boot, clid->cl_id); clid->cl_boot, clid->cl_id);
status = nfserr_stale_clientid; status = nfserr_stale_clientid;
...@@ -1234,7 +1234,7 @@ nfsd4_renew(clientid_t *clid) ...@@ -1234,7 +1234,7 @@ nfsd4_renew(clientid_t *clid)
printk("nfsd4_renew: clientid not found!\n"); printk("nfsd4_renew: clientid not found!\n");
status = nfserr_expired; status = nfserr_expired;
out: out:
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
...@@ -1246,7 +1246,7 @@ nfs4_laundromat(void) ...@@ -1246,7 +1246,7 @@ nfs4_laundromat(void)
time_t cutoff = get_seconds() - NFSD_LEASE_TIME; time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
time_t t, return_val = NFSD_LEASE_TIME; time_t t, return_val = NFSD_LEASE_TIME;
down(&client_sema); nfs4_lock_state();
dprintk("NFSD: laundromat service - starting, examining clients\n"); dprintk("NFSD: laundromat service - starting, examining clients\n");
list_for_each_safe(pos, next, &client_lru) { list_for_each_safe(pos, next, &client_lru) {
...@@ -1263,7 +1263,7 @@ nfs4_laundromat(void) ...@@ -1263,7 +1263,7 @@ nfs4_laundromat(void)
} }
if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT) if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT)
return_val = NFSD_LAUNDROMAT_MINTIMEOUT; return_val = NFSD_LAUNDROMAT_MINTIMEOUT;
up(&client_sema); nfs4_unlock_state();
return return_val; return return_val;
} }
...@@ -1277,7 +1277,7 @@ laundromat_main(void *not_used) ...@@ -1277,7 +1277,7 @@ laundromat_main(void *not_used)
schedule_delayed_work(&laundromat_work, t*HZ); schedule_delayed_work(&laundromat_work, t*HZ);
} }
/* search openstateid_hashtbl[] for stateid */ /* search stateid_hashtbl[] for stateid */
struct nfs4_stateid * struct nfs4_stateid *
find_stateid(stateid_t *stid) find_stateid(stateid_t *stid)
{ {
...@@ -1285,9 +1285,9 @@ find_stateid(stateid_t *stid) ...@@ -1285,9 +1285,9 @@ find_stateid(stateid_t *stid)
struct nfs4_stateid *local = NULL; struct nfs4_stateid *local = NULL;
u32 st_id = stid->si_stateownerid; u32 st_id = stid->si_stateownerid;
u32 f_id = stid->si_fileid; u32 f_id = stid->si_fileid;
unsigned int hashval = openstateid_hashval(st_id, f_id); unsigned int hashval = stateid_hashval(st_id, f_id);
list_for_each_safe(pos, next, &openstateid_hashtbl[hashval]) { list_for_each_safe(pos, next, &stateid_hashtbl[hashval]) {
local = list_entry(pos, struct nfs4_stateid, st_hash); local = list_entry(pos, struct nfs4_stateid, st_hash);
if((local->st_stateid.si_stateownerid == st_id) && if((local->st_stateid.si_stateownerid == st_id) &&
(local->st_stateid.si_fileid == f_id)) (local->st_stateid.si_fileid == f_id))
...@@ -1298,7 +1298,7 @@ find_stateid(stateid_t *stid) ...@@ -1298,7 +1298,7 @@ find_stateid(stateid_t *stid)
/* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */ /* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */
struct nfs4_stateowner * struct nfs4_stateowner *
find_stateowner_id(u32 st_id) { find_openstateowner_id(u32 st_id) {
struct list_head *pos, *next; struct list_head *pos, *next;
struct nfs4_stateowner *local = NULL; struct nfs4_stateowner *local = NULL;
unsigned int hashval = ownerid_hashval(st_id); unsigned int hashval = ownerid_hashval(st_id);
...@@ -1474,7 +1474,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei ...@@ -1474,7 +1474,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
* starting by trying to look up the stateowner. * starting by trying to look up the stateowner.
* If stateowner is not found - stateid is bad. * If stateowner is not found - stateid is bad.
*/ */
if (!(sop = find_stateowner_id(stateid->si_stateownerid))) { if (!(sop = find_openstateowner_id(stateid->si_stateownerid))) {
printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n"); printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
status = nfserr_bad_stateid; status = nfserr_bad_stateid;
goto out; goto out;
...@@ -1503,7 +1503,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs ...@@ -1503,7 +1503,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
(int)current_fh->fh_dentry->d_name.len, (int)current_fh->fh_dentry->d_name.len,
current_fh->fh_dentry->d_name.name); current_fh->fh_dentry->d_name.name);
oc->oc_stateowner = NULL; oc->oc_stateowner = NULL;
down(&client_sema); /* XXX need finer grained locking */ nfs4_lock_state();
if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid, if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
&oc->oc_req_stateid, &oc->oc_req_stateid,
...@@ -1523,7 +1523,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs ...@@ -1523,7 +1523,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
stp->st_stateid.si_generation); stp->st_stateid.si_generation);
status = nfs_ok; status = nfs_ok;
out: out:
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
int int
...@@ -1536,7 +1536,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n ...@@ -1536,7 +1536,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
(int)current_fh->fh_dentry->d_name.len, (int)current_fh->fh_dentry->d_name.len,
current_fh->fh_dentry->d_name.name); current_fh->fh_dentry->d_name.name);
down(&client_sema); /* XXX need finer grained locking */ nfs4_lock_state();
if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid,
&od->od_stateid, &od->od_stateid,
CHECK_FH, &od->od_stateowner, &stp))) CHECK_FH, &od->od_stateowner, &stp)))
...@@ -1561,7 +1561,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n ...@@ -1561,7 +1561,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
status = nfs_ok; status = nfs_ok;
out: out:
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
...@@ -1575,7 +1575,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos ...@@ -1575,7 +1575,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
(int)current_fh->fh_dentry->d_name.len, (int)current_fh->fh_dentry->d_name.len,
current_fh->fh_dentry->d_name.name); current_fh->fh_dentry->d_name.name);
down(&client_sema); /* XXX need finer grained locking */ nfs4_lock_state();
if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid,
&close->cl_stateid, &close->cl_stateid,
CHECK_FH, CHECK_FH,
...@@ -1591,7 +1591,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos ...@@ -1591,7 +1591,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
/* release_open_state() calls nfsd_close() if needed */ /* release_open_state() calls nfsd_close() if needed */
release_open_state(stp,close); release_open_state(stp,close);
out: out:
up(&client_sema); nfs4_unlock_state();
return status; return status;
} }
...@@ -1615,8 +1615,8 @@ nfs4_state_init(void) ...@@ -1615,8 +1615,8 @@ nfs4_state_init(void)
INIT_LIST_HEAD(&ownerstr_hashtbl[i]); INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
INIT_LIST_HEAD(&ownerid_hashtbl[i]); INIT_LIST_HEAD(&ownerid_hashtbl[i]);
} }
for (i = 0; i < OPENSTATEID_HASH_SIZE; i++) { for (i = 0; i < STATEID_HASH_SIZE; i++) {
INIT_LIST_HEAD(&openstateid_hashtbl[i]); INIT_LIST_HEAD(&stateid_hashtbl[i]);
} }
memset(&zerostateid, 0, sizeof(stateid_t)); memset(&zerostateid, 0, sizeof(stateid_t));
memset(&onestateid, ~0, sizeof(stateid_t)); memset(&onestateid, ~0, sizeof(stateid_t));
...@@ -1665,7 +1665,7 @@ __nfs4_state_shutdown(void) ...@@ -1665,7 +1665,7 @@ __nfs4_state_shutdown(void)
void void
nfs4_state_shutdown(void) nfs4_state_shutdown(void)
{ {
down(&client_sema); nfs4_lock_state();
__nfs4_state_shutdown(); __nfs4_state_shutdown();
up(&client_sema); nfs4_unlock_state();
} }
...@@ -119,14 +119,14 @@ struct nfs4_replay { ...@@ -119,14 +119,14 @@ struct nfs4_replay {
/* /*
* nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner * nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner
* *
* o so_peropenstate list is used to ensure no dangling nfs4_stateid * o so_perfilestate list is used to ensure no dangling nfs4_stateid
* reverences when we release a stateowner. * reverences when we release a stateowner.
*/ */
struct nfs4_stateowner { struct nfs4_stateowner {
struct list_head so_idhash; /* hash by so_id */ struct list_head so_idhash; /* hash by so_id */
struct list_head so_strhash; /* hash by op_name */ struct list_head so_strhash; /* hash by op_name */
struct list_head so_perclient; /* nfs4_client->cl_perclient */ struct list_head so_perclient; /* nfs4_client->cl_perclient */
struct list_head so_peropenstate; /* list: nfs4_stateid */ struct list_head so_perfilestate; /* list: nfs4_stateid */
u32 so_id; u32 so_id;
struct nfs4_client * so_client; struct nfs4_client * so_client;
u32 so_seqid; u32 so_seqid;
...@@ -145,7 +145,7 @@ struct nfs4_file { ...@@ -145,7 +145,7 @@ struct nfs4_file {
struct list_head fi_perfile; /* list: nfs4_stateid */ struct list_head fi_perfile; /* list: nfs4_stateid */
struct inode *fi_inode; struct inode *fi_inode;
u32 fi_id; /* used with stateowner->so_id u32 fi_id; /* used with stateowner->so_id
* for openstateid_hashtbl hash */ * for stateid_hashtbl hash */
}; };
/* /*
...@@ -155,9 +155,9 @@ struct nfs4_file { ...@@ -155,9 +155,9 @@ struct nfs4_file {
*/ */
struct nfs4_stateid { struct nfs4_stateid {
struct list_head st_hash; /* openstateid_hashtbl[]*/ struct list_head st_hash;
struct list_head st_perfile; /* file_hashtbl[]*/ struct list_head st_perfile;
struct list_head st_peropenstate; /* nfs4_stateowner->so_peropenstate */ struct list_head st_perfilestate;
struct nfs4_stateowner * st_stateowner; struct nfs4_stateowner * st_stateowner;
struct nfs4_file * st_file; struct nfs4_file * st_file;
stateid_t st_stateid; stateid_t st_stateid;
...@@ -183,6 +183,6 @@ extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, ...@@ -183,6 +183,6 @@ extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
stateid_t *stateid, int flags, struct nfs4_stateid **stpp); stateid_t *stateid, int flags, struct nfs4_stateid **stpp);
extern int nfs4_share_conflict(struct svc_fh *current_fh, extern int nfs4_share_conflict(struct svc_fh *current_fh,
unsigned int deny_type); unsigned int deny_type);
extern void nfsd4_lock_state(void); extern void nfs4_lock_state(void);
extern void nfsd4_unlock_state(void); extern void nfs4_unlock_state(void);
#endif /* NFSD4_STATE_H */ #endif /* NFSD4_STATE_H */
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