Introduction
Subsystems (2)
PATCH 1/1 Introduction
Following are 19 assorted nfsv4 server patches for 2.6-latest. Mostly tidy-ups and minor bug fixes.
They would all be suitable for 2.6.13.
Thanks,
NeilBrown
[PATCH kNFSd 001 of 19] nfsd4: reboot recovery fix
[PATCH kNFSd 002 of 19] nfsd4: fix sync'ing of recovery directory [PATCH kNFSd 003 of 19] nfsd4: lookup_one_len takes i_sem
[PATCH kNFSd 004 of 19] nfsd4: prevent multiple unlinks of recovery directories [PATCH kNFSd 005 of 19] nfsd4: fix release_lockowner
[PATCH kNFSd 006 of 19] nfsd4: ERR_GRACE should bump seqid on open [PATCH kNFSd 007 of 19] nfsd4: ERR_GRACE should bump seqid on lock [PATCH kNFSd 008 of 19] nfsd4: stop overusing RECLAIM_BAD
[PATCH kNFSd 009 of 19] nfsd4: comment indentation
[PATCH kNFSd 010 of 19] nfsd4: fix open_reclaim seqid
[PATCH kNFSd 011 of 19] nfsd4: seqid comments
[PATCH kNFSd 012 of 19] nfsd4: relax new lock seqid check
[PATCH kNFSd 013 of 19] nfsd4: always update stateid on open
[PATCH kNFSd 014 of 19] nfsd4: return better error on io incompatible with open mode [PATCH kNFSd 015 of 19] nfsd4: renew lease on seqid modifying operations [PATCH kNFSd 016 of 19] nfsd4: clarify close_lru handling
[PATCH kNFSd 017 of 19] nfsd4: clean up nfs4_preprocess_seqid_op [PATCH kNFSd 018 of 19] nfsd4: check lock type against openmode. [PATCH kNFSd 019 of 19] nfsd4: fix fh_expire_type
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: ERR_GRACE should bump seqid on open
The GRACE and NOGRACE errors should bump the sequence id on open. So we delay the handling of these errors until nfsd4_process_open2, at which point we've set the open owner, so the encode routine will be able to bump the sequence id.
### Diffstat output
./fs/nfsd/nfs4proc.c | 6 ------ ./fs/nfsd/nfs4state.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-)
fs/nfsd/nfs4proc.c renamed from fs/nfsd/nfs4proc.c~current~ +0 -6
@@ -169,12 +169,6 @@ nfsd4_open(struct svc_rqst *rqstp, struc (int )open->op_fname.len, open->op_fname.data, open->op_stateowner); -if (nfs4_in_grace () && open->op_claim_type !=NFS4_OPEN_CLAIM_PREVIOUS ) -return nfserr_grace; - -if (!nfs4_in_grace () && open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS ) -return nfserr_no_grace; -/* This check required by spec. */ if (open->op_create && open->op_claim_type !=NFS4_OPEN_CLAIM_NULL )return nfserr_inval;
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +6 -0
@@ -1790,6 +1790,12 @@ nfsd4_process_open2(struct svc_rqst *rqsstruct nfs4_delegation *dp =NULL ;int status; +if (nfs4_in_grace () && open->op_claim_type !=NFS4_OPEN_CLAIM_PREVIOUS ) +return nfserr_grace; + +if (!nfs4_in_grace () && open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS ) +return nfserr_no_grace; + status = nfserr_inval;if (!TEST_ACCESS (open->op_share_access) || !TEST_DENY (open->op_share_deny)) goto out;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: prevent multiple unlinks of recovery directories
In reply to NeilBrownMake sure we don't try to delete client recovery directories multiple times; fixes some spurious error messages.
### Diffstat output
./fs/nfsd/nfs4recover.c | 1 + 1 files changed, 1 insertion(+)
fs/nfsd/nfs4recover.c renamed from fs/nfsd/nfs4recover.c~current~ +1 -0
@@ -316,6 +316,7 @@ nfsd4_remove_clid_dir(struct nfs4_clientif (!rec_dir_init || !clp->cl_firststate)return ; + clp->cl_firststate =0 ;nfs4_save_user (&uid, &gid); status =nfsd4_unlink_clid_dir (clp->cl_recdir,HEXDIR_LEN -1 );nfs4_reset_user (uid, gid);
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: always update stateid on open
In reply to NeilBrownAn OPEN from the same client/open stateowner requires a stateid update because of the share/deny access update.
### Diffstat output
./fs/nfsd/nfs4state.c | 1 + 1 files changed, 1 insertion(+)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -0
@@ -1820,6 +1820,7 @@ nfsd4_process_open2(struct svc_rqst *rqs status =nfs4_upgrade_open (rqstp, current_fh, stp, open);if (status) goto out; +update_stateid (&stp->st_stateid); }else {/* Stateid was not found, this is a new OPEN */ int flags =0 ;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: return better error on io incompatible with open mode
In reply to NeilBrownfrom RFC 3530:
"Share reservations are established by OPEN operations and by their nature are mandatory in that when the OPEN denies READ or WRITE operations, that denial results in such operations being rejected with error NFS4ERR_LOCKED."
(Note that share_denied is really only a legal error for OPEN.)
### Diffstat output
./fs/nfsd/nfs4state.c | 2 +- ./include/linux/nfsd/nfsd.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -1
@@ -1295,7 +1295,7 @@ nfs4_share_conflict(struct svc_fh *curre fp =find_file (ino);if (!fp)return nfs_ok; - ret = nfserr_share_denied; + ret = nfserr_locked;/* Search for conflicting share reservations */ list_for_each_entry (stp, &fp->fi_stateids, st_perfile) { if (test_bit(deny_type, &stp->st_deny_bmap) ||
include/linux/nfsd/nfsd.h renamed from include/linux/nfsd/nfsd.h~current~ +1 -0
@@ -231,6 +231,7 @@ void nfsd_lockd_shutdown(void);#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD)#define nfserr_badname __constant_htonl(NFSERR_BADNAME)#define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN) +#define nfserr_locked __constant_htonl(NFSERR_LOCKED)/* error codes for internal use */ /* if a request fails due to kmalloc failure, it gets dropped.
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: clarify close_lru handling
In reply to NeilBrownThe handling of close_lru in preprocess_stateid_op was a source of some confusion here recently. Try to make the logic a little clearer, by renaming find_openstateowner_id to make its purpose clearer and untangling some unnecessarily complicated goto's.
### Diffstat output
./fs/nfsd/nfs4state.c | 40 ++++++++++++++-------------------------- 1 files changed, 14 insertions(+), 26 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +14 -26
@@ -1988,14 +1988,11 @@ laundromat_main(void *not_used)queue_delayed_work (laundry_wq, &laundromat_work, t*HZ ); } -/* search ownerid_hashtbl[] and close_lru for stateid owner -* (stateid->si_stateownerid) -*/ static struct nfs4_stateowner * -find_openstateowner_id (u32 st_id,int flags) { +search_close_lru (u32 st_id,int flags) +{struct nfs4_stateowner *local =NULL ; -dprintk ("NFSD: find_openstateowner_id %d\n" , st_id);if (flags &CLOSE_STATE ) {list_for_each_entry (local, &close_lru, so_close_lru) {if (local->so_id == st_id)
@@ -2193,13 +2190,19 @@ nfs4_preprocess_seqid_op(struct svc_fh ** We return BAD_STATEID if filehandle doesn't match stateid, * the confirmed flag is incorrecly set, or the generation * number is incorrect. -* If there is no entry in the openfile table for this id, -* we can't always return BAD_STATEID; -* this might be a retransmitted CLOSE which has arrived after -* the openfile has been released. */ -if (!(stp =find_stateid (stateid, flags))) - goto no_nfs4_stateid; + stp =find_stateid (stateid, flags); +if (stp ==NULL ) { +/* +* Also, we should make sure this isn't just the result of +* a replayed close: +*/ + sop =search_close_lru (stateid->si_stateownerid, flags); +if (sop ==NULL ) +return nfserr_bad_stateid; + *sopp = sop; + goto check_replay; + } status = nfserr_bad_stateid;
@@ -2263,21 +2266,6 @@ nfs4_preprocess_seqid_op(struct svc_fh * out:return status; - -no_nfs4_stateid: - -/* -* We determine whether this is a bad stateid or a replay, -* starting by trying to look up the stateowner. -* If stateowner is not found - stateid is bad. -*/ -if (!(sop =find_openstateowner_id (stateid->si_stateownerid, flags))) { -printk ("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n" ); - status = nfserr_bad_stateid; - goto out; - } - *sopp = sop; - check_replay:if (seqid == sop->so_seqid -1 ) {printk ("NFSD: preprocess_seqid_op: retransmission?\n" );
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix fh_expire_type
In reply to NeilBrownAfter discussion at the recent NFSv4 bake-a-thon, I realized that my assumption that NFS4_FH_PERSISTENT required filehandles to persist was a misreading of the spec. This also fixes an interoperability problem with the Solaris client.
### Diffstat output
./fs/nfsd/nfs4xdr.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +2 -2
@@ -1366,9 +1366,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, sif ((buflen -=4 ) <0 ) goto out_resource;if (exp->ex_flags &NFSEXP_NOSUBTREECHECK ) -WRITE32 (NFS4_FH_VOLATILE_ANY ); +WRITE32 (NFS4_FH_PERSISTENT );else -WRITE32 (NFS4_FH_VOLATILE_ANY |NFS4_FH_VOL_RENAME ); +WRITE32 (NFS4_FH_PERSISTENT |NFS4_FH_VOL_RENAME ); }if (bmval0 &FATTR4_WORD0_CHANGE ) {/*
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix release_lockowner
In reply to NeilBrownWe oops in list_for_each_entry(), because release_stateowner frees something on the list we're traversing.
### Diffstat output
./fs/nfsd/nfs4state.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +6 -1
@@ -3084,7 +3084,12 @@ nfsd4_release_lockowner(struct svc_rqst* of the lockowner state released; so don't release any until all * have been checked. */ status = nfs_ok; -list_for_each_entry (sop, &matches, so_perclient) { +while (!list_empty (&matches)) { + sop = list_entry(matches.next, struct nfs4_stateowner, + so_perclient); +/* unhash_stateowner deletes so_perclient only +* for openowners. */ +list_del (&sop->so_perclient);release_stateowner (sop); } out:
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: stop overusing RECLAIM_BAD
In reply to NeilBrownA misreading of the spec lead us to convert all errors on open and lock reclaims to RECLAIM_BAD. This causes problems--for example, a reboot within the grace period could lead to reclaims with stale stateid's, and we'd like to return STALE errors in those cases.
What rfc3530 actually says about RECLAIM_BAD: "The reclaim provided by the client does not match any of the server's state consistency checks and is bad." I'm assuming that "state consistency checks" refers to checks for consistency with the state recorded to stable storage, and that the error should be reserved for that case.
### Diffstat output
./fs/nfsd/nfs4state.c | 25 +++++++------------------ 1 files changed, 7 insertions(+), 18 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +7 -18
@@ -1531,8 +1531,6 @@ renew: status = nfs_ok;renew_client (sop->so_client); out: -if (status && open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS ) - status = nfserr_reclaim_bad;return status; }
@@ -1688,17 +1686,11 @@ nfs4_upgrade_open(struct svc_rqst *rqstp/* decrement seqid on successful reclaim, it will be bumped in encode_open */ static void -nfs4_set_claim_prev (struct nfsd4_open *open,int *status) +nfs4_set_claim_prev (struct nfsd4_open *open) { -if (open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS ) { -if (*status) - *status = nfserr_reclaim_bad; -else { - open->op_stateowner->so_confirmed =1 ; - open->op_stateowner->so_client->cl_firststate =1 ; - open->op_stateowner->so_seqid--; - } - } + open->op_stateowner->so_confirmed =1 ; + open->op_stateowner->so_client->cl_firststate =1 ; + open->op_stateowner->so_seqid--; }/*
@@ -1863,8 +1855,8 @@ nfsd4_process_open2(struct svc_rqst *rqs out:if (fp)put_nfs4_file (fp); -/* CLAIM_PREVIOUS has different error returns */ -nfs4_set_claim_prev (open, &status); +if (status ==0 && open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS ) +nfs4_set_claim_prev (open);/* * To finish the open response, we just need to set the rflags. */
@@ -2738,11 +2730,8 @@ nfsd4_lock(struct svc_rqst *rqstp, strucCHECK_FH |OPEN_STATE , &open_sop, &open_stp, &lock->v.new.clientid); -if (status) { -if (lock->lk_reclaim) - status = nfserr_reclaim_bad; +if (status) goto out; - }/* create lockowner and lock stateid */ fp = open_stp->st_file; strhashval = lock_ownerstr_hashval(fp->fi_inode,
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: comment indentation
In reply to NeilBrownYeah, it's trivial, but this drives me up the wall....
### Diffstat output
./fs/nfsd/nfs4state.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +9 -9
@@ -2704,11 +2704,11 @@ nfsd4_lock(struct svc_rqst *rqstp, strucnfs4_lock_state ();if (lock->lk_is_new) { -/* -* Client indicates that this is a new lockowner. -* Use open owner and open stateid to create lock owner and lock -* stateid. -*/ +/* +* Client indicates that this is a new lockowner. +* Use open owner and open stateid to create lock owner and +* lock stateid. +*/ struct nfs4_stateid *open_stp =NULL ;struct nfs4_file *fp;
@@ -2842,10 +2842,10 @@ conflicting_lock: out_destroy_new_stateid:if (lock->lk_is_new) {dprintk ("NFSD: nfsd4_lock: destroy new stateid!\n" ); -/* -* An error encountered after instantiation of the new -* stateid has forced us to destroy it. -*/ +/* +* An error encountered after instantiation of the new +* stateid has forced us to destroy it. +*/ if (!seqid_mutating_err (status)) open_sop->so_seqid--;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: seqid comments
In reply to NeilBrownAdd some comments on the use of so_seqid, in an attempt to avoid some of the confusion outlined in the previous patch....
### Diffstat output
./fs/nfsd/nfs4xdr.c | 8 ++++---- ./include/linux/nfsd/state.h | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-)
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +4 -4
@@ -1210,10 +1210,10 @@ nfsd4_decode_compound(struct nfsd4_compo save = resp->p;/* -* Routine for encoding the result of a -* "seqid-mutating" NFSv4 operation. This is -* where seqids are incremented, and the -* replay cache is filled. +* Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This +* is where sequence id's are incremented, and the replay cache is filled. +* Note that we increment sequence id's here, at the last moment, so we're sure +* we know whether the error to be returned is a sequence id mutating error. */ #define ENCODE_SEQID_OP_TAIL (stateowner) do { \
include/linux/nfsd/state.h renamed from include/linux/nfsd/state.h~current~ +3 -1
@@ -203,7 +203,9 @@ struct nfs4_stateowner {int so_is_open_owner;/* 1=openowner,0=lockowner */ u32 so_id;struct nfs4_client * so_client; -u32 so_seqid; +/* after increment in ENCODE_SEQID_OP_TAIL, represents the next +* sequence id expected from the client: */ +u32 so_seqid;struct xdr_netobj so_owner;/* open owner name */ int so_confirmed;/* successful OPEN_CONFIRM? */ struct nfs4_replay so_replay;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: reboot recovery fix
In reply to NeilBrownWe need to remove the recovery directory here too. (This chunk just got lost somehow in the process of commuting the reboot recovery patches past the other patches.)
### Diffstat output
./fs/nfsd/nfs4state.c | 1 + 1 files changed, 1 insertion(+)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -0
@@ -874,6 +874,7 @@ nfsd4_setclientid_confirm(struct svc_rqs* change request correctly. */ atomic_set (&conf->cl_callback.cb_set,0 );gen_confirm (conf); +nfsd4_remove_clid_dir (unconf);expire_client (unconf); status = nfs_ok;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: lookup_one_len takes i_sem
In reply to NeilBrownOops, this lookup_one_len needs the i_sem.
### Diffstat output
./fs/nfsd/nfs4recover.c | 2 ++ 1 files changed, 2 insertions(+)
fs/nfsd/nfs4recover.c renamed from fs/nfsd/nfs4recover.c~current~ +2 -0
@@ -289,7 +289,9 @@ nfsd4_unlink_clid_dir(char *name, int nadprintk ("NFSD: nfsd4_unlink_clid_dir. name %.*s\n" , namlen, name); +down (&rec_dir.dentry->d_inode->i_sem); dentry =lookup_one_len (name, rec_dir.dentry, namlen); +up (&rec_dir.dentry->d_inode->i_sem);if (IS_ERR (dentry)) { status =PTR_ERR (dentry);return status;
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: relax new lock seqid check
In reply to NeilBrownWe're insisting that the lock sequence id field passed in the open_to_lockowner struct always be zero. This is probably thanks to the sentence in rfc3530:
"The first request issued for any given lock_owner is issued with a sequence number of zero."
But there doesn't seem to be any problem with allowing initial sequence numbers other than zero. And currently this is causing lock reclaims from the Linux client to fail.
In the spirit of "be liberal in what you accept, conservative in what you send", we'll relax the check (and patch the Linux client as well).
### Diffstat output
./fs/nfsd/nfs4state.c | 5 ----- 1 files changed, 5 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +0 -5
@@ -2715,11 +2715,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc goto out; } -/* is the new lock seqid presented by the client zero? */ - status = nfserr_bad_seqid; -if (lock->v.new.lock_seqid !=0 ) - goto out; -/* validate and update open stateid and open seqid */ status = nfs4_preprocess_seqid_op(current_fh, lock->lk_new_open_seqid,
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix sync'ing of recovery directory
In reply to NeilBrownWe need to fsync the recovery directory after writing to it, but we weren't doing this correctly. (For example, we weren't taking the i_sem when calling ->fsync().)
Just reuse the existing nfsd fsync code instead.
### Diffstat output
./fs/nfsd/nfs4recover.c | 29 ++++++++--------------------- ./fs/nfsd/vfs.c | 2 +- ./include/linux/nfsd/nfsd.h | 1 + 3 files changed, 10 insertions(+), 22 deletions(-)
fs/nfsd/nfs4recover.c renamed from fs/nfsd/nfs4recover.c~current~ +8 -21
@@ -119,25 +119,12 @@ out:return status; } -static int -nfsd4_rec_fsync (struct dentry *dentry) +static void +nfsd4_sync_rec_dir (void ) { -struct file *filp; -int status = nfs_ok; - -dprintk ("NFSD: nfs4_fsync_rec_dir\n" ); - filp =dentry_open (dget (dentry),mntget (rec_dir.mnt),O_RDWR ); -if (IS_ERR (filp)) { - status =PTR_ERR (filp); - goto out; - } -if (filp->f_op && filp->f_op->fsync) - status = filp->f_op->fsync (filp, filp->f_dentry,0 ); -fput (filp); -out: -if (status) -printk ("nfsd4: unable to sync recovery directory\n" ); -return status; +down (&rec_dir.dentry->d_inode->i_sem); +nfsd_sync_dir (rec_dir.dentry); +up (&rec_dir.dentry->d_inode->i_sem); }int
@@ -176,7 +163,7 @@ out_unlock:up (&rec_dir.dentry->d_inode->i_sem);if (status ==0 ) { clp->cl_firststate =1 ; - status =nfsd4_rec_fsync (rec_dir.dentry); +nfsd4_sync_rec_dir (); }nfs4_reset_user (uid, gid);dprintk ("NFSD: nfsd4_create_clid_dir returns %d\n" , status);
@@ -331,7 +318,7 @@ nfsd4_remove_clid_dir(struct nfs4_client status =nfsd4_unlink_clid_dir (clp->cl_recdir,HEXDIR_LEN -1 );nfs4_reset_user (uid, gid);if (status ==0 ) - status =nfsd4_rec_fsync (rec_dir.dentry); +nfsd4_sync_rec_dir ();if (status)printk ("NFSD: Failed to remove expired client state directory" " %.*s\n" ,HEXDIR_LEN , clp->cl_recdir);
@@ -362,7 +349,7 @@ nfsd4_recdir_purge_old(void) {return ; status =nfsd4_list_rec_dir (rec_dir.dentry, purge_old);if (status ==0 ) - status =nfsd4_rec_fsync (rec_dir.dentry); +nfsd4_sync_rec_dir ();if (status)printk ("nfsd4: failed to purge old clients from recovery" " directory %s\n" , rec_dir.dentry->d_name.name);
fs/nfsd/vfs.c renamed from fs/nfsd/vfs.c~current~ +1 -1
@@ -733,7 +733,7 @@ nfsd_sync(struct file *filp)up (&inode->i_sem); } -static void +void nfsd_sync_dir (struct dentry *dp) {nfsd_dosync (NULL , dp, dp->d_inode->i_fop);
include/linux/nfsd/nfsd.h renamed from include/linux/nfsd/nfsd.h~current~ +1 -0
@@ -124,6 +124,7 @@ int nfsd_statfs(struct svc_rqst *, struint nfsd_notify_change (struct inode *,struct iattr *);int nfsd_permission (struct svc_export *,struct dentry *,int ); +void nfsd_sync_dir (struct dentry *dp);#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )#ifdef CONFIG_NFSD_V2_ACL
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix open_reclaim seqid
In reply to NeilBrownThe sequence number we store in the sequence id is the last one we received from the client. So on the next operation we'll check that the client gives us the next higher number.
We increment sequence id's at the last moment, in encode, so that we're sure of knowing the right error return. (The decision to increment the sequence id depends on the exact error returned.)
However on the *first* use of a sequence number, if we set the sequence number to the one received from the client and then let the increment happen on encode, we'll be left with a sequence number one to high.
For that reason, ENCODE_SEQID_OP_TAIL only increments the sequence id on *confirmed* stateowners.
This creates a problem for open reclaims, which are confirmed on first use. Therefore the open reclaim code, as a special exception, *decrements* the sequence id, cancelling out the undesired increment on encode. But this prevents the sequence id from ever being incremented in the case where multiple reclaims are sent with the same openowner. Yuch!
We could add another exception to the open reclaim code, decrementing the sequence id only if this is the first use of the open owner.
But it's simpler by far to modify the meaning of the op_seqid field: instead of representing the previous value sent by the client, we take op_seqid, after encoding, to represent the *next* sequence id that we expect from the client. This eliminates the need for special-case handling of the first use of a stateowner.
### Diffstat output
./fs/nfsd/nfs4state.c | 15 ++++++--------- ./fs/nfsd/nfs4xdr.c | 3 +-- 2 files changed, 7 insertions(+), 11 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +6 -9
@@ -1483,7 +1483,7 @@ nfsd4_process_open1(struct nfsd4_open *oif (sop) { open->op_stateowner = sop;/* check for replay */ -if (open->op_seqid == sop->so_seqid){ +if (open->op_seqid == sop->so_seqid -1 ){if (sop->so_replay.rp_buflen)return NFSERR_REPLAY_ME ;else {
@@ -1498,7 +1498,7 @@ nfsd4_process_open1(struct nfsd4_open *o goto renew; } }else if (sop->so_confirmed) { -if (open->op_seqid == sop->so_seqid +1 ) +if (open->op_seqid == sop->so_seqid) goto renew; status = nfserr_bad_seqid; goto out;
@@ -1684,13 +1684,11 @@ nfs4_upgrade_open(struct svc_rqst *rqstp } -/* decrement seqid on successful reclaim, it will be bumped in encode_open */ static void nfs4_set_claim_prev (struct nfsd4_open *open) { open->op_stateowner->so_confirmed =1 ; open->op_stateowner->so_client->cl_firststate =1 ; - open->op_stateowner->so_seqid--; }/*
@@ -2234,7 +2232,7 @@ nfs4_preprocess_seqid_op(struct svc_fh ** For the moment, we ignore the possibility of * generation number wraparound. */ -if (seqid != sop->so_seqid +1 ) +if (seqid != sop->so_seqid) goto check_replay;if (sop->so_confirmed) {
@@ -2280,12 +2278,12 @@ no_nfs4_stateid: *sopp = sop; check_replay: -if (seqid == sop->so_seqid) { +if (seqid == sop->so_seqid -1 ) {printk ("NFSD: preprocess_seqid_op: retransmission?\n" );/* indicate replay to calling function */ status =NFSERR_REPLAY_ME ; }else { -printk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n" , sop->so_seqid +1 , seqid); +printk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n" , sop->so_seqid, seqid); *sopp =NULL ; status = nfserr_bad_seqid;
@@ -2608,7 +2606,6 @@ find_lockstateowner_str(struct inode *in* occured. * * strhashval = lock_ownerstr_hashval -* so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode */ static struct nfs4_stateowner *
@@ -2633,7 +2630,7 @@ alloc_init_lock_stateowner(unsigned int sop->so_is_open_owner =0 ; sop->so_id = current_ownerid++; sop->so_client = clp; - sop->so_seqid = lock->lk_new_lock_seqid -1 ; + sop->so_seqid = lock->lk_new_lock_seqid; sop->so_confirmed =1 ; rp = &sop->so_replay; rp->rp_status =NFSERR_SERVERFAULT ;
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +1 -2
@@ -1218,8 +1218,7 @@ nfsd4_decode_compound(struct nfsd4_compo#define ENCODE_SEQID_OP_TAIL (stateowner) do { \ if (seqid_mutating_err(nfserr) && stateowner) { \ - if (stateowner->so_confirmed) \ - stateowner->so_seqid++; \ + stateowner->so_seqid++; \ stateowner->so_replay.rp_status = nfserr; \ stateowner->so_replay.rp_buflen = \ (((char *)(resp)->p - (char *)save)); \
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: renew lease on seqid modifying operations
In reply to NeilBrownnfs4_preprocess_seqid_op is called by NFSv4 operations that imply an implicit renewal of the client lease.
### Diffstat output
./fs/nfsd/nfs4state.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -1
@@ -2258,7 +2258,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *printk ("NFSD: preprocess_seqid_op: old stateid!\n" ); goto out; } -/* XXX renew the client lease here */ +renew_client (sop->so_client); status = nfs_ok; out:
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: clean up nfs4_preprocess_seqid_op
In reply to NeilBrownAs long as we're here, do some miscellaneous cleanup.
### Diffstat output
./fs/nfsd/nfs4state.c | 58 +++++++++++++++++++------------------------------- 1 files changed, 23 insertions(+), 35 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +23 -35
@@ -2165,7 +2165,6 @@ out:static int nfs4_preprocess_seqid_op (struct svc_fh *current_fh,u32 seqid,stateid_t *stateid,int flags,struct nfs4_stateowner **sopp,struct nfs4_stateid **stpp,clientid_t *lockclid) { -int status;struct nfs4_stateid *stp;struct nfs4_stateowner *sop;
@@ -2173,19 +2172,17 @@ nfs4_preprocess_seqid_op(struct svc_fh *"stateid = (%08x/%08x/%08x/%08x)\n" , seqid, stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, stateid->si_generation); - + *stpp =NULL ; *sopp =NULL ; - status = nfserr_bad_stateid;if (ZERO_STATEID (stateid) ||ONE_STATEID (stateid)) {printk ("NFSD: preprocess_seqid_op: magic stateid!\n" ); - goto out; +return nfserr_bad_stateid; } - status = nfserr_stale_stateid;if (STALE_STATEID (stateid)) - goto out; +return nfserr_stale_stateid;/* * We return BAD_STATEID if filehandle doesn't match stateid, * the confirmed flag is incorrecly set, or the generation
@@ -2204,8 +2201,6 @@ nfs4_preprocess_seqid_op(struct svc_fh * goto check_replay; } - status = nfserr_bad_stateid; -/* for new lock stateowners: * check that the lock->v.new.open_stateid * refers to an open stateowner
@@ -2218,14 +2213,14 @@ nfs4_preprocess_seqid_op(struct svc_fh *struct nfs4_client *clp = sop->so_client;if (!sop->so_is_open_owner) - goto out; +return nfserr_bad_stateid;if (!cmp_clid (&clp->cl_clientid, lockclid)) - goto out; +return nfserr_bad_stateid; }if ((flags &CHECK_FH ) &&nfs4_check_fh (current_fh, stp)) {printk ("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n" ); - goto out; +return nfserr_bad_stateid; } *stpp = stp;
@@ -2239,45 +2234,38 @@ nfs4_preprocess_seqid_op(struct svc_fh *if (seqid != sop->so_seqid) goto check_replay; -if (sop->so_confirmed) { -if (flags &CONFIRM ) { -printk ("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n" ); - goto out; - } - } -else { -if (!(flags &CONFIRM )) { -printk ("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n" ); - goto out; - } +if (sop->so_confirmed && flags &CONFIRM ) { +printk ("NFSD: preprocess_seqid_op: expected" +" unconfirmed stateowner!\n" ); +return nfserr_bad_stateid; + } +if (!sop->so_confirmed && !(flags &CONFIRM )) { +printk ("NFSD: preprocess_seqid_op: stateowner not" +" confirmed yet!\n" ); +return nfserr_bad_stateid; }if (stateid->si_generation > stp->st_stateid.si_generation) {printk ("NFSD: preprocess_seqid_op: future stateid?!\n" ); - goto out; +return nfserr_bad_stateid; } - status = nfserr_old_stateid;if (stateid->si_generation < stp->st_stateid.si_generation) {printk ("NFSD: preprocess_seqid_op: old stateid!\n" ); - goto out; +return nfserr_old_stateid; }renew_client (sop->so_client); - status = nfs_ok; +return nfs_ok; -out: -return status; check_replay:if (seqid == sop->so_seqid -1 ) {printk ("NFSD: preprocess_seqid_op: retransmission?\n" );/* indicate replay to calling function */ - status =NFSERR_REPLAY_ME ; - }else { -printk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n" , sop->so_seqid, seqid); - - *sopp =NULL ; - status = nfserr_bad_seqid; +return NFSERR_REPLAY_ME ; } - goto out; +printk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n" , + sop->so_seqid, seqid); + *sopp =NULL ; +return nfserr_bad_seqid; }int
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: check lock type against openmode.
In reply to NeilBrownWe shouldn't be allowing, e.g., write locks on files not open for read. To enforce this, we add a pointer from the lock stateid back to the open stateid it came from, so that the check will continue to be correct even after the open is upgraded or downgraded.
### Diffstat output
./fs/nfsd/nfs4state.c | 49 ++++++++++++++++++++++++++++--------------- ./include/linux/nfsd/state.h | 5 ++++ 2 files changed, 38 insertions(+), 16 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +33 -16
@@ -1160,6 +1160,7 @@ init_stateid(struct nfs4_stateid *stp, s stp->st_deny_bmap =0 ;__set_bit (open->op_share_access, &stp->st_access_bmap);__set_bit (open->op_share_deny, &stp->st_deny_bmap); + stp->st_openstp =NULL ; } static void
@@ -2158,12 +2159,18 @@ out:return status; } +static inline int +setlkflg (int type) +{ +return (type ==NFS4_READW_LT || type ==NFS4_READ_LT ) ? +RD_STATE :WR_STATE ; +}/* * Checks for sequence id mutating operations. */ static int -nfs4_preprocess_seqid_op (struct svc_fh *current_fh,u32 seqid,stateid_t *stateid,int flags,struct nfs4_stateowner **sopp,struct nfs4_stateid **stpp,clientid_t *lockclid) +nfs4_preprocess_seqid_op (struct svc_fh *current_fh,u32 seqid,stateid_t *stateid,int flags,struct nfs4_stateowner **sopp,struct nfs4_stateid **stpp,struct nfsd4_lock *lock) {struct nfs4_stateid *stp;struct nfs4_stateowner *sop;
@@ -2201,21 +2208,31 @@ nfs4_preprocess_seqid_op(struct svc_fh * goto check_replay; } -/* for new lock stateowners: -* check that the lock->v.new.open_stateid -* refers to an open stateowner -* -* check that the lockclid (nfs4_lock->v.new.clientid) is the same -* as the open_stateid->st_stateowner->so_client->clientid -*/ -if (lockclid) { +if (lock) {struct nfs4_stateowner *sop = stp->st_stateowner; +clientid_t *lockclid = &lock->v.new.clientid;struct nfs4_client *clp = sop->so_client; +int lkflg =0 ; +int status; + + lkflg =setlkflg (lock->lk_type); + +if (lock->lk_is_new) { +if (!sop->so_is_open_owner) +return nfserr_bad_stateid; +if (!cmp_clid (&clp->cl_clientid, lockclid)) +return nfserr_bad_stateid; +/* stp is the open stateid */ + status =nfs4_check_openmode (stp, lkflg); +if (status) +return status; + }else { +/* stp is the lock stateid */ + status =nfs4_check_openmode (stp->st_openstp, lkflg); +if (status) +return status; + } -if (!sop->so_is_open_owner) -return nfserr_bad_stateid; -if (!cmp_clid (&clp->cl_clientid, lockclid)) -return nfserr_bad_stateid; }if ((flags &CHECK_FH ) &&nfs4_check_fh (current_fh, stp)) {
@@ -2642,6 +2659,7 @@ alloc_init_lock_stateid(struct nfs4_stat stp->st_vfs_file = open_stp->st_vfs_file;/* FIXME refcount?? */ stp->st_access_bmap = open_stp->st_access_bmap; stp->st_deny_bmap = open_stp->st_deny_bmap; + stp->st_openstp = open_stp; out:return stp;
@@ -2697,8 +2715,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc lock->lk_new_open_seqid, &lock->lk_new_open_stateid,CHECK_FH |OPEN_STATE , - &open_sop, &open_stp, - &lock->v.new.clientid); + &open_sop, &open_stp, lock);if (status) goto out;/* create lockowner and lock stateid */
@@ -2726,7 +2743,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc lock->lk_old_lock_seqid, &lock->lk_old_lock_stateid,CHECK_FH |LOCK_STATE , - &lock->lk_stateowner, &lock_stp, NULL); + &lock->lk_stateowner, &lock_stp, lock);if (status) goto out; }
include/linux/nfsd/state.h renamed from include/linux/nfsd/state.h~current~ +5 -0
@@ -237,6 +237,10 @@ struct nfs4_file {* st_perlockowner: (open stateid) list of lock nfs4_stateowners * st_access_bmap: used only for open stateid * st_deny_bmap: used only for open stateid +* st_openstp: open stateid lock stateid was derived from +* +* XXX: open stateids and lock stateids have diverged sufficiently that +* we should consider defining separate structs for the two cases. */ struct nfs4_stateid {
@@ -250,6 +254,7 @@ struct nfs4_stateid {struct file * st_vfs_file;unsigned long st_access_bmap;unsigned long st_deny_bmap; +struct nfs4_stateid * st_openstp; };/* flags for preprocess_seqid_op() */
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: ERR_GRACE should bump seqid on lock
In reply to NeilBrownA GRACE or NOGRACE response to a lock request should also bump the sequence id. So we delay the handling of grace period errors till after we've found the relevant owner.
### Diffstat output
./fs/nfsd/nfs4state.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +7 -5
@@ -2706,11 +2706,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc (long long ) lock->lk_offset, (long long) lock->lk_length); -if (nfs4_in_grace () && !lock->lk_reclaim) -return nfserr_grace; -if (!nfs4_in_grace () && lock->lk_reclaim) -return nfserr_no_grace; -if (check_lock_length (lock->lk_offset, lock->lk_length))return nfserr_inval;
@@ -2785,6 +2780,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struc goto out; } + status = nfserr_grace; +if (nfs4_in_grace () && !lock->lk_reclaim) + goto out; + status = nfserr_no_grace; +if (!nfs4_in_grace () && lock->lk_reclaim) + goto out; +locks_init_lock (&file_lock);switch (lock->lk_type) {case NFS4_READ_LT :
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs