On Wed, Jul 24, 2019 at 05:07:20PM -0400, Vivek Goyal wrote: > Move new mapping setup code in a separate function. More code will come > in fuse_iomap_begin() and its becoming too big.
Reviewed-by: Liu Bo <[email protected]> thanks, -liubo > > Signed-off-by: Vivek Goyal <[email protected]> > --- > fs/fuse/file.c | 116 +++++++++++++++++++++++++++---------------------- > 1 file changed, 64 insertions(+), 52 deletions(-) > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index 93f8e62e2b5b..a2c19e4a28b5 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -1882,6 +1882,67 @@ static void fuse_fill_iomap(struct inode *inode, > loff_t pos, loff_t length, > } > } > > +static int iomap_begin_setup_new_mapping(struct inode *inode, loff_t pos, > + loff_t length, unsigned flags, > + struct iomap *iomap) > +{ > + struct fuse_inode *fi = get_fuse_inode(inode); > + struct fuse_conn *fc = get_fuse_conn(inode); > + struct fuse_dax_mapping *dmap, *alloc_dmap = NULL; > + int ret; > + > + /* Can't do reclaim in fault path yet due to lock ordering. > + * Read path takes shared inode lock and that's not sufficient > + * for inline range reclaim. Caller needs to drop lock, wait > + * and retry. > + */ > + if (flags & IOMAP_FAULT || !(flags & IOMAP_WRITE)) { > + alloc_dmap = alloc_dax_mapping(fc); > + if (!alloc_dmap) > + return -ENOSPC; > + } else { > + alloc_dmap = alloc_dax_mapping_reclaim(fc, inode); > + if (IS_ERR(alloc_dmap)) > + return PTR_ERR(alloc_dmap); > + } > + > + /* If we are here, we should have memory allocated */ > + if (WARN_ON(!alloc_dmap)) > + return -EBUSY; > + > + /* > + * Drop read lock and take write lock so that only one > + * caller can try to setup mapping and other waits > + */ > + down_write(&fi->i_dmap_sem); > + /* > + * We dropped lock. Check again if somebody else setup > + * mapping already. > + */ > + dmap = fuse_dax_interval_tree_iter_first(&fi->dmap_tree, pos, > + pos); > + if (dmap) { > + fuse_fill_iomap(inode, pos, length, iomap, dmap, flags); > + dmap_add_to_free_pool(fc, alloc_dmap); > + up_write(&fi->i_dmap_sem); > + return 0; > + } > + > + /* Setup one mapping */ > + ret = fuse_setup_one_mapping(inode, > + ALIGN_DOWN(pos, FUSE_DAX_MEM_RANGE_SZ), alloc_dmap); > + if (ret < 0) { > + printk("fuse_setup_one_mapping() failed. err=%d" > + " pos=0x%llx\n", ret, pos); > + dmap_add_to_free_pool(fc, alloc_dmap); > + up_write(&fi->i_dmap_sem); > + return ret; > + } > + fuse_fill_iomap(inode, pos, length, iomap, alloc_dmap, flags); > + up_write(&fi->i_dmap_sem); > + return 0; > +} > + > /* This is just for DAX and the mapping is ephemeral, do not use it for other > * purposes since there is no block device with a permanent mapping. > */ > @@ -1890,8 +1951,7 @@ static int fuse_iomap_begin(struct inode *inode, loff_t > pos, loff_t length, > { > struct fuse_inode *fi = get_fuse_inode(inode); > struct fuse_conn *fc = get_fuse_conn(inode); > - struct fuse_dax_mapping *dmap, *alloc_dmap = NULL; > - int ret; > + struct fuse_dax_mapping *dmap; > > /* We don't support FIEMAP */ > BUG_ON(flags & IOMAP_REPORT); > @@ -1932,56 +1992,8 @@ static int fuse_iomap_begin(struct inode *inode, > loff_t pos, loff_t length, > if (pos >= i_size_read(inode)) > goto iomap_hole; > > - /* Can't do reclaim in fault path yet due to lock ordering. > - * Read path takes shared inode lock and that's not sufficient > - * for inline range reclaim. Caller needs to drop lock, wait > - * and retry. > - */ > - if (flags & IOMAP_FAULT || !(flags & IOMAP_WRITE)) { > - alloc_dmap = alloc_dax_mapping(fc); > - if (!alloc_dmap) > - return -ENOSPC; > - } else { > - alloc_dmap = alloc_dax_mapping_reclaim(fc, inode); > - if (IS_ERR(alloc_dmap)) > - return PTR_ERR(alloc_dmap); > - } > - > - /* If we are here, we should have memory allocated */ > - if (WARN_ON(!alloc_dmap)) > - return -EBUSY; > - > - /* > - * Drop read lock and take write lock so that only one > - * caller can try to setup mapping and other waits > - */ > - down_write(&fi->i_dmap_sem); > - /* > - * We dropped lock. Check again if somebody else setup > - * mapping already. > - */ > - dmap = fuse_dax_interval_tree_iter_first(&fi->dmap_tree, pos, > - pos); > - if (dmap) { > - fuse_fill_iomap(inode, pos, length, iomap, dmap, flags); > - dmap_add_to_free_pool(fc, alloc_dmap); > - up_write(&fi->i_dmap_sem); > - return 0; > - } > - > - /* Setup one mapping */ > - ret = fuse_setup_one_mapping(inode, > - ALIGN_DOWN(pos, FUSE_DAX_MEM_RANGE_SZ), alloc_dmap); > - if (ret < 0) { > - printk("fuse_setup_one_mapping() failed. err=%d" > - " pos=0x%llx\n", ret, pos); > - dmap_add_to_free_pool(fc, alloc_dmap); > - up_write(&fi->i_dmap_sem); > - return ret; > - } > - fuse_fill_iomap(inode, pos, length, iomap, alloc_dmap, flags); > - up_write(&fi->i_dmap_sem); > - return 0; > + return iomap_begin_setup_new_mapping(inode, pos, length, flags, > + iomap); > } > > /* > -- > 2.17.2
