aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs_dev.c
diff options
context:
space:
mode:
authorBenny Halevy <bhalevy@panasas.com>2011-05-24 11:04:02 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-05-29 13:52:31 -0400
commit35c8bb543c9e83197e6375142d1d1c2ee3cf017d (patch)
treef0f8a69c1586a8d24526223ed70a922c934f9b87 /fs/nfs/pnfs_dev.c
parent1be5683b03a766670b3b629bf6bfeab3ca9239d8 (diff)
NFSv4.1: use layout driver in global device cache
pnfs deviceids are unique per server, per layout type. struct nfs_client is currently used to distinguish deviceids from different nfs servers, yet these may clash between different layout types on the same server. Therefore, use the layout driver associated with each deviceid at insertion time to look it up, unhash, or delete it. Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'fs/nfs/pnfs_dev.c')
-rw-r--r--fs/nfs/pnfs_dev.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index 8fd3839df299..c65e133ce9c0 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -67,14 +67,16 @@ nfs4_deviceid_hash(const struct nfs4_deviceid *id)
67} 67}
68 68
69static struct nfs4_deviceid_node * 69static struct nfs4_deviceid_node *
70_lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id, 70_lookup_deviceid(const struct pnfs_layoutdriver_type *ld,
71 const struct nfs_client *clp, const struct nfs4_deviceid *id,
71 long hash) 72 long hash)
72{ 73{
73 struct nfs4_deviceid_node *d; 74 struct nfs4_deviceid_node *d;
74 struct hlist_node *n; 75 struct hlist_node *n;
75 76
76 hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) 77 hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node)
77 if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) { 78 if (d->ld == ld && d->nfs_client == clp &&
79 !memcmp(&d->deviceid, id, sizeof(*id))) {
78 if (atomic_read(&d->ref)) 80 if (atomic_read(&d->ref))
79 return d; 81 return d;
80 else 82 else
@@ -90,13 +92,14 @@ _lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
90 * @id deviceid to look up 92 * @id deviceid to look up
91 */ 93 */
92struct nfs4_deviceid_node * 94struct nfs4_deviceid_node *
93_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id, 95_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
96 const struct nfs_client *clp, const struct nfs4_deviceid *id,
94 long hash) 97 long hash)
95{ 98{
96 struct nfs4_deviceid_node *d; 99 struct nfs4_deviceid_node *d;
97 100
98 rcu_read_lock(); 101 rcu_read_lock();
99 d = _lookup_deviceid(clp, id, hash); 102 d = _lookup_deviceid(ld, clp, id, hash);
100 if (d && !atomic_inc_not_zero(&d->ref)) 103 if (d && !atomic_inc_not_zero(&d->ref))
101 d = NULL; 104 d = NULL;
102 rcu_read_unlock(); 105 rcu_read_unlock();
@@ -104,9 +107,10 @@ _find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
104} 107}
105 108
106struct nfs4_deviceid_node * 109struct nfs4_deviceid_node *
107nfs4_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id) 110nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
111 const struct nfs_client *clp, const struct nfs4_deviceid *id)
108{ 112{
109 return _find_get_deviceid(clp, id, nfs4_deviceid_hash(id)); 113 return _find_get_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
110} 114}
111EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid); 115EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
112 116
@@ -119,13 +123,14 @@ EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
119 * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise. 123 * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
120 */ 124 */
121struct nfs4_deviceid_node * 125struct nfs4_deviceid_node *
122nfs4_unhash_put_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id) 126nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
127 const struct nfs_client *clp, const struct nfs4_deviceid *id)
123{ 128{
124 struct nfs4_deviceid_node *d; 129 struct nfs4_deviceid_node *d;
125 130
126 spin_lock(&nfs4_deviceid_lock); 131 spin_lock(&nfs4_deviceid_lock);
127 rcu_read_lock(); 132 rcu_read_lock();
128 d = _lookup_deviceid(clp, id, nfs4_deviceid_hash(id)); 133 d = _lookup_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
129 rcu_read_unlock(); 134 rcu_read_unlock();
130 if (!d) { 135 if (!d) {
131 spin_unlock(&nfs4_deviceid_lock); 136 spin_unlock(&nfs4_deviceid_lock);
@@ -150,11 +155,12 @@ EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
150 * @id deviceid to delete 155 * @id deviceid to delete
151 */ 156 */
152void 157void
153nfs4_delete_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id) 158nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
159 const struct nfs_client *clp, const struct nfs4_deviceid *id)
154{ 160{
155 struct nfs4_deviceid_node *d; 161 struct nfs4_deviceid_node *d;
156 162
157 d = nfs4_unhash_put_deviceid(clp, id); 163 d = nfs4_unhash_put_deviceid(ld, clp, id);
158 if (!d) 164 if (!d)
159 return; 165 return;
160 d->ld->free_deviceid_node(d); 166 d->ld->free_deviceid_node(d);
@@ -194,7 +200,7 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new)
194 200
195 spin_lock(&nfs4_deviceid_lock); 201 spin_lock(&nfs4_deviceid_lock);
196 hash = nfs4_deviceid_hash(&new->deviceid); 202 hash = nfs4_deviceid_hash(&new->deviceid);
197 d = _find_get_deviceid(new->nfs_client, &new->deviceid, hash); 203 d = _find_get_deviceid(new->ld, new->nfs_client, &new->deviceid, hash);
198 if (d) { 204 if (d) {
199 spin_unlock(&nfs4_deviceid_lock); 205 spin_unlock(&nfs4_deviceid_lock);
200 return d; 206 return d;