mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
NFS Client Bugfixes for Linux 5.17-rc
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEnZ5MQTpR7cLU7KEp18tUv7ClQOsFAmICusMACgkQ18tUv7Cl QOu0dhAA3o1X0b4vjpZldfRSBzf5dL6smzvqiA1gOFSCdpfST7Tp5VWGjZNxgYBP wuwJMFuVpo8UQkbRrxo4zmqzZbiukpt7JsS4a3W0cCZ0iNIXtKkE4YIBWs67rUWZ z4LQ33ouJJdwQikJqycMbR/4Mg1j7VFzjmbVEM/FRJSv7IbYDRGvs7TqrzTndoeX ll0jAHsuUvFfq29WXTMq2PH0AiY+CxLnkvTuLL7QnG+bGVj2psTQi/kqC3R5+qLN M3aYDaKfb9SYZ3pdQkZV88IQsNQjlde3B1KWc7vJdXx8eUvxBF9tWU9TC85Y4mdg 5ZNK/AX3DnICI1AcTq7/8nxUhOH7rEeroWIsA52oPEzG7f9Qkt1hUKzQRg5N7VMA VHxLY5i39zOyYnDP/lkcnGaExMefG0imB+ZnYYbmIH70tzhheGYPaBNjwLCU8Jvh NDjjEWBvjCR33EyOA/j/ZB/o1Xgu6FJU+oCgd82oNeVlcqDTPYxYWtSZqcIN1yp7 DUGJ893WpMgFFSAERaMX0JpjdbnH6/u8BvkKKwd6ERGGBqXuMwrdL9DmOpJroqUP 3gq2l+fFgDbAryvKs8ipneUUGbOiIdP4spiP44Rg/mZQrEajeUyuuFhxqM//Bfe4 O60nIrVNwIhjzu/ciIe4Z+KVs9KQm34LEtzRxEfp1SMFGrsGhRQ= =JA1A -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
e6251ab455
@ -13571,7 +13571,7 @@ F: tools/testing/selftests/nci/
|
||||
|
||||
NFS, SUNRPC, AND LOCKD CLIENTS
|
||||
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
|
||||
S: Maintained
|
||||
W: http://client.linux-nfs.org
|
||||
|
@ -177,6 +177,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
|
||||
INIT_LIST_HEAD(&clp->cl_superblocks);
|
||||
clp->cl_rpcclient = ERR_PTR(-EINVAL);
|
||||
|
||||
clp->cl_flags = cl_init->init_flags;
|
||||
clp->cl_proto = cl_init->proto;
|
||||
clp->cl_nconnect = cl_init->nconnect;
|
||||
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)
|
||||
list_add_tail(&new->cl_share_link,
|
||||
&nn->nfs_client_list);
|
||||
spin_unlock(&nn->nfs_client_lock);
|
||||
new->cl_flags = cl_init->init_flags;
|
||||
return rpc_ops->init_client(new, cl_init);
|
||||
}
|
||||
|
||||
|
24
fs/nfs/dir.c
24
fs/nfs/dir.c
@ -80,6 +80,7 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir
|
||||
ctx->dir_cookie = 0;
|
||||
ctx->dup_cookie = 0;
|
||||
ctx->page_index = 0;
|
||||
ctx->eof = false;
|
||||
spin_lock(&dir->i_lock);
|
||||
if (list_empty(&nfsi->open_files) &&
|
||||
(nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
|
||||
@ -168,6 +169,7 @@ struct nfs_readdir_descriptor {
|
||||
unsigned int cache_entry_index;
|
||||
signed char duped;
|
||||
bool plus;
|
||||
bool eob;
|
||||
bool eof;
|
||||
};
|
||||
|
||||
@ -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,
|
||||
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);
|
||||
out:
|
||||
@ -988,7 +991,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
|
||||
ent = &array->array[i];
|
||||
if (!dir_emit(desc->ctx, ent->name, ent->name_len,
|
||||
nfs_compat_user_ino64(ent->ino), ent->d_type)) {
|
||||
desc->eof = true;
|
||||
desc->eob = true;
|
||||
break;
|
||||
}
|
||||
memcpy(desc->verf, verf, sizeof(desc->verf));
|
||||
@ -1004,7 +1007,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
|
||||
desc->duped = 1;
|
||||
}
|
||||
if (array->page_is_eof)
|
||||
desc->eof = true;
|
||||
desc->eof = !desc->eob;
|
||||
|
||||
kunmap(desc->page);
|
||||
dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %llu\n",
|
||||
@ -1041,12 +1044,13 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
|
||||
goto out;
|
||||
|
||||
desc->page_index = 0;
|
||||
desc->cache_entry_index = 0;
|
||||
desc->last_cookie = desc->dir_cookie;
|
||||
desc->duped = 0;
|
||||
|
||||
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];
|
||||
nfs_do_filldir(desc, verf);
|
||||
}
|
||||
@ -1105,9 +1109,15 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
|
||||
desc->duped = dir_ctx->duped;
|
||||
page_index = dir_ctx->page_index;
|
||||
desc->attr_gencount = dir_ctx->attr_gencount;
|
||||
desc->eof = dir_ctx->eof;
|
||||
memcpy(desc->verf, dir_ctx->verf, sizeof(desc->verf));
|
||||
spin_unlock(&file->f_lock);
|
||||
|
||||
if (desc->eof) {
|
||||
res = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(NFS_INO_FORCE_READDIR, &nfsi->flags) &&
|
||||
list_is_singular(&nfsi->open_files))
|
||||
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)
|
||||
|
||||
nfs_do_filldir(desc, nfsi->cookieverf);
|
||||
nfs_readdir_page_unlock_and_put_cached(desc);
|
||||
} while (!desc->eof);
|
||||
} while (!desc->eob && !desc->eof);
|
||||
|
||||
spin_lock(&file->f_lock);
|
||||
dir_ctx->dir_cookie = desc->dir_cookie;
|
||||
@ -1149,9 +1159,10 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
|
||||
dir_ctx->duped = desc->duped;
|
||||
dir_ctx->attr_gencount = desc->attr_gencount;
|
||||
dir_ctx->page_index = desc->page_index;
|
||||
dir_ctx->eof = desc->eof;
|
||||
memcpy(dir_ctx->verf, desc->verf, sizeof(dir_ctx->verf));
|
||||
spin_unlock(&file->f_lock);
|
||||
|
||||
out_free:
|
||||
kfree(desc);
|
||||
|
||||
out:
|
||||
@ -1193,6 +1204,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
|
||||
if (offset == 0)
|
||||
memset(dir_ctx->verf, 0, sizeof(dir_ctx->verf));
|
||||
dir_ctx->duped = 0;
|
||||
dir_ctx->eof = false;
|
||||
}
|
||||
spin_unlock(&filp->f_lock);
|
||||
return offset;
|
||||
|
@ -8032,7 +8032,8 @@ static int _nfs41_proc_get_locations(struct nfs_server *server,
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @page: buffer
|
||||
* @cred: credential to use for this operation
|
||||
|
@ -107,6 +107,7 @@ struct nfs_open_dir_context {
|
||||
__u64 dup_cookie;
|
||||
pgoff_t page_index;
|
||||
signed char duped;
|
||||
bool eof;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ret = sprintf(buf, "%pISc\n", &saddr);
|
||||
out:
|
||||
mutex_unlock(&sock->recv_mutex);
|
||||
xprt_put(xprt);
|
||||
return ret + 1;
|
||||
}
|
||||
|
@ -413,6 +413,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(ep->re_attr.send_cq)) {
|
||||
rc = PTR_ERR(ep->re_attr.send_cq);
|
||||
ep->re_attr.send_cq = NULL;
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
@ -421,6 +422,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(ep->re_attr.recv_cq)) {
|
||||
rc = PTR_ERR(ep->re_attr.recv_cq);
|
||||
ep->re_attr.recv_cq = NULL;
|
||||
goto out_destroy;
|
||||
}
|
||||
ep->re_receive_count = 0;
|
||||
@ -459,6 +461,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
|
||||
ep->re_pd = ib_alloc_pd(device, 0);
|
||||
if (IS_ERR(ep->re_pd)) {
|
||||
rc = PTR_ERR(ep->re_pd);
|
||||
ep->re_pd = NULL;
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
|
@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport)
|
||||
unsigned short get_srcport(struct rpc_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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user