Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSv4.1/flexfiles: Add refcounting to struct nfs4_ff_layout_mirror

We do want to share mirrors between layout segments, so add a refcount
to enable that.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

+28 -9
+27 -9
fs/nfs/flexfilelayout/flexfilelayout.c
··· 135 135 return 0; 136 136 } 137 137 138 + static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags) 139 + { 140 + struct nfs4_ff_layout_mirror *mirror; 141 + 142 + mirror = kzalloc(sizeof(*mirror), gfp_flags); 143 + if (mirror != NULL) { 144 + spin_lock_init(&mirror->lock); 145 + atomic_set(&mirror->ref, 1); 146 + } 147 + return mirror; 148 + } 149 + 150 + static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror) 151 + { 152 + kfree(mirror->fh_versions); 153 + nfs4_ff_layout_put_deviceid(mirror->mirror_ds); 154 + kfree(mirror); 155 + } 156 + 157 + static void ff_layout_put_mirror(struct nfs4_ff_layout_mirror *mirror) 158 + { 159 + if (mirror != NULL && atomic_dec_and_test(&mirror->ref)) 160 + ff_layout_free_mirror(mirror); 161 + } 162 + 138 163 static void ff_layout_free_mirror_array(struct nfs4_ff_layout_segment *fls) 139 164 { 140 165 int i; ··· 169 144 /* normally mirror_ds is freed in 170 145 * .free_deviceid_node but we still do it here 171 146 * for .alloc_lseg error path */ 172 - if (fls->mirror_array[i]) { 173 - kfree(fls->mirror_array[i]->fh_versions); 174 - nfs4_ff_layout_put_deviceid(fls->mirror_array[i]->mirror_ds); 175 - kfree(fls->mirror_array[i]); 176 - } 147 + ff_layout_put_mirror(fls->mirror_array[i]); 177 148 } 178 149 kfree(fls->mirror_array); 179 150 fls->mirror_array = NULL; ··· 283 262 if (ds_count != 1) 284 263 goto out_err_free; 285 264 286 - fls->mirror_array[i] = 287 - kzalloc(sizeof(struct nfs4_ff_layout_mirror), 288 - gfp_flags); 265 + fls->mirror_array[i] = ff_layout_alloc_mirror(gfp_flags); 289 266 if (fls->mirror_array[i] == NULL) { 290 267 rc = -ENOMEM; 291 268 goto out_err_free; 292 269 } 293 270 294 - spin_lock_init(&fls->mirror_array[i]->lock); 295 271 fls->mirror_array[i]->ds_count = ds_count; 296 272 fls->mirror_array[i]->lseg = &fls->generic_hdr; 297 273
+1
fs/nfs/flexfilelayout/flexfilelayout.h
··· 77 77 u32 uid; 78 78 u32 gid; 79 79 struct rpc_cred *cred; 80 + atomic_t ref; 80 81 spinlock_t lock; 81 82 struct nfs4_ff_layoutstat read_stat; 82 83 struct nfs4_ff_layoutstat write_stat;