Skip to content

Commit a1eaecb

Browse files
Benny HalevyBoaz Harrosh
authored andcommitted
NFSv4.1: make deviceid cache global
Move deviceid cache from the pnfs files layout driver to the generic layer in preparation for the objects layout driver. Signed-off-by: Benny Halevy <[email protected]>
1 parent 45df3c8 commit a1eaecb

File tree

6 files changed

+194
-103
lines changed

6 files changed

+194
-103
lines changed

fs/nfs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
1515
delegation.o idmap.o \
1616
callback.o callback_xdr.o callback_proc.o \
1717
nfs4namespace.o
18-
nfs-$(CONFIG_NFS_V4_1) += pnfs.o
18+
nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
1919
nfs-$(CONFIG_SYSCTL) += sysctl.o
2020
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
2121

fs/nfs/nfs4filelayout.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
421421
struct nfs4_deviceid *id,
422422
gfp_t gfp_flags)
423423
{
424+
struct nfs4_deviceid_node *d;
424425
struct nfs4_file_layout_dsaddr *dsaddr;
425426
int status = -EINVAL;
426427
struct nfs_server *nfss = NFS_SERVER(lo->plh_inode);
@@ -440,12 +441,13 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
440441
}
441442

442443
/* find and reference the deviceid */
443-
dsaddr = nfs4_fl_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id);
444-
if (dsaddr == NULL) {
444+
d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id);
445+
if (d == NULL) {
445446
dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
446447
if (dsaddr == NULL)
447448
goto out;
448-
}
449+
} else
450+
dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
449451
fl->dsaddr = dsaddr;
450452

451453
if (fl->first_stripe_index < 0 ||
@@ -535,7 +537,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
535537

536538
memcpy(id, p, sizeof(*id));
537539
p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
538-
print_deviceid(id);
540+
nfs4_print_deviceid(id);
539541

540542
nfl_util = be32_to_cpup(p++);
541543
if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)

fs/nfs/nfs4filelayout.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ struct nfs4_pnfs_ds {
5959
#define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001
6060

6161
struct nfs4_file_layout_dsaddr {
62-
struct hlist_node node;
63-
struct nfs_client *nfs_client;
64-
struct nfs4_deviceid deviceid;
65-
atomic_t ref;
62+
struct nfs4_deviceid_node id_node;
6663
unsigned long flags;
6764
u32 stripe_count;
6865
u8 *stripe_indices;
@@ -96,13 +93,10 @@ extern struct nfs_fh *
9693
nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
9794

9895
extern void print_ds(struct nfs4_pnfs_ds *ds);
99-
extern void print_deviceid(struct nfs4_deviceid *dev_id);
10096
u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset);
10197
u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j);
10298
struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
10399
u32 ds_idx);
104-
extern struct nfs4_file_layout_dsaddr *
105-
nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id);
106100
extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
107101
struct nfs4_file_layout_dsaddr *
108102
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);

fs/nfs/nfs4filelayoutdev.c

Lines changed: 13 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,6 @@
3636

3737
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
3838

39-
/*
40-
* Device ID RCU cache. A device ID is unique per client ID and layout type.
41-
*/
42-
#define NFS4_FL_DEVICE_ID_HASH_BITS 5
43-
#define NFS4_FL_DEVICE_ID_HASH_SIZE (1 << NFS4_FL_DEVICE_ID_HASH_BITS)
44-
#define NFS4_FL_DEVICE_ID_HASH_MASK (NFS4_FL_DEVICE_ID_HASH_SIZE - 1)
45-
46-
static inline u32
47-
nfs4_fl_deviceid_hash(struct nfs4_deviceid *id)
48-
{
49-
unsigned char *cptr = (unsigned char *)id->data;
50-
unsigned int nbytes = NFS4_DEVICEID4_SIZE;
51-
u32 x = 0;
52-
53-
while (nbytes--) {
54-
x *= 37;
55-
x += *cptr++;
56-
}
57-
return x & NFS4_FL_DEVICE_ID_HASH_MASK;
58-
}
59-
60-
static struct hlist_head filelayout_deviceid_cache[NFS4_FL_DEVICE_ID_HASH_SIZE];
61-
static DEFINE_SPINLOCK(filelayout_deviceid_lock);
62-
6339
/*
6440
* Data server cache
6541
*
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds)
8965
ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
9066
}
9167

92-
void
93-
print_ds_list(struct nfs4_file_layout_dsaddr *dsaddr)
94-
{
95-
int i;
96-
97-
ifdebug(FACILITY) {
98-
printk("%s dsaddr->ds_num %d\n", __func__,
99-
dsaddr->ds_num);
100-
for (i = 0; i < dsaddr->ds_num; i++)
101-
print_ds(dsaddr->ds_list[i]);
102-
}
103-
}
104-
105-
void print_deviceid(struct nfs4_deviceid *id)
106-
{
107-
u32 *p = (u32 *)id;
108-
109-
dprintk("%s: device id= [%x%x%x%x]\n", __func__,
110-
p[0], p[1], p[2], p[3]);
111-
}
112-
11368
/* nfs4_ds_cache_lock is held */
11469
static struct nfs4_pnfs_ds *
11570
_data_server_lookup_locked(u32 ip_addr, u32 port)
@@ -207,7 +162,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
207162
struct nfs4_pnfs_ds *ds;
208163
int i;
209164

210-
print_deviceid(&dsaddr->deviceid);
165+
nfs4_print_deviceid(&dsaddr->id_node.deviceid);
211166

212167
for (i = 0; i < dsaddr->ds_num; i++) {
213168
ds = dsaddr->ds_list[i];
@@ -431,8 +386,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
431386
dsaddr->stripe_indices = stripe_indices;
432387
stripe_indices = NULL;
433388
dsaddr->ds_num = num;
434-
dsaddr->nfs_client = NFS_SERVER(ino)->nfs_client;
435-
memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id));
389+
nfs4_init_deviceid_node(&dsaddr->id_node, NFS_SERVER(ino)->nfs_client,
390+
&pdev->dev_id);
436391

437392
for (i = 0; i < dsaddr->ds_num; i++) {
438393
int j;
@@ -505,8 +460,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
505460
static struct nfs4_file_layout_dsaddr *
506461
decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags)
507462
{
508-
struct nfs4_file_layout_dsaddr *d, *new;
509-
long hash;
463+
struct nfs4_deviceid_node *d;
464+
struct nfs4_file_layout_dsaddr *n, *new;
510465

511466
new = decode_device(inode, dev, gfp_flags);
512467
if (!new) {
@@ -515,20 +470,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
515470
return NULL;
516471
}
517472

518-
spin_lock(&filelayout_deviceid_lock);
519-
d = nfs4_fl_find_get_deviceid(new->nfs_client, &new->deviceid);
520-
if (d) {
521-
spin_unlock(&filelayout_deviceid_lock);
473+
d = nfs4_insert_deviceid_node(&new->id_node);
474+
n = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
475+
if (n != new) {
522476
nfs4_fl_free_deviceid(new);
523-
return d;
477+
return n;
524478
}
525479

526-
INIT_HLIST_NODE(&new->node);
527-
atomic_set(&new->ref, 1);
528-
hash = nfs4_fl_deviceid_hash(&new->deviceid);
529-
hlist_add_head_rcu(&new->node, &filelayout_deviceid_cache[hash]);
530-
spin_unlock(&filelayout_deviceid_lock);
531-
532480
return new;
533481
}
534482

@@ -600,34 +548,8 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla
600548
void
601549
nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
602550
{
603-
if (atomic_dec_and_lock(&dsaddr->ref, &filelayout_deviceid_lock)) {
604-
hlist_del_rcu(&dsaddr->node);
605-
spin_unlock(&filelayout_deviceid_lock);
606-
607-
synchronize_rcu();
551+
if (nfs4_put_deviceid_node(&dsaddr->id_node))
608552
nfs4_fl_free_deviceid(dsaddr);
609-
}
610-
}
611-
612-
struct nfs4_file_layout_dsaddr *
613-
nfs4_fl_find_get_deviceid(struct nfs_client *clp, struct nfs4_deviceid *id)
614-
{
615-
struct nfs4_file_layout_dsaddr *d;
616-
struct hlist_node *n;
617-
long hash = nfs4_fl_deviceid_hash(id);
618-
619-
rcu_read_lock();
620-
hlist_for_each_entry_rcu(d, n, &filelayout_deviceid_cache[hash], node) {
621-
if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) {
622-
if (!atomic_inc_not_zero(&d->ref))
623-
goto fail;
624-
rcu_read_unlock();
625-
return d;
626-
}
627-
}
628-
fail:
629-
rcu_read_unlock();
630-
return NULL;
631553
}
632554

633555
/*
@@ -675,15 +597,15 @@ static void
675597
filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr,
676598
int err, u32 ds_addr)
677599
{
678-
u32 *p = (u32 *)&dsaddr->deviceid;
600+
u32 *p = (u32 *)&dsaddr->id_node.deviceid;
679601

680602
printk(KERN_ERR "NFS: data server %x connection error %d."
681603
" Deviceid [%x%x%x%x] marked out of use.\n",
682604
ds_addr, err, p[0], p[1], p[2], p[3]);
683605

684-
spin_lock(&filelayout_deviceid_lock);
606+
spin_lock(&nfs4_ds_cache_lock);
685607
dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY;
686-
spin_unlock(&filelayout_deviceid_lock);
608+
spin_unlock(&nfs4_ds_cache_lock);
687609
}
688610

689611
struct nfs4_pnfs_ds *

fs/nfs/pnfs.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
157157
void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
158158
int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
159159

160+
/* pnfs_dev.c */
161+
struct nfs4_deviceid_node {
162+
struct hlist_node node;
163+
const struct nfs_client *nfs_client;
164+
struct nfs4_deviceid deviceid;
165+
atomic_t ref;
166+
};
167+
168+
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
169+
struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
170+
struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
171+
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
172+
const struct nfs_client *,
173+
const struct nfs4_deviceid *);
174+
struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *);
175+
bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *);
176+
160177
static inline int lo_fail_bit(u32 iomode)
161178
{
162179
return iomode == IOMODE_RW ?

0 commit comments

Comments
 (0)