nfs server patches for review
Subsystems (3)
These are some nfs server patches I intend to submit for 2.6.24.
I'm also keeping this sort of thing in the nfs-server-stable branch, at
git://linux-nfs.org/~bfields/linux.git nfs-server-stable
That repository has a bunch of random other (mainly nfs-related) projects, but that particular branch is reserved for nfsd patches that I expect to be ready in time for the next merge window. If you have something nfsd-related that I've overlooked, please let me know.
Nothing earth-shaking here right now, just minor cleanups, bugfixes, and support from Peter Staubach for reporting 64 bit inode numbers.
--b.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/15 nfsd: tone down inaccurate dprintk
From: J. Bruce Fields <[email protected]>
The nfserr_dropit happens routinely on upcalls (so a kmalloc failure is almost never the actual cause), but I occasionally get a complant from some tester that's worried because they ran across this message after turning on debugging to research some unrelated problem.
--- fs/nfsd/nfssvc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
fs/nfsd/nfssvc.c +1 -1
@@ -549,7 +549,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)if (nfserr == nfserr_jukebox && rqstp->rq_vers ==2 ) nfserr = nfserr_dropit;if (nfserr == nfserr_dropit) { -dprintk ("nfsd: Dropping request due to malloc failure!\n" ); +dprintk ("nfsd: Dropping request; may be revisited later\n" );nfsd_cache_update (rqstp,RC_NOCACHE ,NULL );return 0 ; }
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 2/15 nfsd: remove unused cache_for_each macro
From: J. Bruce Fields <[email protected]>
This macro is unused.
--- include/linux/sunrpc/cache.h | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-)
include/linux/sunrpc/cache.h +0 -10
@@ -136,16 +136,6 @@ sunrpc_cache_update(struct cache_detail *detail, struct cache_head *new, struct cache_head *old, int hash); -#define cache_for_each (pos, detail, index, member) \ - for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \ - ({if (index==0)read_unlock(&(detail)->hash_lock); index--;}); \ - ) \ - for (pos = container_of((detail)->hash_table[index], typeof(*pos), member); \ - &pos->member; \ - pos = container_of(pos->member.next, typeof(*pos), member)) - - -extern void cache_clean_deferred (void *owner);static inline struct cache_head *cache_get (struct cache_head *h)
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 3/15 nfsd: fix horrible indentation in nfsd_setattr
From: Christoph Hellwig <[email protected]>
--- fs/nfsd/vfs.c | 43 ++++++++++++++++++++++++++----------------- 1 files changed, 26 insertions(+), 17 deletions(-)
fs/nfsd/vfs.c +26 -17
@@ -294,7 +294,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,if (!iap->ia_valid) goto out; -/* NFSv2 does not differentiate between "set-[ac]time-to-now" +/* +* NFSv2 does not differentiate between "set-[ac]time-to-now" * which only requires access, and "set-[ac]time-to-X" which * requires ownership. * So if it looks like it might be "set both to the same time which
@@ -307,25 +308,33 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,*/ #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)#define MAX_TOUCH_TIME_ERROR (30*60) -if ((iap->ia_valid &BOTH_TIME_SET ) ==BOTH_TIME_SET - && iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec - ) { -/* Looks probable. Now just make sure time is in the right ballpark. -* Solaris, at least, doesn't seem to care what the time request is. -* We require it be within 30 minutes of now. -*/ -time_t delta = iap->ia_atime.tv_sec -get_seconds (); -if (delta<0 ) delta = -delta; -if (delta <MAX_TOUCH_TIME_ERROR && -inode_change_ok (inode, iap) !=0 ) { -/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME -* this will cause notify_change to set these times to "now" +if ((iap->ia_valid &BOTH_TIME_SET ) ==BOTH_TIME_SET && + iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) { +/* +* Looks probable. +* +* Now just make sure time is in the right ballpark. +* Solaris, at least, doesn't seem to care what the time +* request is. We require it be within 30 minutes of now. */ - iap->ia_valid &= ~BOTH_TIME_SET ; - } +time_t delta = iap->ia_atime.tv_sec -get_seconds (); +if (delta <0 ) + delta = -delta; +if (delta <MAX_TOUCH_TIME_ERROR && +inode_change_ok (inode, iap) !=0 ) { +/* +* Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME. +* This will cause notify_change to set these times +* to "now" +*/ + iap->ia_valid &= ~BOTH_TIME_SET ; + } } -/* The size case is special. It changes the file as well as the attributes. */ +/* +* The size case is special. +* It changes the file as well as the attributes. +*/ if (iap->ia_valid &ATTR_SIZE ) {if (iap->ia_size < inode->i_size) { err =nfsd_permission (rqstp, fhp->fh_export, dentry,MAY_TRUNC |MAY_OWNER_OVERRIDE );
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 4/15 knfsd: delete code made redundant by map_new_errors
From: J. Bruce Fields <[email protected]>
I moved this check into map_new_errors, but forgot to delete the original. Oops.
--- fs/nfsd/nfssvc.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
fs/nfsd/nfssvc.c +0 -2
@@ -546,8 +546,6 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)/* Now call the procedure handler, and encode NFS status. */ nfserr = proc->pc_func (rqstp, rqstp->rq_argp, rqstp->rq_resp); nfserr =map_new_errors (rqstp->rq_vers, nfserr); -if (nfserr == nfserr_jukebox && rqstp->rq_vers ==2 ) - nfserr = nfserr_dropit;if (nfserr == nfserr_dropit) {dprintk ("nfsd: Dropping request; may be revisited later\n" );nfsd_cache_update (rqstp,RC_NOCACHE ,NULL );
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 5/15 knfsd: cleanup of nfsd4 cmp_* functions
From: J. Bruce Fields <[email protected]>
Benny Halevy suggested renaming cmp_* to same_* to make the meaning of the return value clearer.
Fix some nearby style deviations while we're at it, including a small swath of creative indentation in nfs4_preprocess_seqid_op().
--- fs/nfsd/nfs4state.c | 91 ++++++++++++++++++++++++++------------------------ 1 files changed, 47 insertions(+), 44 deletions(-)
fs/nfsd/nfs4state.c +47 -44
@@ -462,26 +462,28 @@ copy_cred(struct svc_cred *target, struct svc_cred *source) { }static inline int -same_name (const char *n1,const char *n2) { +same_name (const char *n1,const char *n2) +{return 0 ==memcmp (n1, n2,HEXDIR_LEN ); }static int -cmp_verf (nfs4_verifier *v1,nfs4_verifier *v2) { -return (!memcmp (v1->data,v2->data,sizeof (v1->data))); +same_verf (nfs4_verifier *v1,nfs4_verifier *v2) +{ +return 0 ==memcmp (v1->data, v2->data,sizeof (v1->data)); }static int -cmp_clid (clientid_t * cl1,clientid_t * cl2) { -return ((cl1->cl_boot == cl2->cl_boot) && - (cl1->cl_id == cl2->cl_id)); +same_clid (clientid_t *cl1,clientid_t *cl2) +{ +return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); }/* XXX what about NGROUP */ static int -cmp_creds (struct svc_cred *cr1,struct svc_cred *cr2){ -return (cr1->cr_uid == cr2->cr_uid); - +same_creds (struct svc_cred *cr1,struct svc_cred *cr2) +{ +return cr1->cr_uid == cr2->cr_uid; } static void
@@ -546,7 +548,7 @@ find_confirmed_client(clientid_t *clid)unsigned int idhashval =clientid_hashval (clid->cl_id);list_for_each_entry (clp, &conf_id_hashtbl[idhashval], cl_idhash) { -if (cmp_clid (&clp->cl_clientid, clid)) +if (same_clid (&clp->cl_clientid, clid))return clp; }return NULL ;
@@ -559,7 +561,7 @@ find_unconfirmed_client(clientid_t *clid)unsigned int idhashval =clientid_hashval (clid->cl_id);list_for_each_entry (clp, &unconf_id_hashtbl[idhashval], cl_idhash) { -if (cmp_clid (&clp->cl_clientid, clid)) +if (same_clid (&clp->cl_clientid, clid))return clp; }return NULL ;
@@ -753,7 +755,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,* or different ip_address */ status = nfserr_clid_inuse; -if (!cmp_creds (&conf->cl_cred, &rqstp->rq_cred) +if (!same_creds (&conf->cl_cred, &rqstp->rq_cred) || conf->cl_addr != sin->sin_addr.s_addr) {dprintk ("NFSD: setclientid: string in use by client" "at %u.%u.%u.%u\n" ,NIPQUAD (conf->cl_addr));
@@ -779,7 +781,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,gen_confirm (new);gen_callback (new, setclid);add_to_unconfirmed (new, strhashval); - }else if (cmp_verf (&conf->cl_verifier, &clverifier)) { + }else if (same_verf (&conf->cl_verifier, &clverifier)) {/* * CASE 1: * cl_name match, confirmed, principal match
@@ -830,7 +832,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,gen_confirm (new);gen_callback (new, setclid);add_to_unconfirmed (new, strhashval); - }else if (!cmp_verf (&conf->cl_confirm, &unconf->cl_confirm)) { + }else if (!same_verf (&conf->cl_confirm, &unconf->cl_confirm)) {/* * CASE3: * confirmed found (name, principal match)
@@ -910,16 +912,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, goto out;if ((conf && unconf) && - (cmp_verf (&unconf->cl_confirm, &confirm)) && - (cmp_verf (&conf->cl_verifier, &unconf->cl_verifier)) && + (same_verf (&unconf->cl_confirm, &confirm)) && + (same_verf (&conf->cl_verifier, &unconf->cl_verifier)) && (same_name (conf->cl_recdir,unconf->cl_recdir)) && - (!cmp_verf (&conf->cl_confirm, &unconf->cl_confirm))) { + (!same_verf (&conf->cl_confirm, &unconf->cl_confirm))) {/* CASE 1: * unconf record that matches input clientid and input confirm. * conf record that matches input clientid. * conf and unconf records match names, verifiers */ -if (!cmp_creds (&conf->cl_cred, &unconf->cl_cred)) +if (!same_creds (&conf->cl_cred, &unconf->cl_cred)) status = nfserr_clid_inuse;else {/* XXX: We just turn off callbacks until we can handle
@@ -933,7 +935,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, } }else if ((conf && !unconf) || ((conf && unconf) && - (!cmp_verf (&conf->cl_verifier, &unconf->cl_verifier) || + (!same_verf (&conf->cl_verifier, &unconf->cl_verifier) || !same_name (conf->cl_recdir, unconf->cl_recdir)))) {/* CASE 2: * conf record that matches input clientid.
@@ -941,18 +943,18 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,* unconf->cl_name or unconf->cl_verifier don't match the * conf record. */ -if (!cmp_creds (&conf->cl_cred,&rqstp->rq_cred)) +if (!same_creds (&conf->cl_cred, &rqstp->rq_cred)) status = nfserr_clid_inuse;else status = nfs_ok; }else if (!conf && unconf - &&cmp_verf (&unconf->cl_confirm, &confirm)) { + &&same_verf (&unconf->cl_confirm, &confirm)) {/* CASE 3: * conf record not found. * unconf record found. * unconf->cl_confirm matches input confirm */ -if (!cmp_creds (&unconf->cl_cred, &rqstp->rq_cred)) { +if (!same_creds (&unconf->cl_cred, &rqstp->rq_cred)) { status = nfserr_clid_inuse; }else { unsigned int hash =
@@ -967,8 +969,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, conf = unconf; status = nfs_ok; } - }else if ((!conf || (conf && !cmp_verf (&conf->cl_confirm, &confirm))) - && (!unconf || (unconf && !cmp_verf (&unconf->cl_confirm, + }else if ((!conf || (conf && !same_verf (&conf->cl_confirm, &confirm))) + && (!unconf || (unconf && !same_verf (&unconf->cl_confirm, &confirm)))) {/* CASE 4: * conf record not found, or if conf, conf->cl_confirm does not
@@ -1207,10 +1209,12 @@ move_to_close_lru(struct nfs4_stateowner *sop) }static int -cmp_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner,clientid_t *clid) { -return ((sop->so_owner.len == owner->len) && - !memcmp (sop->so_owner.data, owner->data, owner->len) && - (sop->so_client->cl_clientid.cl_id == clid->cl_id)); +same_owner_str (struct nfs4_stateowner *sop,struct xdr_netobj *owner, +clientid_t *clid) +{ +return (sop->so_owner.len == owner->len) && +0 ==memcmp (sop->so_owner.data, owner->data, owner->len) && + (sop->so_client->cl_clientid.cl_id == clid->cl_id); } static struct nfs4_stateowner *
@@ -1219,7 +1223,7 @@ find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)struct nfs4_stateowner *so =NULL ;list_for_each_entry (so, &ownerstr_hashtbl[hashval], so_strhash) { -if (cmp_owner_str (so, &open->op_owner, &open->op_clientid)) +if (same_owner_str (so, &open->op_owner, &open->op_clientid))return so; }return NULL ;
@@ -2181,21 +2185,20 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei 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)) +if (!sop->so_is_open_owner) +return nfserr_bad_stateid; +if (!same_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; +/* 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 ((flags &CHECK_FH ) &&nfs4_check_fh (current_fh, stp)) {
@@ -2561,7 +2564,7 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,struct nfs4_stateowner *op;list_for_each_entry (op, &lock_ownerstr_hashtbl[hashval], so_strhash) { -if (cmp_owner_str (op, owner, clid)) +if (same_owner_str (op, owner, clid))return op; }return NULL ;
@@ -3025,7 +3028,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,INIT_LIST_HEAD (&matches);for (i =0 ; i <LOCK_HASH_SIZE ; i++) {list_for_each_entry (sop, &lock_ownerid_hashtbl[i], so_idhash) { -if (!cmp_owner_str (sop, owner, clid)) +if (!same_owner_str (sop, owner, clid))continue ;list_for_each_entry (stp, &sop->so_stateids, st_perstateowner) {
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 6/15 knfsd: demote some printk()s to dprintk()s
From: J. Bruce Fields <[email protected]>
To quote a recent mail from Andrew Morton:
Look: if there's a way in which an unprivileged user can trigger a printk we fix it, end of story.
OK. I assume that goes double for printk()s that might be triggered by random hosts on the internet. So, disable some printk()s that look like they could be triggered by malfunctioning or malicious clients. For now, just downgrade them to dprintk()s.
--- fs/nfsd/nfs4proc.c | 4 ++-- fs/nfsd/nfs4state.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-)
fs/nfsd/nfs4proc.c +2 -2
@@ -238,12 +238,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,break ;case NFS4_OPEN_CLAIM_DELEGATE_PREV : open->op_stateowner->so_confirmed =1 ; -printk ("NFSD: unsupported OPEN claim type %d\n" , +dprintk ("NFSD: unsupported OPEN claim type %d\n" , open->op_claim_type); status = nfserr_notsupp; goto out;default : -printk ("NFSD: Invalid OPEN claim type %d\n" , +dprintk ("NFSD: Invalid OPEN claim type %d\n" , open->op_claim_type); status = nfserr_inval; goto out;
fs/nfsd/nfs4state.c +10 -10
@@ -509,7 +509,7 @@ check_name(struct xdr_netobj name) {if (name.len ==0 )return 0 ;if (name.len >NFS4_OPAQUE_LIMIT ) { -printk ("NFSD: check_name: name too long(%d)!\n" , name.len); +dprintk ("NFSD: check_name: name too long(%d)!\n" , name.len);return 0 ; }return 1 ;
@@ -1742,7 +1742,7 @@ out:if (open->op_claim_type ==NFS4_OPEN_CLAIM_PREVIOUS && flag ==NFS4_OPEN_DELEGATE_NONE && open->op_delegate_type !=NFS4_OPEN_DELEGATE_NONE ) -printk ("NFSD: WARNING: refusing delegation reclaim\n" ); +dprintk ("NFSD: WARNING: refusing delegation reclaim\n" ); open->op_delegate_type = flag; }
@@ -2151,7 +2151,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei *sopp =NULL ;if (ZERO_STATEID (stateid) ||ONE_STATEID (stateid)) { -printk ("NFSD: preprocess_seqid_op: magic stateid!\n" ); +dprintk ("NFSD: preprocess_seqid_op: magic stateid!\n" );return nfserr_bad_stateid; }
@@ -2202,7 +2202,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei }if ((flags &CHECK_FH ) &&nfs4_check_fh (current_fh, stp)) { -printk ("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n" ); +dprintk ("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n" );return nfserr_bad_stateid; }
@@ -2218,22 +2218,22 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei goto check_replay;if (sop->so_confirmed && flags &CONFIRM ) { -printk ("NFSD: preprocess_seqid_op: expected" +dprintk ("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" +dprintk ("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" ); +dprintk ("NFSD: preprocess_seqid_op: future stateid?!\n" );return nfserr_bad_stateid; }if (stateid->si_generation < stp->st_stateid.si_generation) { -printk ("NFSD: preprocess_seqid_op: old stateid!\n" ); +dprintk ("NFSD: preprocess_seqid_op: old stateid!\n" );return nfserr_old_stateid; }renew_client (sop->so_client);
@@ -2245,7 +2245,7 @@ check_replay:/* indicate replay to calling function */ return nfserr_replay_me; } -printk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n" , +dprintk ("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n" , sop->so_seqid, seqid); *sopp =NULL ;return nfserr_bad_seqid;
@@ -2858,7 +2858,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, file_lock.fl_type =F_WRLCK ;break ;default : -printk ("NFSD: nfs4_lockt: bad lock type!\n" ); +dprintk ("NFSD: nfs4_lockt: bad lock type!\n" ); status = nfserr_inval; goto out; }
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 7/15 knfsd: nfs4 name->id mapping not correctly parsing negative downcall
From: J. Bruce Fields <[email protected]>
Note that qword_get() returns length or -1, not an -ERROR.
--- fs/nfsd/nfs4idmap.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
fs/nfsd/nfs4idmap.c +5 -3
@@ -207,6 +207,7 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) {struct ent ent, *res;char *buf1, *bp; +int len;int error = -EINVAL ;if (buf[buflen -1 ] !='\n' )
@@ -248,10 +249,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) goto out;/* Name */ - error =qword_get (&buf, buf1,PAGE_SIZE ); -if (error == -EINVAL ) + error = -EINVAL ; + len =qword_get (&buf, buf1,PAGE_SIZE ); +if (len <0 ) goto out; -if (error == -ENOENT ) +if (len ==0 )set_bit (CACHE_NEGATIVE , &ent.h.flags);else {if (error >=IDMAP_NAMESZ ) {
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 8/15 knfsd: spawn kernel thread to probe callback channel
From: J. Bruce Fields <[email protected]>
We want to allow gss on the callback channel, so people using krb5 can still get the benefits of delegations.
But looking up the rpc credential can take some time in that case. And we shouldn't delay the response to setclientid_confirm while we wait.
It may be inefficient, but for now the simplest solution is just to spawn a new thread as necessary for the purpose.
(Thanks to Adrian Bunk for catching a missing static here.)
--- fs/nfsd/nfs4callback.c | 71 +++++++++++++++++++++++------------------------- 1 files changed, 34 insertions(+), 37 deletions(-)
fs/nfsd/nfs4callback.c +34 -37
@@ -39,6 +39,7 @@#include <linux/errno.h> #include <linux/delay.h> #include <linux/sched.h> +#include <linux/kthread.h> #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/svc.h> #include <linux/sunrpc/clnt.h>
@@ -365,6 +366,35 @@ nfsd4_lookupcred(struct nfs4_client *clp, int taskflags)return ret; } +/* Reference counting, callback cleanup, etc., all look racy as heck. +* And why is cb_set an atomic? */ + +static int do_probe_callback (void *data) +{ +struct nfs4_client *clp = data; +struct nfs4_callback *cb = &clp->cl_callback; +struct rpc_message msg = { + .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL ], + .rpc_argp = clp, + }; +int status; + + msg.rpc_cred =nfsd4_lookupcred (clp,0 ); +if (IS_ERR (msg.rpc_cred)) + goto out; + status =rpc_call_sync (cb->cb_client, &msg,RPC_TASK_SOFT ); +put_rpccred (msg.rpc_cred); + +if (status) { +rpc_shutdown_client (cb->cb_client); + cb->cb_client =NULL ; + }else +atomic_set (&cb->cb_set,1 ); +out: +put_nfs4_client (clp); +return 0 ; +} +/* * Set up the callback client and put a NFSPROC4_CB_NULL on the wire... */
@@ -390,11 +420,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ .flags = (RPC_CLNT_CREATE_NOPING), }; -struct rpc_message msg = { - .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL ], - .rpc_argp = clp, - }; -int status; +struct task_struct *t;if (atomic_read (&cb->cb_set))return ;
@@ -426,16 +452,11 @@ nfsd4_probe_callback(struct nfs4_client *clp)/* the task holds a reference to the nfs4_client struct */ atomic_inc (&clp->cl_count); - msg.rpc_cred =nfsd4_lookupcred (clp,0 ); -if (IS_ERR (msg.rpc_cred)) - goto out_release_clp; - status =rpc_call_async (cb->cb_client, &msg,RPC_TASK_ASYNC , &nfs4_cb_null_ops,NULL ); -put_rpccred (msg.rpc_cred); + t =kthread_run (do_probe_callback, clp,"nfs4_cb_probe" ); -if (status !=0 ) { -dprintk ("NFSD: asynchronous NFSPROC4_CB_NULL failed!\n" ); +if (IS_ERR (t)) goto out_release_clp; - } +return ; out_release_clp:
@@ -447,30 +468,6 @@ out_err: (int)clp->cl_name.len, clp->cl_name.data); } -static void -nfs4_cb_null (struct rpc_task *task,void *dummy) -{ -struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; -struct nfs4_callback *cb = &clp->cl_callback; -__be32 addr =htonl (cb->cb_addr); - -dprintk ("NFSD: nfs4_cb_null task->tk_status %d\n" , task->tk_status); - -if (task->tk_status <0 ) { -dprintk ("NFSD: callback establishment to client %.*s failed\n" , - (int )clp->cl_name.len, clp->cl_name.data); - goto out; - } -atomic_set (&cb->cb_set,1 ); -dprintk ("NFSD: callback set to client %u.%u.%u.%u\n" ,NIPQUAD (addr)); -out: -put_nfs4_client (clp); -} - -static const struct rpc_call_ops nfs4_cb_null_ops = { - .rpc_call_done = nfs4_cb_null, -}; -/* * called with dp->dl_count inc'ed. * nfs4_lock_state() may or may not have been called.
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 9/15 knfsd: move nfsv4 slab creation/destruction to module init/exit
From: J. Bruce Fields <[email protected]>
We have some slabs that the nfs4 server uses to store state objects. We're currently creating and destroying those slabs whenever the server is brought up or down. That seems excessive; may as well just do that in module initialization and exit.
Also add some minor header cleanup. (Thanks to Andrew Morton for that and a compile fix.)
--- fs/nfsd/nfs4state.c | 22 ++++++++++------------ fs/nfsd/nfsctl.c | 5 ++++- fs/nfsd/nfssvc.c | 4 +--- include/linux/nfsd/nfsd.h | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 24 deletions(-)
fs/nfsd/nfs4state.c +10 -12
@@ -1021,7 +1021,7 @@ nfsd4_free_slab(struct kmem_cache **slab) *slab =NULL ; } -static void +void nfsd4_free_slabs (void ) {nfsd4_free_slab (&stateowner_slab);
@@ -3152,11 +3152,14 @@ nfs4_check_open_reclaim(clientid_t *clid)/* initialization to perform at module load time: */ -void +int nfs4_state_init (void ) { -int i; +int i, status; + status =nfsd4_init_slabs (); +if (status) +return status;for (i =0 ; i <CLIENT_HASH_SIZE ; i++) {INIT_LIST_HEAD (&conf_id_hashtbl[i]);INIT_LIST_HEAD (&conf_str_hashtbl[i]);
@@ -3185,6 +3188,7 @@ nfs4_state_init(void)for (i =0 ; i <CLIENT_HASH_SIZE ; i++)INIT_LIST_HEAD (&reclaim_str_hashtbl[i]); reclaim_str_hashtbl_size =0 ; +return 0 ; } static void
@@ -3245,20 +3249,15 @@ __nfs4_state_start(void)set_max_delegations (); } -int +void nfs4_state_start (void ) { -int status; -if (nfs4_init) -return 0 ; - status =nfsd4_init_slabs (); -if (status) -return status; +return ;nfsd4_load_reboot_recovery_data ();__nfs4_state_start (); nfs4_init =1 ; -return 0 ; +return ; }int
@@ -3316,7 +3315,6 @@ nfs4_state_shutdown(void)nfs4_lock_state ();nfs4_release_reclaim ();__nfs4_state_shutdown (); -nfsd4_free_slabs ();nfs4_unlock_state (); }
fs/nfsd/nfsctl.c +4 -1
@@ -679,11 +679,13 @@ static int __init init_nfsd(void)int retval;printk (KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n" ); + retval =nfs4_state_init ();/* nfs4 locking state */ +if (retval) +return retval;nfsd_stat_init ();/* Statistics */ nfsd_cache_init ();/* RPC reply cache */ nfsd_export_init ();/* Exports table */ nfsd_lockd_init ();/* lockd->nfsd callbacks */ -nfs4_state_init ();/* NFSv4 locking state */ nfsd_idmap_init ();/* Name to ID mapping */ if (proc_mkdir ("fs/nfs" ,NULL )) {struct proc_dir_entry *entry;
@@ -712,6 +714,7 @@ static void __exit exit_nfsd(void)nfsd_stat_shutdown ();nfsd_lockd_shutdown ();nfsd_idmap_shutdown (); +nfsd4_free_slabs ();unregister_filesystem (&nfsd_fs_type); }
fs/nfsd/nfssvc.c +1 -3
@@ -349,9 +349,7 @@ nfsd_svc(unsigned short port, int nrservs) error =nfsd_racache_init (2 *nrservs);if (error<0 ) goto out; - error =nfs4_state_start (); -if (error<0 ) - goto out; +nfs4_state_start ();nfsd_reset_versions ();
include/linux/nfsd/nfsd.h +10 -8
@@ -153,19 +153,21 @@ extern int nfsd_max_blksize;*/ #ifdef CONFIG_NFSD_V4 extern unsigned int max_delegations; -void nfs4_state_init (void ); -int nfs4_state_start (void ); +int nfs4_state_init (void ); +void nfsd4_free_slabs (void ); +void nfs4_state_start (void );void nfs4_state_shutdown (void );time_t nfs4_lease_time (void );void nfs4_reset_lease (time_t leasetime);int nfs4_reset_recoverydir (char *recdir);#else -static inline void nfs4_state_init (void ){}; -static inline int nfs4_state_start (void ){return 0 ;} -static inline void nfs4_state_shutdown (void ){} -static inline time_t nfs4_lease_time (void ){return 0 ;} -static inline void nfs4_reset_lease (time_t leasetime){} -static inline int nfs4_reset_recoverydir (char *recdir) {return 0 ;} +static inline int nfs4_state_init (void ) {return 0 ; } +static inline void nfsd4_free_slabs (void ) { } +static inline void nfs4_state_start (void ) { } +static inline void nfs4_state_shutdown (void ) { } +static inline time_t nfs4_lease_time (void ) {return 0 ; } +static inline void nfs4_reset_lease (time_t leasetime) { } +static inline int nfs4_reset_recoverydir (char *recdir) {return 0 ; }#endif /*
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 10/15 knfsd: Validate filehandle type in fsid_source
From: Neil Brown <[email protected]>
fsid_source decided where to get the 'fsid' number to return for a GETATTR based on the type of filehandle. It can be from the device, from the fsid, or from the UUID.
It is possible for the filehandle to be inconsistent with the export information, so make sure the export information actually has the info implied by the value returned by fsid_source.
--- fs/nfsd/nfsfh.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-)
fs/nfsd/nfsfh.c +15 -5
@@ -566,13 +566,23 @@ enum fsid_source fsid_source(struct svc_fh *fhp)case FSID_DEV :case FSID_ENCODE_DEV :case FSID_MAJOR_MINOR : -return FSIDSOURCE_DEV ; +if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags + &FS_REQUIRES_DEV ) +return FSIDSOURCE_DEV ; +break ;case FSID_NUM : -return FSIDSOURCE_FSID ; -default :if (fhp->fh_export->ex_flags &NFSEXP_FSID )return FSIDSOURCE_FSID ; -else -return FSIDSOURCE_UUID ; +break ; +default : +break ; } +/* either a UUID type filehandle, or the filehandle doesn't +* match the export. +*/ +if (fhp->fh_export->ex_flags &NFSEXP_FSID ) +return FSIDSOURCE_FSID ; +if (fhp->fh_export->ex_uuid) +return FSIDSOURCE_UUID ; +return FSIDSOURCE_DEV ; }
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 11/15 knfsd: fix callback rpc cred
From: J. Bruce Fields <[email protected]>
It doesn't make sense to make the callback with credentials that the client made the setclientid with. Instead the spec requires that the callback occur with the credentials the client authenticated *to*. It probably doesn't matter what we use for auth_unix, and some more infrastructure will be needed for auth_gss, so let's just remove the cred lookup for now.
--- fs/nfsd/nfs4callback.c | 33 --------------------------------- 1 files changed, 0 insertions(+), 33 deletions(-)
fs/nfsd/nfs4callback.c +0 -33
@@ -344,28 +344,6 @@ static struct rpc_version * nfs_cb_version[] = { &nfs_cb_version4, }; -/* -* Use the SETCLIENTID credential -*/ -static struct rpc_cred * -nfsd4_lookupcred (struct nfs4_client *clp,int taskflags) -{ -struct auth_cred acred; -struct rpc_clnt *clnt = clp->cl_callback.cb_client; -struct rpc_cred *ret; - -get_group_info (clp->cl_cred.cr_group_info); - acred.uid = clp->cl_cred.cr_uid; - acred.gid = clp->cl_cred.cr_gid; - acred.group_info = clp->cl_cred.cr_group_info; - -dprintk ("NFSD: looking up %s cred\n" , - clnt->cl_auth->au_ops->au_name); - ret =rpcauth_lookup_credcache (clnt->cl_auth, &acred, taskflags); -put_group_info (clp->cl_cred.cr_group_info); -return ret; -} -/* Reference counting, callback cleanup, etc., all look racy as heck. * And why is cb_set an atomic? */
@@ -379,18 +357,13 @@ static int do_probe_callback(void *data) };int status; - msg.rpc_cred =nfsd4_lookupcred (clp,0 ); -if (IS_ERR (msg.rpc_cred)) - goto out; status =rpc_call_sync (cb->cb_client, &msg,RPC_TASK_SOFT ); -put_rpccred (msg.rpc_cred);if (status) {rpc_shutdown_client (cb->cb_client); cb->cb_client =NULL ; }else atomic_set (&cb->cb_set,1 ); -out:put_nfs4_client (clp);return 0 ; }
@@ -488,10 +461,6 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)if ((!atomic_read (&clp->cl_callback.cb_set)) || !clnt)return ; - msg.rpc_cred =nfsd4_lookupcred (clp,0 ); -if (IS_ERR (msg.rpc_cred)) - goto out; - cbr->cbr_trunc =0 ;/* XXX need to implement truncate optimization */ cbr->cbr_dp = dp;
@@ -512,8 +481,6 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) status =rpc_call_sync (clnt, &msg,RPC_TASK_SOFT ); } out_put_cred: -put_rpccred (msg.rpc_cred); -out:if (status == -EIO )atomic_set (&clp->cl_callback.cb_set,0 );/* Success or failure, now we're either waiting for lease expiration
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 12/15 nfsd warning fix
From: Andrew Morton <[email protected]>
fs/nfsd/nfsctl.c: In function 'write_filehandle':fs/nfsd/nfsctl.c:301: warning: 'maxsize' may be used uninitialized in this function
--- fs/nfsd/nfsctl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
fs/nfsd/nfsctl.c +1 -1
@@ -298,7 +298,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)* qword quoting is used, so filehandle will be \x.... */ char *dname, *path; -int maxsize; +int uninitialized_var (maxsize );char *mesg = buf;int len;struct auth_domain *dom;
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 13/15 knfsd: remove code duplication in nfsd4_setclientid()
From: J. Bruce Fields <[email protected]>
Each branch of this if-then-else has a bunch of duplicated code that we could just put at the end.
--- fs/nfsd/nfs4state.c | 30 ++++++------------------------ 1 files changed, 6 insertions(+), 24 deletions(-)
fs/nfsd/nfs4state.c +6 -24
@@ -774,13 +774,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, new =create_client (clname, dname);if (new ==NULL ) goto out; -copy_verf (new, &clverifier); - new->cl_addr = sin->sin_addr.s_addr; -copy_cred (&new->cl_cred,&rqstp->rq_cred);gen_clid (new); -gen_confirm (new); -gen_callback (new, setclid); -add_to_unconfirmed (new, strhashval); }else if (same_verf (&conf->cl_verifier, &clverifier)) {/* * CASE 1:
@@ -806,13 +800,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, new =create_client (clname, dname);if (new ==NULL ) goto out; -copy_verf (new,&conf->cl_verifier); - new->cl_addr = sin->sin_addr.s_addr; -copy_cred (&new->cl_cred,&rqstp->rq_cred);copy_clid (new, conf); -gen_confirm (new); -gen_callback (new, setclid); -add_to_unconfirmed (new,strhashval); }else if (!unconf) {/* * CASE 2:
@@ -825,13 +813,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, new =create_client (clname, dname);if (new ==NULL ) goto out; -copy_verf (new,&clverifier); - new->cl_addr = sin->sin_addr.s_addr; -copy_cred (&new->cl_cred,&rqstp->rq_cred);gen_clid (new); -gen_confirm (new); -gen_callback (new, setclid); -add_to_unconfirmed (new, strhashval); }else if (!same_verf (&conf->cl_confirm, &unconf->cl_confirm)) {/* * CASE3:
@@ -852,19 +834,19 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, new =create_client (clname, dname);if (new ==NULL ) goto out; -copy_verf (new,&clverifier); - new->cl_addr = sin->sin_addr.s_addr; -copy_cred (&new->cl_cred,&rqstp->rq_cred);gen_clid (new); -gen_confirm (new); -gen_callback (new, setclid); -add_to_unconfirmed (new, strhashval); }else {/* No cases hit !!! */ status = nfserr_inval; goto out; } +copy_verf (new, &clverifier); + new->cl_addr = sin->sin_addr.s_addr; +copy_cred (&new->cl_cred, &rqstp->rq_cred); +gen_confirm (new); +gen_callback (new, setclid); +add_to_unconfirmed (new, strhashval); setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; setclid->se_clientid.cl_id = new->cl_clientid.cl_id;memcpy (setclid->se_confirm.data, new->cl_confirm.data,sizeof (setclid->se_confirm.data));
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 14/15 svcgss: move init code into separate function
From: J. Bruce Fields <[email protected]>
We've let svcauth_gss_accept() get much too long and hairy. The RPC_GSS_PROC_INIT and RPC_GSS_PROC_CONTINUE_INIT cases share very little with the other cases, so it's very natural to split them off into a separate function.
This will also nicely isolate the piece of code we need to parametrize to authenticating gss-protected NFSv4 callbacks on behalf of the NFS client.
--- net/sunrpc/auth_gss/svcauth_gss.c | 144 ++++++++++++++++++++----------------- 1 files changed, 77 insertions(+), 67 deletions(-)
net/sunrpc/auth_gss/svcauth_gss.c +77 -67
@@ -632,7 +632,8 @@ svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o)return 0 ; } -/* Verify the checksum on the header and return SVC_OK on success. +/* +* Verify the checksum on the header and return SVC_OK on success. * Otherwise, return SVC_DROP (in the case of a bad sequence number) * or return SVC_DENIED and indicate error in authp. */
@@ -962,6 +963,78 @@ gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip) }/* +* Having read the cred already and found we're in the context +* initiation case, read the verifier and initiate (or check the results +* of) upcalls to userspace for help with context initiation. If +* the upcall results are available, write the verifier and result. +* Otherwise, drop the request pending an answer to the upcall. +*/ +static int svcauth_gss_handle_init (struct svc_rqst *rqstp, +struct rpc_gss_wire_cred *gc,__be32 *authp) +{ +struct kvec *argv = &rqstp->rq_arg.head[0 ]; +struct kvec *resv = &rqstp->rq_res.head[0 ]; +struct xdr_netobj tmpobj; +struct rsi *rsip, rsikey; + +/* Read the verifier; should be NULL: */ + *authp = rpc_autherr_badverf; +if (argv->iov_len <2 *4 ) +return SVC_DENIED ; +if (svc_getnl (argv) !=RPC_AUTH_NULL ) +return SVC_DENIED ; +if (svc_getnl (argv) !=0 ) +return SVC_DENIED ; + +/* Martial context handle and token for upcall: */ + *authp = rpc_autherr_badcred; +if (gc->gc_proc ==RPC_GSS_PROC_INIT && gc->gc_ctx.len !=0 ) +return SVC_DENIED ; +memset (&rsikey,0 ,sizeof (rsikey)); +if (dup_netobj (&rsikey.in_handle, &gc->gc_ctx)) +return SVC_DROP ; + *authp = rpc_autherr_badverf; +if (svc_safe_getnetobj (argv, &tmpobj)) { +kfree (rsikey.in_handle.data); +return SVC_DENIED ; + } +if (dup_netobj (&rsikey.in_token, &tmpobj)) { +kfree (rsikey.in_handle.data); +return SVC_DROP ; + } + +/* Perform upcall, or find upcall result: */ + rsip =rsi_lookup (&rsikey); +rsi_free (&rsikey); +if (!rsip) +return SVC_DROP ; +switch (cache_check (&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { +case -EAGAIN : +case -ETIMEDOUT : +case -ENOENT : +/* No upcall result: */ +return SVC_DROP ; +case 0 : +/* Got an answer to the upcall; use it: */ +if (gss_write_init_verf (rqstp, rsip)) +return SVC_DROP ; +if (resv->iov_len +4 >PAGE_SIZE ) +return SVC_DROP ; +svc_putnl (resv,RPC_SUCCESS ); +if (svc_safe_putnetobj (resv, &rsip->out_handle)) +return SVC_DROP ; +if (resv->iov_len +3 *4 >PAGE_SIZE ) +return SVC_DROP ; +svc_putnl (resv, rsip->major_status); +svc_putnl (resv, rsip->minor_status); +svc_putnl (resv,GSS_SEQ_WIN ); +if (svc_safe_putnetobj (resv, &rsip->out_token)) +return SVC_DROP ; + } +return SVC_COMPLETE ; +} + +/* * Accept an rpcsec packet. * If context establishment, punt to user space * If data exchange, verify/decrypt
@@ -975,11 +1048,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)struct kvec *argv = &rqstp->rq_arg.head[0 ];struct kvec *resv = &rqstp->rq_res.head[0 ];u32 crlen; -struct xdr_netobj tmpobj;struct gss_svc_data *svcdata = rqstp->rq_auth_data;struct rpc_gss_wire_cred *gc;struct rsc *rsci =NULL ; -struct rsi *rsip, rsikey;__be32 *rpcstart;__be32 *reject_stat = resv->iov_base + resv->iov_len;int ret;
@@ -1024,30 +1095,14 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)if ((gc->gc_proc !=RPC_GSS_PROC_DATA ) && (rqstp->rq_proc !=0 )) goto auth_err; -/* -* We've successfully parsed the credential. Let's check out the -* verifier. An AUTH_NULL verifier is allowed (and required) for -* INIT and CONTINUE_INIT requests. AUTH_RPCSEC_GSS is required for -* PROC_DATA and PROC_DESTROY. -* -* AUTH_NULL verifier is 0 (AUTH_NULL), 0 (length). -* AUTH_RPCSEC_GSS verifier is: -* 6 (AUTH_RPCSEC_GSS), length, checksum. -* checksum is calculated over rpcheader from xid up to here. -*/ *authp = rpc_autherr_badverf;switch (gc->gc_proc) {case RPC_GSS_PROC_INIT :case RPC_GSS_PROC_CONTINUE_INIT : -if (argv->iov_len <2 *4 ) - goto auth_err; -if (svc_getnl (argv) !=RPC_AUTH_NULL ) - goto auth_err; -if (svc_getnl (argv) !=0 ) - goto auth_err; -break ; +return svcauth_gss_handle_init (rqstp, gc, authp);case RPC_GSS_PROC_DATA :case RPC_GSS_PROC_DESTROY : +/* Look up the context, and check the verifier: */ *authp = rpcsec_gsserr_credproblem; rsci =gss_svc_searchbyctx (&gc->gc_ctx);if (!rsci)
@@ -1068,51 +1123,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)/* now act upon the command: */ switch (gc->gc_proc) { -case RPC_GSS_PROC_INIT : -case RPC_GSS_PROC_CONTINUE_INIT : - *authp = rpc_autherr_badcred; -if (gc->gc_proc ==RPC_GSS_PROC_INIT && gc->gc_ctx.len !=0 ) - goto auth_err; -memset (&rsikey,0 ,sizeof (rsikey)); -if (dup_netobj (&rsikey.in_handle, &gc->gc_ctx)) - goto drop; - *authp = rpc_autherr_badverf; -if (svc_safe_getnetobj (argv, &tmpobj)) { -kfree (rsikey.in_handle.data); - goto auth_err; - } -if (dup_netobj (&rsikey.in_token, &tmpobj)) { -kfree (rsikey.in_handle.data); - goto drop; - } - - rsip =rsi_lookup (&rsikey); -rsi_free (&rsikey); -if (!rsip) { - goto drop; - } -switch (cache_check (&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { -case -EAGAIN : -case -ETIMEDOUT : -case -ENOENT : - goto drop; -case 0 : -if (gss_write_init_verf (rqstp, rsip)) - goto drop; -if (resv->iov_len +4 >PAGE_SIZE ) - goto drop; -svc_putnl (resv,RPC_SUCCESS ); -if (svc_safe_putnetobj (resv, &rsip->out_handle)) - goto drop; -if (resv->iov_len +3 *4 >PAGE_SIZE ) - goto drop; -svc_putnl (resv, rsip->major_status); -svc_putnl (resv, rsip->minor_status); -svc_putnl (resv,GSS_SEQ_WIN ); -if (svc_safe_putnetobj (resv, &rsip->out_token)) - goto drop; - } - goto complete;case RPC_GSS_PROC_DESTROY :if (gss_write_verf (rqstp, rsci->mechctx, gc->gc_seq)) goto auth_err;
@@ -1159,7 +1169,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) goto out; } auth_err: -/* Restore write pointer to original value: */ +/* Restore write pointer to its original value: */ xdr_ressize_check (rqstp, reject_stat); ret =SVC_DENIED ; goto out;
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 15/15 knfsd: 64 bit ino support for NFS server
From: Peter Staubach <[email protected]>
Modify the NFS server code to support 64 bit ino's, as appropriate for the system and the NFS protocol version.
The gist of the changes is to query the underlying file system for attributes and not just to use the cached attributes in the inode. For this specific purpose, the inode only contains an ino field which unsigned long, which is large enough on 64 bit platforms, but is not large enough on 32 bit platforms.
I haven't been able to find any reason why ->getattr can't be called while i_mutex. The specification indicates that i_mutex is not required to be held in order to invoke ->getattr, but it doesn't say that i_mutex can't be held while invoking ->getattr.
I also haven't come to any conclusions regarding the value of lease_get_mtime() and whether it should or should not be invoked by fill_post_wcc() too. I chose not to change this because I thought that it was safer to leave well enough alone. If we decide to make a change, it can be done separately.
--- fs/nfsd/nfs3xdr.c | 59 ++++++++++++++++++++----------------------- fs/nfsd/nfs4xdr.c | 17 ++++++------ fs/nfsd/nfsxdr.c | 4 +++ include/linux/nfsd/nfsfh.h | 42 +++---------------------------- include/linux/nfsd/xdr4.h | 4 +- 5 files changed, 45 insertions(+), 81 deletions(-)
fs/nfsd/nfs3xdr.c +27 -32
@@ -174,9 +174,6 @@ static __be32 * encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) { - struct dentry *dentry = fhp->fh_dentry; -struct timespec time; - *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); *p++ =htonl ((u32 ) stat->mode); *p++ =htonl ((u32 ) stat->nlink);
@@ -191,10 +188,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, *p++ =htonl ((u32 )MAJOR (stat->rdev)); *p++ =htonl ((u32 )MINOR (stat->rdev)); p =encode_fsid (p, fhp); - p =xdr_encode_hyper (p, (u64 ) stat->ino); + p =xdr_encode_hyper (p, stat->ino); p =encode_time3 (p, &stat->atime); -lease_get_mtime (dentry->d_inode, &time); - p =encode_time3 (p, &time); + p =encode_time3 (p, &stat->mtime); p =encode_time3 (p, &stat->ctime);return p;
@@ -203,31 +199,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,static __be32 *encode_saved_post_attr (struct svc_rqst *rqstp,__be32 *p,struct svc_fh *fhp) { -struct inode *inode = fhp->fh_dentry->d_inode; -/* Attributes to follow */ *p++ = xdr_one; - - *p++ =htonl (nfs3_ftypes[(fhp->fh_post_mode &S_IFMT ) >>12 ]); - *p++ =htonl ((u32 ) fhp->fh_post_mode); - *p++ =htonl ((u32 ) fhp->fh_post_nlink); - *p++ =htonl ((u32 )nfsd_ruid (rqstp, fhp->fh_post_uid)); - *p++ =htonl ((u32 )nfsd_rgid (rqstp, fhp->fh_post_gid)); -if (S_ISLNK (fhp->fh_post_mode) && fhp->fh_post_size >NFS3_MAXPATHLEN ) { - p =xdr_encode_hyper (p, (u64 )NFS3_MAXPATHLEN ); - }else { - p =xdr_encode_hyper (p, (u64 ) fhp->fh_post_size); - } - p =xdr_encode_hyper (p, ((u64 )fhp->fh_post_blocks) <<9 ); - *p++ = fhp->fh_post_rdev[0 ]; - *p++ = fhp->fh_post_rdev[1 ]; - p =encode_fsid (p, fhp); - p =xdr_encode_hyper (p, (u64 ) inode->i_ino); - p =encode_time3 (p, &fhp->fh_post_atime); - p =encode_time3 (p, &fhp->fh_post_mtime); - p =encode_time3 (p, &fhp->fh_post_ctime); - -return p; +return encode_fattr3 (rqstp, p, fhp, &fhp->fh_post_attr); }/*
@@ -246,6 +220,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) err =vfs_getattr (fhp->fh_export->ex_mnt, dentry, &stat);if (!err) { *p++ = xdr_one;/* attributes follow */ +lease_get_mtime (dentry->d_inode, &stat.mtime);return encode_fattr3 (rqstp, p, fhp, &stat); } }
@@ -284,6 +259,23 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)return encode_post_op_attr (rqstp, p, fhp); } +/* +* Fill in the post_op attr for the wcc data +*/ +void fill_post_wcc (struct svc_fh *fhp) +{ +int err; + +if (fhp->fh_post_saved) +printk ("nfsd: inode locked twice during operation.\n" ); + + err =vfs_getattr (fhp->fh_export->ex_mnt, fhp->fh_dentry, + &fhp->fh_post_attr); +if (err) + fhp->fh_post_saved =0 ; +else + fhp->fh_post_saved =1 ; +}/* * XDR decode functions
@@ -643,8 +635,11 @@ int nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, struct nfsd3_attrstat *resp) { - if (resp->status == 0) + if (resp->status == 0) { + lease_get_mtime(resp->fh.fh_dentry->d_inode, + &resp->stat.mtime); p =encode_fattr3 (rqstp, p, &resp->fh, &resp->stat); + }return xdr_ressize_check (rqstp, p); }
@@ -802,7 +797,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,static __be32 *encode_entry_baggage (struct nfsd3_readdirres *cd,__be32 *p,const char *name, -int namlen,ino_t ino) +int namlen,u64 ino) { *p++ = xdr_one;/* mark entry present */ p =xdr_encode_hyper (p, ino);/* file id */
@@ -873,7 +868,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,#define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))static int encode_entry (struct readdir_cd *ccd,const char *name,int namlen, -loff_t offset,ino_t ino,unsigned int d_type,int plus) +loff_t offset,u64 ino,unsigned int d_type,int plus) { struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, common);
fs/nfsd/nfs4xdr.c +8 -9
@@ -1679,7 +1679,7 @@ out_acl:if (bmval0 &FATTR4_WORD0_FILEID ) {if ((buflen -=8 ) <0 ) goto out_resource; -WRITE64 ((u64 ) stat.ino); +WRITE64 (stat.ino); }if (bmval0 &FATTR4_WORD0_FILES_AVAIL ) {if ((buflen -=8 ) <0 )
@@ -1821,16 +1821,15 @@ out_acl:WRITE32 (stat.mtime.tv_nsec); }if (bmval1 &FATTR4_WORD1_MOUNTED_ON_FILEID ) { -struct dentry *mnt_pnt, *mnt_root; -if ((buflen -=8 ) <0 ) goto out_resource; - mnt_root = exp->ex_mnt->mnt_root; -if (mnt_root->d_inode == dentry->d_inode) { - mnt_pnt = exp->ex_mnt->mnt_mountpoint; -WRITE64 ((u64 ) mnt_pnt->d_inode->i_ino); - }else -WRITE64 ((u64 ) stat.ino); +if (exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { + err =vfs_getattr (exp->ex_mnt->mnt_parent, + exp->ex_mnt->mnt_mountpoint, &stat); +if (err) + goto out_nfserr; + } +WRITE64 (stat.ino); } *attrlenp =htonl ((char *)p - (char *)attrlenp -4 ); *countp = p - buffer;
fs/nfsd/nfsxdr.c +4 -0
@@ -523,6 +523,10 @@ nfssvc_encode_entry(void *ccdv, const char *name, cd->common.err = nfserr_toosmall;return -EINVAL ; } +if (ino > ~((u32 )0 )) { + cd->common.err = nfserr_fbig; +return -EINVAL ; + } *p++ = xdr_one;/* mark entry present */ *p++ =htonl ((u32 ) ino);/* file id */ p =xdr_encode_array (p, name, namlen);/* name length & name */
include/linux/nfsd/nfsfh.h +4 -38
57 lines not on this page · raw message
include/linux/nfsd/xdr4.h +2 -2
@@ -428,8 +428,8 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) cinfo->atomic =1 ; cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; - cinfo->after_ctime_sec = fhp->fh_post_ctime.tv_sec; - cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec; + cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; + cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; }int nfs4svc_encode_voidres (struct svc_rqst *,__be32 *,void *);
Signature · 11 lines
1.5.3.rc5.19.g0734d ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ NFS maillist - [email protected] https://lists.sourceforge.net/lists/listinfo/nfs
Re: [PATCH 08/15] knfsd: spawn kernel thread to probe callback channel
In reply to J. Bruce FieldsQuoted 3 lines · On Monday August 27, [email protected] wrote:
+/* Reference counting, callback cleanup, etc., all look racy as heck.
+ * And why iscb_setan atomic? */
Agreed.... so do we really want this code in mainline? is the old code so bad that this is better?
- cb_set should not be atomic.
- This looks like a job for async-rpc rather than a kernel thread
- If you do use a thread, you at least want __module_get before starting the thread, and module_put_and_exit to terminate the thread.
- Can you just use 'cb_client' rather than cb_set? If you move rpc_create into the thread, you don't need to set cb_client until the callback is successful. Then add a 'cb_active' flag bit so that you don't have two callbacks at the same time, and it should be less racy..
The other 14 patches all look ok.
Thanks,
NeilBrown
Re: [PATCH 08/15] knfsd: spawn kernel thread to probe callback channel
Quoted 7 lines · Neil Brown
Quoted 3 lines · On Monday August 27, [email protected] wrote:
+/* Reference counting, callback cleanup, etc., all look racy as heck.
+ * And why iscb_setan atomic? */Agreed.... so do we really want this code in mainline? is the old code so bad that this is better?
The code in question is just moved, not rewritten, so those are preexisting problems that I was just adding a whiny comment about in hopes it would remind me some more patches were probably needed. (Thanks for the reminder....)
Quoted 2 lines
-
cb_setshould not be atomic.
- This looks like a job for async-rpc rather than a kernel thread
The problem isn't the wait for the rpc itself, it's the creation of the new cred that's needed in the gss case. That could also be made asynchronous, but as there's several other delicate changes in the pipeline (keyring stuff, etc.), I'd rather not touch it for now.
Quoted 8 lines
- If you do use a thread, you at least want
__module_getbefore starting the thread, andmodule_put_and_exitto terminate the thread.
- Can you just use 'cb_client' rather thancb_set? If you moverpc_createinto the thread, you don't need to setcb_clientuntil the callback is successful. Then add a 'cb_active' flag bit so that you don't have two callbacks at the same time, and it should be less racy..
Yep, probably so.
--b.