@@ -275,14 +275,10 @@ __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args,
}
found:
- if (!server->pnfs_curr_ld->delete_deviceid) {
- res = cpu_to_be32(NFS4ERR_NOTSUPP);
- break;
- }
if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE)
dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, "
"deleting instead\n", __func__);
- server->pnfs_curr_ld->delete_deviceid(clp, &dev->cbd_dev_id);
+ nfs4_delete_deviceid(clp, &dev->cbd_dev_id);
}
out:
@@ -881,7 +881,6 @@ static struct pnfs_layoutdriver_type filelayout_type = {
.read_pagelist = filelayout_read_pagelist,
.write_pagelist = filelayout_write_pagelist,
.free_deviceid_node = filelayout_free_deveiceid_node,
- .delete_deviceid = filelayout_delete_deviceid,
};
static int __init nfs4filelayout_init(void)
@@ -101,6 +101,5 @@ extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr *
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
-void filelayout_delete_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
#endif /* FS_NFS_NFS4FILELAYOUT_H */
@@ -553,42 +553,6 @@ nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
nfs4_put_deviceid_node(&dsaddr->id_node);
}
-static struct nfs4_file_layout_dsaddr *
-nfs4_fl_unhash_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
-{
- struct nfs4_file_layout_dsaddr *d;
- struct hlist_node *n;
- long hash = nfs4_fl_deviceid_hash(id);
-
- dprintk("%s: hash %ld\n", __func__, hash);
- rcu_read_lock();
- hlist_for_each_entry_rcu(d, n, &filelayout_deviceid_cache[hash], node)
- if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id)))
- goto found;
- rcu_read_unlock();
- return NULL;
-
-found:
- rcu_read_unlock();
- spin_lock(&filelayout_deviceid_lock);
- hlist_del_init_rcu(&d->node);
- spin_unlock(&filelayout_deviceid_lock);
- synchronize_rcu();
-
- return d;
-}
-
-void
-filelayout_delete_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
-{
- struct nfs4_file_layout_dsaddr *d;
-
- d = nfs4_fl_unhash_deviceid(clp, id);
- /* balance the initial ref taken in decode_and_add_device */
- if (d && atomic_dec_and_test(&d->ref))
- nfs4_fl_free_deviceid(d);
-}
-
/*
* Want res = (offset - layout->pattern_offset)/ layout->stripe_unit
* Then: ((res + fsi) % dsaddr->stripe_count)
@@ -94,7 +94,6 @@ struct pnfs_layoutdriver_type {
enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how);
void (*free_deviceid_node) (struct nfs4_deviceid_node *);
- void (*delete_deviceid)(const struct nfs_client *, const struct nfs4_deviceid *);
};
struct pnfs_layout_hdr {
@@ -174,6 +173,7 @@ struct nfs4_deviceid_node {
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
+void nfs4_delete_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
const struct pnfs_layoutdriver_type *,
const struct nfs_client *,
@@ -94,6 +94,64 @@ fail:
}
EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
+/*
+ * Unhash and put deviceid
+ *
+ * @clp nfs_client associated with deviceid
+ * @id the deviceid to unhash
+ *
+ * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
+ */
+struct nfs4_deviceid_node *
+nfs4_unhash_put_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
+{
+ struct nfs4_deviceid_node *d;
+ struct hlist_node *n;
+ long hash = nfs4_deviceid_hash(id);
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node)
+ if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id)))
+ goto found;
+ rcu_read_unlock();
+ return NULL;
+
+found:
+ rcu_read_unlock();
+ spin_lock(&nfs4_deviceid_lock);
+ hlist_del_init_rcu(&d->node);
+ spin_unlock(&nfs4_deviceid_lock);
+ synchronize_rcu();
+
+ /* balance the initial ref set in pnfs_insert_deviceid */
+ if (atomic_dec_and_test(&d->ref))
+ return d;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
+
+/*
+ * Delete a deviceid from cache
+ *
+ * @clp struct nfs_client qualifying the deviceid
+ * @id deviceid to delete
+ */
+void
+nfs4_delete_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
+{
+ struct nfs4_deviceid_node *d;
+
+ d = nfs4_unhash_put_deviceid(clp, id);
+ if (!d)
+ return;
+ if (d->ld->free_deviceid_node)
+ d->ld->free_deviceid_node(d);
+ else
+ kfree(d);
+}
+EXPORT_SYMBOL_GPL(nfs4_delete_deviceid);
+
void
nfs4_init_deviceid_node(struct nfs4_deviceid_node *d,
const struct pnfs_layoutdriver_type *ld,
Signed-off-by: Benny Halevy <bhalevy@panasas.com> --- fs/nfs/callback_proc.c | 6 +---- fs/nfs/nfs4filelayout.c | 1 - fs/nfs/nfs4filelayout.h | 1 - fs/nfs/nfs4filelayoutdev.c | 36 --------------------------- fs/nfs/pnfs.h | 2 +- fs/nfs/pnfs_dev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 44 deletions(-)