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

NFSv4.1: Don't cache deviceids that have no notifications

The spec says that once all layouts that reference a given deviceid
have been returned, then we are only allowed to continue to cache
the deviceid if the metadata server supports notifications.

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

+13
+2
fs/nfs/nfs4proc.c
··· 7962 7962 status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 7963 7963 if (res.notification & ~args.notify_types) 7964 7964 dprintk("%s: unsupported notification\n", __func__); 7965 + if (res.notification != args.notify_types) 7966 + pdev->nocache = 1; 7965 7967 7966 7968 dprintk("<-- %s status=%d\n", __func__, status); 7967 7969
+2
fs/nfs/pnfs.h
··· 203 203 struct page **pages; 204 204 unsigned int pgbase; 205 205 unsigned int pglen; /* reply buffer length */ 206 + unsigned char nocache : 1;/* May not be cached */ 206 207 }; 207 208 208 209 #define NFS4_PNFS_GETDEVLIST_MAXNUM 16 ··· 292 291 enum { 293 292 NFS_DEVICEID_INVALID = 0, /* set when MDS clientid recalled */ 294 293 NFS_DEVICEID_UNAVAILABLE, /* device temporarily unavailable */ 294 + NFS_DEVICEID_NOCACHE, /* device may not be cached */ 295 295 }; 296 296 297 297 /* pnfs_dev.c */
+9
fs/nfs/pnfs_dev.c
··· 149 149 */ 150 150 d = server->pnfs_curr_ld->alloc_deviceid_node(server, pdev, 151 151 gfp_flags); 152 + if (d && pdev->nocache) 153 + set_bit(NFS_DEVICEID_NOCACHE, &d->flags); 152 154 153 155 out_free_pages: 154 156 for (i = 0; i < max_pages; i++) ··· 237 235 return; 238 236 } 239 237 hlist_del_init_rcu(&d->node); 238 + clear_bit(NFS_DEVICEID_NOCACHE, &d->flags); 240 239 spin_unlock(&nfs4_deviceid_lock); 241 240 242 241 /* balance the initial ref set in pnfs_insert_deviceid */ ··· 272 269 bool 273 270 nfs4_put_deviceid_node(struct nfs4_deviceid_node *d) 274 271 { 272 + if (test_bit(NFS_DEVICEID_NOCACHE, &d->flags)) { 273 + if (atomic_add_unless(&d->ref, -1, 2)) 274 + return false; 275 + nfs4_delete_deviceid(d->ld, d->nfs_client, &d->deviceid); 276 + } 275 277 if (!atomic_dec_and_test(&d->ref)) 276 278 return false; 277 279 d->ld->free_deviceid_node(d); ··· 320 312 if (d->nfs_client == clp && atomic_read(&d->ref)) { 321 313 hlist_del_init_rcu(&d->node); 322 314 hlist_add_head(&d->tmpnode, &tmp); 315 + clear_bit(NFS_DEVICEID_NOCACHE, &d->flags); 323 316 } 324 317 rcu_read_unlock(); 325 318 spin_unlock(&nfs4_deviceid_lock);