Patches to be added to the 'devel' branch
Subsystems (4)
cover Patches to be added to the 'devel' branch
The following series of patches will be added to the 'devel' branch today. There are no major bugfixes or new features. Most of the patches are just cleanups, and there are a few optimisations.
The only minor new feature to report is Jeff's patch to report an error if we are unable to accommodate a remount request.
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
A message that is not in the archive (sent off-list or not yet received): 20080612192159.24528.43756.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
PATCH 1/37 NFS: Fix a preemption count leak in nfs_update_request
The commit 2785259631697ebb0749a3782cca206e2e542939 (nfs: use GFP_NOFS preloads for radix-tree insertion) appears to have introduced a bug:
We only want to call radix_tree_preload() once after creating a request. Calling it every time we loop after we created the request, will cause preemption count leaks.
---
fs/nfs/write.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
fs/nfs/write.c +4 -7
@@ -584,13 +584,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,/* Loop over all inode entries and see if we find * A request for the page we wish to update */ -if (new) { -if (radix_tree_preload (GFP_NOFS )) { -nfs_release_request (new); -return ERR_PTR (-ENOMEM ); - } - } -spin_lock (&inode->i_lock); req =nfs_page_find_request_locked (page);if (req) {
@@ -630,6 +623,10 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, new =nfs_create_request (ctx, inode, page, offset, bytes);if (IS_ERR (new))return new; +if (radix_tree_preload (GFP_NOFS )) { +nfs_release_request (new); +return ERR_PTR (-ENOMEM ); + } }/* We have a request for our page.
PATCH 2/37 NFS: nfs_updatepage(): don't mark page as dirty if an error occurred
In reply to a message not in the archive---
fs/nfs/write.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
fs/nfs/write.c +4 -3
@@ -736,12 +736,13 @@ int nfs_updatepage(struct file *file, struct page *page, } status =nfs_writepage_setup (ctx, page, offset, count); -__set_page_dirty_nobuffers (page); +if (status <0 ) +nfs_set_pageerror (page); +else +__set_page_dirty_nobuffers (page);dprintk ("NFS: nfs_updatepage returns %d (isize %Ld)\n" , status, (long long )i_size_read (inode)); -if (status <0 ) -nfs_set_pageerror (page);return status; }
PATCH 3/37 NFS: Add correct bounds checking to NFSv2 locks
In reply to a message not in the archiveNFSv2 file locking currently fails the Connectathon tests, because the calls to the VFS locking code do not return an EINVAL error if the struct file_lock overflows the 32-bit boundaries.
The problem is due to the fact that we occasionally call helpers from fs/locks.c in order to avoid RPC calls to the server when we know that a local process holds the lock. These helpers are, of course, always 64-bit enabled, so EINVAL is not returned in cases when it would if the call had gone to the NLM code.
For consistency, we therefore add support for a bounds-checking helper.
---
fs/nfs/file.c | 20 +++++++++++++++----- fs/nfs/proc.c | 24 ++++++++++++++++++++++++ include/linux/nfs_xdr.h | 1 + 3 files changed, 40 insertions(+), 5 deletions(-)
fs/nfs/file.c +15 -5
@@ -593,6 +593,7 @@ out:static int nfs_lock (struct file *filp,int cmd,struct file_lock *fl) {struct inode * inode = filp->f_mapping->host; +int ret = -ENOLCK ; dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", inode->i_sb->s_id, inode->i_ino,
@@ -602,13 +603,22 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)/* No mandatory locks over NFS */ if (__mandatory_lock (inode) && fl->fl_type !=F_UNLCK ) -return -ENOLCK ; + goto out_err; + +if (NFS_PROTO (inode)->lock_check_bounds !=NULL ) { + ret =NFS_PROTO (inode)->lock_check_bounds (fl); +if (ret <0 ) + goto out_err; + }if (IS_GETLK (cmd)) -return do_getlk (filp, cmd, fl); -if (fl->fl_type ==F_UNLCK ) -return do_unlk (filp, cmd, fl); -return do_setlk (filp, cmd, fl); + ret =do_getlk (filp, cmd, fl); +else if (fl->fl_type ==F_UNLCK ) + ret =do_unlk (filp, cmd, fl); +else + ret =do_setlk (filp, cmd, fl); +out_err: +return ret; }/*
fs/nfs/proc.c +24 -0
@@ -598,6 +598,29 @@ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)return nlmclnt_proc (NFS_SERVER (inode)->nlm_host, cmd, fl); } +/* Helper functions for NFS lock bounds checking */ +#define NFS_LOCK32_OFFSET_MAX ((__s32)0x7fffffffUL) +static int nfs_lock_check_bounds (const struct file_lock *fl) +{ +__s32 start, end; + + start = (__s32 )fl->fl_start; +if ((loff_t )start != fl->fl_start) + goto out_einval; + +if (fl->fl_end !=OFFSET_MAX ) { + end = (__s32 )fl->fl_end; +if ((loff_t )end != fl->fl_end) + goto out_einval; + }else + end =NFS_LOCK32_OFFSET_MAX ; + +if (start <0 || start > end) + goto out_einval; +return 0 ; +out_einval: +return -EINVAL ; +}const struct nfs_rpc_ops nfs_v2_clientops = { .version =2 ,/* protocol version */
@@ -633,4 +656,5 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .file_open = nfs_open, .file_release = nfs_release, .lock = nfs_proc_lock, + .lock_check_bounds = nfs_lock_check_bounds, };
include/linux/nfs_xdr.h +1 -0
@@ -832,6 +832,7 @@ struct nfs_rpc_ops {int (*file_open) (struct inode *,struct file *);int (*file_release) (struct inode *,struct file *);int (*lock)(struct file *,int ,struct file_lock *); +int (*lock_check_bounds)(const struct file_lock *);void (*clear_acl_cache)(struct inode *); };
PATCH 4/37 SUNRPC: Ensure we exit early in case of an encode error
In reply to a message not in the archiveAll errors from call_encode(), with exception of EAGAIN are fatal, so we should immediately return instead of proceeding to xprt_transmit().
---
net/sunrpc/clnt.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
net/sunrpc/clnt.c +7 -2
@@ -890,7 +890,6 @@ call_encode(struct rpc_task *task) task->tk_msg.rpc_argp);if (task->tk_status == -ENOMEM ) {/* XXX: Is this sane? */ -rpc_delay (task,3 *HZ ); task->tk_status = -EAGAIN ; } }
@@ -1048,8 +1047,14 @@ call_transmit(struct rpc_task *task)BUG_ON (task->tk_rqstp->rq_bytes_sent !=0 );call_encode (task);/* Did the encode result in an error condition? */ -if (task->tk_status !=0 ) +if (task->tk_status !=0 ) { +/* Was the error nonfatal? */ +if (task->tk_status == -EAGAIN ) +rpc_delay (task,HZ >>4 ); +else +rpc_exit (task, task->tk_status);return ; + } }xprt_transmit (task);if (task->tk_status <0 )
PATCH 5/37 SUNRPC: An ENOMEM error from call_encode is always fatal
In reply to a message not in the archiveThe special 'ENOMEM' case that was previously flagged as non-fatal is
bogus: auth_gss always returns EAGAIN for non-fatal errors, and may in fact return ENOMEM in the special case where xdr_buf_read_netobj runs out of preallocated buffer space (invariably a _fatal_ error, since there is no provision for preallocating larger buffers).
---
net/sunrpc/clnt.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
net/sunrpc/clnt.c +0 -4
@@ -888,10 +888,6 @@ call_encode(struct rpc_task *task) task->tk_status =rpcauth_wrap_req (task, encode, req, p, task->tk_msg.rpc_argp); -if (task->tk_status == -ENOMEM ) { -/* XXX: Is this sane? */ - task->tk_status = -EAGAIN ; - } }/*
A message that is not in the archive (sent off-list or not yet received): 20080612192200.24528.71693.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
Re: [PATCH 05/37] SUNRPC: An ENOMEM error from call_encode is always fatal
Quoted 5 lines · Trond Myklebust
The special 'ENOMEM' case that was previously flagged as non-fatal is
bogus:auth_gssalways returns EAGAIN for non-fatal errors, and may in fact return ENOMEM in the special case wherexdr_buf_read_netobjruns out of preallocated buffer space (invariably a _fatal_ error, since there is no provision for preallocating larger buffers).
For a minute I was worried about the krb5p code that tries to do some allocations that may fail, but you're right, it takes care to return EAGAIN in that case (in alloc_enc_pages). Makes sense to me.
--b.
Quoted 27 lines
Signed-off-by Trond Myklebust <[email protected]>---
net/sunrpc/clnt.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)net/sunrpc/clnt.c +0
-5@@ -888,10 +888,6 @@ call_encode(struct rpc_task *task) task->tk_status =rpcauth_wrap_req (task, encode, req, p, task->tk_msg.rpc_argp); -if (task->tk_status == -ENOMEM ) { -/* XXX: Is this sane? */ - task->tk_status = -EAGAIN ; - } }/* -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/37 NFS: Optimise append writes with holes
In reply to a message not in the archiveIf a file is being extended, and we're creating a hole, we might as well declare the entire page to be up to date.
This patch significantly improves the write performance for sparse files in the case where lseek(SEEK_END) is used to append several non-contiguous writes at intervals of < PAGE_SIZE.
---
fs/nfs/file.c | 20 ++++++++++++++++++++ fs/nfs/write.c | 12 +++--------- 2 files changed, 23 insertions(+), 9 deletions(-)
fs/nfs/file.c +20 -0
@@ -344,6 +344,26 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,unsigned offset = pos & (PAGE_CACHE_SIZE -1 );int status; +/* +* Zero any uninitialised parts of the page, and then mark the page +* as up to date if it turns out that we're extending the file. +*/ +if (!PageUptodate (page)) { +unsigned pglen =nfs_page_length (page); +unsigned end = offset + len; + +if (pglen ==0 ) { +zero_user_segments (page,0 , offset, + end,PAGE_CACHE_SIZE ); +SetPageUptodate (page); + }else if (end >= pglen) { +zero_user_segment (page, end,PAGE_CACHE_SIZE ); +if (offset ==0 ) +SetPageUptodate (page); + }else +zero_user_segment (page, pglen,PAGE_CACHE_SIZE ); + } +lock_kernel (); status =nfs_updatepage (file, page, offset, copied);unlock_kernel ();
fs/nfs/write.c +3 -9
@@ -616,7 +616,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,spin_unlock (&inode->i_lock);radix_tree_preload_end (); req = new; - goto zero_page; + goto out; }spin_unlock (&inode->i_lock);
@@ -649,19 +649,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, req->wb_offset = offset; req->wb_pgbase = offset; req->wb_bytes =max (end, rqend) - req->wb_offset; - goto zero_page; + goto out; }if (end > rqend) req->wb_bytes = end - req->wb_offset; -return req; -zero_page: -/* If this page might potentially be marked as up to date, -* then we need to zero any uninitalised data. */ -if (req->wb_pgbase ==0 && req->wb_bytes !=PAGE_CACHE_SIZE - && !PageUptodate (req->wb_page)) -zero_user_segment (req->wb_page, req->wb_bytes,PAGE_CACHE_SIZE ); +out:return req; }
PATCH 7/37 NFS: Revert commit 44dd151d
In reply to a message not in the archiveRevert commit 44dd151d "NFS: Don't mark a written page as uptodate until it is on disk". While it is true that the write may fail, that is always the case. There is no reason why we should treat data on pages that are not already marked as PG_uptodate as being special. The only thing we gain is a noticeable slowdown when re-reading these pages.
---
fs/nfs/write.c | 13 ++----------- 1 files changed, 2 insertions(+), 11 deletions(-)
fs/nfs/write.c +2 -11
@@ -188,6 +188,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, }/* Update file length */ nfs_grow_file (page, offset, count); +nfs_mark_uptodate (page, req->wb_pgbase, req->wb_bytes);nfs_clear_page_tag_locked (req);return 0 ; }
@@ -743,12 +744,7 @@ int nfs_updatepage(struct file *file, struct page *page,static void nfs_writepage_release (struct nfs_page *req) { -if (PageError (req->wb_page)) { -nfs_end_page_writeback (req->wb_page); -nfs_inode_remove_request (req); - }else if (!nfs_reschedule_unstable_write (req)) { -/* Set the PG_uptodate flag */ -nfs_mark_uptodate (req->wb_page, req->wb_pgbase, req->wb_bytes); +if (PageError (req->wb_page) || !nfs_reschedule_unstable_write (req)) {nfs_end_page_writeback (req->wb_page);nfs_inode_remove_request (req); }else
@@ -1069,8 +1065,6 @@ static void nfs_writeback_release_full(void *calldata)dprintk (" marked for commit\n" ); goto next; } -/* Set the PG_uptodate flag? */ -nfs_mark_uptodate (page, req->wb_pgbase, req->wb_bytes);dprintk (" OK\n" ); remove_request:nfs_end_page_writeback (page);
@@ -1309,9 +1303,6 @@ static void nfs_commit_release(void *calldata)* returned by the server against all stored verfs. */ if (!memcmp (req->wb_verf.verifier, data->verf.verifier,sizeof (data->verf.verifier))) {/* We have a match */ -/* Set the PG_uptodate flag */ -nfs_mark_uptodate (req->wb_page, req->wb_pgbase, - req->wb_bytes);nfs_inode_remove_request (req);dprintk (" OK\n" ); goto next;
PATCH 8/37 SUNRPC: Use GFP_NOFS when allocating credentials
In reply to a message not in the archiveSince the credentials may be allocated during the call to rpc_new_task(), which again may be called by a memory allocator...
---
net/sunrpc/auth_gss/auth_gss.c | 10 +++++----- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_token.c | 2 +- net/sunrpc/auth_unix.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-)
net/sunrpc/auth_gss/auth_gss.c +5 -5
@@ -146,7 +146,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - dest->data =kmemdup (p, len,GFP_KERNEL ); + dest->data =kmemdup (p, len,GFP_NOFS );if (unlikely (dest->data ==NULL ))return ERR_PTR (-ENOMEM ); dest->len = len;
@@ -171,7 +171,7 @@ gss_alloc_context(void) {struct gss_cl_ctx *ctx; - ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ); + ctx =kzalloc (sizeof (*ctx),GFP_NOFS );if (ctx !=NULL ) { ctx->gc_proc =RPC_GSS_PROC_DATA ; ctx->gc_seq =1 ;/* NetApp 6.4R1 doesn't accept seq. no. 0 */
@@ -341,7 +341,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) {struct gss_upcall_msg *gss_msg; - gss_msg =kzalloc (sizeof (*gss_msg),GFP_KERNEL ); + gss_msg =kzalloc (sizeof (*gss_msg),GFP_NOFS );if (gss_msg !=NULL ) {INIT_LIST_HEAD (&gss_msg->list);rpc_init_wait_queue (&gss_msg->rpc_waitqueue,"RPCSEC_GSS upcall waitq" );
@@ -503,7 +503,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)if (mlen >MSG_BUF_MAXSIZE ) goto out; err = -ENOMEM ; - buf =kmalloc (mlen,GFP_KERNEL ); + buf =kmalloc (mlen,GFP_NOFS );if (!buf) goto out;
@@ -806,7 +806,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)dprintk ("RPC: gss_create_cred for uid %d, flavor %d\n" , acred->uid, auth->au_flavor); -if (!(cred =kzalloc (sizeof (*cred),GFP_KERNEL ))) +if (!(cred =kzalloc (sizeof (*cred),GFP_NOFS ))) goto out_err;rpcauth_init_cred (&cred->gc_base, acred, auth, &gss_credops);
net/sunrpc/auth_gss/gss_krb5_mech.c +2 -2
@@ -70,7 +70,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - res->data =kmemdup (p, len,GFP_KERNEL ); + res->data =kmemdup (p, len,GFP_NOFS );if (unlikely (res->data ==NULL ))return ERR_PTR (-ENOMEM ); res->len = len;
@@ -131,7 +131,7 @@ gss_import_sec_context_kerberos(const void *p,struct krb5_ctx *ctx;int tmp; -if (!(ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ))) +if (!(ctx =kzalloc (sizeof (*ctx),GFP_NOFS ))) goto out_err; p =simple_get_bytes (p, end, &ctx->initiate,sizeof (ctx->initiate));
net/sunrpc/auth_gss/gss_spkm3_mech.c +2 -2
@@ -76,7 +76,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - res->data =kmemdup (p, len,GFP_KERNEL ); + res->data =kmemdup (p, len,GFP_NOFS );if (unlikely (res->data ==NULL ))return ERR_PTR (-ENOMEM );return q;
@@ -90,7 +90,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len,struct spkm3_ctx *ctx;int version; -if (!(ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ))) +if (!(ctx =kzalloc (sizeof (*ctx),GFP_NOFS ))) goto out_err; p =simple_get_bytes (p, end, &version,sizeof (version));
net/sunrpc/auth_gss/gss_spkm3_token.c +1 -1
@@ -90,7 +90,7 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits)int decode_asn1_bitstring (struct xdr_netobj *out,char *in,int enclen,int explen) { -if (!(out->data =kzalloc (explen,GFP_KERNEL ))) +if (!(out->data =kzalloc (explen,GFP_NOFS )))return 0 ; out->len = explen;memcpy (out->data, in, enclen);
net/sunrpc/auth_unix.c +1 -1
@@ -66,7 +66,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)dprintk ("RPC: allocating UNIX cred for uid %d gid %d\n" , acred->uid, acred->gid); -if (!(cred =kmalloc (sizeof (*cred),GFP_KERNEL ))) +if (!(cred =kmalloc (sizeof (*cred),GFP_NOFS )))return ERR_PTR (-ENOMEM );rpcauth_init_cred (&cred->uc_base, acred, auth, &unix_credops);
A message that is not in the archive (sent off-list or not yet received): 20080612192200.24528.65570.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 2 lines · Trond Myklebust
Since the credentials may be allocated during the call to
rpc_new_task(), which again may be called by a memory allocator...
Most of these are only called in gssd process's context when it performs the downcall. Which doesn't change the fact that they're needed for the rpc_new_task() to succeed, OK, so this isn't an objection to this patch--but is there any plan for how we'll deal with e.g. memory allocations that gssd does on its own?
--b.
Quoted 135 lines
Signed-off-by Trond Myklebust <[email protected]>---
net/sunrpc/auth_gss/auth_gss.c | 10 +++++----- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_mech.c | 4 ++-- net/sunrpc/auth_gss/gss_spkm3_token.c | 2 +- net/sunrpc/auth_unix.c | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-)net/sunrpc/auth_gss/auth_gss.c +5
-5@@ -146,7 +146,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - dest->data =kmemdup (p, len,GFP_KERNEL ); + dest->data =kmemdup (p, len,GFP_NOFS );if (unlikely (dest->data ==NULL ))return ERR_PTR (-ENOMEM ); dest->len = len;@@ -171,7 +171,7 @@ gss_alloc_context(void) {struct gss_cl_ctx *ctx; - ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ); + ctx =kzalloc (sizeof (*ctx),GFP_NOFS );if (ctx !=NULL ) { ctx->gc_proc =RPC_GSS_PROC_DATA ; ctx->gc_seq =1 ;/* NetApp 6.4R1 doesn't accept seq. no. 0 */ @@ -341,7 +341,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) {struct gss_upcall_msg *gss_msg; - gss_msg =kzalloc (sizeof (*gss_msg),GFP_KERNEL ); + gss_msg =kzalloc (sizeof (*gss_msg),GFP_NOFS );if (gss_msg !=NULL ) {INIT_LIST_HEAD (&gss_msg->list);rpc_init_wait_queue (&gss_msg->rpc_waitqueue,"RPCSEC_GSS upcall waitq" );@@ -503,7 +503,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)if (mlen >MSG_BUF_MAXSIZE ) goto out; err = -ENOMEM ; - buf =kmalloc (mlen,GFP_KERNEL ); + buf =kmalloc (mlen,GFP_NOFS );if (!buf) goto out;@@ -806,7 +806,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)dprintk ("RPC: gss_create_cred for uid %d, flavor %d\n" , acred->uid, auth->au_flavor); -if (!(cred =kzalloc (sizeof (*cred),GFP_KERNEL ))) +if (!(cred =kzalloc (sizeof (*cred),GFP_NOFS ))) goto out_err;rpcauth_init_cred (&cred->gc_base, acred, auth, &gss_credops);net/sunrpc/auth_gss/gss_krb5_mech.c +2
-2@@ -70,7 +70,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - res->data =kmemdup (p, len,GFP_KERNEL ); + res->data =kmemdup (p, len,GFP_NOFS );if (unlikely (res->data ==NULL ))return ERR_PTR (-ENOMEM ); res->len = len;@@ -131,7 +131,7 @@ gss_import_sec_context_kerberos(const void *p,struct krb5_ctx *ctx;int tmp; -if (!(ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ))) +if (!(ctx =kzalloc (sizeof (*ctx),GFP_NOFS ))) goto out_err; p =simple_get_bytes (p, end, &ctx->initiate,sizeof (ctx->initiate));net/sunrpc/auth_gss/gss_spkm3_mech.c +2
-2@@ -76,7 +76,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) q = (const void *)((const char *)p + len);if (unlikely (q > end || q < p))return ERR_PTR (-EFAULT ); - res->data =kmemdup (p, len,GFP_KERNEL ); + res->data =kmemdup (p, len,GFP_NOFS );if (unlikely (res->data ==NULL ))return ERR_PTR (-ENOMEM );return q;@@ -90,7 +90,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len,struct spkm3_ctx *ctx;int version; -if (!(ctx =kzalloc (sizeof (*ctx),GFP_KERNEL ))) +if (!(ctx =kzalloc (sizeof (*ctx),GFP_NOFS ))) goto out_err; p =simple_get_bytes (p, end, &version,sizeof (version));net/sunrpc/auth_gss/gss_spkm3_token.c +1
-1@@ -90,7 +90,7 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits)int decode_asn1_bitstring (struct xdr_netobj *out,char *in,int enclen,int explen) { -if (!(out->data =kzalloc (explen,GFP_KERNEL ))) +if (!(out->data =kzalloc (explen,GFP_NOFS )))return 0 ; out->len = explen;memcpy (out->data, in, enclen);net/sunrpc/auth_unix.c +1
-2@@ -66,7 +66,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)dprintk ("RPC: allocating UNIX cred for uid %d gid %d\n" , acred->uid, acred->gid); -if (!(cred =kmalloc (sizeof (*cred),GFP_KERNEL ))) +if (!(cred =kmalloc (sizeof (*cred),GFP_NOFS )))return ERR_PTR (-ENOMEM );rpcauth_init_cred (&cred->uc_base, acred, auth, &unix_credops); --To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 9 lines · J. Bruce Fields
Quoted 2 lines · Trond Myklebust
Since the credentials may be allocated during the call to
rpc_new_task(), which again may be called by a memory allocator...Most of these are only called in gssd process's context when it performs the downcall. Which doesn't change the fact that they're needed for the
rpc_new_task()to succeed, OK, so this isn't an objection to this patch--but is there any plan for how we'll deal with e.g. memory allocations that gssd does on its own?
You mean alloc_enc_pages()? We should really try to avoid sleeping there...
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 5 lines · Trond Myklebust
Quoted 4 lines · J. Bruce Fields
Quoted 2 lines · Trond Myklebust
Since the credentials may be allocated during the call to
rpc_new_task(), which again may be called by a memory allocator...
Quoted 8 lines
Quoted 5 lines
Most of these are only called in gssd process's context when it performs the downcall. Which doesn't change the fact that they're needed for the
rpc_new_task()to succeed, OK, so this isn't an objection to this patch--but is there any plan for how we'll deal with e.g. memory allocations that gssd does on its own?You mean
alloc_enc_pages()? We should really try to avoid sleeping there...
No, that may be a problem too, but I mean: if we're worried about a deadlock due to some allocations that gssd performs on the downcall at the end of the context initiation, then shouldn't we also be worried about all the other allocations that gssd performs itself?
--b.
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 4 lines · J. Bruce Fields
No, that may be a problem too, but I mean: if we're worried about a deadlock due to some allocations that gssd performs on the downcall at the end of the context initiation, then shouldn't we also be worried about all the other allocations that gssd performs itself?
Definitely.
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 7 lines · Trond Myklebust
Quoted 4 lines · J. Bruce Fields
No, that may be a problem too, but I mean: if we're worried about a deadlock due to some allocations that gssd performs on the downcall at the end of the context initiation, then shouldn't we also be worried about all the other allocations that gssd performs itself?
Definitely.
Do you have any ideas (however speculative) about how we'll deal with that?
--b.
Re: [PATCH 08/37] SUNRPC: Use GFP_NOFS when allocating credentials
Quoted 11 lines · J. Bruce Fields
Quoted 7 lines · Trond Myklebust
Quoted 4 lines · J. Bruce Fields
No, that may be a problem too, but I mean: if we're worried about a deadlock due to some allocations that gssd performs on the downcall at the end of the context initiation, then shouldn't we also be worried about all the other allocations that gssd performs itself?
Definitely.
Do you have any ideas (however speculative) about how we'll deal with that?
Not really: AFAIK there are no mechanisms for fully pre-provisioning the necessary resources that a userland app may need to ensure it can function. mlock() won't, for instance, allow you to pre-provision the socket buffer space that the kerberos stuff needs to communicate...
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
PATCH 9/37 NFS: do_setlk(): don't flush caches when we have a delegation
In reply to a message not in the archive---
fs/nfs/file.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/nfs/file.c +2 -1
@@ -602,7 +602,8 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)* This makes locking act as a cache coherency point. */ nfs_sync_mapping (filp->f_mapping); -nfs_zap_caches (inode); +if (!nfs_have_delegation (inode,FMODE_READ )) +nfs_zap_caches (inode); out:return status; }
PATCH 10/37 NFS: Update help text for CONFIG_NFS_FS
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: refresh the help text for Kconfig items related to the NFS client. Remove obsolete URLs, and make the language consistent among the options.
Also move the ROOT_NFS config option next to the options related to the NFS client.
---
fs/Kconfig | 115 ++++++++++++++++++++++++++++++------------------------------ 1 files changed, 57 insertions(+), 58 deletions(-)
fs/Kconfig +57 -58
@@ -1544,10 +1544,6 @@ config UFS_FS The recently released UFS2 variant (used in FreeBSD 5.x) is READ-ONLY supported. - If you only intend to mount files from some other Unix over the - network using NFS, you don't need the UFS file system support (but - you need NFS file system support obviously). - Note that this option is generally not needed for floppies, since a good portable way to transport files and directories between unixes (and even other operating systems) is given by the tar program ("man
@@ -1587,6 +1583,7 @@ menuconfig NETWORK_FILESYSTEMS Say Y here to get to see options for network filesystems and filesystem-related networking code, such as NFS daemon and RPCSEC security modules. + This option alone does not add any kernel code. If you say N, all options in this submenu will be skipped and
@@ -1595,76 +1592,92 @@ menuconfig NETWORK_FILESYSTEMS if NETWORK_FILESYSTEMS config NFS_FS - tristate "NFS file system support" + tristate "NFS client support" depends on INET select LOCKD select SUNRPC select NFS_ACL_SUPPORT if NFS_V3_ACL help - If you are connected to some other (usually local) Unix computer - (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing - on that computer (the NFS server) using the Network File Sharing - protocol, say Y. "Mounting files" means that the client can access - the files with usual UNIX commands as if they were sitting on the - client's hard disk. For this to work, the server must run the - programs nfsd and mountd (but does not need to have NFS file system - support enabled in its kernel). NFS is explained in the Network - Administrator's Guide, available from - <http://www.tldp.org/docs.html#guide>, on its man page: "man - nfs", and in the NFS-HOWTO. - - A superior but less widely used alternative to NFS is provided by - the Coda file system; see "Coda file system support" below. + Choose Y here if you want to access files residing on other + computers using Sun's Network File System protocol. To compile + this file system support as a module, choose M here: the module + will be called nfs. - If you say Y here, you should have said Y to TCP/IP networking also. - This option would enlarge your kernel by about 27 KB. + To mount file systems exported by NFS servers, you also need to + install the user space mount.nfs command which can be found in + the Linux nfs-utils package, available from http://linux-nfs.org/. + Information about using the mount command is available in the + mount(8) man page. More detail about the Linux NFS client + implementation is available via the nfs(5) man page. - To compile this file system support as a module, choose M here: the - module will be called nfs. + Below you can choose which versions of the NFS protocol are + available in the kernel to mount NFS servers. Support for NFS + version 2 (RFC 1094) is always available when NFS_FS is selected. - If you are configuring a diskless machine which will mount its root - file system over NFS at boot time, say Y here and to "Kernel - level IP autoconfiguration" above and to "Root file system on NFS" - below. You cannot compile this driver as a module in this case. - There are two packages designed for booting diskless machines over - the net: netboot, available from - <http://ftp1.sourceforge.net/netboot/>, and Etherboot, - available from <http://ftp1.sourceforge.net/etherboot/>. + To configure a system which mounts its root file system via NFS + at boot time, say Y here, select "Kernel level IP + autoconfiguration" in the NETWORK menu, and select "Root file + system on NFS" below. You cannot compile this file system as a + module in this case. - If you don't know what all this is about, say N. + If unsure, say N. config NFS_V3 - bool "Provide NFSv3 client support" + bool "NFS client support for NFS version 3" depends on NFS_FS help - Say Y here if you want your NFS client to be able to speak version - 3 of the NFS protocol. + This option enables support for version 3 of the NFS protocol + (RFC 1813) in the kernel's NFS client. If unsure, say Y. config NFS_V3_ACL - bool "Provide client support for the NFSv3 ACL protocol extension" + bool "NFS client support for the NFSv3 ACL protocol extension" depends on NFS_V3 help - Implement the NFSv3 ACL protocol extension for manipulating POSIX - Access Control Lists. The server should also be compiled with - the NFSv3 ACL protocol extension; see the CONFIG_NFSD_V3_ACL option. + Some NFS servers support an auxiliary NFSv3 ACL protocol that + Sun added to Solaris but never became an official part of the + NFS version 3 protocol. This protocol extension allows + applications on NFS clients to manipulate POSIX Access Control + Lists on files residing on NFS servers. NFS servers enforce + ACLs on local files whether this protocol is available or not. + + Choose Y here if your NFS server supports the Solaris NFSv3 ACL + protocol extension and you want your NFS client to allow + applications to access and modify ACLs on files on the server. + + Most NFS servers don't support the Solaris NFSv3 ACL protocol + extension. You can choose N here or specify the "noacl" mount + option to prevent your NFS client from trying to use the NFSv3 + ACL protocol. If unsure, say N. config NFS_V4 - bool "Provide NFSv4 client support (EXPERIMENTAL)" + bool "NFS client support for NFS version 4 (EXPERIMENTAL)" depends on NFS_FS && EXPERIMENTAL select RPCSEC_GSS_KRB5 help - Say Y here if you want your NFS client to be able to speak the newer - version 4 of the NFS protocol. + This option enables support for version 4 of the NFS protocol + (RFC 3530) in the kernel's NFS client. - Note: Requires auxiliary userspace daemons which may be found on - http://www.citi.umich.edu/projects/nfsv4/ + To mount NFS servers using NFSv4, you also need to install user + space programs which can be found in the Linux nfs-utils package, + available from http://linux-nfs.org/. If unsure, say N. +config ROOT_NFS + bool "Root file system on NFS" + depends on NFS_FS=y && IP_PNP + help + If you want your system to mount its root file system via NFS, + choose Y here. This is common practice for managing systems + without local permanent storage. For details, read + <file:Documentation/filesystems/nfsroot.txt>. + + Most people say N here. + config NFSD tristate "NFS server support" depends on INET
@@ -1746,20 +1759,6 @@ config NFSD_V4 If unsure, say N. -config ROOT_NFS - bool "Root file system on NFS" - depends on NFS_FS=y && IP_PNP - help - If you want your Linux box to mount its whole root file system (the - one containing the directory /) from some other computer over the - net via NFS (presumably because your box doesn't have a hard disk), - say Y. Read <file:Documentation/filesystems/nfsroot.txt> for - details. It is likely that in this case, you also want to say Y to - "Kernel level IP autoconfiguration" so that your box can discover - its network address at boot time. - - Most people say N here. - config LOCKD tristate
PATCH 11/37 SUNRPC: Add a function to display the name of an RPC procedure
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Improve debugging messages in call_start() and call_verify() by having them show the RPC procedure name instead of the procedure number.
---
net/sunrpc/clnt.c | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-)
net/sunrpc/clnt.c +19 -4
@@ -690,6 +690,21 @@ rpc_restart_call(struct rpc_task *task) }EXPORT_SYMBOL_GPL (rpc_restart_call); +#ifdef RPC_DEBUG +static const char *rpc_proc_name (const struct rpc_task *task) +{ +const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; + +if (proc) { +if (proc->p_name) +return proc->p_name; +else +return "NULL" ; + }else +return "no proc" ; +} +#endif +/* * 0. Initial state *
@@ -701,9 +716,9 @@ call_start(struct rpc_task *task) {struct rpc_clnt *clnt = task->tk_client; -dprintk ("RPC: %5u call_start %s%d proc %d (%s)\n" , task->tk_pid, +dprintk ("RPC: %5u call_start %s%d proc %s (%s)\n" , task->tk_pid, clnt->cl_protname, clnt->cl_vers, - task->tk_msg.rpc_proc->p_proc, +rpc_proc_name (task), (RPC_IS_ASYNC (task) ?"async" :"sync" ));/* Increment call count */
@@ -1432,10 +1447,10 @@ call_verify(struct rpc_task *task) error = -EPROTONOSUPPORT ; goto out_err;case RPC_PROC_UNAVAIL : -dprintk ("RPC: %5u %s: proc %p unsupported by program %u, " +dprintk ("RPC: %5u %s: proc %s unsupported by program %u, " "version %u on server %s\n" , task->tk_pid, __func__, - task->tk_msg.rpc_proc, +rpc_proc_name (task), task->tk_client->cl_prog, task->tk_client->cl_vers, task->tk_client->cl_server);
PATCH 12/37 SUNRPC: Rename "call_" functions that are no longer FSM states
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
The RPC client uses a finite state machine to move RPC tasks through each step of an RPC request. Each state is contained in a function in net/sunrpc/clnt.c, and named call_foo.
Some of the functions named call_foo have changed over the past few years and are no longer states in the FSM. These include: call_encode, call_header, and call_verify. As a clean up, rename the functions that have changed.
---
net/sunrpc/clnt.c | 35 ++++++++++++++--------------------- 1 files changed, 14 insertions(+), 21 deletions(-)
net/sunrpc/clnt.c +14 -21
@@ -58,7 +58,6 @@ static void call_start(struct rpc_task *task);static void call_reserve (struct rpc_task *task);static void call_reserveresult (struct rpc_task *task);static void call_allocate (struct rpc_task *task); -static void call_encode (struct rpc_task *task);static void call_decode (struct rpc_task *task);static void call_bind (struct rpc_task *task);static void call_bind_status (struct rpc_task *task);
@@ -70,9 +69,9 @@ static void call_refreshresult(struct rpc_task *task);static void call_timeout (struct rpc_task *task);static void call_connect (struct rpc_task *task);static void call_connect_status (struct rpc_task *task); -static __be32 *call_header (struct rpc_task *task); -static __be32 *call_verify (struct rpc_task *task); +static __be32 *rpc_encode_header (struct rpc_task *task); +static __be32 *rpc_verify_header (struct rpc_task *task);static int rpc_ping (struct rpc_clnt *clnt,int flags);static void rpc_register_client (struct rpc_clnt *clnt)
@@ -876,7 +875,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)* 3. Encode arguments of an RPC call */ static void -call_encode (struct rpc_task *task) +rpc_xdr_encode (struct rpc_task *task) {struct rpc_rqst *req = task->tk_rqstp;kxdrproc_t encode;
@@ -891,13 +890,14 @@ call_encode(struct rpc_task *task) (char *)req->rq_buffer + req->rq_callsize, req->rq_rcvsize); -/* Encode header and provided arguments */ - encode = task->tk_msg.rpc_proc->p_encode; -if (!(p =call_header (task))) { -printk (KERN_INFO "RPC: call_header failed, exit EIO\n" ); + p =rpc_encode_header (task); +if (p ==NULL ) { +printk (KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n" );rpc_exit (task, -EIO );return ; } + + encode = task->tk_msg.rpc_proc->p_encode;if (encode ==NULL )return ;
@@ -1056,7 +1056,7 @@ call_transmit(struct rpc_task *task)/* Encode here so that rpcsec_gss can use correct sequence number. */ if (rpc_task_need_encode (task)) {BUG_ON (task->tk_rqstp->rq_bytes_sent !=0 ); -call_encode (task); +rpc_xdr_encode (task);/* Did the encode result in an error condition? */ if (task->tk_status !=0 ) {/* Was the error nonfatal? */
@@ -1240,8 +1240,7 @@ call_decode(struct rpc_task *task) goto out_retry; } -/* Verify the RPC header */ - p =call_verify (task); + p =rpc_verify_header (task);if (IS_ERR (p)) {if (p ==ERR_PTR (-EAGAIN )) goto out_retry;
@@ -1259,7 +1258,7 @@ call_decode(struct rpc_task *task)return ; out_retry: task->tk_status =0 ; -/* Note: call_verify() may have freed the RPC slot */ +/* Note: rpc_verify_header() may have freed the RPC slot */ if (task->tk_rqstp == req) { req->rq_received = req->rq_rcv_buf.len =0 ;if (task->tk_client->cl_discrtry)
@@ -1306,11 +1305,8 @@ call_refreshresult(struct rpc_task *task)return ; } -/* -* Call header serialization -*/ static __be32 * -call_header (struct rpc_task *task) +rpc_encode_header (struct rpc_task *task) {struct rpc_clnt *clnt = task->tk_client;struct rpc_rqst *req = task->tk_rqstp;
@@ -1330,11 +1326,8 @@ call_header(struct rpc_task *task)return p; } -/* -* Reply header verification -*/ static __be32 * -call_verify (struct rpc_task *task) +rpc_verify_header (struct rpc_task *task) {struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0 ];int len = task->tk_rqstp->rq_rcv_buf.len >>2 ;
@@ -1408,7 +1401,7 @@ call_verify(struct rpc_task *task) task->tk_action = call_bind; goto out_retry;case RPC_AUTH_TOOWEAK : -printk (KERN_NOTICE "call_verify: server %s requires stronger " +printk (KERN_NOTICE "RPC: server %s requires stronger " "authentication.\n" , task->tk_client->cl_server);break ;default :
PATCH 13/37 SUNRPC: Don't display the rpc_show_tasks header if there are no tasks
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: don't display the rpc_show_tasks column header unless there is at least one task to display. As far as I can tell, it is safe to let the list_for_each_entry macro decide that each list is empty.
scripts/checkpatch.pl also wants a KERN_FOO at the start of any newly added printk() calls, so this and subsequent patches will also add KERN_INFO.
---
net/sunrpc/clnt.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)
net/sunrpc/clnt.c +12 -7
@@ -1526,24 +1526,30 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, intEXPORT_SYMBOL_GPL (rpc_call_null);#ifdef RPC_DEBUG +static void rpc_show_header (void ) +{ +printk (KERN_INFO "-pid- proc flgs status -client- -prog- --rqstp- " +"-timeout -rpcwait -action- ---ops--\n" ); +} +void rpc_show_tasks (void ) {struct rpc_clnt *clnt;struct rpc_task *t; +int header =0 ;spin_lock (&rpc_client_lock); -if (list_empty (&all_clients)) - goto out; -printk ("-pid- proc flgs status -client- -prog- --rqstp- -timeout " -"-rpcwait -action- ---ops--\n" );list_for_each_entry (clnt, &all_clients, cl_clients) { -if (list_empty (&clnt->cl_tasks)) -continue ;spin_lock (&clnt->cl_lock);list_for_each_entry (t, &clnt->cl_tasks, tk_task) {const char *rpc_waitq ="none" ;int proc; +if (!header) { +rpc_show_header (); + header++; + } +if (t->tk_msg.rpc_proc) proc = t->tk_msg.rpc_proc->p_proc;else
@@ -1563,7 +1569,6 @@ void rpc_show_tasks(void) }spin_unlock (&clnt->cl_lock); } -out:spin_unlock (&rpc_client_lock); }#endif
PATCH 14/37 SUNRPC: Refactor rpc_show_tasks
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: move the logic that displays each task to its own function. This removes indentation and makes future changes easier.
---
net/sunrpc/clnt.c | 46 ++++++++++++++++++++++++---------------------- 1 files changed, 24 insertions(+), 22 deletions(-)
net/sunrpc/clnt.c +24 -22
@@ -1532,40 +1532,42 @@ static void rpc_show_header(void) "-timeout -rpcwait -action- ---ops--\n"); } +static void rpc_show_task (const struct rpc_clnt *clnt, +const struct rpc_task *task) +{ +const char *rpc_waitq ="none" ; +int proc =-1 ; + +if (task->tk_msg.rpc_proc) + proc = task->tk_msg.rpc_proc->p_proc; + +if (RPC_IS_QUEUED (task)) + rpc_waitq =rpc_qname (task->tk_waitqueue); + +printk (KERN_INFO "%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n" , + task->tk_pid, proc, + task->tk_flags, task->tk_status, + clnt, clnt->cl_prog, + task->tk_rqstp, task->tk_timeout, + rpc_waitq, + task->tk_action, task->tk_ops); +} +void rpc_show_tasks (void ) {struct rpc_clnt *clnt; -struct rpc_task *t; +struct rpc_task *task;int header =0 ;spin_lock (&rpc_client_lock);list_for_each_entry (clnt, &all_clients, cl_clients) {spin_lock (&clnt->cl_lock); -list_for_each_entry (t, &clnt->cl_tasks, tk_task) { -const char *rpc_waitq ="none" ; -int proc; - +list_for_each_entry (task, &clnt->cl_tasks, tk_task) {if (!header) {rpc_show_header (); header++; } - -if (t->tk_msg.rpc_proc) - proc = t->tk_msg.rpc_proc->p_proc; -else - proc =-1 ; - -if (RPC_IS_QUEUED (t)) - rpc_waitq =rpc_qname (t->tk_waitqueue); - -printk ("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n" , - t->tk_pid, proc, - t->tk_flags, t->tk_status, - t->tk_client, - (t->tk_client ? t->tk_client->cl_prog :0 ), - t->tk_rqstp, t->tk_timeout, - rpc_waitq, - t->tk_action, t->tk_ops); +rpc_show_task (clnt, task); }spin_unlock (&clnt->cl_lock); }
PATCH 15/37 SUNRPC: Display some debugging information as text rather than numbers
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
In rpc_show_tasks(), display the program name, version number, procedure name and tk_action as human-readable variable-length text fields rather than columnar numbers.
Doing the symbol lookup here helps in cases where we have actual debugging output from a kernel log, but don't have access to the kernel image or RPC module that generated the output.
Sample output:
-pid- flgs status -client- --rqstp- -timeout ---ops--
5608 0001 -11 eeb42690 f6d93710 0 f8fa1764 nfsv3 WRITE a:call_transmit_status q:none 5609 0001 -11 eeb42690 f6d937e0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5610 0001 -11 eeb42690 f6d93230 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5611 0001 -11 eeb42690 f6d93300 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5612 0001 -11 eeb42690 f6d93090 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5613 0001 -11 eeb42690 f6d933d0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5614 0001 -11 eeb42690 f6d93cc0 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5615 0001 -11 eeb42690 f6d93a50 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5616 0001 -11 eeb42690 f6d93640 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5617 0001 -11 eeb42690 f6d93b20 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending 5618 0001 -11 eeb42690 f6d93160 0 f8fa1764 nfsv3 WRITE a:call_status q:xprt_sending
---
net/sunrpc/clnt.c | 29 ++++++++++++++++------------- 1 files changed, 16 insertions(+), 13 deletions(-)
net/sunrpc/clnt.c +16 -13
@@ -25,6 +25,7 @@#include <linux/module.h> #include <linux/types.h> +#include <linux/kallsyms.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/smp_lock.h>
@@ -1528,29 +1529,31 @@ EXPORT_SYMBOL_GPL(rpc_call_null);#ifdef RPC_DEBUG static void rpc_show_header (void ) { -printk (KERN_INFO "-pid- proc flgs status -client- -prog- --rqstp- " -"-timeout -rpcwait -action- ---ops--\n" ); +printk (KERN_INFO "-pid- flgs status -client- --rqstp- " +"-timeout ---ops--\n" ); }static void rpc_show_task (const struct rpc_clnt *clnt,const struct rpc_task *task) {const char *rpc_waitq ="none" ; -int proc =-1 ; - -if (task->tk_msg.rpc_proc) - proc = task->tk_msg.rpc_proc->p_proc; +char *p, action[KSYM_SYMBOL_LEN ];if (RPC_IS_QUEUED (task)) rpc_waitq =rpc_qname (task->tk_waitqueue); -printk (KERN_INFO "%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n" , - task->tk_pid, proc, - task->tk_flags, task->tk_status, - clnt, clnt->cl_prog, - task->tk_rqstp, task->tk_timeout, - rpc_waitq, - task->tk_action, task->tk_ops); +/* map tk_action pointer to a function name; then trim off +* the "+0x0 [sunrpc]" */ +sprint_symbol (action, (unsigned long )task->tk_action); + p =strchr (action,'+' ); +if (p) + *p ='\0' ; + +printk (KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n" , + task->tk_pid, task->tk_flags, task->tk_status, + clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, + clnt->cl_protname, clnt->cl_vers,rpc_proc_name (task), + action, rpc_waitq); }void rpc_show_tasks (void )
PATCH 16/37 NFS: Make nfs_fsync methods consistent
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: Report the same debugging info, count function calls the same, and use similar function naming in nfs_fsync_dir() and nfs_fsync().
---
fs/nfs/dir.c | 3 ++- fs/nfs/file.c | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-)
fs/nfs/dir.c +2 -1
@@ -629,10 +629,11 @@ out:*/ static int nfs_fsync_dir (struct file *filp,struct dentry *dentry,int datasync) { -dfprintk (VFS ,"NFS: fsync_dir(%s/%s) datasync %d\n" , +dfprintk (VFS ,"NFS: fsync dir(%s/%s) datasync %d\n" , dentry->d_parent->d_name.name, dentry->d_name.name, datasync); +nfs_inc_stats (dentry->d_inode,NFSIOS_VFSFSYNC );return 0 ; }
fs/nfs/file.c +7 -5
@@ -50,7 +50,7 @@ static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,static ssize_t nfs_file_write (struct kiocb *,const struct iovec *iov,unsigned long nr_segs,loff_t pos);static int nfs_file_flush (struct file *,fl_owner_t id); -static int nfs_fsync (struct file *,struct dentry *dentry,int datasync); +static int nfs_file_fsync (struct file *,struct dentry *dentry,int datasync);static int nfs_check_flags (int flags);static int nfs_lock (struct file *filp,int cmd,struct file_lock *fl);static int nfs_flock (struct file *filp,int cmd,struct file_lock *fl);
@@ -72,7 +72,7 @@ const struct file_operations nfs_file_operations = { .open = nfs_file_open, .flush = nfs_file_flush, .release = nfs_file_release, - .fsync = nfs_fsync, + .fsync = nfs_file_fsync, .lock = nfs_lock, .flock = nfs_flock, .splice_read = nfs_file_splice_read,
@@ -181,7 +181,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) }/* -* Helper for nfs_file_flush() and nfs_fsync() +* Helper for nfs_file_flush() and nfs_file_fsync() * * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to * disk, but it retrieves and clears ctx->error after synching, despite
@@ -296,12 +296,14 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)* whether any write errors occurred for this process. */ static int -nfs_fsync (struct file *file,struct dentry *dentry,int datasync) +nfs_file_fsync (struct file *file,struct dentry *dentry,int datasync) {struct nfs_open_context *ctx =nfs_file_open_context (file);struct inode *inode = dentry->d_inode; -dfprintk (VFS ,"nfs: fsync(%s/%ld)\n" , inode->i_sb->s_id, inode->i_ino); +dfprintk (VFS ,"NFS: fsync file(%s/%s) datasync %d\n" , + dentry->d_parent->d_name.name, dentry->d_name.name, + datasync);nfs_inc_stats (inode,NFSIOS_VFSFSYNC );return nfs_do_fsync (ctx, inode);
PATCH 17/37 NFS: Make nfs_llseek methods consistent
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: Report the same debugging info in nfs_llseek_dir() and nfs_llseek_file().
---
fs/nfs/dir.c | 12 ++++++++++-- fs/nfs/file.c | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-)
fs/nfs/dir.c +10 -2
@@ -603,7 +603,15 @@ out:static loff_t nfs_llseek_dir (struct file *filp,loff_t offset,int origin) { -mutex_lock (&filp->f_path.dentry->d_inode->i_mutex); +struct dentry *dentry = filp->f_path.dentry; +struct inode *inode = dentry->d_inode; + +dfprintk (VFS ,"NFS: llseek dir(%s/%s, %lld, %d)\n" , + dentry->d_parent->d_name.name, + dentry->d_name.name, + offset, origin); + +mutex_lock (&inode->i_mutex);switch (origin) {case 1 : offset += filp->f_pos;
@@ -619,7 +627,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)nfs_file_open_context (filp)->dir_cookie =0 ; } out: -mutex_unlock (&filp->f_path.dentry->d_inode->i_mutex); +mutex_unlock (&inode->i_mutex);return offset; }
fs/nfs/file.c +5 -0
@@ -170,6 +170,11 @@ force_reval:static loff_t nfs_file_llseek (struct file *filp,loff_t offset,int origin) { +dfprintk (VFS ,"NFS: llseek file(%s/%s, %lld, %d)\n" , + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name, + offset, origin); +/* origin == SEEK_END => we must revalidate the cached file length */ if (origin ==SEEK_END ) {struct inode *inode = filp->f_mapping->host;
PATCH 18/37 NFS: Make nfs_open methods consistent
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: Report the same debugging info and count function calls the same for files and directories in nfs_opendir() and nfs_file_open().
---
fs/nfs/dir.c | 7 +++++-- fs/nfs/file.c | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-)
fs/nfs/dir.c +5 -2
@@ -133,8 +133,11 @@ nfs_opendir(struct inode *inode, struct file *filp) {int res; -dfprintk (VFS ,"NFS: opendir(%s/%ld)\n" , - inode->i_sb->s_id, inode->i_ino); +dfprintk (VFS ,"NFS: open dir(%s/%s)\n" , + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name); + +nfs_inc_stats (inode,NFSIOS_VFSOPEN );lock_kernel ();/* Call generic open code in order to cache credentials */
fs/nfs/file.c +4 -0
@@ -119,6 +119,10 @@ nfs_file_open(struct inode *inode, struct file *filp) {int res; +dfprintk (VFS ,"NFS: open file(%s/%s)\n" , + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name); + res =nfs_check_flags (filp->f_flags);if (res)return res;
PATCH 19/37 NFS: Add debugging facility for NFS aops
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Recent work in fs/nfs/file.c neglected to add appropriate trace debugging for the NFS client's address space operations.
---
fs/nfs/file.c | 29 +++++++++++++++++++++++++++-- 1 files changed, 27 insertions(+), 2 deletions(-)
fs/nfs/file.c +27 -2
@@ -335,6 +335,11 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,struct page *page; index = pos >>PAGE_CACHE_SHIFT ; +dfprintk (PAGECACHE ,"NFS: write_begin(%s/%s(%ld), %u@%lld)\n" , + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, + mapping->host->i_ino, len, (long long ) pos); + page =__grab_cache_page (mapping, index);if (!page)return -ENOMEM ;
@@ -355,6 +360,11 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,unsigned offset = pos & (PAGE_CACHE_SIZE -1 );int status; +dfprintk (PAGECACHE ,"NFS: write_end(%s/%s(%ld), %u@%lld)\n" , + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, + mapping->host->i_ino, len, (long long ) pos); +/* * Zero any uninitialised parts of the page, and then mark the page * as up to date if it turns out that we're extending the file.
@@ -389,6 +399,8 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,static void nfs_invalidate_page (struct page *page,unsigned long offset) { +dfprintk (PAGECACHE ,"NFS: invalidate_page(%p, %lu)\n" , page, offset); +if (offset !=0 )return ;/* Cancel any unstarted writes on this page */
@@ -397,13 +409,20 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)static int nfs_release_page (struct page *page,gfp_t gfp) { +dfprintk (PAGECACHE ,"NFS: release_page(%p)\n" , page); +/* If PagePrivate() is set, then the page is not freeable */ return 0 ; }static int nfs_launder_page (struct page *page) { -return nfs_wb_page (page->mapping->host, page); +struct inode *inode = page->mapping->host; + +dfprintk (PAGECACHE ,"NFS: launder_page(%ld, %llu)\n" , + inode->i_ino, (long long )page_offset (page)); + +return nfs_wb_page (inode, page); }const struct address_space_operations nfs_file_aops = {
@@ -423,13 +442,19 @@ const struct address_space_operations nfs_file_aops = {static int nfs_vm_page_mkwrite (struct vm_area_struct *vma,struct page *page) {struct file *filp = vma->vm_file; +struct dentry *dentry = filp->f_path.dentry;unsigned pagelen;int ret = -EINVAL ;struct address_space *mapping; +dfprintk (PAGECACHE ,"NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n" , + dentry->d_parent->d_name.name, dentry->d_name.name, + filp->f_mapping->host->i_ino, + (long long )page_offset (page)); +lock_page (page); mapping = page->mapping; -if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) +if (mapping != dentry->d_inode->i_mapping) goto out_unlock; ret =0 ;
PATCH 20/37 NFS: Use NFSDBG_FILE for all fops
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: some fops use NFSDBG_FILE, some use NFSDBG_VFS. Let's use NFSDBG_FILE for all fops, and consistently report file names instead of inode numbers.
---
fs/nfs/dir.c | 10 +++++---- fs/nfs/direct.c | 4 ++-- fs/nfs/file.c | 59 ++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 43 insertions(+), 30 deletions(-)
fs/nfs/dir.c +5 -5
@@ -133,7 +133,7 @@ nfs_opendir(struct inode *inode, struct file *filp) {int res; -dfprintk (VFS ,"NFS: open dir(%s/%s)\n" , +dfprintk (FILE ,"NFS: open dir(%s/%s)\n" , filp->f_path.dentry->d_parent->d_name.name, filp->f_path.dentry->d_name.name);
@@ -531,7 +531,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)struct nfs_fattr fattr;long res; -dfprintk (VFS ,"NFS: readdir(%s/%s) starting at cookie %Lu\n" , +dfprintk (FILE ,"NFS: readdir(%s/%s) starting at cookie %llu\n" , dentry->d_parent->d_name.name, dentry->d_name.name, (long long )filp->f_pos);nfs_inc_stats (inode,NFSIOS_VFSGETDENTS );
@@ -598,7 +598,7 @@ out:unlock_kernel ();if (res >0 ) res =0 ; -dfprintk (VFS ,"NFS: readdir(%s/%s) returns %ld\n" , +dfprintk (FILE ,"NFS: readdir(%s/%s) returns %ld\n" , dentry->d_parent->d_name.name, dentry->d_name.name, res);return res;
@@ -609,7 +609,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)struct dentry *dentry = filp->f_path.dentry;struct inode *inode = dentry->d_inode; -dfprintk (VFS ,"NFS: llseek dir(%s/%s, %lld, %d)\n" , +dfprintk (FILE ,"NFS: llseek dir(%s/%s, %lld, %d)\n" , dentry->d_parent->d_name.name, dentry->d_name.name, offset, origin);
@@ -640,7 +640,7 @@ out:*/ static int nfs_fsync_dir (struct file *filp,struct dentry *dentry,int datasync) { -dfprintk (VFS ,"NFS: fsync dir(%s/%s) datasync %d\n" , +dfprintk (FILE ,"NFS: fsync dir(%s/%s) datasync %d\n" , dentry->d_parent->d_name.name, dentry->d_name.name, datasync);
fs/nfs/direct.c +2 -2
@@ -890,7 +890,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, count =iov_length (iov, nr_segs);nfs_add_stats (mapping->host,NFSIOS_DIRECTREADBYTES , count); -dprintk ("nfs: direct read(%s/%s, %zd@%Ld)\n" , +dfprintk (FILE ,"NFS: direct read(%s/%s, %zd@%Ld)\n" , file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, (long long ) pos);
@@ -947,7 +947,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, count =iov_length (iov, nr_segs);nfs_add_stats (mapping->host,NFSIOS_DIRECTWRITTENBYTES , count); -dfprintk (VFS ,"nfs: direct write(%s/%s, %zd@%Ld)\n" , +dfprintk (FILE ,"NFS: direct write(%s/%s, %zd@%Ld)\n" , file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, (long long ) pos);
fs/nfs/file.c +36 -23
146 lines not on this page · raw message
PATCH 21/37 NFS: Fix trace debugging nits in write.c
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: fix a few dprintk messages that still need to show the RPC task ID correctly, and be sure we use the preferred %lld or %llu instead of %Ld or %Lu.
---
fs/nfs/write.c | 27 ++++++++++++++------------- 1 files changed, 14 insertions(+), 13 deletions(-)
fs/nfs/write.c +14 -13
@@ -713,10 +713,10 @@ int nfs_updatepage(struct file *file, struct page *page,nfs_inc_stats (inode,NFSIOS_VFSUPDATEPAGE ); -dprintk ("NFS: nfs_updatepage(%s/%s %d@%Ld)\n" , +dprintk ("NFS: nfs_updatepage(%s/%s %d@%lld)\n" , file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, count, - (long long )(page_offset (page) +offset)); + (long long )(page_offset (page) + offset));/* If we're not using byte range locks, and we know the page * is up to date, it may be more efficient to extend the write
@@ -736,7 +736,7 @@ int nfs_updatepage(struct file *file, struct page *page,else __set_page_dirty_nobuffers (page); -dprintk ("NFS: nfs_updatepage returns %d (isize %Ld)\n" , +dprintk ("NFS: nfs_updatepage returns %d (isize %lld)\n" , status, (long long )i_size_read (inode));return status; }
@@ -821,7 +821,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req,NFS_PROTO (inode)->write_setup (data, &msg); dprintk("NFS: %5u initiated write call " - "(req %s/%Ld, %u bytes @ offset %Lu)\n", + "(req %s/%lld, %u bytes @ offset %llu)\n", data->task.tk_pid, inode->i_sb->s_id, (long long)NFS_FILEID(inode),
@@ -965,13 +965,13 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,static void nfs_writeback_done_partial (struct rpc_task *task,void *calldata) {struct nfs_write_data *data = calldata; -struct nfs_page *req = data->req; -dprintk ("NFS: write (%s/%Ld %d@%Ld)" , - req->wb_context->path.dentry->d_inode->i_sb->s_id, - (long long )NFS_FILEID (req->wb_context->path.dentry->d_inode), - req->wb_bytes, - (long long )req_offset (req)); +dprintk ("NFS: %5u write(%s/%lld %d@%lld)" , + task->tk_pid, + data->req->wb_context->path.dentry->d_inode->i_sb->s_id, + (long long ) +NFS_FILEID (data->req->wb_context->path.dentry->d_inode), + data->req->wb_bytes, (long long )req_offset (data->req));nfs_writeback_done (task, data); }
@@ -1045,7 +1045,8 @@ static void nfs_writeback_release_full(void *calldata)nfs_list_remove_request (req); - dprintk("NFS: write (%s/%Ld %d@%Ld)", + dprintk("NFS: %5u write (%s/%lld %d@%lld)", + data->task.tk_pid, req->wb_context->path.dentry->d_inode->i_sb->s_id, (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), req->wb_bytes,
@@ -1118,7 +1119,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)static unsigned long complain;if (time_before (complain, jiffies)) { -dprintk ("NFS: faulty NFS server %s:" +dprintk ("NFS: faulty NFS server %s:" " (committed = %d) != (stable = %d)\n" ,NFS_SERVER (data->inode)->nfs_client->cl_hostname, resp->verf->committed, argp->stable);
@@ -1287,7 +1288,7 @@ static void nfs_commit_release(void *calldata)dec_bdi_stat (req->wb_page->mapping->backing_dev_info,BDI_RECLAIMABLE ); - dprintk("NFS: commit (%s/%Ld %d@%Ld)", + dprintk("NFS: commit (%s/%lld %d@%lld)", req->wb_context->path.dentry->d_inode->i_sb->s_id, (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), req->wb_bytes,
PATCH 22/37 SUNRPC: Remove obsolete messages during transport connect
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Recent changes to the RPC client's transport connect logic make connect status values ECONNREFUSED and ECONNRESET impossible.
Clean up xprt_connect_status() to account for these changes.
---
net/sunrpc/xprt.c | 8 +------- 1 files changed, 1 insertions(+), 7 deletions(-)
net/sunrpc/xprt.c +1 -7
@@ -690,7 +690,7 @@ static void xprt_connect_status(struct rpc_task *task) {struct rpc_xprt *xprt = task->tk_xprt; -if (task->tk_status >=0 ) { +if (task->tk_status ==0 ) { xprt->stat.connect_count++; xprt->stat.connect_time += (long )jiffies - xprt->stat.connect_start; dprintk("RPC: %5u xprt_connect_status: connection established\n",
@@ -699,12 +699,6 @@ static void xprt_connect_status(struct rpc_task *task) }switch (task->tk_status) { -case -ECONNREFUSED : -case -ECONNRESET : -dprintk ("RPC: %5u xprt_connect_status: server %s refused " -"connection\n" , task->tk_pid, - task->tk_client->cl_server); -break ;case -ENOTCONN :dprintk ("RPC: %5u xprt_connect_status: connection broken\n" , task->tk_pid);
PATCH 23/37 fs/nfs/nfsroot.c: remove CVS keyword
In reply to a message not in the archiveFrom: Adrian Bunk <[email protected]>
This patch removes a CVS keyword that wasn't updated for a long time from a comment.
---
fs/nfs/nfsroot.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
fs/nfs/nfsroot.c +0 -2
@@ -1,6 +1,4 @@/* -* $Id: nfsroot.c,v 1.45 1998/03/07 10:44:46 mj Exp $ -* * Copyright (C) 1995, 1996 Gero Kuhlmann <[email protected]> * * Allow an NFS filesystem to be mounted as root. The way this works is:
PATCH 24/37 NFS: implement option checking when remounting NFS filesystems (resend)
In reply to a message not in the archiveFrom: Jeff Layton <[email protected]>
When remounting an NFS or NFS4 filesystem, the new NFS options are not respected, yet the remount will still return success. This patch adds a remount_fs sb op for NFS that checks any new nfs mount options against the existing ones and fails the mount if any have changed.
This is only implemented for string-based mount options since doing this with binary options isn't really feasible.
This is essentially the same as the original patch I sent out, but adds a check to see if the addr= option has changed.
---
fs/nfs/super.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 76 insertions(+), 0 deletions(-)
fs/nfs/super.c +76 -0
@@ -207,6 +207,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);static void nfs_kill_super (struct super_block *);static void nfs_put_super (struct super_block *); +static int nfs_remount (struct super_block *sb,int *flags,char *raw_data);static struct file_system_type nfs_fs_type = { .owner =THIS_MODULE ,
@@ -234,6 +235,7 @@ static const struct super_operations nfs_sops = { .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, .show_stats = nfs_show_stats, + .remount_fs = nfs_remount, };#ifdef CONFIG_NFS_V4
@@ -278,6 +280,7 @@ static const struct super_operations nfs4_sops = { .umount_begin = nfs_umount_begin, .show_options = nfs_show_options, .show_stats = nfs_show_stats, + .remount_fs = nfs_remount, };#endif
@@ -1398,6 +1401,79 @@ out_invalid_fh:return -EINVAL ; } +static int +nfs_compare_remount_data (struct nfs_server *nfss, +struct nfs_parsed_mount_data *data) +{ +if (data->flags != nfss->flags || + data->rsize != nfss->rsize || + data->wsize != nfss->wsize || + data->retrans != nfss->client->cl_timeout->to_retries || + data->auth_flavors[0 ] != nfss->client->cl_auth->au_flavor || + data->acregmin != nfss->acregmin /HZ || + data->acregmax != nfss->acregmax /HZ || + data->acdirmin != nfss->acdirmin /HZ || + data->acdirmax != nfss->acdirmax /HZ || + data->timeo != (10U * nfss->client->cl_timeout->to_initval /HZ ) || + data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || +memcmp (&data->nfs_server.address, &nfss->nfs_client->cl_addr, + data->nfs_server.addrlen) !=0 ) +return -EINVAL ; + +return 0 ; +} + +static int +nfs_remount (struct super_block *sb,int *flags,char *raw_data) +{ +int error; +struct nfs_server *nfss = sb->s_fs_info; +struct nfs_parsed_mount_data *data; +struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data; +struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; + +/* +* Userspace mount programs that send binary options generally send +* them populated with default values. We have no way to know which +* ones were explicitly specified. Fall back to legacy behavior and +* just return success. +*/ +if ((sb->s_type == &nfs4_fs_type && options4->version ==1 ) || + (sb->s_type == &nfs_fs_type && options->version >=1 && + options->version <=6 )) +return 0 ; + + data =kzalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) +return -ENOMEM ; + +/* fill out struct with values from existing mount */ + data->flags = nfss->flags; + data->rsize = nfss->rsize; + data->wsize = nfss->wsize; + data->retrans = nfss->client->cl_timeout->to_retries; + data->auth_flavors[0 ] = nfss->client->cl_auth->au_flavor; + data->acregmin = nfss->acregmin /HZ ; + data->acregmax = nfss->acregmax /HZ ; + data->acdirmin = nfss->acdirmin /HZ ; + data->acdirmax = nfss->acdirmax /HZ ; + data->timeo =10U * nfss->client->cl_timeout->to_initval /HZ ; + data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; +memcpy (&data->nfs_server.address, &nfss->nfs_client->cl_addr, + data->nfs_server.addrlen); + +/* overwrite those values with any that were specified */ + error =nfs_parse_mount_options ((char *)options, data); +if (error <0 ) + goto out; + +/* compare new mount options with old ones */ + error =nfs_compare_remount_data (nfss, data); +out: +kfree (data); +return error; +} +/* * Initialise the common bits of the superblock */
PATCH 25/37 rpc: bring back cl_chatty
In reply to a message not in the archiveFrom: Olga Kornievskaia <[email protected]>
The cl_chatty flag alows us to control whether a given rpc client leaves
"server X not responding, timed out"
messages in the syslog. Such messages make sense for ordinary nfs clients (where an unresponsive server means applications on the mountpoint are probably hanging), but not for the callback client (which can fail more commonly, with the only result just of disabling some optimizations).
Previously cl_chatty was removed, do to lack of users; reinstate it, and use it for the nfsd's callback client.
---
fs/nfsd/nfs4callback.c | 2 +- include/linux/sunrpc/clnt.h | 4 +++- net/sunrpc/clnt.c | 16 +++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-)
fs/nfsd/nfs4callback.c +1 -1
@@ -381,7 +381,7 @@ static int do_probe_callback(void *data) .program = &cb_program, .version = nfs_cb_version[1]->number, .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ - .flags = (RPC_CLNT_CREATE_NOPING), + .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), };struct rpc_message msg = { .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL ],
include/linux/sunrpc/clnt.h +3 -1
@@ -42,7 +42,8 @@ struct rpc_clnt { unsigned int cl_softrtry : 1,/* soft timeouts */ cl_discrtry : 1,/* disconnect before retry */ - cl_autobind : 1;/* use getport() */ + cl_autobind : 1,/* use getport() */ + cl_chatty : 1;/* be verbose */struct rpc_rtt * cl_rtt;/* RTO estimator data */ const struct rpc_timeout *cl_timeout;/* Timeout strategy */
@@ -114,6 +115,7 @@ struct rpc_create_args {#define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 3)#define RPC_CLNT_CREATE_NOPING (1UL << 4)#define RPC_CLNT_CREATE_DISCRTRY (1UL << 5) +#define RPC_CLNT_CREATE_QUIET (1UL << 6)struct rpc_clnt *rpc_create (struct rpc_create_args *args); struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
net/sunrpc/clnt.c +11 -5
@@ -324,6 +324,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) clnt->cl_autobind =1 ;if (args->flags &RPC_CLNT_CREATE_DISCRTRY ) clnt->cl_discrtry =1 ; +if (!(args->flags &RPC_CLNT_CREATE_QUIET )) + clnt->cl_chatty =1 ;return clnt; }
@@ -1149,7 +1151,8 @@ call_status(struct rpc_task *task)rpc_exit (task, status);break ;default : -printk ("%s: RPC call returned error %d\n" , +if (clnt->cl_chatty) +printk ("%s: RPC call returned error %d\n" , clnt->cl_protname, -status);rpc_exit (task, status); }
@@ -1174,7 +1177,8 @@ call_timeout(struct rpc_task *task) task->tk_timeouts++;if (RPC_IS_SOFT (task)) { -printk (KERN_NOTICE "%s: server %s not responding, timed out\n" , +if (clnt->cl_chatty) +printk (KERN_NOTICE "%s: server %s not responding, timed out\n" , clnt->cl_protname, clnt->cl_server);rpc_exit (task, -EIO );return ;
@@ -1182,7 +1186,8 @@ call_timeout(struct rpc_task *task)if (!(task->tk_flags &RPC_CALL_MAJORSEEN )) { task->tk_flags |=RPC_CALL_MAJORSEEN ; -printk (KERN_NOTICE "%s: server %s not responding, still trying\n" , +if (clnt->cl_chatty) +printk (KERN_NOTICE "%s: server %s not responding, still trying\n" , clnt->cl_protname, clnt->cl_server); }rpc_force_rebind (clnt);
@@ -1213,8 +1218,9 @@ call_decode(struct rpc_task *task) task->tk_pid, task->tk_status);if (task->tk_flags &RPC_CALL_MAJORSEEN ) { -printk (KERN_NOTICE "%s: server %s OK\n" , - clnt->cl_protname, clnt->cl_server); +if (clnt->cl_chatty) +printk (KERN_NOTICE "%s: server %s OK\n" , + clnt->cl_protname, clnt->cl_server); task->tk_flags &= ~RPC_CALL_MAJORSEEN ; }
PATCH 26/37 rpc: eliminate unused variable in auth_gss upcall code
In reply to a message not in the archiveFrom: \"J. Bruce Fields\" <[email protected]>
Also, a minor comment grammar fix in the same file.
---
net/sunrpc/auth_gss/auth_gss.c | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-)
net/sunrpc/auth_gss/auth_gss.c +1 -3
@@ -272,7 +272,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid)return NULL ; } -/* Try to add a upcall to the pipefs queue. +/* Try to add an upcall to the pipefs queue. * If an upcall owned by our uid already exists, then we return a reference * to that upcall instead of adding the new upcall. */
@@ -493,7 +493,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) {const void *p, *end;void *buf; -struct rpc_clnt *clnt;struct gss_upcall_msg *gss_msg;struct inode *inode = filp->f_path.dentry->d_inode;struct gss_cl_ctx *ctx;
@@ -507,7 +506,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)if (!buf) goto out; - clnt =RPC_I (inode)->private; err = -EFAULT ;if (copy_from_user (buf, src, mlen)) goto err;
PATCH 27/37 rpc: remove some unused macros
In reply to a message not in the archiveFrom: \"J. Bruce Fields\" <[email protected]>
There used to be a print_hexl() function that used isprint(), now gone. I don't know why NFS_NGROUPS and CA_RUN_AS_MACHINE were here.
I also don't know why another #define that's actually used was marked "unused".
---
net/sunrpc/auth_gss/auth_gss.c | 13 +------------ 1 files changed, 1 insertions(+), 12 deletions(-)
net/sunrpc/auth_gss/auth_gss.c +1 -12
@@ -63,22 +63,11 @@ static const struct rpc_credops gss_nullops;# define RPCDBG_FACILITY RPCDBG_AUTH#endif -#define NFS_NGROUPS 16 - -#define GSS_CRED_SLACK 1024/* XXX: unused */ +#define GSS_CRED_SLACK 1024/* length of a krb5 verifier (48), plus data added before arguments when * using integrity (two 4-byte integers): */ #define GSS_VERF_SLACK 100 -/* XXX this define must match the gssd define -* as it is passed to gssd to signal the use of -* machine creds should be part of the shared rpc interface */ - -#define CA_RUN_AS_MACHINE 0x00000200 - -/* dump the buffer in `emacs-hexl' style */ -#define isprint (c) ((c > 0x1f) && (c < 0x7f)) -struct gss_auth {struct kref kref;struct rpc_auth rpc_auth;
PATCH 28/37 rpc: minor cleanup of scheduler callback code
In reply to a message not in the archiveFrom: \"J. Bruce Fields\" <[email protected]>
Try to make the comment here a little more clear and concise.
Also, this macro definition seems unnecessary.
---
include/linux/sunrpc/sched.h | 1 - net/sunrpc/sched.c | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-)
include/linux/sunrpc/sched.h +0 -1
@@ -135,7 +135,6 @@ struct rpc_task_setup {#define RPC_IS_SWAPPER (t) ((t)->tk_flags & RPC_TASK_SWAPPER)#define RPC_DO_ROOTOVERRIDE (t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)#define RPC_ASSASSINATED (t) ((t)->tk_flags & RPC_TASK_KILLED) -#define RPC_DO_CALLBACK (t) ((t)->tk_callback != NULL)#define RPC_IS_SOFT (t) ((t)->tk_flags & RPC_TASK_SOFT)#define RPC_TASK_RUNNING 0
net/sunrpc/sched.c +5 -9
@@ -626,19 +626,15 @@ static void __rpc_execute(struct rpc_task *task)/* * Execute any pending callback. */ -if (RPC_DO_CALLBACK (task)) { -/* Define a callback save pointer */ +if (task->tk_callback) {void (*save_callback)(struct rpc_task *);/* -* If a callback exists, save it, reset it, -* call it. -* The save is needed to stop from resetting -* another callback set within the callback handler -* - Dave +* We set tk_callback to NULL before calling it, +* in case it sets the tk_callback field itself: */ - save_callback=task->tk_callback; - task->tk_callback=NULL ; + save_callback = task->tk_callback; + task->tk_callback =NULL ;save_callback (task); }
PATCH 29/37 NFS: Fix the ftruncate() credential problem
In reply to a message not in the archiveftruncate() access checking is supposed to be performed at open() time, just like reads and writes.
---
fs/nfs/inode.c | 4 ++-- fs/nfs/nfs3proc.c | 2 ++ fs/nfs/nfs4proc.c | 47 +++++++++++++++++++++++------------------------ fs/nfs/proc.c | 2 ++ 4 files changed, 29 insertions(+), 26 deletions(-)
fs/nfs/inode.c +2 -2
@@ -347,7 +347,7 @@ out_no_inode: goto out; } -#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET) +#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE)int nfs_setattr (struct dentry *dentry,struct iattr *attr)
@@ -369,7 +369,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)/* Optimization: if the end result is no change, don't RPC */ attr->ia_valid &=NFS_VALID_ATTRS ; -if (attr->ia_valid ==0 ) +if ((attr->ia_valid & ~ATTR_FILE ) ==0 )return 0 ;lock_kernel ();
fs/nfs/nfs3proc.c +2 -0
@@ -129,6 +129,8 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,int status;dprintk ("NFS call setattr\n" ); +if (sattr->ia_valid &ATTR_FILE ) + msg.rpc_cred =nfs_file_cred (sattr->ia_file);nfs_fattr_init (fattr); status =rpc_call_sync (NFS_CLIENT (inode), &msg,0 );if (status ==0 )
fs/nfs/nfs4proc.c +23 -24
114 lines not on this page · raw message
fs/nfs/proc.c +2 -0
@@ -129,6 +129,8 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, sattr->ia_mode &=S_IALLUGO ;dprintk ("NFS call setattr\n" ); +if (sattr->ia_valid &ATTR_FILE ) + msg.rpc_cred =nfs_file_cred (sattr->ia_file);nfs_fattr_init (fattr); status =rpc_call_sync (NFS_CLIENT (inode), &msg,0 );if (status ==0 )
PATCH 30/37 SUNRPC: Ensure all transports set rq_xtime consistently
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
The RPC client uses the rq_xtime field in each RPC request to determine the round-trip time of the request. Currently, the rq_xtime field is initialized by each transport just before it starts enqueing a request to be sent. However, transports do not handle initializing this value consistently; sometimes they don't initialize it at all.
To make the measurement of request round-trip time consistent for all RPC client transport capabilities, pull rq_xtime initialization into the RPC client's generic transport logic. Now all transports will get a standardized RTT measure automatically, from:
xprt_transmit()
to
xprt_complete_rqst()
This makes round-trip time calculation more accurate for the TCP transport. The socket ->sendmsg() method can return "-EAGAIN" if the socket's output buffer is full, so the TCP transport's ->send_request() method may call the ->sendmsg() method repeatedly until it gets all of the request's bytes queued in the socket's buffer.
Currently, the TCP transport sets the rq_xtime field every time through that loop so the final value is the timestamp just before the *last* call to the underlying socket's ->sendmsg() method. After this patch, the rq_xtime field contains a timestamp that reflects the time just before the *first* call to ->sendmsg().
This is consequential under heavy workloads because large requests often take multiple ->sendmsg() calls to get all the bytes of a request queued. The TCP transport causes the request to sleep until the remote end of the socket has received enough bytes to clear space in the socket's local output buffer. This delay can be quite significant.
The method introduced by this patch is a more accurate measure of RTT for stream transports, since the server can cause enough back pressure to delay (ie increase the latency of) requests from the client.
Additionally, this patch corrects the behavior of the RDMA transport, which entirely neglected to initialize the rq_xtime field. RPC performance metrics for RDMA transports now display correct RPC request round trip times.
---
net/sunrpc/xprt.c | 1 + net/sunrpc/xprtsock.c | 2 -- 2 files changed, 1 insertions(+), 2 deletions(-)
net/sunrpc/xprt.c +1 -0
@@ -872,6 +872,7 @@ void xprt_transmit(struct rpc_task *task)return ; req->rq_connect_cookie = xprt->connect_cookie; + req->rq_xtime = jiffies; status = xprt->ops->send_request (task);if (status ==0 ) {dprintk ("RPC: %5u xmit complete\n" , task->tk_pid);
net/sunrpc/xprtsock.c +0 -2
@@ -579,7 +579,6 @@ static int xs_udp_send_request(struct rpc_task *task) req->rq_svec->iov_base, req->rq_svec->iov_len); - req->rq_xtime = jiffies; status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, xdr,
@@ -671,7 +670,6 @@ static int xs_tcp_send_request(struct rpc_task *task)* to cope with writespace callbacks arriving _after_ we have * called sendmsg(). */ while (1 ) { - req->rq_xtime = jiffies; status =xs_sendpages (transport->sock,NULL ,0 , xdr, req->rq_bytes_sent);
PATCH 31/37 NFS: Remove the redundant file_open entry from struct nfs_rpc_ops
In reply to a message not in the archiveAll instances are set to nfs_open(), so we should just remove the redundant indirection. Ditto for the file_release op
---
fs/nfs/file.c | 4 ++-- fs/nfs/nfs3proc.c | 2 -- fs/nfs/nfs4proc.c | 2 -- fs/nfs/proc.c | 2 -- include/linux/nfs_xdr.h | 2 -- 5 files changed, 2 insertions(+), 10 deletions(-)
fs/nfs/file.c +2 -2
@@ -129,7 +129,7 @@ nfs_file_open(struct inode *inode, struct file *filp)nfs_inc_stats (inode,NFSIOS_VFSOPEN );lock_kernel (); - res =NFS_PROTO (inode)->file_open (inode, filp); + res =nfs_open (inode, filp);unlock_kernel ();return res; }
@@ -147,7 +147,7 @@ nfs_file_release(struct inode *inode, struct file *filp)if (filp->f_mode &FMODE_WRITE )nfs_wb_all (dentry->d_inode);nfs_inc_stats (inode,NFSIOS_VFSRELEASE ); -return NFS_PROTO (inode)->file_release (inode, filp); +return nfs_release (inode, filp); }/**
fs/nfs/nfs3proc.c +0 -2
@@ -803,8 +803,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .write_done = nfs3_write_done, .commit_setup = nfs3_proc_commit_setup, .commit_done = nfs3_commit_done, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs3_proc_lock, .clear_acl_cache = nfs3_forget_cached_acls, };
fs/nfs/nfs4proc.c +0 -2
@@ -3724,8 +3724,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .write_done = nfs4_write_done, .commit_setup = nfs4_proc_commit_setup, .commit_done = nfs4_commit_done, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs4_proc_lock, .clear_acl_cache = nfs4_zap_acl_attr, };
fs/nfs/proc.c +0 -2
@@ -655,8 +655,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .write_setup = nfs_proc_write_setup, .write_done = nfs_write_done, .commit_setup = nfs_proc_commit_setup, - .file_open = nfs_open, - .file_release = nfs_release, .lock = nfs_proc_lock, .lock_check_bounds = nfs_lock_check_bounds, };
include/linux/nfs_xdr.h +0 -2
@@ -829,8 +829,6 @@ struct nfs_rpc_ops {int (*write_done) (struct rpc_task *,struct nfs_write_data *);void (*commit_setup) (struct nfs_write_data *,struct rpc_message *);int (*commit_done) (struct rpc_task *,struct nfs_write_data *); -int (*file_open) (struct inode *,struct file *); -int (*file_release) (struct inode *,struct file *);int (*lock)(struct file *,int ,struct file_lock *);int (*lock_check_bounds)(const struct file_lock *);void (*clear_acl_cache)(struct inode *);
PATCH 32/37 NFS: Move fs/nfs/iostat.h to include/linux
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
The fs/nfs/iostat.h header has definitions that were designed to be exposed to user space. Move these definitions under include/linux so user space can use the definitions in applications that read /proc/self/mountstats.
Also address a handful of coding style issues called out by checkpatch.pl in fs/nfs/iostat.h.
---
fs/nfs/iostat.h | 119 +++++--------------------------------------- include/linux/nfs_iostat.h | 119 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 106 deletions(-)
fs/nfs/iostat.h +13 -106
@@ -5,135 +5,41 @@* * Copyright (C) 2005, 2006 Chuck Lever <[email protected]> * -* NFS client per-mount statistics provide information about the health of -* the NFS client and the health of each NFS mount point. Generally these -* are not for detailed problem diagnosis, but simply to indicate that there -* is a problem. -* -* These counters are not meant to be human-readable, but are meant to be -* integrated into system monitoring tools such as "sar" and "iostat". As -* such, the counters are sampled by the tools over time, and are never -* zeroed after a file system is mounted. Moving averages can be computed -* by the tools by taking the difference between two instantaneous samples -* and dividing that by the time between the samples. */ #ifndef _NFS_IOSTAT#define _NFS_IOSTAT -#define NFS_IOSTAT_VERS "1.0" - -/* - * NFS byte counters - * - * 1. SERVER - the number of payload bytes read from or written to the - * server by the NFS client via an NFS READ or WRITE request. - * - * 2. NORMAL - the number of bytes read or written by applications via - * the read(2) and write(2) system call interfaces. - * - * 3. DIRECT - the number of bytes read or written from files opened - * with the O_DIRECT flag. - * - * These counters give a view of the data throughput into and out of the NFS - * client. Comparing the number of bytes requested by an application with the - * number of bytes the client requests from the server can provide an - * indication of client efficiency (per-op, cache hits, etc). - * - * These counters can also help characterize which access methods are in - * use. DIRECT by itself shows whether there is any O_DIRECT traffic. - * NORMAL + DIRECT shows how much data is going through the system call - * interface. A large amount of SERVER traffic without much NORMAL or - * DIRECT traffic shows that applications are using mapped files. - * - * NFS page counters - * - * These count the number of pages read or written via nfs_readpage(), - * nfs_readpages(), or their write equivalents. - */ -enum nfs_stat_bytecounters { - NFSIOS_NORMALREADBYTES = 0, - NFSIOS_NORMALWRITTENBYTES, - NFSIOS_DIRECTREADBYTES, - NFSIOS_DIRECTWRITTENBYTES, - NFSIOS_SERVERREADBYTES, - NFSIOS_SERVERWRITTENBYTES, - NFSIOS_READPAGES, - NFSIOS_WRITEPAGES, - __NFSIOS_BYTESMAX, -}; - -/* - * NFS event counters - * - * These counters provide a low-overhead way of monitoring client activity - * without enabling NFS trace debugging. The counters show the rate at - * which VFS requests are made, and how often the client invalidates its - * data and attribute caches. This allows system administrators to monitor - * such things as how close-to-open is working, and answer questions such - * as "why are there so many GETATTR requests on the wire?" - * - * They also count anamolous events such as short reads and writes, silly - * renames due to close-after-delete, and operations that change the size - * of a file (such operations can often be the source of data corruption - * if applications aren't using file locking properly). - */ -enum nfs_stat_eventcounters { - NFSIOS_INODEREVALIDATE = 0, - NFSIOS_DENTRYREVALIDATE, - NFSIOS_DATAINVALIDATE, - NFSIOS_ATTRINVALIDATE, - NFSIOS_VFSOPEN, - NFSIOS_VFSLOOKUP, - NFSIOS_VFSACCESS, - NFSIOS_VFSUPDATEPAGE, - NFSIOS_VFSREADPAGE, - NFSIOS_VFSREADPAGES, - NFSIOS_VFSWRITEPAGE, - NFSIOS_VFSWRITEPAGES, - NFSIOS_VFSGETDENTS, - NFSIOS_VFSSETATTR, - NFSIOS_VFSFLUSH, - NFSIOS_VFSFSYNC, - NFSIOS_VFSLOCK, - NFSIOS_VFSRELEASE, - NFSIOS_CONGESTIONWAIT, - NFSIOS_SETATTRTRUNC, - NFSIOS_EXTENDWRITE, - NFSIOS_SILLYRENAME, - NFSIOS_SHORTREAD, - NFSIOS_SHORTWRITE, - NFSIOS_DELAY, - __NFSIOS_COUNTSMAX, -}; - -#ifdef __KERNEL__ -#include <linux/percpu.h> #include <linux/cache.h> +#include <linux/nfs_iostat.h> struct nfs_iostats {unsigned long long bytes[__NFSIOS_BYTESMAX];unsigned long events[__NFSIOS_COUNTSMAX]; }____cacheline_aligned ; -static inline void nfs_inc_server_stats(struct nfs_server *server, enum nfs_stat_eventcounters stat) +static inline void nfs_inc_server_stats (struct nfs_server *server, +enum nfs_stat_eventcounters stat) {struct nfs_iostats *iostats;int cpu; cpu =get_cpu (); iostats =per_cpu_ptr (server->io_stats, cpu); - iostats->events[stat] ++; + iostats->events[stat]++;put_cpu_no_resched (); } -static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat) +static inline void nfs_inc_stats (struct inode *inode, +enum nfs_stat_eventcounters stat) {nfs_inc_server_stats (NFS_SERVER (inode), stat); } -static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_stat_bytecounters stat, unsigned long addend) +static inline void nfs_add_server_stats (struct nfs_server *server, +enum nfs_stat_bytecounters stat, +unsigned long addend) {struct nfs_iostats *iostats;int cpu;
@@ -144,7 +50,9 @@ static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_statput_cpu_no_resched (); } -static inline void nfs_add_stats (struct inode *inode,enum nfs_stat_bytecounters stat,unsigned long addend) +static inline void nfs_add_stats (struct inode *inode, +enum nfs_stat_bytecounters stat, +unsigned long addend) {nfs_add_server_stats (NFS_SERVER (inode), stat, addend); }
@@ -160,5 +68,4 @@ static inline void nfs_free_iostats(struct nfs_iostats *stats) free_percpu(stats); } -#endif -#endif +#endif /* _NFS_IOSTAT */
include/linux/nfs_iostat.h new file +119 -0
119 lines not on this page · raw message
PATCH 33/37 NFS: Fix a warning in nfs4_async_handle_error
In reply to a message not in the archiveWe're not modifying the nfs_server when we call nfs_inc_server_stats and friends, so allow the compiler to pass 'const' pointers too.
---
fs/nfs/iostat.h | 8 ++++---- fs/nfs/nfs4proc.c | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-)
fs/nfs/iostat.h +4 -4
@@ -19,7 +19,7 @@ struct nfs_iostats {unsigned long events[__NFSIOS_COUNTSMAX]; }____cacheline_aligned ; -static inline void nfs_inc_server_stats (struct nfs_server *server, +static inline void nfs_inc_server_stats (const struct nfs_server *server,enum nfs_stat_eventcounters stat) {struct nfs_iostats *iostats;
@@ -31,13 +31,13 @@ static inline void nfs_inc_server_stats(struct nfs_server *server,put_cpu_no_resched (); } -static inline void nfs_inc_stats (struct inode *inode, +static inline void nfs_inc_stats (const struct inode *inode,enum nfs_stat_eventcounters stat) {nfs_inc_server_stats (NFS_SERVER (inode), stat); } -static inline void nfs_add_server_stats (struct nfs_server *server, +static inline void nfs_add_server_stats (const struct nfs_server *server,enum nfs_stat_bytecounters stat,unsigned long addend) {
@@ -50,7 +50,7 @@ static inline void nfs_add_server_stats(struct nfs_server *server,put_cpu_no_resched (); } -static inline void nfs_add_stats (struct inode *inode, +static inline void nfs_add_stats (const struct inode *inode,enum nfs_stat_bytecounters stat,unsigned long addend) {
fs/nfs/nfs4proc.c +1 -2
@@ -2766,8 +2766,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) task->tk_status =0 ;return -EAGAIN ;case -NFS4ERR_DELAY : -nfs_inc_server_stats ((struct nfs_server *) server, -NFSIOS_DELAY ); +nfs_inc_server_stats (server,NFSIOS_DELAY );case -NFS4ERR_GRACE :rpc_delay (task,NFS4_POLL_RETRY_MAX ); task->tk_status =0 ;
PATCH 34/37 NFS: Ensure we zap only the access and acl caches when setting new acls
In reply to a message not in the archive...and ensure that we obey the NFS_INO_INVALID_ACL flag when retrieving the acls.
---
fs/nfs/inode.c | 4 +--- fs/nfs/internal.h | 1 + fs/nfs/nfs3acl.c | 9 ++++++--- fs/nfs/nfs4proc.c | 5 ++++- 4 files changed, 12 insertions(+), 7 deletions(-)
fs/nfs/inode.c +1 -3
@@ -57,8 +57,6 @@ static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;static void nfs_invalidate_inode (struct inode *);static int nfs_update_inode (struct inode *,struct nfs_fattr *); -static void nfs_zap_acl_cache (struct inode *); -static struct kmem_cache * nfs_inode_cachep; static inline unsigned long
@@ -167,7 +165,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) } } -static void nfs_zap_acl_cache (struct inode *inode) +void nfs_zap_acl_cache (struct inode *inode) {void (*clear_acl_cache)(struct inode *);
fs/nfs/internal.h +1 -0
@@ -150,6 +150,7 @@ extern void nfs_clear_inode(struct inode *);#ifdef CONFIG_NFS_V4 extern void nfs4_clear_inode (struct inode *);#endif +void nfs_zap_acl_cache (struct inode *inode);/* super.c */ extern struct file_system_type nfs_xdev_fs_type;
fs/nfs/nfs3acl.c +6 -3
@@ -5,6 +5,8 @@#include <linux/posix_acl_xattr.h> #include <linux/nfsacl.h> +#include "internal.h" +#define NFSDBG_FACILITY NFSDBG_PROCssize_t nfs3_listxattr (struct dentry *dentry,char *buffer,size_t size)
@@ -205,6 +207,8 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type) status =nfs_revalidate_inode (server, inode);if (status <0 )return ERR_PTR (status); +if (NFS_I (inode)->cache_validity &NFS_INO_INVALID_ACL ) +nfs_zap_acl_cache (inode); acl =nfs3_get_cached_acl (inode, type);if (acl !=ERR_PTR (-EAGAIN ))return acl;
@@ -319,9 +323,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,dprintk ("NFS call setacl\n" ); msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL ]; status =rpc_call_sync (server->client_acl, &msg,0 ); -spin_lock (&inode->i_lock); -NFS_I (inode)->cache_validity |=NFS_INO_INVALID_ACCESS ; -spin_unlock (&inode->i_lock); +nfs_access_zap_cache (inode); +nfs_zap_acl_cache (inode);dprintk ("NFS reply setacl: %d\n" , status);/* pages may have been allocated at the xdr layer. */
fs/nfs/nfs4proc.c +4 -1
@@ -2705,6 +2705,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) ret =nfs_revalidate_inode (server, inode);if (ret <0 )return ret; +if (NFS_I (inode)->cache_validity &NFS_INO_INVALID_ACL ) +nfs_zap_acl_cache (inode); ret =nfs4_read_cached_acl (inode, buf, buflen);if (ret != -ENOENT )return ret;
@@ -2732,7 +2734,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflnfs_inode_return_delegation (inode);buf_to_pages (buf, buflen, arg.acl_pages, &arg.acl_pgbase); ret =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); -nfs_zap_caches (inode); +nfs_access_zap_cache (inode); +nfs_zap_acl_cache (inode);return ret; }
PATCH 35/37 NFS: Allow any value for the "retry" option
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
The kernel NFS mount option parser should ignore the retry= mount option since it is meaningful only in user space. Today it expects a number rather than arbitrary text, so it ignores the option if the value is numeric, but chokes if there are other characters in the value.
Change it to allow any text (except ",") as its value.
---
fs/nfs/super.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/nfs/super.c +2 -1
@@ -101,6 +101,8 @@ enum {static match_table_t nfs_mount_option_tokens = { { Opt_userspace,"bg" }, { Opt_userspace,"fg" }, + { Opt_userspace,"retry=%s" }, + { Opt_soft,"soft" }, { Opt_hard,"hard" }, { Opt_intr,"intr" },
@@ -136,7 +138,6 @@ static match_table_t nfs_mount_option_tokens = { { Opt_acdirmin, "acdirmin=%u" }, { Opt_acdirmax, "acdirmax=%u" }, { Opt_actimeo, "actimeo=%u" }, - { Opt_userspace, "retry=%u" }, { Opt_namelen, "namlen=%u" }, { Opt_mountport, "mountport=%u" }, { Opt_mountvers, "mountvers=%u" },
PATCH 36/37 NFS: Treat "intr" and "nointr" options as deprecated
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up: the "intr" and "nointr" mount options were recently retired. Document this in the NFS mount option parser.
---
fs/nfs/super.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-)
fs/nfs/super.c +4 -6
@@ -65,7 +65,6 @@enum {/* Mount options that take no arguments */ Opt_soft, Opt_hard, - Opt_intr, Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac,
@@ -105,8 +104,8 @@ static match_table_t nfs_mount_option_tokens = { { Opt_soft, "soft" }, { Opt_hard, "hard" }, - { Opt_intr, "intr" }, - { Opt_nointr, "nointr" }, + { Opt_deprecated, "intr" }, + { Opt_deprecated, "nointr" }, { Opt_posix, "posix" }, { Opt_noposix, "noposix" }, { Opt_cto, "cto" },
@@ -787,9 +786,6 @@ static int nfs_parse_mount_options(char *raw,case Opt_hard: mnt->flags &= ~NFS_MOUNT_SOFT ;break ; -case Opt_intr: -case Opt_nointr: -break ;case Opt_posix: mnt->flags |=NFS_MOUNT_POSIX ;break ;
@@ -1105,6 +1101,8 @@ static int nfs_parse_mount_options(char *raw,case Opt_userspace:case Opt_deprecated: +dfprintk (MOUNT ,"NFS: ignoring mount option " +"'%s'\n" , p);break ;default :
PATCH 37/37 NFS: missing newline in NFS mount debugging message
In reply to a message not in the archiveFrom: Chuck Lever <[email protected]>
Clean up.
---
fs/nfs/super.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
fs/nfs/super.c +1 -1
@@ -1190,7 +1190,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,if (status ==0 )return 0 ; -dfprintk (MOUNT ,"NFS: unable to mount server %s, error %d" , +dfprintk (MOUNT ,"NFS: unable to mount server %s, error %d\n" , hostname, status);return status; }