Loading fs/nfs/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ delegation.o idmap.o \ callback.o callback_xdr.o callback_proc.o \ nfs4namespace.o nfs-$(CONFIG_NFS_V4_1) += pnfs.o nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o nfs-$(CONFIG_SYSCTL) += sysctl.o nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o Loading fs/nfs/nfs4filelayout.c +6 −4 Original line number Diff line number Diff line Loading @@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, struct nfs4_deviceid *id, gfp_t gfp_flags) { struct nfs4_deviceid_node *d; struct nfs4_file_layout_dsaddr *dsaddr; int status = -EINVAL; struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); Loading @@ -440,12 +441,13 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, } /* find and reference the deviceid */ dsaddr = nfs4_fl_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id); if (dsaddr == NULL) { d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id); if (d == NULL) { dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); if (dsaddr == NULL) goto out; } } else dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); fl->dsaddr = dsaddr; if (fl->first_stripe_index < 0 || Loading Loading @@ -535,7 +537,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, memcpy(id, p, sizeof(*id)); p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); print_deviceid(id); nfs4_print_deviceid(id); nfl_util = be32_to_cpup(p++); if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) Loading fs/nfs/nfs4filelayout.h +1 −7 Original line number Diff line number Diff line Loading @@ -59,10 +59,7 @@ struct nfs4_pnfs_ds { #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 struct nfs4_file_layout_dsaddr { struct hlist_node node; struct nfs_client *nfs_client; struct nfs4_deviceid deviceid; atomic_t ref; struct nfs4_deviceid_node id_node; unsigned long flags; u32 stripe_count; u8 *stripe_indices; Loading Loading @@ -96,13 +93,10 @@ extern struct nfs_fh * nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); extern void print_ds(struct nfs4_pnfs_ds *ds); extern void print_deviceid(struct nfs4_deviceid *dev_id); u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx); extern struct nfs4_file_layout_dsaddr * nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id); extern void nfs4_fl_put_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); Loading fs/nfs/nfs4filelayoutdev.c +13 −91 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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) Loading Loading @@ -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]; Loading Loading @@ -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; Loading Loading @@ -505,8 +460,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) 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) { Loading @@ -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; } Loading Loading @@ -600,35 +548,9 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla 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; } /* * Want res = (offset - layout->pattern_offset)/ layout->stripe_unit Loading Loading @@ -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 * Loading fs/nfs/pnfs.h +17 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,23 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier); void pnfs_set_layoutcommit(struct nfs_write_data *wdata); int pnfs_layoutcommit_inode(struct inode *inode, bool sync); /* pnfs_dev.c */ struct nfs4_deviceid_node { struct hlist_node node; const struct nfs_client *nfs_client; struct nfs4_deviceid deviceid; atomic_t ref; }; 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_init_deviceid_node(struct nfs4_deviceid_node *, const struct nfs_client *, const struct nfs4_deviceid *); struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *); bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *); static inline int lo_fail_bit(u32 iomode) { return iomode == IOMODE_RW ? Loading Loading
fs/nfs/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ delegation.o idmap.o \ callback.o callback_xdr.o callback_proc.o \ nfs4namespace.o nfs-$(CONFIG_NFS_V4_1) += pnfs.o nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o nfs-$(CONFIG_SYSCTL) += sysctl.o nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o Loading
fs/nfs/nfs4filelayout.c +6 −4 Original line number Diff line number Diff line Loading @@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, struct nfs4_deviceid *id, gfp_t gfp_flags) { struct nfs4_deviceid_node *d; struct nfs4_file_layout_dsaddr *dsaddr; int status = -EINVAL; struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); Loading @@ -440,12 +441,13 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, } /* find and reference the deviceid */ dsaddr = nfs4_fl_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id); if (dsaddr == NULL) { d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id); if (d == NULL) { dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); if (dsaddr == NULL) goto out; } } else dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); fl->dsaddr = dsaddr; if (fl->first_stripe_index < 0 || Loading Loading @@ -535,7 +537,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, memcpy(id, p, sizeof(*id)); p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); print_deviceid(id); nfs4_print_deviceid(id); nfl_util = be32_to_cpup(p++); if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) Loading
fs/nfs/nfs4filelayout.h +1 −7 Original line number Diff line number Diff line Loading @@ -59,10 +59,7 @@ struct nfs4_pnfs_ds { #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 struct nfs4_file_layout_dsaddr { struct hlist_node node; struct nfs_client *nfs_client; struct nfs4_deviceid deviceid; atomic_t ref; struct nfs4_deviceid_node id_node; unsigned long flags; u32 stripe_count; u8 *stripe_indices; Loading Loading @@ -96,13 +93,10 @@ extern struct nfs_fh * nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); extern void print_ds(struct nfs4_pnfs_ds *ds); extern void print_deviceid(struct nfs4_deviceid *dev_id); u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx); extern struct nfs4_file_layout_dsaddr * nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id); extern void nfs4_fl_put_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); Loading
fs/nfs/nfs4filelayoutdev.c +13 −91 Original line number Diff line number Diff line Loading @@ -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 * Loading Loading @@ -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) Loading Loading @@ -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]; Loading Loading @@ -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; Loading Loading @@ -505,8 +460,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) 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) { Loading @@ -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; } Loading Loading @@ -600,35 +548,9 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla 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; } /* * Want res = (offset - layout->pattern_offset)/ layout->stripe_unit Loading Loading @@ -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 * Loading
fs/nfs/pnfs.h +17 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,23 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier); void pnfs_set_layoutcommit(struct nfs_write_data *wdata); int pnfs_layoutcommit_inode(struct inode *inode, bool sync); /* pnfs_dev.c */ struct nfs4_deviceid_node { struct hlist_node node; const struct nfs_client *nfs_client; struct nfs4_deviceid deviceid; atomic_t ref; }; 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_init_deviceid_node(struct nfs4_deviceid_node *, const struct nfs_client *, const struct nfs4_deviceid *); struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *); bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *); static inline int lo_fail_bit(u32 iomode) { return iomode == IOMODE_RW ? Loading