Skip to content

Commit 1976b2b

Browse files
olgakorn1amschuma-ntap
authored andcommitted
NFSv4.1 query for fs_location attr on a new file system
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 <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 8a59bb9 commit 1976b2b

File tree

5 files changed

+81
-15
lines changed

5 files changed

+81
-15
lines changed

fs/nfs/client.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,13 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
860860
server->namelen = pathinfo.max_namelen;
861861
}
862862

863+
if (clp->rpc_ops->discover_trunking != NULL &&
864+
(server->caps & NFS_CAP_FS_LOCATIONS)) {
865+
error = clp->rpc_ops->discover_trunking(server, mntfh);
866+
if (error < 0)
867+
return error;
868+
}
869+
863870
return 0;
864871
}
865872

fs/nfs/nfs4_fs.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ struct nfs4_state_maintenance_ops {
260260
};
261261

262262
struct nfs4_mig_recovery_ops {
263-
int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
264-
struct page *, const struct cred *);
263+
int (*get_locations)(struct nfs_server *, struct nfs_fh *,
264+
struct nfs4_fs_locations *, struct page *, const struct cred *);
265265
int (*fsid_present)(struct inode *, const struct cred *);
266266
};
267267

@@ -302,8 +302,9 @@ extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
302302
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
303303
extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
304304
struct nfs4_fs_locations *, struct page *);
305-
extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
306-
struct page *page, const struct cred *);
305+
extern int nfs4_proc_get_locations(struct nfs_server *, struct nfs_fh *,
306+
struct nfs4_fs_locations *,
307+
struct page *page, const struct cred *);
307308
extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
308309
extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *,
309310
struct dentry *,

fs/nfs/nfs4proc.c

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3935,6 +3935,60 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
39353935
return err;
39363936
}
39373937

3938+
static int _nfs4_discover_trunking(struct nfs_server *server,
3939+
struct nfs_fh *fhandle)
3940+
{
3941+
struct nfs4_fs_locations *locations = NULL;
3942+
struct page *page;
3943+
const struct cred *cred;
3944+
struct nfs_client *clp = server->nfs_client;
3945+
const struct nfs4_state_maintenance_ops *ops =
3946+
clp->cl_mvops->state_renewal_ops;
3947+
int status = -ENOMEM;
3948+
3949+
cred = ops->get_state_renewal_cred(clp);
3950+
if (cred == NULL) {
3951+
cred = nfs4_get_clid_cred(clp);
3952+
if (cred == NULL)
3953+
return -ENOKEY;
3954+
}
3955+
3956+
page = alloc_page(GFP_KERNEL);
3957+
locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
3958+
if (page == NULL || locations == NULL)
3959+
goto out;
3960+
3961+
status = nfs4_proc_get_locations(server, fhandle, locations, page,
3962+
cred);
3963+
if (status)
3964+
goto out;
3965+
out:
3966+
if (page)
3967+
__free_page(page);
3968+
kfree(locations);
3969+
return status;
3970+
}
3971+
3972+
static int nfs4_discover_trunking(struct nfs_server *server,
3973+
struct nfs_fh *fhandle)
3974+
{
3975+
struct nfs4_exception exception = {
3976+
.interruptible = true,
3977+
};
3978+
struct nfs_client *clp = server->nfs_client;
3979+
int err = 0;
3980+
3981+
if (!nfs4_has_session(clp))
3982+
goto out;
3983+
do {
3984+
err = nfs4_handle_exception(server,
3985+
_nfs4_discover_trunking(server, fhandle),
3986+
&exception);
3987+
} while (exception.retry);
3988+
out:
3989+
return err;
3990+
}
3991+
39383992
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
39393993
struct nfs_fsinfo *info)
39403994
{
@@ -7823,18 +7877,18 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
78237877
* appended to this compound to identify the client ID which is
78247878
* performing recovery.
78257879
*/
7826-
static int _nfs40_proc_get_locations(struct inode *inode,
7880+
static int _nfs40_proc_get_locations(struct nfs_server *server,
7881+
struct nfs_fh *fhandle,
78277882
struct nfs4_fs_locations *locations,
78287883
struct page *page, const struct cred *cred)
78297884
{
7830-
struct nfs_server *server = NFS_SERVER(inode);
78317885
struct rpc_clnt *clnt = server->client;
78327886
u32 bitmask[2] = {
78337887
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
78347888
};
78357889
struct nfs4_fs_locations_arg args = {
78367890
.clientid = server->nfs_client->cl_clientid,
7837-
.fh = NFS_FH(inode),
7891+
.fh = fhandle,
78387892
.page = page,
78397893
.bitmask = bitmask,
78407894
.migration = 1, /* skip LOOKUP */
@@ -7880,17 +7934,17 @@ static int _nfs40_proc_get_locations(struct inode *inode,
78807934
* When the client supports GETATTR(fs_locations_info), it can
78817935
* be plumbed in here.
78827936
*/
7883-
static int _nfs41_proc_get_locations(struct inode *inode,
7937+
static int _nfs41_proc_get_locations(struct nfs_server *server,
7938+
struct nfs_fh *fhandle,
78847939
struct nfs4_fs_locations *locations,
78857940
struct page *page, const struct cred *cred)
78867941
{
7887-
struct nfs_server *server = NFS_SERVER(inode);
78887942
struct rpc_clnt *clnt = server->client;
78897943
u32 bitmask[2] = {
78907944
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
78917945
};
78927946
struct nfs4_fs_locations_arg args = {
7893-
.fh = NFS_FH(inode),
7947+
.fh = fhandle,
78947948
.page = page,
78957949
.bitmask = bitmask,
78967950
.migration = 1, /* skip LOOKUP */
@@ -7939,11 +7993,11 @@ static int _nfs41_proc_get_locations(struct inode *inode,
79397993
* -NFS4ERR_LEASE_MOVED is returned if the server still has leases
79407994
* from this client that require migration recovery.
79417995
*/
7942-
int nfs4_proc_get_locations(struct inode *inode,
7996+
int nfs4_proc_get_locations(struct nfs_server *server,
7997+
struct nfs_fh *fhandle,
79437998
struct nfs4_fs_locations *locations,
79447999
struct page *page, const struct cred *cred)
79458000
{
7946-
struct nfs_server *server = NFS_SERVER(inode);
79478001
struct nfs_client *clp = server->nfs_client;
79488002
const struct nfs4_mig_recovery_ops *ops =
79498003
clp->cl_mvops->mig_recovery_ops;
@@ -7956,10 +8010,11 @@ int nfs4_proc_get_locations(struct inode *inode,
79568010
(unsigned long long)server->fsid.major,
79578011
(unsigned long long)server->fsid.minor,
79588012
clp->cl_hostname);
7959-
nfs_display_fhandle(NFS_FH(inode), __func__);
8013+
nfs_display_fhandle(fhandle, __func__);
79608014

79618015
do {
7962-
status = ops->get_locations(inode, locations, page, cred);
8016+
status = ops->get_locations(server, fhandle, locations, page,
8017+
cred);
79638018
if (status != -NFS4ERR_DELAY)
79648019
break;
79658020
nfs4_handle_exception(server, status, &exception);
@@ -10428,6 +10483,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
1042810483
.free_client = nfs4_free_client,
1042910484
.create_server = nfs4_create_server,
1043010485
.clone_server = nfs_clone_server,
10486+
.discover_trunking = nfs4_discover_trunking,
1043110487
};
1043210488

1043310489
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {

fs/nfs/nfs4state.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2098,7 +2098,8 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
20982098
}
20992099

21002100
inode = d_inode(server->super->s_root);
2101-
result = nfs4_proc_get_locations(inode, locations, page, cred);
2101+
result = nfs4_proc_get_locations(server, NFS_FH(inode), locations,
2102+
page, cred);
21022103
if (result) {
21032104
dprintk("<-- %s: failed to retrieve fs_locations: %d\n",
21042105
__func__, result);

include/linux/nfs_xdr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,7 @@ struct nfs_rpc_ops {
17971797
struct nfs_server *(*create_server)(struct fs_context *);
17981798
struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
17991799
struct nfs_fattr *, rpc_authflavor_t);
1800+
int (*discover_trunking)(struct nfs_server *, struct nfs_fh *);
18001801
};
18011802

18021803
/*

0 commit comments

Comments
 (0)