|
@@ -36,30 +36,6 @@
|
|
|
|
|
|
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
|
|
|
|
|
|
-/*
|
|
|
- * Device ID RCU cache. A device ID is unique per client ID and layout type.
|
|
|
- */
|
|
|
-#define NFS4_FL_DEVICE_ID_HASH_BITS 5
|
|
|
-#define NFS4_FL_DEVICE_ID_HASH_SIZE (1 << NFS4_FL_DEVICE_ID_HASH_BITS)
|
|
|
-#define NFS4_FL_DEVICE_ID_HASH_MASK (NFS4_FL_DEVICE_ID_HASH_SIZE - 1)
|
|
|
-
|
|
|
-static inline u32
|
|
|
-nfs4_fl_deviceid_hash(struct nfs4_deviceid *id)
|
|
|
-{
|
|
|
- unsigned char *cptr = (unsigned char *)id->data;
|
|
|
- unsigned int nbytes = NFS4_DEVICEID4_SIZE;
|
|
|
- u32 x = 0;
|
|
|
-
|
|
|
- while (nbytes--) {
|
|
|
- x *= 37;
|
|
|
- x += *cptr++;
|
|
|
- }
|
|
|
- return x & NFS4_FL_DEVICE_ID_HASH_MASK;
|
|
|
-}
|
|
|
-
|
|
|
-static struct hlist_head filelayout_deviceid_cache[NFS4_FL_DEVICE_ID_HASH_SIZE];
|
|
|
-static DEFINE_SPINLOCK(filelayout_deviceid_lock);
|
|
|
-
|
|
|
/*
|
|
|
* Data server cache
|
|
|
*
|
|
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds)
|
|
|
ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
-print_ds_list(struct nfs4_file_layout_dsaddr *dsaddr)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- ifdebug(FACILITY) {
|
|
|
- printk("%s dsaddr->ds_num %d\n", __func__,
|
|
|
- dsaddr->ds_num);
|
|
|
- for (i = 0; i < dsaddr->ds_num; i++)
|
|
|
- print_ds(dsaddr->ds_list[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void print_deviceid(struct nfs4_deviceid *id)
|
|
|
-{
|
|
|
- u32 *p = (u32 *)id;
|
|
|
-
|
|
|
- dprintk("%s: device id= [%x%x%x%x]\n", __func__,
|
|
|
- p[0], p[1], p[2], p[3]);
|
|
|
-}
|
|
|
-
|
|
|
/* nfs4_ds_cache_lock is held */
|
|
|
static struct nfs4_pnfs_ds *
|
|
|
_data_server_lookup_locked(u32 ip_addr, u32 port)
|
|
@@ -207,7 +162,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
|
|
|
struct nfs4_pnfs_ds *ds;
|
|
|
int i;
|
|
|
|
|
|
- print_deviceid(&dsaddr->deviceid);
|
|
|
+ nfs4_print_deviceid(&dsaddr->id_node.deviceid);
|
|
|
|
|
|
for (i = 0; i < dsaddr->ds_num; i++) {
|
|
|
ds = dsaddr->ds_list[i];
|
|
@@ -431,8 +386,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
|
|
|
dsaddr->stripe_indices = stripe_indices;
|
|
|
stripe_indices = NULL;
|
|
|
dsaddr->ds_num = num;
|
|
|
- dsaddr->nfs_client = NFS_SERVER(ino)->nfs_client;
|
|
|
- memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id));
|
|
|
+ nfs4_init_deviceid_node(&dsaddr->id_node, NFS_SERVER(ino)->nfs_client,
|
|
|
+ &pdev->dev_id);
|
|
|
|
|
|
for (i = 0; i < dsaddr->ds_num; i++) {
|
|
|
int j;
|
|
@@ -505,8 +460,8 @@ out_err:
|
|
|
static struct nfs4_file_layout_dsaddr *
|
|
|
decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags)
|
|
|
{
|
|
|
- struct nfs4_file_layout_dsaddr *d, *new;
|
|
|
- long hash;
|
|
|
+ struct nfs4_deviceid_node *d;
|
|
|
+ struct nfs4_file_layout_dsaddr *n, *new;
|
|
|
|
|
|
new = decode_device(inode, dev, gfp_flags);
|
|
|
if (!new) {
|
|
@@ -515,20 +470,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- spin_lock(&filelayout_deviceid_lock);
|
|
|
- d = nfs4_fl_find_get_deviceid(new->nfs_client, &new->deviceid);
|
|
|
- if (d) {
|
|
|
- spin_unlock(&filelayout_deviceid_lock);
|
|
|
+ d = nfs4_insert_deviceid_node(&new->id_node);
|
|
|
+ n = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
|
|
|
+ if (n != new) {
|
|
|
nfs4_fl_free_deviceid(new);
|
|
|
- return d;
|
|
|
+ return n;
|
|
|
}
|
|
|
|
|
|
- INIT_HLIST_NODE(&new->node);
|
|
|
- atomic_set(&new->ref, 1);
|
|
|
- hash = nfs4_fl_deviceid_hash(&new->deviceid);
|
|
|
- hlist_add_head_rcu(&new->node, &filelayout_deviceid_cache[hash]);
|
|
|
- spin_unlock(&filelayout_deviceid_lock);
|
|
|
-
|
|
|
return new;
|
|
|
}
|
|
|
|
|
@@ -600,34 +548,8 @@ out_free:
|
|
|
void
|
|
|
nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
|
|
|
{
|
|
|
- if (atomic_dec_and_lock(&dsaddr->ref, &filelayout_deviceid_lock)) {
|
|
|
- hlist_del_rcu(&dsaddr->node);
|
|
|
- spin_unlock(&filelayout_deviceid_lock);
|
|
|
-
|
|
|
- synchronize_rcu();
|
|
|
+ if (nfs4_put_deviceid_node(&dsaddr->id_node))
|
|
|
nfs4_fl_free_deviceid(dsaddr);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-struct nfs4_file_layout_dsaddr *
|
|
|
-nfs4_fl_find_get_deviceid(struct nfs_client *clp, struct nfs4_deviceid *id)
|
|
|
-{
|
|
|
- struct nfs4_file_layout_dsaddr *d;
|
|
|
- struct hlist_node *n;
|
|
|
- long hash = nfs4_fl_deviceid_hash(id);
|
|
|
-
|
|
|
- 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))) {
|
|
|
- if (!atomic_inc_not_zero(&d->ref))
|
|
|
- goto fail;
|
|
|
- rcu_read_unlock();
|
|
|
- return d;
|
|
|
- }
|
|
|
- }
|
|
|
-fail:
|
|
|
- rcu_read_unlock();
|
|
|
- return NULL;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -675,15 +597,15 @@ static void
|
|
|
filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr,
|
|
|
int err, u32 ds_addr)
|
|
|
{
|
|
|
- u32 *p = (u32 *)&dsaddr->deviceid;
|
|
|
+ u32 *p = (u32 *)&dsaddr->id_node.deviceid;
|
|
|
|
|
|
printk(KERN_ERR "NFS: data server %x connection error %d."
|
|
|
" Deviceid [%x%x%x%x] marked out of use.\n",
|
|
|
ds_addr, err, p[0], p[1], p[2], p[3]);
|
|
|
|
|
|
- spin_lock(&filelayout_deviceid_lock);
|
|
|
+ spin_lock(&nfs4_ds_cache_lock);
|
|
|
dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY;
|
|
|
- spin_unlock(&filelayout_deviceid_lock);
|
|
|
+ spin_unlock(&nfs4_ds_cache_lock);
|
|
|
}
|
|
|
|
|
|
struct nfs4_pnfs_ds *
|