diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-09 14:48:32 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-27 12:32:24 -0400 |
commit | df52699e4fcefe30ebe4f1db48bd161254a0b102 (patch) | |
tree | 7b590d25515d0fa5bbbe5c48e76a0857a73e10b0 /fs/nfs/pnfs_dev.c | |
parent | 4e59080397faadee59d39ffa2116dc8607adc9c9 (diff) | |
download | op-kernel-dev-df52699e4fcefe30ebe4f1db48bd161254a0b102.zip op-kernel-dev-df52699e4fcefe30ebe4f1db48bd161254a0b102.tar.gz |
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>
Diffstat (limited to 'fs/nfs/pnfs_dev.c')
-rw-r--r-- | fs/nfs/pnfs_dev.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c index 7e07f4b..2961fcd 100644 --- a/fs/nfs/pnfs_dev.c +++ b/fs/nfs/pnfs_dev.c @@ -149,6 +149,8 @@ nfs4_get_device_info(struct nfs_server *server, */ d = server->pnfs_curr_ld->alloc_deviceid_node(server, pdev, gfp_flags); + if (d && pdev->nocache) + set_bit(NFS_DEVICEID_NOCACHE, &d->flags); out_free_pages: for (i = 0; i < max_pages; i++) @@ -235,6 +237,7 @@ nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld, return; } hlist_del_init_rcu(&d->node); + clear_bit(NFS_DEVICEID_NOCACHE, &d->flags); spin_unlock(&nfs4_deviceid_lock); /* balance the initial ref set in pnfs_insert_deviceid */ @@ -269,6 +272,11 @@ EXPORT_SYMBOL_GPL(nfs4_init_deviceid_node); bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *d) { + if (test_bit(NFS_DEVICEID_NOCACHE, &d->flags)) { + if (atomic_add_unless(&d->ref, -1, 2)) + return false; + nfs4_delete_deviceid(d->ld, d->nfs_client, &d->deviceid); + } if (!atomic_dec_and_test(&d->ref)) return false; d->ld->free_deviceid_node(d); @@ -312,6 +320,7 @@ _deviceid_purge_client(const struct nfs_client *clp, long hash) if (d->nfs_client == clp && atomic_read(&d->ref)) { hlist_del_init_rcu(&d->node); hlist_add_head(&d->tmpnode, &tmp); + clear_bit(NFS_DEVICEID_NOCACHE, &d->flags); } rcu_read_unlock(); spin_unlock(&nfs4_deviceid_lock); |