Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35c8bb54 authored by Benny Halevy's avatar Benny Halevy Committed by Boaz Harrosh
Browse files

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: default avatarBenny Halevy <bhalevy@panasas.com>
parent 1be5683b
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -278,7 +278,7 @@ __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args,
		if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE)
		if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE)
			dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, "
			dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, "
				"deleting instead\n", __func__);
				"deleting instead\n", __func__);
		nfs4_delete_deviceid(clp, &dev->cbd_dev_id);
		nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id);
	}
	}


out:
out:
+2 −1
Original line number Original line Diff line number Diff line
@@ -441,7 +441,8 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
	}
	}


	/* find and reference the deviceid */
	/* find and reference the deviceid */
	d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id);
	d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
				   NFS_SERVER(lo->plh_inode)->nfs_client, id);
	if (d == NULL) {
	if (d == NULL) {
		dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
		dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
		if (dsaddr == NULL)
		if (dsaddr == NULL)
+3 −3
Original line number Original line Diff line number Diff line
@@ -171,9 +171,9 @@ struct nfs4_deviceid_node {
};
};


void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
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_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_delete_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
			     const struct pnfs_layoutdriver_type *,
			     const struct pnfs_layoutdriver_type *,
			     const struct nfs_client *,
			     const struct nfs_client *,
+17 −11
Original line number Original line Diff line number Diff line
@@ -67,14 +67,16 @@ nfs4_deviceid_hash(const struct nfs4_deviceid *id)
}
}


static struct nfs4_deviceid_node *
static struct nfs4_deviceid_node *
_lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
_lookup_deviceid(const struct pnfs_layoutdriver_type *ld,
		 const struct nfs_client *clp, const struct nfs4_deviceid *id,
		 long hash)
		 long hash)
{
{
	struct nfs4_deviceid_node *d;
	struct nfs4_deviceid_node *d;
	struct hlist_node *n;
	struct hlist_node *n;


	hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node)
	hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node)
		if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) {
		if (d->ld == ld && d->nfs_client == clp &&
		    !memcmp(&d->deviceid, id, sizeof(*id))) {
			if (atomic_read(&d->ref))
			if (atomic_read(&d->ref))
				return d;
				return d;
			else
			else
@@ -90,13 +92,14 @@ _lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
 * @id deviceid to look up
 * @id deviceid to look up
 */
 */
struct nfs4_deviceid_node *
struct nfs4_deviceid_node *
_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
		   const struct nfs_client *clp, const struct nfs4_deviceid *id,
		   long hash)
		   long hash)
{
{
	struct nfs4_deviceid_node *d;
	struct nfs4_deviceid_node *d;


	rcu_read_lock();
	rcu_read_lock();
	d = _lookup_deviceid(clp, id, hash);
	d = _lookup_deviceid(ld, clp, id, hash);
	if (d && !atomic_inc_not_zero(&d->ref))
	if (d && !atomic_inc_not_zero(&d->ref))
		d = NULL;
		d = NULL;
	rcu_read_unlock();
	rcu_read_unlock();
@@ -104,9 +107,10 @@ _find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
}
}


struct nfs4_deviceid_node *
struct nfs4_deviceid_node *
nfs4_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
		       const struct nfs_client *clp, const struct nfs4_deviceid *id)
{
{
	return _find_get_deviceid(clp, id, nfs4_deviceid_hash(id));
	return _find_get_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
}
}
EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);


@@ -119,13 +123,14 @@ EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
 * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
 * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
 */
 */
struct nfs4_deviceid_node *
struct nfs4_deviceid_node *
nfs4_unhash_put_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
			 const struct nfs_client *clp, const struct nfs4_deviceid *id)
{
{
	struct nfs4_deviceid_node *d;
	struct nfs4_deviceid_node *d;


	spin_lock(&nfs4_deviceid_lock);
	spin_lock(&nfs4_deviceid_lock);
	rcu_read_lock();
	rcu_read_lock();
	d = _lookup_deviceid(clp, id, nfs4_deviceid_hash(id));
	d = _lookup_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
	rcu_read_unlock();
	rcu_read_unlock();
	if (!d) {
	if (!d) {
		spin_unlock(&nfs4_deviceid_lock);
		spin_unlock(&nfs4_deviceid_lock);
@@ -150,11 +155,12 @@ EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
 * @id deviceid to delete
 * @id deviceid to delete
 */
 */
void
void
nfs4_delete_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
		     const struct nfs_client *clp, const struct nfs4_deviceid *id)
{
{
	struct nfs4_deviceid_node *d;
	struct nfs4_deviceid_node *d;


	d = nfs4_unhash_put_deviceid(clp, id);
	d = nfs4_unhash_put_deviceid(ld, clp, id);
	if (!d)
	if (!d)
		return;
		return;
	d->ld->free_deviceid_node(d);
	d->ld->free_deviceid_node(d);
@@ -194,7 +200,7 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new)


	spin_lock(&nfs4_deviceid_lock);
	spin_lock(&nfs4_deviceid_lock);
	hash = nfs4_deviceid_hash(&new->deviceid);
	hash = nfs4_deviceid_hash(&new->deviceid);
	d = _find_get_deviceid(new->nfs_client, &new->deviceid, hash);
	d = _find_get_deviceid(new->ld, new->nfs_client, &new->deviceid, hash);
	if (d) {
	if (d) {
		spin_unlock(&nfs4_deviceid_lock);
		spin_unlock(&nfs4_deviceid_lock);
		return d;
		return d;