Loading fs/nfs/nfs4super.c +3 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,9 @@ static int __init init_nfs_v4(void) static void __exit exit_nfs_v4(void) { /* Not called in the _init(), conditionally loaded */ nfs4_pnfs_v3_ds_connect_unload(); unregister_nfs_version(&nfs_v4); nfs4_unregister_sysctl(); nfs_idmap_quit(); Loading fs/nfs/pnfs.h +6 −1 Original line number Diff line number Diff line Loading @@ -323,9 +323,10 @@ void pnfs_generic_write_commit_done(struct rpc_task *task, void *data); void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags); void nfs4_pnfs_v3_ds_connect_unload(void); void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, struct nfs4_deviceid_node *devid, unsigned int timeo, unsigned int retrans, u32 versoin, u32 minor_version, unsigned int retrans, u32 version, u32 minor_version, rpc_authflavor_t au_flavor); struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, Loading Loading @@ -615,6 +616,10 @@ static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void) return NULL; } static inline void nfs4_pnfs_v3_ds_connect_unload(void) { } #endif /* CONFIG_NFS_V4_1 */ #endif /* FS_NFS_PNFS_H */ fs/nfs/pnfs_nfs.c +84 −4 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <linux/nfs_fs.h> #include <linux/nfs_page.h> #include <linux/sunrpc/addr.h> #include <linux/module.h> #include "nfs4session.h" #include "internal.h" Loading Loading @@ -550,7 +551,75 @@ static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds) wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING); } static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, static struct nfs_client *(*get_v3_ds_connect)( struct nfs_client *mds_clp, const struct sockaddr *ds_addr, int ds_addrlen, int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans, rpc_authflavor_t au_flavor); static bool load_v3_ds_connect(void) { if (!get_v3_ds_connect) { get_v3_ds_connect = symbol_request(nfs3_set_ds_client); WARN_ON_ONCE(!get_v3_ds_connect); } return(get_v3_ds_connect != NULL); } void __exit nfs4_pnfs_v3_ds_connect_unload(void) { if (get_v3_ds_connect) { symbol_put(nfs3_set_ds_client); get_v3_ds_connect = NULL; } } EXPORT_SYMBOL_GPL(nfs4_pnfs_v3_ds_connect_unload); static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, unsigned int timeo, unsigned int retrans, rpc_authflavor_t au_flavor) { struct nfs_client *clp = ERR_PTR(-EIO); struct nfs4_pnfs_ds_addr *da; int status = 0; dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, au_flavor); if (!load_v3_ds_connect()) goto out; list_for_each_entry(da, &ds->ds_addrs, da_node) { dprintk("%s: DS %s: trying address %s\n", __func__, ds->ds_remotestr, da->da_remotestr); clp = get_v3_ds_connect(mds_srv->nfs_client, (struct sockaddr *)&da->da_addr, da->da_addrlen, IPPROTO_TCP, timeo, retrans, au_flavor); if (!IS_ERR(clp)) break; } if (IS_ERR(clp)) { status = PTR_ERR(clp); goto out; } smp_wmb(); ds->ds_clp = clp; dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); out: return status; } static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, unsigned int timeo, unsigned int retrans, Loading @@ -562,7 +631,7 @@ static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, int status = 0; dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor); au_flavor); list_for_each_entry(da, &ds->ds_addrs, da_node) { dprintk("%s: DS %s: trying address %s\n", Loading Loading @@ -609,8 +678,19 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { int err = 0; err = _nfs4_pnfs_ds_connect(mds_srv, ds, timeo, retrans, minor_version, au_flavor); if (version == 3) { err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, retrans, au_flavor); } else if (version == 4) { err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo, retrans, minor_version, au_flavor); } else { dprintk("%s: unsupported DS version %d\n", __func__, version); err = -EPROTONOSUPPORT; } if (err) nfs4_mark_deviceid_unavailable(devid); nfs4_clear_ds_conn_bit(ds); Loading Loading
fs/nfs/nfs4super.c +3 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,9 @@ static int __init init_nfs_v4(void) static void __exit exit_nfs_v4(void) { /* Not called in the _init(), conditionally loaded */ nfs4_pnfs_v3_ds_connect_unload(); unregister_nfs_version(&nfs_v4); nfs4_unregister_sysctl(); nfs_idmap_quit(); Loading
fs/nfs/pnfs.h +6 −1 Original line number Diff line number Diff line Loading @@ -323,9 +323,10 @@ void pnfs_generic_write_commit_done(struct rpc_task *task, void *data); void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags); void nfs4_pnfs_v3_ds_connect_unload(void); void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, struct nfs4_deviceid_node *devid, unsigned int timeo, unsigned int retrans, u32 versoin, u32 minor_version, unsigned int retrans, u32 version, u32 minor_version, rpc_authflavor_t au_flavor); struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, Loading Loading @@ -615,6 +616,10 @@ static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void) return NULL; } static inline void nfs4_pnfs_v3_ds_connect_unload(void) { } #endif /* CONFIG_NFS_V4_1 */ #endif /* FS_NFS_PNFS_H */
fs/nfs/pnfs_nfs.c +84 −4 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <linux/nfs_fs.h> #include <linux/nfs_page.h> #include <linux/sunrpc/addr.h> #include <linux/module.h> #include "nfs4session.h" #include "internal.h" Loading Loading @@ -550,7 +551,75 @@ static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds) wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING); } static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, static struct nfs_client *(*get_v3_ds_connect)( struct nfs_client *mds_clp, const struct sockaddr *ds_addr, int ds_addrlen, int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans, rpc_authflavor_t au_flavor); static bool load_v3_ds_connect(void) { if (!get_v3_ds_connect) { get_v3_ds_connect = symbol_request(nfs3_set_ds_client); WARN_ON_ONCE(!get_v3_ds_connect); } return(get_v3_ds_connect != NULL); } void __exit nfs4_pnfs_v3_ds_connect_unload(void) { if (get_v3_ds_connect) { symbol_put(nfs3_set_ds_client); get_v3_ds_connect = NULL; } } EXPORT_SYMBOL_GPL(nfs4_pnfs_v3_ds_connect_unload); static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, unsigned int timeo, unsigned int retrans, rpc_authflavor_t au_flavor) { struct nfs_client *clp = ERR_PTR(-EIO); struct nfs4_pnfs_ds_addr *da; int status = 0; dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, au_flavor); if (!load_v3_ds_connect()) goto out; list_for_each_entry(da, &ds->ds_addrs, da_node) { dprintk("%s: DS %s: trying address %s\n", __func__, ds->ds_remotestr, da->da_remotestr); clp = get_v3_ds_connect(mds_srv->nfs_client, (struct sockaddr *)&da->da_addr, da->da_addrlen, IPPROTO_TCP, timeo, retrans, au_flavor); if (!IS_ERR(clp)) break; } if (IS_ERR(clp)) { status = PTR_ERR(clp); goto out; } smp_wmb(); ds->ds_clp = clp; dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); out: return status; } static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, unsigned int timeo, unsigned int retrans, Loading @@ -562,7 +631,7 @@ static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, int status = 0; dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor); au_flavor); list_for_each_entry(da, &ds->ds_addrs, da_node) { dprintk("%s: DS %s: trying address %s\n", Loading Loading @@ -609,8 +678,19 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { int err = 0; err = _nfs4_pnfs_ds_connect(mds_srv, ds, timeo, retrans, minor_version, au_flavor); if (version == 3) { err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, retrans, au_flavor); } else if (version == 4) { err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo, retrans, minor_version, au_flavor); } else { dprintk("%s: unsupported DS version %d\n", __func__, version); err = -EPROTONOSUPPORT; } if (err) nfs4_mark_deviceid_unavailable(devid); nfs4_clear_ds_conn_bit(ds); Loading