Skip to content

Commit 8db4a1d

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
NFSv4/flexfiles: fix to allocate mirror->dss before use
Move mirror_array's dss_count initialization and dss allocation to ff_layout_alloc_mirror(), just before the loop that initializes each nfs4_ff_layout_ds_stripe's nfs_file_localio. Also handle NULL return from kcalloc() and remove one level of indent in ff_layout_alloc_mirror(). This commit fixes dangling nfsd_serv refcount issues seen when using NFS LOCALIO and then attempting to stop the NFSD service. Fixes: 20b1d75 ("NFSv4/flexfiles: Add support for striped layouts") Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
1 parent 3a86608 commit 8db4a1d

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,31 @@ ff_layout_remove_mirror(struct nfs4_ff_layout_mirror *mirror)
270270
mirror->layout = NULL;
271271
}
272272

273-
static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags)
273+
static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(u32 dss_count,
274+
gfp_t gfp_flags)
274275
{
275276
struct nfs4_ff_layout_mirror *mirror;
276-
u32 dss_id;
277277

278278
mirror = kzalloc(sizeof(*mirror), gfp_flags);
279-
if (mirror != NULL) {
280-
spin_lock_init(&mirror->lock);
281-
refcount_set(&mirror->ref, 1);
282-
INIT_LIST_HEAD(&mirror->mirrors);
283-
for (dss_id = 0; dss_id < mirror->dss_count; dss_id++)
284-
nfs_localio_file_init(&mirror->dss[dss_id].nfl);
279+
if (mirror == NULL)
280+
return NULL;
281+
282+
spin_lock_init(&mirror->lock);
283+
refcount_set(&mirror->ref, 1);
284+
INIT_LIST_HEAD(&mirror->mirrors);
285+
286+
mirror->dss_count = dss_count;
287+
mirror->dss =
288+
kcalloc(dss_count, sizeof(struct nfs4_ff_layout_ds_stripe),
289+
gfp_flags);
290+
if (mirror->dss == NULL) {
291+
kfree(mirror);
292+
return NULL;
285293
}
294+
295+
for (u32 dss_id = 0; dss_id < mirror->dss_count; dss_id++)
296+
nfs_localio_file_init(&mirror->dss[dss_id].nfl);
297+
286298
return mirror;
287299
}
288300

@@ -507,17 +519,12 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
507519
if (dss_count > 1 && stripe_unit == 0)
508520
goto out_err_free;
509521

510-
fls->mirror_array[i] = ff_layout_alloc_mirror(gfp_flags);
522+
fls->mirror_array[i] = ff_layout_alloc_mirror(dss_count, gfp_flags);
511523
if (fls->mirror_array[i] == NULL) {
512524
rc = -ENOMEM;
513525
goto out_err_free;
514526
}
515527

516-
fls->mirror_array[i]->dss_count = dss_count;
517-
fls->mirror_array[i]->dss =
518-
kcalloc(dss_count, sizeof(struct nfs4_ff_layout_ds_stripe),
519-
gfp_flags);
520-
521528
for (dss_id = 0; dss_id < dss_count; dss_id++) {
522529
dss_info = &fls->mirror_array[i]->dss[dss_id];
523530
dss_info->mirror = fls->mirror_array[i];

0 commit comments

Comments
 (0)