* [PATCH AUTOSEL 5.15 02/41] NFSv4 only print the label when its queried
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 03/41] nfs: nfs4clinet: check the return value of kstrdup() Sasha Levin
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit 2c52c8376db7160a1dd8a681c61c9258405ef143 ]
When the bitmask of the attributes doesn't include the security label,
don't bother printing it. Since the label might not be null terminated,
adjust the printing format accordingly.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4xdr.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index a8cff19c6f00c..5e886518f2d45 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4197,10 +4197,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
} else
printk(KERN_WARNING "%s: label too long (%u)!\n",
__func__, len);
+ if (label && label->label)
+ dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n",
+ __func__, label->len, (char *)label->label,
+ label->len, label->pi, label->lfs);
}
- if (label && label->label)
- dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__,
- (char *)label->label, label->len, label->pi, label->lfs);
return status;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 03/41] nfs: nfs4clinet: check the return value of kstrdup()
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 02/41] NFSv4 only print the label when its queried Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 04/41] NFSv4.1: Fix uninitialised variable in devicenotify Sasha Levin
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Xiaoke Wang, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Xiaoke Wang <xkernel.wang@foxmail.com>
[ Upstream commit fbd2057e5329d3502a27491190237b6be52a1cb6 ]
kstrdup() returns NULL when some internal memory errors happen, it is
better to check the return value of it so to catch the memory error in
time.
Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4client.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index af57332503bed..ed06b68b2b4e9 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -1368,8 +1368,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
}
nfs_put_client(clp);
- if (server->nfs_client->cl_hostname == NULL)
+ if (server->nfs_client->cl_hostname == NULL) {
server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
+ if (server->nfs_client->cl_hostname == NULL)
+ return -ENOMEM;
+ }
nfs_server_insert_lists(server);
return nfs_probe_destination(server);
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 04/41] NFSv4.1: Fix uninitialised variable in devicenotify
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 02/41] NFSv4 only print the label when its queried Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 03/41] nfs: nfs4clinet: check the return value of kstrdup() Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 06/41] NFSv4 remove zero number of fs_locations entries error check Sasha Levin
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Trond Myklebust, rtm, Anna Schumaker, Sasha Levin, anna.schumaker,
linux-nfs
From: Trond Myklebust <trond.myklebust@hammerspace.com>
[ Upstream commit b05bf5c63b326ce1da84ef42498d8e0e292e694c ]
When decode_devicenotify_args() exits with no entries, we need to
ensure that the struct cb_devicenotifyargs is initialised to
{ 0, NULL } in order to avoid problems in
nfs4_callback_devicenotify().
Reported-by: <rtm@csail.mit.edu>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/callback.h | 2 +-
fs/nfs/callback_proc.c | 2 +-
fs/nfs/callback_xdr.c | 18 +++++++++---------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 6a2033131c068..ccd4f245cae24 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -170,7 +170,7 @@ struct cb_devicenotifyitem {
};
struct cb_devicenotifyargs {
- int ndevs;
+ uint32_t ndevs;
struct cb_devicenotifyitem *devs;
};
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index ed9d580826f5a..f2bc5b5b764b7 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -358,7 +358,7 @@ __be32 nfs4_callback_devicenotify(void *argp, void *resp,
struct cb_process_state *cps)
{
struct cb_devicenotifyargs *args = argp;
- int i;
+ uint32_t i;
__be32 res = 0;
struct nfs_client *clp = cps->clp;
struct nfs_server *server = NULL;
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 4c48d85f65170..ce3d1d5b1291f 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -258,11 +258,9 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
void *argp)
{
struct cb_devicenotifyargs *args = argp;
+ uint32_t tmp, n, i;
__be32 *p;
__be32 status = 0;
- u32 tmp;
- int n, i;
- args->ndevs = 0;
/* Num of device notifications */
p = xdr_inline_decode(xdr, sizeof(uint32_t));
@@ -271,7 +269,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
goto out;
}
n = ntohl(*p++);
- if (n <= 0)
+ if (n == 0)
goto out;
if (n > ULONG_MAX / sizeof(*args->devs)) {
status = htonl(NFS4ERR_BADXDR);
@@ -330,19 +328,21 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
dev->cbd_immediate = 0;
}
- args->ndevs++;
-
dprintk("%s: type %d layout 0x%x immediate %d\n",
__func__, dev->cbd_notify_type, dev->cbd_layout_type,
dev->cbd_immediate);
}
+ args->ndevs = n;
+ dprintk("%s: ndevs %d\n", __func__, args->ndevs);
+ return 0;
+err:
+ kfree(args->devs);
out:
+ args->devs = NULL;
+ args->ndevs = 0;
dprintk("%s: status %d ndevs %d\n",
__func__, ntohl(status), args->ndevs);
return status;
-err:
- kfree(args->devs);
- goto out;
}
static __be32 decode_sessionid(struct xdr_stream *xdr,
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 06/41] NFSv4 remove zero number of fs_locations entries error check
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (2 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 04/41] NFSv4.1: Fix uninitialised variable in devicenotify Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 07/41] NFSv4 store server support for fs_location attribute Sasha Levin
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit 90e12a3191040bd3854d3e236c35921e4e92a044 ]
Remove the check for the zero length fs_locations reply in the
xdr decoding, and instead check for that in the migration code.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4state.c | 3 +++
fs/nfs/nfs4xdr.c | 2 --
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f22818a80c2c7..acc1cd3e63a48 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -2105,6 +2105,9 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
}
result = -NFS4ERR_NXIO;
+ if (!locations->nlocations)
+ goto out;
+
if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) {
dprintk("<-- %s: No fs_locations data, migration skipped\n",
__func__);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5e886518f2d45..2a1bf0a72d5bf 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3693,8 +3693,6 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
if (unlikely(!p))
goto out_eio;
n = be32_to_cpup(p);
- if (n <= 0)
- goto out_eio;
for (res->nlocations = 0; res->nlocations < n; res->nlocations++) {
u32 m;
struct nfs4_fs_location *loc;
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 07/41] NFSv4 store server support for fs_location attribute
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (3 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 06/41] NFSv4 remove zero number of fs_locations entries error check Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 08/41] NFSv4.1 query for fs_location attr on a new file system Sasha Levin
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit 8a59bb93b7e3cca389af44781a429ac12ac49be6 ]
Define and store if server returns it supports fs_locations attribute
as a capability.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4proc.c | 2 ++
include/linux/nfs_fs_sb.h | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 443eab71c9a9e..367a1b99b7550 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3894,6 +3894,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
server->caps |= NFS_CAP_SECURITY_LABEL;
#endif
+ if (res.attr_bitmask[0] & FATTR4_WORD0_FS_LOCATIONS)
+ server->caps |= NFS_CAP_FS_LOCATIONS;
if (!(res.attr_bitmask[0] & FATTR4_WORD0_FILEID))
server->fattr_valid &= ~NFS_ATTR_FATTR_FILEID;
if (!(res.attr_bitmask[1] & FATTR4_WORD1_MODE))
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 2a9acbfe00f0f..9a6e70ccde56e 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -287,5 +287,5 @@ struct nfs_server {
#define NFS_CAP_COPY_NOTIFY (1U << 27)
#define NFS_CAP_XATTR (1U << 28)
#define NFS_CAP_READ_PLUS (1U << 29)
-
+#define NFS_CAP_FS_LOCATIONS (1U << 30)
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 08/41] NFSv4.1 query for fs_location attr on a new file system
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (4 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 07/41] NFSv4 store server support for fs_location attribute Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 09/41] NFSv4 expose nfs_parse_server_name function Sasha Levin
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit 1976b2b31462151403c9fc110204fcc2a77bdfd1 ]
Query the server for other possible trunkable locations for a given
file system on a 4.1+ mount.
v2:
-- added missing static to nfs4_discover_trunking,
reported by the kernel test robot
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/client.c | 7 ++++
fs/nfs/nfs4_fs.h | 9 ++---
fs/nfs/nfs4proc.c | 76 +++++++++++++++++++++++++++++++++++------
fs/nfs/nfs4state.c | 3 +-
include/linux/nfs_xdr.h | 1 +
5 files changed, 81 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 23e165d5ec9ca..d7a8636581266 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -860,6 +860,13 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
server->namelen = pathinfo.max_namelen;
}
+ if (clp->rpc_ops->discover_trunking != NULL &&
+ (server->caps & NFS_CAP_FS_LOCATIONS)) {
+ error = clp->rpc_ops->discover_trunking(server, mntfh);
+ if (error < 0)
+ return error;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ba78df4b13d94..1a048ee653a11 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -261,8 +261,8 @@ struct nfs4_state_maintenance_ops {
};
struct nfs4_mig_recovery_ops {
- int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
- struct page *, const struct cred *);
+ int (*get_locations)(struct nfs_server *, struct nfs_fh *,
+ struct nfs4_fs_locations *, struct page *, const struct cred *);
int (*fsid_present)(struct inode *, const struct cred *);
};
@@ -303,8 +303,9 @@ extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
struct nfs4_fs_locations *, struct page *);
-extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
- struct page *page, const struct cred *);
+extern int nfs4_proc_get_locations(struct nfs_server *, struct nfs_fh *,
+ struct nfs4_fs_locations *,
+ struct page *page, const struct cred *);
extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *,
struct dentry *,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 367a1b99b7550..389fa72d4ca98 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3952,6 +3952,60 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
return err;
}
+static int _nfs4_discover_trunking(struct nfs_server *server,
+ struct nfs_fh *fhandle)
+{
+ struct nfs4_fs_locations *locations = NULL;
+ struct page *page;
+ const struct cred *cred;
+ struct nfs_client *clp = server->nfs_client;
+ const struct nfs4_state_maintenance_ops *ops =
+ clp->cl_mvops->state_renewal_ops;
+ int status = -ENOMEM;
+
+ cred = ops->get_state_renewal_cred(clp);
+ if (cred == NULL) {
+ cred = nfs4_get_clid_cred(clp);
+ if (cred == NULL)
+ return -ENOKEY;
+ }
+
+ page = alloc_page(GFP_KERNEL);
+ locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
+ if (page == NULL || locations == NULL)
+ goto out;
+
+ status = nfs4_proc_get_locations(server, fhandle, locations, page,
+ cred);
+ if (status)
+ goto out;
+out:
+ if (page)
+ __free_page(page);
+ kfree(locations);
+ return status;
+}
+
+static int nfs4_discover_trunking(struct nfs_server *server,
+ struct nfs_fh *fhandle)
+{
+ struct nfs4_exception exception = {
+ .interruptible = true,
+ };
+ struct nfs_client *clp = server->nfs_client;
+ int err = 0;
+
+ if (!nfs4_has_session(clp))
+ goto out;
+ do {
+ err = nfs4_handle_exception(server,
+ _nfs4_discover_trunking(server, fhandle),
+ &exception);
+ } while (exception.retry);
+out:
+ return err;
+}
+
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fsinfo *info)
{
@@ -7886,18 +7940,18 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
* appended to this compound to identify the client ID which is
* performing recovery.
*/
-static int _nfs40_proc_get_locations(struct inode *inode,
+static int _nfs40_proc_get_locations(struct nfs_server *server,
+ struct nfs_fh *fhandle,
struct nfs4_fs_locations *locations,
struct page *page, const struct cred *cred)
{
- struct nfs_server *server = NFS_SERVER(inode);
struct rpc_clnt *clnt = server->client;
u32 bitmask[2] = {
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
};
struct nfs4_fs_locations_arg args = {
.clientid = server->nfs_client->cl_clientid,
- .fh = NFS_FH(inode),
+ .fh = fhandle,
.page = page,
.bitmask = bitmask,
.migration = 1, /* skip LOOKUP */
@@ -7943,17 +7997,17 @@ static int _nfs40_proc_get_locations(struct inode *inode,
* When the client supports GETATTR(fs_locations_info), it can
* be plumbed in here.
*/
-static int _nfs41_proc_get_locations(struct inode *inode,
+static int _nfs41_proc_get_locations(struct nfs_server *server,
+ struct nfs_fh *fhandle,
struct nfs4_fs_locations *locations,
struct page *page, const struct cred *cred)
{
- struct nfs_server *server = NFS_SERVER(inode);
struct rpc_clnt *clnt = server->client;
u32 bitmask[2] = {
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
};
struct nfs4_fs_locations_arg args = {
- .fh = NFS_FH(inode),
+ .fh = fhandle,
.page = page,
.bitmask = bitmask,
.migration = 1, /* skip LOOKUP */
@@ -8002,11 +8056,11 @@ static int _nfs41_proc_get_locations(struct inode *inode,
* -NFS4ERR_LEASE_MOVED is returned if the server still has leases
* from this client that require migration recovery.
*/
-int nfs4_proc_get_locations(struct inode *inode,
+int nfs4_proc_get_locations(struct nfs_server *server,
+ struct nfs_fh *fhandle,
struct nfs4_fs_locations *locations,
struct page *page, const struct cred *cred)
{
- struct nfs_server *server = NFS_SERVER(inode);
struct nfs_client *clp = server->nfs_client;
const struct nfs4_mig_recovery_ops *ops =
clp->cl_mvops->mig_recovery_ops;
@@ -8019,10 +8073,11 @@ int nfs4_proc_get_locations(struct inode *inode,
(unsigned long long)server->fsid.major,
(unsigned long long)server->fsid.minor,
clp->cl_hostname);
- nfs_display_fhandle(NFS_FH(inode), __func__);
+ nfs_display_fhandle(fhandle, __func__);
do {
- status = ops->get_locations(inode, locations, page, cred);
+ status = ops->get_locations(server, fhandle, locations, page,
+ cred);
if (status != -NFS4ERR_DELAY)
break;
nfs4_handle_exception(server, status, &exception);
@@ -10516,6 +10571,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.free_client = nfs4_free_client,
.create_server = nfs4_create_server,
.clone_server = nfs_clone_server,
+ .discover_trunking = nfs4_discover_trunking,
};
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index acc1cd3e63a48..51f5cb41e87a4 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -2097,7 +2097,8 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
}
inode = d_inode(server->super->s_root);
- result = nfs4_proc_get_locations(inode, locations, page, cred);
+ result = nfs4_proc_get_locations(server, NFS_FH(inode), locations,
+ page, cred);
if (result) {
dprintk("<-- %s: failed to retrieve fs_locations: %d\n",
__func__, result);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index e9698b6278a52..ecd74cc347974 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1805,6 +1805,7 @@ struct nfs_rpc_ops {
struct nfs_server *(*create_server)(struct fs_context *);
struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
struct nfs_fattr *, rpc_authflavor_t);
+ int (*discover_trunking)(struct nfs_server *, struct nfs_fh *);
};
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 09/41] NFSv4 expose nfs_parse_server_name function
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (5 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 08/41] NFSv4.1 query for fs_location attr on a new file system Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 10/41] NFSv4 handle port presence in fs_location server string Sasha Levin
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit f5b27cc6761e27ee6387a24df1a99ca77b360fea ]
Make nfs_parse_server_name available outside of nfs4namespace.c.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4_fs.h | 3 ++-
fs/nfs/nfs4namespace.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 1a048ee653a11..0eb8e5d2ec395 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -281,7 +281,8 @@ struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *,
int nfs4_submount(struct fs_context *, struct nfs_server *);
int nfs4_replace_transport(struct nfs_server *server,
const struct nfs4_fs_locations *locations);
-
+size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
+ size_t salen, struct net *net);
/* nfs4proc.c */
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
extern int nfs4_async_handle_error(struct rpc_task *task,
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 873342308dc0d..f1ed4f60a7f33 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -164,8 +164,8 @@ static int nfs4_validate_fspath(struct dentry *dentry,
return 0;
}
-static size_t nfs_parse_server_name(char *string, size_t len,
- struct sockaddr *sa, size_t salen, struct net *net)
+size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
+ size_t salen, struct net *net)
{
ssize_t ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 10/41] NFSv4 handle port presence in fs_location server string
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (6 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 09/41] NFSv4 expose nfs_parse_server_name function Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 11/41] SUNRPC allow for unspecified transport time in rpc_clnt_add_xprt Sasha Levin
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, linux-nfs
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit a8d54baba7c65db2d3278873def61f8d3753d766 ]
An fs_location attribute returns a string that can be ipv4, ipv6,
or DNS name. An ip location can have a port appended to it and if
no port is present a default port needs to be set. If rpc_pton()
fails to parse, try calling rpc_uaddr2socaddr() that can convert
an universal address.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/nfs4_fs.h | 2 +-
fs/nfs/nfs4namespace.c | 17 +++++++++++------
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 0eb8e5d2ec395..f8672a34fd635 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -282,7 +282,7 @@ int nfs4_submount(struct fs_context *, struct nfs_server *);
int nfs4_replace_transport(struct nfs_server *server,
const struct nfs4_fs_locations *locations);
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
- size_t salen, struct net *net);
+ size_t salen, struct net *net, int port);
/* nfs4proc.c */
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
extern int nfs4_async_handle_error(struct rpc_task *task,
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index f1ed4f60a7f33..3680c8da510c9 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -165,15 +165,20 @@ static int nfs4_validate_fspath(struct dentry *dentry,
}
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
- size_t salen, struct net *net)
+ size_t salen, struct net *net, int port)
{
ssize_t ret;
ret = rpc_pton(net, string, len, sa, salen);
if (ret == 0) {
- ret = nfs_dns_resolve_name(net, string, len, sa, salen);
- if (ret < 0)
- ret = 0;
+ ret = rpc_uaddr2sockaddr(net, string, len, sa, salen);
+ if (ret == 0) {
+ ret = nfs_dns_resolve_name(net, string, len, sa, salen);
+ if (ret < 0)
+ ret = 0;
+ }
+ } else if (port) {
+ rpc_set_port(sa, port);
}
return ret;
}
@@ -328,7 +333,7 @@ static int try_location(struct fs_context *fc,
nfs_parse_server_name(buf->data, buf->len,
&ctx->nfs_server.address,
sizeof(ctx->nfs_server._address),
- fc->net_ns);
+ fc->net_ns, 0);
if (ctx->nfs_server.addrlen == 0)
continue;
@@ -496,7 +501,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server,
continue;
salen = nfs_parse_server_name(buf->data, buf->len,
- sap, addr_bufsize, net);
+ sap, addr_bufsize, net, 0);
if (salen == 0)
continue;
rpc_set_port(sap, NFS_PORT);
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 11/41] SUNRPC allow for unspecified transport time in rpc_clnt_add_xprt
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (7 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 10/41] NFSv4 handle port presence in fs_location server string Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 12/41] net/sunrpc: fix reference count leaks in rpc_sysfs_xprt_state_change Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 13/41] sunrpc: Fix potential race conditions in rpc_sysfs_xprt_state_change() Sasha Levin
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Olga Kornievskaia, Anna Schumaker, Sasha Levin, trond.myklebust,
anna.schumaker, chuck.lever, davem, kuba, linux-nfs, netdev
From: Olga Kornievskaia <kolga@netapp.com>
[ Upstream commit b8a09619a56334414cbd7f935a0796240d0cc07e ]
If the supplied argument doesn't specify the transport type, use the
type of the existing rpc clnt and its existing transport.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/clnt.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f056ff9314442..5da1d7e8468a5 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2903,7 +2903,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
unsigned long connect_timeout;
unsigned long reconnect_timeout;
unsigned char resvport, reuseport;
- int ret = 0;
+ int ret = 0, ident;
rcu_read_lock();
xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
@@ -2917,8 +2917,11 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
reuseport = xprt->reuseport;
connect_timeout = xprt->connect_timeout;
reconnect_timeout = xprt->max_reconnect_timeout;
+ ident = xprt->xprt_class->ident;
rcu_read_unlock();
+ if (!xprtargs->ident)
+ xprtargs->ident = ident;
xprt = xprt_create_transport(xprtargs);
if (IS_ERR(xprt)) {
ret = PTR_ERR(xprt);
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 12/41] net/sunrpc: fix reference count leaks in rpc_sysfs_xprt_state_change
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (8 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 11/41] SUNRPC allow for unspecified transport time in rpc_clnt_add_xprt Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 13/41] sunrpc: Fix potential race conditions in rpc_sysfs_xprt_state_change() Sasha Levin
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Xiyu Yang, Xin Xiong, Xin Tan, Anna Schumaker, Sasha Levin,
trond.myklebust, anna.schumaker, chuck.lever, davem, kuba,
linux-nfs, netdev
From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
[ Upstream commit 776d794f28c95051bc70405a7b1fa40115658a18 ]
The refcount leak issues take place in an error handling path. When the
3rd argument buf doesn't match with "offline", "online" or "remove", the
function simply returns -EINVAL and forgets to decrease the reference
count of a rpc_xprt object and a rpc_xprt_switch object increased by
rpc_sysfs_xprt_kobj_get_xprt() and
rpc_sysfs_xprt_kobj_get_xprt_switch(), causing reference count leaks of
both unused objects.
Fix this issue by jumping to the error handling path labelled with
out_put when buf matches none of "offline", "online" or "remove".
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Xin Xiong <xiongx18@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/sysfs.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
index 9a6f17e18f73b..379cf0e4d965b 100644
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -291,8 +291,10 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
online = 1;
else if (!strncmp(buf, "remove", 6))
remove = 1;
- else
- return -EINVAL;
+ else {
+ count = -EINVAL;
+ goto out_put;
+ }
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE)) {
count = -EINTR;
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH AUTOSEL 5.15 13/41] sunrpc: Fix potential race conditions in rpc_sysfs_xprt_state_change()
2022-02-03 20:32 [PATCH AUTOSEL 5.15 01/41] NFS: change nfs_access_get_cached to only report the mask Sasha Levin
` (9 preceding siblings ...)
2022-02-03 20:32 ` [PATCH AUTOSEL 5.15 12/41] net/sunrpc: fix reference count leaks in rpc_sysfs_xprt_state_change Sasha Levin
@ 2022-02-03 20:32 ` Sasha Levin
10 siblings, 0 replies; 12+ messages in thread
From: Sasha Levin @ 2022-02-03 20:32 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Anna Schumaker, Sasha Levin, trond.myklebust, anna.schumaker,
chuck.lever, davem, kuba, linux-nfs, netdev
From: Anna Schumaker <Anna.Schumaker@Netapp.com>
[ Upstream commit 1a48db3fef499f615b56093947ec4b0d3d8e3021 ]
We need to use test_and_set_bit() when changing xprt state flags to
avoid potentially getting xps->xps_nactive out of sync.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sunrpc/sysfs.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
index 379cf0e4d965b..326a31422a3c1 100644
--- a/net/sunrpc/sysfs.c
+++ b/net/sunrpc/sysfs.c
@@ -305,25 +305,28 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
goto release_tasks;
}
if (offline) {
- set_bit(XPRT_OFFLINE, &xprt->state);
- spin_lock(&xps->xps_lock);
- xps->xps_nactive--;
- spin_unlock(&xps->xps_lock);
+ if (!test_and_set_bit(XPRT_OFFLINE, &xprt->state)) {
+ spin_lock(&xps->xps_lock);
+ xps->xps_nactive--;
+ spin_unlock(&xps->xps_lock);
+ }
} else if (online) {
- clear_bit(XPRT_OFFLINE, &xprt->state);
- spin_lock(&xps->xps_lock);
- xps->xps_nactive++;
- spin_unlock(&xps->xps_lock);
+ if (test_and_clear_bit(XPRT_OFFLINE, &xprt->state)) {
+ spin_lock(&xps->xps_lock);
+ xps->xps_nactive++;
+ spin_unlock(&xps->xps_lock);
+ }
} else if (remove) {
if (test_bit(XPRT_OFFLINE, &xprt->state)) {
- set_bit(XPRT_REMOVE, &xprt->state);
- xprt_force_disconnect(xprt);
- if (test_bit(XPRT_CONNECTED, &xprt->state)) {
- if (!xprt->sending.qlen &&
- !xprt->pending.qlen &&
- !xprt->backlog.qlen &&
- !atomic_long_read(&xprt->queuelen))
- rpc_xprt_switch_remove_xprt(xps, xprt);
+ if (!test_and_set_bit(XPRT_REMOVE, &xprt->state)) {
+ xprt_force_disconnect(xprt);
+ if (test_bit(XPRT_CONNECTED, &xprt->state)) {
+ if (!xprt->sending.qlen &&
+ !xprt->pending.qlen &&
+ !xprt->backlog.qlen &&
+ !atomic_long_read(&xprt->queuelen))
+ rpc_xprt_switch_remove_xprt(xps, xprt);
+ }
}
} else {
count = -EINVAL;
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread