Commit e6251ab4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfs-for-5.17-2' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client fixes from Anna Schumaker:
 "Stable Fixes:

   - Fix initialization of nfs_client cl_flags

  Other Fixes:

   - Fix performance issues with uncached readdir calls

   - Fix potential pointer dereferences in rpcrdma_ep_create

   - Fix nfs4_proc_get_locations() kernel-doc comment

   - Fix locking during sunrpc sysfs reads

   - Update my email address in the MAINTAINERS file to my new
     kernel.org email"

* tag 'nfs-for-5.17-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  SUNRPC: lock against ->sock changing during sysfs read
  MAINTAINERS: Update my email address
  NFS: Fix nfs4_proc_get_locations() kernel-doc comment
  xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create
  NFS: Fix initialisation of nfs_client cl_flags field
  NFS: Avoid duplicate uncached readdir calls on eof
  NFS: Don't skip directory entries when doing uncached readdir
  NFS: Don't overfill uncached readdir pages
parents 555f3d7b b49ea673
...@@ -13571,7 +13571,7 @@ F: tools/testing/selftests/nci/ ...@@ -13571,7 +13571,7 @@ F: tools/testing/selftests/nci/
NFS, SUNRPC, AND LOCKD CLIENTS NFS, SUNRPC, AND LOCKD CLIENTS
M: Trond Myklebust <trond.myklebust@hammerspace.com> M: Trond Myklebust <trond.myklebust@hammerspace.com>
M: Anna Schumaker <anna.schumaker@netapp.com> M: Anna Schumaker <anna@kernel.org>
L: linux-nfs@vger.kernel.org L: linux-nfs@vger.kernel.org
S: Maintained S: Maintained
W: http://client.linux-nfs.org W: http://client.linux-nfs.org
......
...@@ -177,6 +177,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) ...@@ -177,6 +177,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
INIT_LIST_HEAD(&clp->cl_superblocks); INIT_LIST_HEAD(&clp->cl_superblocks);
clp->cl_rpcclient = ERR_PTR(-EINVAL); clp->cl_rpcclient = ERR_PTR(-EINVAL);
clp->cl_flags = cl_init->init_flags;
clp->cl_proto = cl_init->proto; clp->cl_proto = cl_init->proto;
clp->cl_nconnect = cl_init->nconnect; clp->cl_nconnect = cl_init->nconnect;
clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1; clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
...@@ -423,7 +424,6 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init) ...@@ -423,7 +424,6 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
list_add_tail(&new->cl_share_link, list_add_tail(&new->cl_share_link,
&nn->nfs_client_list); &nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock); spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
return rpc_ops->init_client(new, cl_init); return rpc_ops->init_client(new, cl_init);
} }
......
...@@ -80,6 +80,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir ...@@ -80,6 +80,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
ctx->dir_cookie = 0; ctx->dir_cookie = 0;
ctx->dup_cookie = 0; ctx->dup_cookie = 0;
ctx->page_index = 0; ctx->page_index = 0;
ctx->eof = false;
spin_lock(&dir->i_lock); spin_lock(&dir->i_lock);
if (list_empty(&nfsi->open_files) && if (list_empty(&nfsi->open_files) &&
(nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
...@@ -168,6 +169,7 @@ struct nfs_readdir_descriptor { ...@@ -168,6 +169,7 @@ struct nfs_readdir_descriptor {
unsigned int cache_entry_index; unsigned int cache_entry_index;
signed char duped; signed char duped;
bool plus; bool plus;
bool eob;
bool eof; bool eof;
}; };
...@@ -867,7 +869,8 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, ...@@ -867,7 +869,8 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
status = nfs_readdir_page_filler(desc, entry, pages, pglen, status = nfs_readdir_page_filler(desc, entry, pages, pglen,
arrays, narrays); arrays, narrays);
} while (!status && nfs_readdir_page_needs_filling(page)); } while (!status && nfs_readdir_page_needs_filling(page) &&
page_mapping(page));
nfs_readdir_free_pages(pages, array_size); nfs_readdir_free_pages(pages, array_size);
out: out:
...@@ -988,7 +991,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc, ...@@ -988,7 +991,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
ent = &array->array[i]; ent = &array->array[i];
if (!dir_emit(desc->ctx, ent->name, ent->name_len, if (!dir_emit(desc->ctx, ent->name, ent->name_len,
nfs_compat_user_ino64(ent->ino), ent->d_type)) { nfs_compat_user_ino64(ent->ino), ent->d_type)) {
desc->eof = true; desc->eob = true;
break; break;
} }
memcpy(desc->verf, verf, sizeof(desc->verf)); memcpy(desc->verf, verf, sizeof(desc->verf));
...@@ -1004,7 +1007,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc, ...@@ -1004,7 +1007,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
desc->duped = 1; desc->duped = 1;
} }
if (array->page_is_eof) if (array->page_is_eof)
desc->eof = true; desc->eof = !desc->eob;
kunmap(desc->page); kunmap(desc->page);
dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %llu\n", dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %llu\n",
...@@ -1041,12 +1044,13 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc) ...@@ -1041,12 +1044,13 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
goto out; goto out;
desc->page_index = 0; desc->page_index = 0;
desc->cache_entry_index = 0;
desc->last_cookie = desc->dir_cookie; desc->last_cookie = desc->dir_cookie;
desc->duped = 0; desc->duped = 0;
status = nfs_readdir_xdr_to_array(desc, desc->verf, verf, arrays, sz); status = nfs_readdir_xdr_to_array(desc, desc->verf, verf, arrays, sz);
for (i = 0; !desc->eof && i < sz && arrays[i]; i++) { for (i = 0; !desc->eob && i < sz && arrays[i]; i++) {
desc->page = arrays[i]; desc->page = arrays[i];
nfs_do_filldir(desc, verf); nfs_do_filldir(desc, verf);
} }
...@@ -1105,9 +1109,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1105,9 +1109,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
desc->duped = dir_ctx->duped; desc->duped = dir_ctx->duped;
page_index = dir_ctx->page_index; page_index = dir_ctx->page_index;
desc->attr_gencount = dir_ctx->attr_gencount; desc->attr_gencount = dir_ctx->attr_gencount;
desc->eof = dir_ctx->eof;
memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf)); memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));
spin_unlock(&file->f_lock); spin_unlock(&file->f_lock);
if (desc->eof) {
res = 0;
goto out_free;
}
if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) && if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) &&
list_is_singular(&nfsi->open_files)) list_is_singular(&nfsi->open_files))
invalidate_mapping_pages(inode->i_mapping, page_index + 1, -1); invalidate_mapping_pages(inode->i_mapping, page_index + 1, -1);
...@@ -1141,7 +1151,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1141,7 +1151,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
nfs_do_filldir(desc, nfsi->cookieverf); nfs_do_filldir(desc, nfsi->cookieverf);
nfs_readdir_page_unlock_and_put_cached(desc); nfs_readdir_page_unlock_and_put_cached(desc);
} while (!desc->eof); } while (!desc->eob && !desc->eof);
spin_lock(&file->f_lock); spin_lock(&file->f_lock);
dir_ctx->dir_cookie = desc->dir_cookie; dir_ctx->dir_cookie = desc->dir_cookie;
...@@ -1149,9 +1159,10 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1149,9 +1159,10 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
dir_ctx->duped = desc->duped; dir_ctx->duped = desc->duped;
dir_ctx->attr_gencount = desc->attr_gencount; dir_ctx->attr_gencount = desc->attr_gencount;
dir_ctx->page_index = desc->page_index; dir_ctx->page_index = desc->page_index;
dir_ctx->eof = desc->eof;
memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf)); memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf));
spin_unlock(&file->f_lock); spin_unlock(&file->f_lock);
out_free:
kfree(desc); kfree(desc);
out: out:
...@@ -1193,6 +1204,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence) ...@@ -1193,6 +1204,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
if (offset == 0) if (offset == 0)
memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf)); memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf));
dir_ctx->duped = 0; dir_ctx->duped = 0;
dir_ctx->eof = false;
} }
spin_unlock(&filp->f_lock); spin_unlock(&filp->f_lock);
return offset; return offset;
......
...@@ -8032,7 +8032,8 @@ static int _nfs41_proc_get_locations(struct nfs_server *server, ...@@ -8032,7 +8032,8 @@ static int _nfs41_proc_get_locations(struct nfs_server *server,
/** /**
* nfs4_proc_get_locations - discover locations for a migrated FSID * nfs4_proc_get_locations - discover locations for a migrated FSID
* @inode: inode on FSID that is migrating * @server: pointer to nfs_server to process
* @fhandle: pointer to the kernel NFS client file handle
* @locations: result of query * @locations: result of query
* @page: buffer * @page: buffer
* @cred: credential to use for this operation * @cred: credential to use for this operation
......
...@@ -107,6 +107,7 @@ struct nfs_open_dir_context { ...@@ -107,6 +107,7 @@ struct nfs_open_dir_context {
__u64 dup_cookie; __u64 dup_cookie;
pgoff_t page_index; pgoff_t page_index;
signed char duped; signed char duped;
bool eof;
}; };
/* /*
......
...@@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj, ...@@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
} }
sock = container_of(xprt, struct sock_xprt, xprt); sock = container_of(xprt, struct sock_xprt, xprt);
if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0) mutex_lock(&sock->recv_mutex);
if (sock->sock == NULL ||
kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
goto out; goto out;
ret = sprintf(buf, "%pISc\n", &saddr); ret = sprintf(buf, "%pISc\n", &saddr);
out: out:
mutex_unlock(&sock->recv_mutex);
xprt_put(xprt); xprt_put(xprt);
return ret + 1; return ret + 1;
} }
......
...@@ -413,6 +413,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) ...@@ -413,6 +413,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
IB_POLL_WORKQUEUE); IB_POLL_WORKQUEUE);
if (IS_ERR(ep->re_attr.send_cq)) { if (IS_ERR(ep->re_attr.send_cq)) {
rc = PTR_ERR(ep->re_attr.send_cq); rc = PTR_ERR(ep->re_attr.send_cq);
ep->re_attr.send_cq = NULL;
goto out_destroy; goto out_destroy;
} }
...@@ -421,6 +422,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) ...@@ -421,6 +422,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
IB_POLL_WORKQUEUE); IB_POLL_WORKQUEUE);
if (IS_ERR(ep->re_attr.recv_cq)) { if (IS_ERR(ep->re_attr.recv_cq)) {
rc = PTR_ERR(ep->re_attr.recv_cq); rc = PTR_ERR(ep->re_attr.recv_cq);
ep->re_attr.recv_cq = NULL;
goto out_destroy; goto out_destroy;
} }
ep->re_receive_count = 0; ep->re_receive_count = 0;
...@@ -459,6 +461,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) ...@@ -459,6 +461,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
ep->re_pd = ib_alloc_pd(device, 0); ep->re_pd = ib_alloc_pd(device, 0);
if (IS_ERR(ep->re_pd)) { if (IS_ERR(ep->re_pd)) {
rc = PTR_ERR(ep->re_pd); rc = PTR_ERR(ep->re_pd);
ep->re_pd = NULL;
goto out_destroy; goto out_destroy;
} }
......
...@@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport) ...@@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport)
unsigned short get_srcport(struct rpc_xprt *xprt) unsigned short get_srcport(struct rpc_xprt *xprt)
{ {
struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt);
return xs_sock_getport(sock->sock); unsigned short ret = 0;
mutex_lock(&sock->recv_mutex);
if (sock->sock)
ret = xs_sock_getport(sock->sock);
mutex_unlock(&sock->recv_mutex);
return ret;
} }
EXPORT_SYMBOL(get_srcport); EXPORT_SYMBOL(get_srcport);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment