NFS Client Bugfixes for Linux 6.1-rc

Bugfixes:
   * Fix some coccicheck warnings
   * Avoid memcpy() run-time warning
   * Fix up various state reclaim / RECLAIM_COMPLETE errors
   * Fix a null pointer dereference in sysfs
   * Fix LOCK races
   * Fix gss_unwrap_resp_integ() crasher
   * Fix zero length clones
   * Fix memleak when allocate slot fails
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEnZ5MQTpR7cLU7KEp18tUv7ClQOsFAmNil9kACgkQ18tUv7Cl
 QOvr2BAA3piO9HMIWIqCbewSIeotzzjdeYSh5qZ7GqRmsz7/KSvN28+dxaXlJVs1
 Vi646NHKsp5rkqXK10su+AjtDDER3P9ybOlZyNkwz6AzkAbpBIreKOqd7AV/mJ0d
 kZv8rdJSaDUlsAjnCcaTyjAr9qdT2olI6gSdPXdVjBkbbNcxtygxAToA0Bw1tTBr
 pP7pSYXbdbl1tZYe5fuvZdbhVRLggrcIYpvSrSho05iFHz5MZIc7g50uvr13Tv4Y
 A0tZg0YCHoxKcAvTjh2M7pjEOzCvBGP9an3me260PljCm+AwFXTQLBLAvHeGm7D5
 sflS60T5rlLBwqvZXa4efXvhWJJTnkQxDLrUKCgoUgLAVuzYrq6oTRUtOgBHnl18
 mj8MR3EHh/t4Y+c7AURK+wBzBaxg02ltUYWVjUT0k1+pDzaFVjnNzEvX+1Nj3Rm/
 Ib4D8zsditwHuug7A95ALNhwLjxBYqJS3b8okn0vIvpKxvLa6jjvXXN2ggDOUQWY
 wfKVa7A3dBmKBWh/uu5s/P5q6pTxYdc9fZUaJZoEXwjYcGXVpfUqeaQGl/IMv4Xp
 Qir8nlcEPGGU4eD8Byl2Fr01NsnHDNDD8QdvJcI+mqy7p1ZPOrqiXYckZdjPIcz2
 4EpjY+IDoOlnPW9FWq+EeyuZVc60rvun4qHfMsf54MGRT8qSaoI=
 =iGEB
 -----END PGP SIGNATURE-----

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

Pull NFS client bugfixes from Anna Schumaker:

 - Fix some coccicheck warnings

 - Avoid memcpy() run-time warning

 - Fix up various state reclaim / RECLAIM_COMPLETE errors

 - Fix a null pointer dereference in sysfs

 - Fix LOCK races

 - Fix gss_unwrap_resp_integ() crasher

 - Fix zero length clones

 - Fix memleak when allocate slot fails

* tag 'nfs-for-6.1-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  nfs4: Fix kmemleak when allocate slot failed
  NFSv4.2: Fixup CLONE dest file size for zero-length count
  SUNRPC: Fix crasher in gss_unwrap_resp_integ()
  NFSv4: Retry LOCK on OLD_STATEID during delegation return
  SUNRPC: Fix null-ptr-deref when xps sysfs alloc failed
  NFSv4.1: We must always send RECLAIM_COMPLETE after a reboot
  NFSv4.1: Handle RECLAIM_COMPLETE trunking errors
  NFSv4: Fix a potential state reclaim deadlock
  NFS: Avoid memcpy() run-time warning for struct sockaddr overflows
  nfs: Remove redundant null checks before kfree
This commit is contained in:
Linus Torvalds 2022-11-02 11:18:13 -07:00
commit 31fc92fc93
20 changed files with 91 additions and 78 deletions

View file

@ -280,7 +280,7 @@ EXPORT_SYMBOL_GPL(nfs_put_client);
static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
{ {
struct nfs_client *clp; struct nfs_client *clp;
const struct sockaddr *sap = data->addr; const struct sockaddr *sap = (struct sockaddr *)data->addr;
struct nfs_net *nn = net_generic(data->net, nfs_net_id); struct nfs_net *nn = net_generic(data->net, nfs_net_id);
int error; int error;
@ -666,7 +666,7 @@ static int nfs_init_server(struct nfs_server *server,
struct rpc_timeout timeparms; struct rpc_timeout timeparms;
struct nfs_client_initdata cl_init = { struct nfs_client_initdata cl_init = {
.hostname = ctx->nfs_server.hostname, .hostname = ctx->nfs_server.hostname,
.addr = (const struct sockaddr *)&ctx->nfs_server.address, .addr = &ctx->nfs_server._address,
.addrlen = ctx->nfs_server.addrlen, .addrlen = ctx->nfs_server.addrlen,
.nfs_mod = ctx->nfs_mod, .nfs_mod = ctx->nfs_mod,
.proto = ctx->nfs_server.protocol, .proto = ctx->nfs_server.protocol,

View file

@ -228,8 +228,7 @@ again:
* *
*/ */
void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
fmode_t type, fmode_t type, const nfs4_stateid *stateid,
const nfs4_stateid *stateid,
unsigned long pagemod_limit) unsigned long pagemod_limit)
{ {
struct nfs_delegation *delegation; struct nfs_delegation *delegation;
@ -239,25 +238,24 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
delegation = rcu_dereference(NFS_I(inode)->delegation); delegation = rcu_dereference(NFS_I(inode)->delegation);
if (delegation != NULL) { if (delegation != NULL) {
spin_lock(&delegation->lock); spin_lock(&delegation->lock);
if (nfs4_is_valid_delegation(delegation, 0)) { nfs4_stateid_copy(&delegation->stateid, stateid);
nfs4_stateid_copy(&delegation->stateid, stateid); delegation->type = type;
delegation->type = type; delegation->pagemod_limit = pagemod_limit;
delegation->pagemod_limit = pagemod_limit; oldcred = delegation->cred;
oldcred = delegation->cred; delegation->cred = get_cred(cred);
delegation->cred = get_cred(cred); clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
clear_bit(NFS_DELEGATION_NEED_RECLAIM, if (test_and_clear_bit(NFS_DELEGATION_REVOKED,
&delegation->flags); &delegation->flags))
spin_unlock(&delegation->lock); atomic_long_inc(&nfs_active_delegations);
rcu_read_unlock();
put_cred(oldcred);
trace_nfs4_reclaim_delegation(inode, type);
return;
}
/* We appear to have raced with a delegation return. */
spin_unlock(&delegation->lock); spin_unlock(&delegation->lock);
rcu_read_unlock();
put_cred(oldcred);
trace_nfs4_reclaim_delegation(inode, type);
} else {
rcu_read_unlock();
nfs_inode_set_delegation(inode, cred, type, stateid,
pagemod_limit);
} }
rcu_read_unlock();
nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit);
} }
static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)

View file

@ -2489,9 +2489,8 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
goto out; goto out;
} }
if (dentry->d_fsdata) /* old devname */
/* old devname */ kfree(dentry->d_fsdata);
kfree(dentry->d_fsdata);
dentry->d_fsdata = NFS_FSDATA_BLOCKED; dentry->d_fsdata = NFS_FSDATA_BLOCKED;
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);

View file

@ -16,8 +16,9 @@
#include "dns_resolve.h" #include "dns_resolve.h"
ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen, ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
struct sockaddr *sa, size_t salen) struct sockaddr_storage *ss, size_t salen)
{ {
struct sockaddr *sa = (struct sockaddr *)ss;
ssize_t ret; ssize_t ret;
char *ip_addr = NULL; char *ip_addr = NULL;
int ip_len; int ip_len;
@ -341,7 +342,7 @@ out:
} }
ssize_t nfs_dns_resolve_name(struct net *net, char *name, ssize_t nfs_dns_resolve_name(struct net *net, char *name,
size_t namelen, struct sockaddr *sa, size_t salen) size_t namelen, struct sockaddr_storage *ss, size_t salen)
{ {
struct nfs_dns_ent key = { struct nfs_dns_ent key = {
.hostname = name, .hostname = name,
@ -354,7 +355,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item); ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item);
if (ret == 0) { if (ret == 0) {
if (salen >= item->addrlen) { if (salen >= item->addrlen) {
memcpy(sa, &item->addr, item->addrlen); memcpy(ss, &item->addr, item->addrlen);
ret = item->addrlen; ret = item->addrlen;
} else } else
ret = -EOVERFLOW; ret = -EOVERFLOW;

View file

@ -32,6 +32,6 @@ extern void nfs_dns_resolver_cache_destroy(struct net *net);
#endif #endif
extern ssize_t nfs_dns_resolve_name(struct net *net, char *name, extern ssize_t nfs_dns_resolve_name(struct net *net, char *name,
size_t namelen, struct sockaddr *sa, size_t salen); size_t namelen, struct sockaddr_storage *sa, size_t salen);
#endif #endif

View file

@ -273,9 +273,9 @@ static const struct constant_table nfs_secflavor_tokens[] = {
* Address family must be initialized, and address must not be * Address family must be initialized, and address must not be
* the ANY address for that family. * the ANY address for that family.
*/ */
static int nfs_verify_server_address(struct sockaddr *addr) static int nfs_verify_server_address(struct sockaddr_storage *addr)
{ {
switch (addr->sa_family) { switch (addr->ss_family) {
case AF_INET: { case AF_INET: {
struct sockaddr_in *sa = (struct sockaddr_in *)addr; struct sockaddr_in *sa = (struct sockaddr_in *)addr;
return sa->sin_addr.s_addr != htonl(INADDR_ANY); return sa->sin_addr.s_addr != htonl(INADDR_ANY);
@ -969,7 +969,7 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
{ {
struct nfs_fs_context *ctx = nfs_fc2context(fc); struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct nfs_fh *mntfh = ctx->mntfh; struct nfs_fh *mntfh = ctx->mntfh;
struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; struct sockaddr_storage *sap = &ctx->nfs_server._address;
int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
int ret; int ret;
@ -1044,7 +1044,7 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
memcpy(sap, &data->addr, sizeof(data->addr)); memcpy(sap, &data->addr, sizeof(data->addr));
ctx->nfs_server.addrlen = sizeof(data->addr); ctx->nfs_server.addrlen = sizeof(data->addr);
ctx->nfs_server.port = ntohs(data->addr.sin_port); ctx->nfs_server.port = ntohs(data->addr.sin_port);
if (sap->sa_family != AF_INET || if (sap->ss_family != AF_INET ||
!nfs_verify_server_address(sap)) !nfs_verify_server_address(sap))
goto out_no_address; goto out_no_address;
@ -1200,7 +1200,7 @@ static int nfs4_parse_monolithic(struct fs_context *fc,
struct nfs4_mount_data *data) struct nfs4_mount_data *data)
{ {
struct nfs_fs_context *ctx = nfs_fc2context(fc); struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; struct sockaddr_storage *sap = &ctx->nfs_server._address;
int ret; int ret;
char *c; char *c;
@ -1314,7 +1314,7 @@ static int nfs_fs_context_validate(struct fs_context *fc)
{ {
struct nfs_fs_context *ctx = nfs_fc2context(fc); struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct nfs_subversion *nfs_mod; struct nfs_subversion *nfs_mod;
struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; struct sockaddr_storage *sap = &ctx->nfs_server._address;
int max_namelen = PAGE_SIZE; int max_namelen = PAGE_SIZE;
int max_pathlen = NFS_MAXPATHLEN; int max_pathlen = NFS_MAXPATHLEN;
int port = 0; int port = 0;
@ -1540,7 +1540,7 @@ static int nfs_init_fs_context(struct fs_context *fc)
ctx->version = nfss->nfs_client->rpc_ops->version; ctx->version = nfss->nfs_client->rpc_ops->version;
ctx->minorversion = nfss->nfs_client->cl_minorversion; ctx->minorversion = nfss->nfs_client->cl_minorversion;
memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr, memcpy(&ctx->nfs_server._address, &nfss->nfs_client->cl_addr,
ctx->nfs_server.addrlen); ctx->nfs_server.addrlen);
if (fc->net_ns != net) { if (fc->net_ns != net) {

View file

@ -69,7 +69,7 @@ static inline fmode_t flags_to_mode(int flags)
struct nfs_client_initdata { struct nfs_client_initdata {
unsigned long init_flags; unsigned long init_flags;
const char *hostname; /* Hostname of the server */ const char *hostname; /* Hostname of the server */
const struct sockaddr *addr; /* Address of the server */ const struct sockaddr_storage *addr; /* Address of the server */
const char *nodename; /* Hostname of the client */ const char *nodename; /* Hostname of the client */
const char *ip_addr; /* IP address of the client */ const char *ip_addr; /* IP address of the client */
size_t addrlen; size_t addrlen;
@ -180,7 +180,7 @@ static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc)
/* mount_clnt.c */ /* mount_clnt.c */
struct nfs_mount_request { struct nfs_mount_request {
struct sockaddr *sap; struct sockaddr_storage *sap;
size_t salen; size_t salen;
char *hostname; char *hostname;
char *dirpath; char *dirpath;
@ -223,7 +223,7 @@ extern void nfs4_server_set_init_caps(struct nfs_server *);
extern struct nfs_server *nfs4_create_server(struct fs_context *); extern struct nfs_server *nfs4_create_server(struct fs_context *);
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *); extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
extern int nfs4_update_server(struct nfs_server *server, const char *hostname, extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
struct sockaddr *sap, size_t salen, struct sockaddr_storage *sap, size_t salen,
struct net *net); struct net *net);
extern void nfs_free_server(struct nfs_server *server); extern void nfs_free_server(struct nfs_server *server);
extern struct nfs_server *nfs_clone_server(struct nfs_server *, extern struct nfs_server *nfs_clone_server(struct nfs_server *,
@ -235,7 +235,7 @@ extern int nfs_client_init_status(const struct nfs_client *clp);
extern int nfs_wait_client_init_complete(const struct nfs_client *clp); extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
extern void nfs_mark_client_ready(struct nfs_client *clp, int state); extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
const struct sockaddr *ds_addr, const struct sockaddr_storage *ds_addr,
int ds_addrlen, int ds_proto, int ds_addrlen, int ds_proto,
unsigned int ds_timeo, unsigned int ds_timeo,
unsigned int ds_retrans, unsigned int ds_retrans,
@ -243,7 +243,7 @@ extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *, extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
struct inode *); struct inode *);
extern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv, extern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
const struct sockaddr *ds_addr, int ds_addrlen, const struct sockaddr_storage *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo, int ds_proto, unsigned int ds_timeo,
unsigned int ds_retrans); unsigned int ds_retrans);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
@ -894,13 +894,13 @@ static inline bool nfs_error_is_fatal_on_server(int err)
* Select between a default port value and a user-specified port value. * Select between a default port value and a user-specified port value.
* If a zero value is set, then autobind will be used. * If a zero value is set, then autobind will be used.
*/ */
static inline void nfs_set_port(struct sockaddr *sap, int *port, static inline void nfs_set_port(struct sockaddr_storage *sap, int *port,
const unsigned short default_port) const unsigned short default_port)
{ {
if (*port == NFS_UNSPEC_PORT) if (*port == NFS_UNSPEC_PORT)
*port = default_port; *port = default_port;
rpc_set_port(sap, *port); rpc_set_port((struct sockaddr *)sap, *port);
} }
struct nfs_direct_req { struct nfs_direct_req {

View file

@ -158,7 +158,7 @@ int nfs_mount(struct nfs_mount_request *info, int timeo, int retrans)
struct rpc_create_args args = { struct rpc_create_args args = {
.net = info->net, .net = info->net,
.protocol = info->protocol, .protocol = info->protocol,
.address = info->sap, .address = (struct sockaddr *)info->sap,
.addrsize = info->salen, .addrsize = info->salen,
.timeout = &mnt_timeout, .timeout = &mnt_timeout,
.servername = info->hostname, .servername = info->hostname,
@ -245,7 +245,7 @@ void nfs_umount(const struct nfs_mount_request *info)
struct rpc_create_args args = { struct rpc_create_args args = {
.net = info->net, .net = info->net,
.protocol = IPPROTO_UDP, .protocol = IPPROTO_UDP,
.address = info->sap, .address = (struct sockaddr *)info->sap,
.addrsize = info->salen, .addrsize = info->salen,
.timeout = &nfs_umnt_timeout, .timeout = &nfs_umnt_timeout,
.servername = info->hostname, .servername = info->hostname,

View file

@ -175,7 +175,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
} }
/* for submounts we want the same server; referrals will reassign */ /* for submounts we want the same server; referrals will reassign */
memcpy(&ctx->nfs_server.address, &client->cl_addr, client->cl_addrlen); memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen);
ctx->nfs_server.addrlen = client->cl_addrlen; ctx->nfs_server.addrlen = client->cl_addrlen;
ctx->nfs_server.port = server->port; ctx->nfs_server.port = server->port;

View file

@ -78,7 +78,7 @@ struct nfs_server *nfs3_clone_server(struct nfs_server *source,
* the MDS. * the MDS.
*/ */
struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv, struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
const struct sockaddr *ds_addr, int ds_addrlen, const struct sockaddr_storage *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans) int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans)
{ {
struct rpc_timeout ds_timeout; struct rpc_timeout ds_timeout;
@ -98,7 +98,7 @@ struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
char buf[INET6_ADDRSTRLEN + 1]; char buf[INET6_ADDRSTRLEN + 1];
/* fake a hostname because lockd wants it */ /* fake a hostname because lockd wants it */
if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0) if (rpc_ntop((struct sockaddr *)ds_addr, buf, sizeof(buf)) <= 0)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
cl_init.hostname = buf; cl_init.hostname = buf;

View file

@ -1093,6 +1093,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
&args.seq_args, &res.seq_res, 0); &args.seq_args, &res.seq_res, 0);
trace_nfs4_clone(src_inode, dst_inode, &args, status); trace_nfs4_clone(src_inode, dst_inode, &args, status);
if (status == 0) { if (status == 0) {
/* a zero-length count means clone to EOF in src */
if (count == 0 && res.dst_fattr->valid & NFS_ATTR_FATTR_SIZE)
count = nfs_size_to_loff_t(res.dst_fattr->size) - dst_offset;
nfs42_copy_dest_done(dst_inode, dst_offset, count); nfs42_copy_dest_done(dst_inode, dst_offset, count);
status = nfs_post_op_update_inode(dst_inode, res.dst_fattr); status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
} }

View file

@ -281,7 +281,7 @@ struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *,
int nfs4_submount(struct fs_context *, struct nfs_server *); int nfs4_submount(struct fs_context *, struct nfs_server *);
int nfs4_replace_transport(struct nfs_server *server, int nfs4_replace_transport(struct nfs_server *server,
const struct nfs4_fs_locations *locations); const struct nfs4_fs_locations *locations);
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa, size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr_storage *ss,
size_t salen, struct net *net, int port); size_t salen, struct net *net, int port);
/* nfs4proc.c */ /* nfs4proc.c */
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *); extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);

View file

@ -346,6 +346,7 @@ int nfs40_init_client(struct nfs_client *clp)
ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE, ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
"NFSv4.0 transport Slot table"); "NFSv4.0 transport Slot table");
if (ret) { if (ret) {
nfs4_shutdown_slot_table(tbl);
kfree(tbl); kfree(tbl);
return ret; return ret;
} }
@ -889,7 +890,7 @@ nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
*/ */
static int nfs4_set_client(struct nfs_server *server, static int nfs4_set_client(struct nfs_server *server,
const char *hostname, const char *hostname,
const struct sockaddr *addr, const struct sockaddr_storage *addr,
const size_t addrlen, const size_t addrlen,
const char *ip_addr, const char *ip_addr,
int proto, const struct rpc_timeout *timeparms, int proto, const struct rpc_timeout *timeparms,
@ -924,7 +925,7 @@ static int nfs4_set_client(struct nfs_server *server,
__set_bit(NFS_CS_MIGRATION, &cl_init.init_flags); __set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status)) if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
__set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags); __set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
server->port = rpc_get_port(addr); server->port = rpc_get_port((struct sockaddr *)addr);
/* Allocate or find a client reference we can use */ /* Allocate or find a client reference we can use */
clp = nfs_get_client(&cl_init); clp = nfs_get_client(&cl_init);
@ -960,7 +961,7 @@ static int nfs4_set_client(struct nfs_server *server,
* the MDS. * the MDS.
*/ */
struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
const struct sockaddr *ds_addr, int ds_addrlen, const struct sockaddr_storage *ds_addr, int ds_addrlen,
int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans, int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans,
u32 minor_version) u32 minor_version)
{ {
@ -980,7 +981,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
}; };
char buf[INET6_ADDRSTRLEN + 1]; char buf[INET6_ADDRSTRLEN + 1];
if (rpc_ntop(ds_addr, buf, sizeof(buf)) <= 0) if (rpc_ntop((struct sockaddr *)ds_addr, buf, sizeof(buf)) <= 0)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
cl_init.hostname = buf; cl_init.hostname = buf;
@ -1148,7 +1149,7 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
/* Get a client record */ /* Get a client record */
error = nfs4_set_client(server, error = nfs4_set_client(server,
ctx->nfs_server.hostname, ctx->nfs_server.hostname,
&ctx->nfs_server.address, &ctx->nfs_server._address,
ctx->nfs_server.addrlen, ctx->nfs_server.addrlen,
ctx->client_address, ctx->client_address,
ctx->nfs_server.protocol, ctx->nfs_server.protocol,
@ -1238,7 +1239,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
rpc_set_port(&ctx->nfs_server.address, NFS_RDMA_PORT); rpc_set_port(&ctx->nfs_server.address, NFS_RDMA_PORT);
error = nfs4_set_client(server, error = nfs4_set_client(server,
ctx->nfs_server.hostname, ctx->nfs_server.hostname,
&ctx->nfs_server.address, &ctx->nfs_server._address,
ctx->nfs_server.addrlen, ctx->nfs_server.addrlen,
parent_client->cl_ipaddr, parent_client->cl_ipaddr,
XPRT_TRANSPORT_RDMA, XPRT_TRANSPORT_RDMA,
@ -1254,7 +1255,7 @@ struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
rpc_set_port(&ctx->nfs_server.address, NFS_PORT); rpc_set_port(&ctx->nfs_server.address, NFS_PORT);
error = nfs4_set_client(server, error = nfs4_set_client(server,
ctx->nfs_server.hostname, ctx->nfs_server.hostname,
&ctx->nfs_server.address, &ctx->nfs_server._address,
ctx->nfs_server.addrlen, ctx->nfs_server.addrlen,
parent_client->cl_ipaddr, parent_client->cl_ipaddr,
XPRT_TRANSPORT_TCP, XPRT_TRANSPORT_TCP,
@ -1303,14 +1304,14 @@ error:
* Returns zero on success, or a negative errno value. * Returns zero on success, or a negative errno value.
*/ */
int nfs4_update_server(struct nfs_server *server, const char *hostname, int nfs4_update_server(struct nfs_server *server, const char *hostname,
struct sockaddr *sap, size_t salen, struct net *net) struct sockaddr_storage *sap, size_t salen, struct net *net)
{ {
struct nfs_client *clp = server->nfs_client; struct nfs_client *clp = server->nfs_client;
struct rpc_clnt *clnt = server->client; struct rpc_clnt *clnt = server->client;
struct xprt_create xargs = { struct xprt_create xargs = {
.ident = clp->cl_proto, .ident = clp->cl_proto,
.net = net, .net = net,
.dstaddr = sap, .dstaddr = (struct sockaddr *)sap,
.addrlen = salen, .addrlen = salen,
.servername = hostname, .servername = hostname,
}; };

View file

@ -164,16 +164,17 @@ static int nfs4_validate_fspath(struct dentry *dentry,
return 0; return 0;
} }
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa, size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr_storage *ss,
size_t salen, struct net *net, int port) size_t salen, struct net *net, int port)
{ {
struct sockaddr *sa = (struct sockaddr *)ss;
ssize_t ret; ssize_t ret;
ret = rpc_pton(net, string, len, sa, salen); ret = rpc_pton(net, string, len, sa, salen);
if (ret == 0) { if (ret == 0) {
ret = rpc_uaddr2sockaddr(net, string, len, sa, salen); ret = rpc_uaddr2sockaddr(net, string, len, sa, salen);
if (ret == 0) { if (ret == 0) {
ret = nfs_dns_resolve_name(net, string, len, sa, salen); ret = nfs_dns_resolve_name(net, string, len, ss, salen);
if (ret < 0) if (ret < 0)
ret = 0; ret = 0;
} }
@ -331,7 +332,7 @@ static int try_location(struct fs_context *fc,
ctx->nfs_server.addrlen = ctx->nfs_server.addrlen =
nfs_parse_server_name(buf->data, buf->len, nfs_parse_server_name(buf->data, buf->len,
&ctx->nfs_server.address, &ctx->nfs_server._address,
sizeof(ctx->nfs_server._address), sizeof(ctx->nfs_server._address),
fc->net_ns, 0); fc->net_ns, 0);
if (ctx->nfs_server.addrlen == 0) if (ctx->nfs_server.addrlen == 0)
@ -483,14 +484,13 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server,
char *page, char *page2, char *page, char *page2,
const struct nfs4_fs_location *location) const struct nfs4_fs_location *location)
{ {
const size_t addr_bufsize = sizeof(struct sockaddr_storage);
struct net *net = rpc_net_ns(server->client); struct net *net = rpc_net_ns(server->client);
struct sockaddr *sap; struct sockaddr_storage *sap;
unsigned int s; unsigned int s;
size_t salen; size_t salen;
int error; int error;
sap = kmalloc(addr_bufsize, GFP_KERNEL); sap = kmalloc(sizeof(*sap), GFP_KERNEL);
if (sap == NULL) if (sap == NULL)
return -ENOMEM; return -ENOMEM;
@ -506,10 +506,10 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server,
continue; continue;
salen = nfs_parse_server_name(buf->data, buf->len, salen = nfs_parse_server_name(buf->data, buf->len,
sap, addr_bufsize, net, 0); sap, sizeof(*sap), net, 0);
if (salen == 0) if (salen == 0)
continue; continue;
rpc_set_port(sap, NFS_PORT); rpc_set_port((struct sockaddr *)sap, NFS_PORT);
error = -ENOMEM; error = -ENOMEM;
hostname = kmemdup_nul(buf->data, buf->len, GFP_KERNEL); hostname = kmemdup_nul(buf->data, buf->len, GFP_KERNEL);

View file

@ -3951,7 +3951,7 @@ static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
for (i = 0; i < location->nservers; i++) { for (i = 0; i < location->nservers; i++) {
struct nfs4_string *srv_loc = &location->servers[i]; struct nfs4_string *srv_loc = &location->servers[i];
struct sockaddr addr; struct sockaddr_storage addr;
size_t addrlen; size_t addrlen;
struct xprt_create xprt_args = { struct xprt_create xprt_args = {
.ident = 0, .ident = 0,
@ -3974,7 +3974,7 @@ static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
clp->cl_net, server->port); clp->cl_net, server->port);
if (!addrlen) if (!addrlen)
return; return;
xprt_args.dstaddr = &addr; xprt_args.dstaddr = (struct sockaddr *)&addr;
xprt_args.addrlen = addrlen; xprt_args.addrlen = addrlen;
servername = kmalloc(srv_loc->len + 1, GFP_KERNEL); servername = kmalloc(srv_loc->len + 1, GFP_KERNEL);
if (!servername) if (!servername)
@ -7138,6 +7138,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
{ {
struct nfs4_lockdata *data = calldata; struct nfs4_lockdata *data = calldata;
struct nfs4_lock_state *lsp = data->lsp; struct nfs4_lock_state *lsp = data->lsp;
struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry));
if (!nfs4_sequence_done(task, &data->res.seq_res)) if (!nfs4_sequence_done(task, &data->res.seq_res))
return; return;
@ -7145,8 +7146,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
data->rpc_status = task->tk_status; data->rpc_status = task->tk_status;
switch (task->tk_status) { switch (task->tk_status) {
case 0: case 0:
renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)), renew_lease(server, data->timestamp);
data->timestamp);
if (data->arg.new_lock && !data->cancelled) { if (data->arg.new_lock && !data->cancelled) {
data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS); data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS);
if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0) if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0)
@ -7167,6 +7167,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
if (!nfs4_stateid_match(&data->arg.open_stateid, if (!nfs4_stateid_match(&data->arg.open_stateid,
&lsp->ls_state->open_stateid)) &lsp->ls_state->open_stateid))
goto out_restart; goto out_restart;
else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN)
goto out_restart;
} else if (!nfs4_stateid_match(&data->arg.lock_stateid, } else if (!nfs4_stateid_match(&data->arg.lock_stateid,
&lsp->ls_stateid)) &lsp->ls_stateid))
goto out_restart; goto out_restart;

View file

@ -1786,6 +1786,7 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp,
static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
{ {
set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
/* Mark all delegations for reclaim */ /* Mark all delegations for reclaim */
nfs_delegation_mark_reclaim(clp); nfs_delegation_mark_reclaim(clp);
nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot); nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
@ -2670,6 +2671,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
if (status < 0) if (status < 0)
goto out_error; goto out_error;
nfs4_state_end_reclaim_reboot(clp); nfs4_state_end_reclaim_reboot(clp);
continue;
} }
/* Detect expired delegations... */ /* Detect expired delegations... */

View file

@ -821,7 +821,7 @@ static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
static struct nfs_client *(*get_v3_ds_connect)( static struct nfs_client *(*get_v3_ds_connect)(
struct nfs_server *mds_srv, struct nfs_server *mds_srv,
const struct sockaddr *ds_addr, const struct sockaddr_storage *ds_addr,
int ds_addrlen, int ds_addrlen,
int ds_proto, int ds_proto,
unsigned int ds_timeo, unsigned int ds_timeo,
@ -882,7 +882,7 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
continue; continue;
} }
clp = get_v3_ds_connect(mds_srv, clp = get_v3_ds_connect(mds_srv,
(struct sockaddr *)&da->da_addr, &da->da_addr,
da->da_addrlen, da->da_transport, da->da_addrlen, da->da_transport,
timeo, retrans); timeo, retrans);
if (IS_ERR(clp)) if (IS_ERR(clp))
@ -951,7 +951,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
put_cred(xprtdata.cred); put_cred(xprtdata.cred);
} else { } else {
clp = nfs4_set_ds_client(mds_srv, clp = nfs4_set_ds_client(mds_srv,
(struct sockaddr *)&da->da_addr, &da->da_addr,
da->da_addrlen, da->da_addrlen,
da->da_transport, timeo, da->da_transport, timeo,
retrans, minor_version); retrans, minor_version);

View file

@ -822,8 +822,7 @@ static int nfs_request_mount(struct fs_context *fc,
{ {
struct nfs_fs_context *ctx = nfs_fc2context(fc); struct nfs_fs_context *ctx = nfs_fc2context(fc);
struct nfs_mount_request request = { struct nfs_mount_request request = {
.sap = (struct sockaddr *) .sap = &ctx->mount_server._address,
&ctx->mount_server.address,
.dirpath = ctx->nfs_server.export_path, .dirpath = ctx->nfs_server.export_path,
.protocol = ctx->mount_server.protocol, .protocol = ctx->mount_server.protocol,
.fh = root_fh, .fh = root_fh,
@ -854,7 +853,7 @@ static int nfs_request_mount(struct fs_context *fc,
* Construct the mount server's address. * Construct the mount server's address.
*/ */
if (ctx->mount_server.address.sa_family == AF_UNSPEC) { if (ctx->mount_server.address.sa_family == AF_UNSPEC) {
memcpy(request.sap, &ctx->nfs_server.address, memcpy(request.sap, &ctx->nfs_server._address,
ctx->nfs_server.addrlen); ctx->nfs_server.addrlen);
ctx->mount_server.addrlen = ctx->nfs_server.addrlen; ctx->mount_server.addrlen = ctx->nfs_server.addrlen;
} }

View file

@ -1989,7 +1989,7 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
goto unwrap_failed; goto unwrap_failed;
mic.len = len; mic.len = len;
mic.data = kmalloc(len, GFP_KERNEL); mic.data = kmalloc(len, GFP_KERNEL);
if (!mic.data) if (ZERO_OR_NULL_PTR(mic.data))
goto unwrap_failed; goto unwrap_failed;
if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len))
goto unwrap_failed; goto unwrap_failed;

View file

@ -518,13 +518,16 @@ void rpc_sysfs_client_setup(struct rpc_clnt *clnt,
struct net *net) struct net *net)
{ {
struct rpc_sysfs_client *rpc_client; struct rpc_sysfs_client *rpc_client;
struct rpc_sysfs_xprt_switch *xswitch =
(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
if (!xswitch)
return;
rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj, rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj,
net, clnt->cl_clid); net, clnt->cl_clid);
if (rpc_client) { if (rpc_client) {
char name[] = "switch"; char name[] = "switch";
struct rpc_sysfs_xprt_switch *xswitch =
(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
int ret; int ret;
clnt->cl_sysfs = rpc_client; clnt->cl_sysfs = rpc_client;
@ -558,6 +561,8 @@ void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch *xprt_switch,
rpc_xprt_switch->xprt_switch = xprt_switch; rpc_xprt_switch->xprt_switch = xprt_switch;
rpc_xprt_switch->xprt = xprt; rpc_xprt_switch->xprt = xprt;
kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD); kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD);
} else {
xprt_switch->xps_sysfs = NULL;
} }
} }
@ -569,6 +574,9 @@ void rpc_sysfs_xprt_setup(struct rpc_xprt_switch *xprt_switch,
struct rpc_sysfs_xprt_switch *switch_obj = struct rpc_sysfs_xprt_switch *switch_obj =
(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
if (!switch_obj)
return;
rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags); rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags);
if (rpc_xprt) { if (rpc_xprt) {
xprt->xprt_sysfs = rpc_xprt; xprt->xprt_sysfs = rpc_xprt;