Skip to content

Commit b9defd6

Browse files
author
Trond Myklebust
committed
NFSv4: Remove duplicate lookups, capability probes and fsinfo calls
When crossing into a new filesystem, the NFSv4 client will look up the new directory, and then call nfs4_server_capabilities() as well as nfs4_do_fsinfo() at least twice. This patch removes the duplicate calls, and reduces the initial lookup to retrieve just a minimal set of attributes. Reviewed-by: Benjamin Coddington <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent b01f21c commit b9defd6

File tree

3 files changed

+48
-58
lines changed

3 files changed

+48
-58
lines changed

fs/nfs/nfs4_fs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ struct nfs4_minor_version_ops {
6363
bool (*match_stateid)(const nfs4_stateid *,
6464
const nfs4_stateid *);
6565
int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
66-
struct nfs_fsinfo *);
66+
struct nfs_fattr *);
6767
void (*free_lock_state)(struct nfs_server *,
6868
struct nfs4_lock_state *);
6969
int (*test_and_free_expired)(struct nfs_server *,
@@ -296,7 +296,8 @@ extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
296296
extern void nfs4_init_sequence(struct nfs4_sequence_args *, struct nfs4_sequence_res *, int, int);
297297
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, const struct cred *, struct nfs4_setclientid_res *);
298298
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, const struct cred *);
299-
extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool);
299+
extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *,
300+
struct nfs_fattr *, bool);
300301
extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, const struct cred *cred);
301302
extern int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred);
302303
extern int nfs4_destroy_clientid(struct nfs_client *clp);

fs/nfs/nfs4getroot.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,28 @@
1212

1313
int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool auth_probe)
1414
{
15-
struct nfs_fsinfo fsinfo;
15+
struct nfs_fattr *fattr = nfs_alloc_fattr();
1616
int ret = -ENOMEM;
1717

18-
fsinfo.fattr = nfs_alloc_fattr();
19-
if (fsinfo.fattr == NULL)
18+
if (fattr == NULL)
2019
goto out;
2120

2221
/* Start by getting the root filehandle from the server */
23-
ret = nfs4_proc_get_rootfh(server, mntfh, &fsinfo, auth_probe);
22+
ret = nfs4_proc_get_rootfh(server, mntfh, fattr, auth_probe);
2423
if (ret < 0) {
2524
dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
2625
goto out;
2726
}
2827

29-
if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_TYPE)
30-
|| !S_ISDIR(fsinfo.fattr->mode)) {
28+
if (!(fattr->valid & NFS_ATTR_FATTR_TYPE) || !S_ISDIR(fattr->mode)) {
3129
printk(KERN_ERR "nfs4_get_rootfh:"
3230
" getroot encountered non-directory\n");
3331
ret = -ENOTDIR;
3432
goto out;
3533
}
3634

37-
memcpy(&server->fsid, &fsinfo.fattr->fsid, sizeof(server->fsid));
35+
memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
3836
out:
39-
nfs_free_fattr(fsinfo.fattr);
37+
nfs_free_fattr(fattr);
4038
return ret;
4139
}

fs/nfs/nfs4proc.c

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4240,15 +4240,18 @@ static int nfs4_discover_trunking(struct nfs_server *server,
42404240
}
42414241

42424242
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
4243-
struct nfs_fsinfo *info)
4243+
struct nfs_fattr *fattr)
42444244
{
4245-
u32 bitmask[3];
4245+
u32 bitmask[3] = {
4246+
[0] = FATTR4_WORD0_TYPE | FATTR4_WORD0_CHANGE |
4247+
FATTR4_WORD0_SIZE | FATTR4_WORD0_FSID,
4248+
};
42464249
struct nfs4_lookup_root_arg args = {
42474250
.bitmask = bitmask,
42484251
};
42494252
struct nfs4_lookup_res res = {
42504253
.server = server,
4251-
.fattr = info->fattr,
4254+
.fattr = fattr,
42524255
.fh = fhandle,
42534256
};
42544257
struct rpc_message msg = {
@@ -4257,27 +4260,20 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
42574260
.rpc_resp = &res,
42584261
};
42594262

4260-
bitmask[0] = nfs4_fattr_bitmap[0];
4261-
bitmask[1] = nfs4_fattr_bitmap[1];
4262-
/*
4263-
* Process the label in the upcoming getfattr
4264-
*/
4265-
bitmask[2] = nfs4_fattr_bitmap[2] & ~FATTR4_WORD2_SECURITY_LABEL;
4266-
4267-
nfs_fattr_init(info->fattr);
4263+
nfs_fattr_init(fattr);
42684264
return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
42694265
}
42704266

42714267
static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
4272-
struct nfs_fsinfo *info)
4268+
struct nfs_fattr *fattr)
42734269
{
42744270
struct nfs4_exception exception = {
42754271
.interruptible = true,
42764272
};
42774273
int err;
42784274
do {
4279-
err = _nfs4_lookup_root(server, fhandle, info);
4280-
trace_nfs4_lookup_root(server, fhandle, info->fattr, err);
4275+
err = _nfs4_lookup_root(server, fhandle, fattr);
4276+
trace_nfs4_lookup_root(server, fhandle, fattr, err);
42814277
switch (err) {
42824278
case 0:
42834279
case -NFS4ERR_WRONGSEC:
@@ -4290,8 +4286,9 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
42904286
return err;
42914287
}
42924288

4293-
static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
4294-
struct nfs_fsinfo *info, rpc_authflavor_t flavor)
4289+
static int nfs4_lookup_root_sec(struct nfs_server *server,
4290+
struct nfs_fh *fhandle, struct nfs_fattr *fattr,
4291+
rpc_authflavor_t flavor)
42954292
{
42964293
struct rpc_auth_create_args auth_args = {
42974294
.pseudoflavor = flavor,
@@ -4301,7 +4298,7 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
43014298
auth = rpcauth_create(&auth_args, server->client);
43024299
if (IS_ERR(auth))
43034300
return -EACCES;
4304-
return nfs4_lookup_root(server, fhandle, info);
4301+
return nfs4_lookup_root(server, fhandle, fattr);
43054302
}
43064303

43074304
/*
@@ -4314,7 +4311,7 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
43144311
* negative errno value.
43154312
*/
43164313
static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
4317-
struct nfs_fsinfo *info)
4314+
struct nfs_fattr *fattr)
43184315
{
43194316
/* Per 3530bis 15.33.5 */
43204317
static const rpc_authflavor_t flav_array[] = {
@@ -4330,16 +4327,17 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
43304327
if (server->auth_info.flavor_len > 0) {
43314328
/* try each flavor specified by user */
43324329
for (i = 0; i < server->auth_info.flavor_len; i++) {
4333-
status = nfs4_lookup_root_sec(server, fhandle, info,
4334-
server->auth_info.flavors[i]);
4330+
status = nfs4_lookup_root_sec(
4331+
server, fhandle, fattr,
4332+
server->auth_info.flavors[i]);
43354333
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
43364334
continue;
43374335
break;
43384336
}
43394337
} else {
43404338
/* no flavors specified by user, try default list */
43414339
for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
4342-
status = nfs4_lookup_root_sec(server, fhandle, info,
4340+
status = nfs4_lookup_root_sec(server, fhandle, fattr,
43434341
flav_array[i]);
43444342
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
43454343
continue;
@@ -4363,28 +4361,22 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
43634361
* nfs4_proc_get_rootfh - get file handle for server's pseudoroot
43644362
* @server: initialized nfs_server handle
43654363
* @fhandle: we fill in the pseudo-fs root file handle
4366-
* @info: we fill in an FSINFO struct
4364+
* @fattr: we fill in a bare bones struct fattr
43674365
* @auth_probe: probe the auth flavours
43684366
*
43694367
* Returns zero on success, or a negative errno.
43704368
*/
43714369
int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
4372-
struct nfs_fsinfo *info,
4373-
bool auth_probe)
4370+
struct nfs_fattr *fattr, bool auth_probe)
43744371
{
43754372
int status = 0;
43764373

43774374
if (!auth_probe)
4378-
status = nfs4_lookup_root(server, fhandle, info);
4375+
status = nfs4_lookup_root(server, fhandle, fattr);
43794376

43804377
if (auth_probe || status == NFS4ERR_WRONGSEC)
4381-
status = server->nfs_client->cl_mvops->find_root_sec(server,
4382-
fhandle, info);
4383-
4384-
if (status == 0)
4385-
status = nfs4_server_capabilities(server, fhandle);
4386-
if (status == 0)
4387-
status = nfs4_do_fsinfo(server, fhandle, info);
4378+
status = server->nfs_client->cl_mvops->find_root_sec(
4379+
server, fhandle, fattr);
43884380

43894381
return nfs4_map_errors(status);
43904382
}
@@ -10351,10 +10343,10 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
1035110343
* Use the state managment nfs_client cl_rpcclient, which uses krb5i (if
1035210344
* possible) as per RFC3530bis and RFC5661 Security Considerations sections
1035310345
*/
10354-
static int
10355-
_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
10356-
struct nfs_fsinfo *info,
10357-
struct nfs4_secinfo_flavors *flavors, bool use_integrity)
10346+
static int _nfs41_proc_secinfo_no_name(struct nfs_server *server,
10347+
struct nfs_fh *fhandle,
10348+
struct nfs4_secinfo_flavors *flavors,
10349+
bool use_integrity)
1035810350
{
1035910351
struct nfs41_secinfo_no_name_args args = {
1036010352
.style = SECINFO_STYLE_CURRENT_FH,
@@ -10398,9 +10390,9 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
1039810390
return status;
1039910391
}
1040010392

10401-
static int
10402-
nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
10403-
struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors)
10393+
static int nfs41_proc_secinfo_no_name(struct nfs_server *server,
10394+
struct nfs_fh *fhandle,
10395+
struct nfs4_secinfo_flavors *flavors)
1040410396
{
1040510397
struct nfs4_exception exception = {
1040610398
.interruptible = true,
@@ -10412,7 +10404,7 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
1041210404

1041310405
/* try to use integrity protection with machine cred */
1041410406
if (_nfs4_is_integrity_protected(server->nfs_client))
10415-
err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
10407+
err = _nfs41_proc_secinfo_no_name(server, fhandle,
1041610408
flavors, true);
1041710409

1041810410
/*
@@ -10422,7 +10414,7 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
1042210414
* the current filesystem's rpc_client and the user cred.
1042310415
*/
1042410416
if (err == -NFS4ERR_WRONGSEC)
10425-
err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
10417+
err = _nfs41_proc_secinfo_no_name(server, fhandle,
1042610418
flavors, false);
1042710419

1042810420
switch (err) {
@@ -10438,9 +10430,8 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
1043810430
return err;
1043910431
}
1044010432

10441-
static int
10442-
nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
10443-
struct nfs_fsinfo *info)
10433+
static int nfs41_find_root_sec(struct nfs_server *server,
10434+
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
1044410435
{
1044510436
int err;
1044610437
struct page *page;
@@ -10456,14 +10447,14 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
1045610447
}
1045710448

1045810449
flavors = page_address(page);
10459-
err = nfs41_proc_secinfo_no_name(server, fhandle, info, flavors);
10450+
err = nfs41_proc_secinfo_no_name(server, fhandle, flavors);
1046010451

1046110452
/*
1046210453
* Fall back on "guess and check" method if
1046310454
* the server doesn't support SECINFO_NO_NAME
1046410455
*/
1046510456
if (err == -NFS4ERR_WRONGSEC || err == -ENOTSUPP) {
10466-
err = nfs4_find_root_sec(server, fhandle, info);
10457+
err = nfs4_find_root_sec(server, fhandle, fattr);
1046710458
goto out_freepage;
1046810459
}
1046910460
if (err)
@@ -10488,8 +10479,8 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
1048810479
flavor = RPC_AUTH_MAXFLAVOR;
1048910480

1049010481
if (flavor != RPC_AUTH_MAXFLAVOR) {
10491-
err = nfs4_lookup_root_sec(server, fhandle,
10492-
info, flavor);
10482+
err = nfs4_lookup_root_sec(server, fhandle, fattr,
10483+
flavor);
1049310484
if (!err)
1049410485
break;
1049510486
}

0 commit comments

Comments
 (0)