Loading fs/iomap.c +13 −8 Original line number Diff line number Diff line Loading @@ -84,8 +84,11 @@ iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags, * Now the data has been copied, commit the range we've copied. This * should not fail unless the filesystem has had a fatal error. */ ret = ops->iomap_end(inode, pos, length, written > 0 ? written : 0, if (ops->iomap_end) { ret = ops->iomap_end(inode, pos, length, written > 0 ? written : 0, flags, &iomap); } return written ? written : ret; } Loading Loading @@ -194,12 +197,9 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data, if (mapping_writably_mapped(inode->i_mapping)) flush_dcache_page(page); pagefault_disable(); copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); pagefault_enable(); flush_dcache_page(page); mark_page_accessed(page); status = iomap_write_end(inode, pos, bytes, copied, page); if (unlikely(status < 0)) Loading Loading @@ -470,13 +470,18 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi, if (ret) return ret; if (fi->fi_flags & FIEMAP_FLAG_SYNC) { ret = filemap_write_and_wait(inode->i_mapping); if (ret) return ret; } while (len > 0) { ret = iomap_apply(inode, start, len, 0, ops, &ctx, iomap_fiemap_actor); /* inode with no (attribute) mapping will give ENOENT */ if (ret == -ENOENT) break; if (ret < 0) return ret; if (ret == 0) Loading fs/xfs/xfs_iomap.c +49 −10 Original line number Diff line number Diff line Loading @@ -1041,20 +1041,14 @@ xfs_file_iomap_begin( return error; trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); xfs_bmbt_to_iomap(ip, iomap, &imap); } else if (nimaps) { xfs_iunlock(ip, XFS_ILOCK_EXCL); trace_xfs_iomap_found(ip, offset, length, 0, &imap); xfs_bmbt_to_iomap(ip, iomap, &imap); } else { ASSERT(nimaps); xfs_iunlock(ip, XFS_ILOCK_EXCL); trace_xfs_iomap_not_found(ip, offset, length, 0, &imap); iomap->blkno = IOMAP_NULL_BLOCK; iomap->type = IOMAP_HOLE; iomap->offset = offset; iomap->length = length; trace_xfs_iomap_found(ip, offset, length, 0, &imap); } xfs_bmbt_to_iomap(ip, iomap, &imap); return 0; } Loading Loading @@ -1116,3 +1110,48 @@ struct iomap_ops xfs_iomap_ops = { .iomap_begin = xfs_file_iomap_begin, .iomap_end = xfs_file_iomap_end, }; static int xfs_xattr_iomap_begin( struct inode *inode, loff_t offset, loff_t length, unsigned flags, struct iomap *iomap) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); struct xfs_bmbt_irec imap; int nimaps = 1, error = 0; unsigned lockmode; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; lockmode = xfs_ilock_data_map_shared(ip); /* if there are no attribute fork or extents, return ENOENT */ if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { error = -ENOENT; goto out_unlock; } ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, &nimaps, XFS_BMAPI_ENTIRE | XFS_BMAPI_ATTRFORK); out_unlock: xfs_iunlock(ip, lockmode); if (!error) { ASSERT(nimaps); xfs_bmbt_to_iomap(ip, iomap, &imap); } return error; } struct iomap_ops xfs_xattr_iomap_ops = { .iomap_begin = xfs_xattr_iomap_begin, }; fs/xfs/xfs_iomap.h +1 −0 Original line number Diff line number Diff line Loading @@ -35,5 +35,6 @@ void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, struct xfs_bmbt_irec *); extern struct iomap_ops xfs_iomap_ops; extern struct iomap_ops xfs_xattr_iomap_ops; #endif /* __XFS_IOMAP_H__*/ fs/xfs/xfs_iops.c +8 −1 Original line number Diff line number Diff line Loading @@ -1009,7 +1009,14 @@ xfs_vn_fiemap( int error; xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED); error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops); if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR; error = iomap_fiemap(inode, fieinfo, start, length, &xfs_xattr_iomap_ops); } else { error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops); } xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); return error; Loading fs/xfs/xfs_trace.h +0 −1 Original line number Diff line number Diff line Loading @@ -1298,7 +1298,6 @@ DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); DEFINE_IOMAP_EVENT(xfs_iomap_alloc); DEFINE_IOMAP_EVENT(xfs_iomap_found); DEFINE_IOMAP_EVENT(xfs_iomap_not_found); DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), Loading Loading
fs/iomap.c +13 −8 Original line number Diff line number Diff line Loading @@ -84,8 +84,11 @@ iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags, * Now the data has been copied, commit the range we've copied. This * should not fail unless the filesystem has had a fatal error. */ ret = ops->iomap_end(inode, pos, length, written > 0 ? written : 0, if (ops->iomap_end) { ret = ops->iomap_end(inode, pos, length, written > 0 ? written : 0, flags, &iomap); } return written ? written : ret; } Loading Loading @@ -194,12 +197,9 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data, if (mapping_writably_mapped(inode->i_mapping)) flush_dcache_page(page); pagefault_disable(); copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes); pagefault_enable(); flush_dcache_page(page); mark_page_accessed(page); status = iomap_write_end(inode, pos, bytes, copied, page); if (unlikely(status < 0)) Loading Loading @@ -470,13 +470,18 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi, if (ret) return ret; if (fi->fi_flags & FIEMAP_FLAG_SYNC) { ret = filemap_write_and_wait(inode->i_mapping); if (ret) return ret; } while (len > 0) { ret = iomap_apply(inode, start, len, 0, ops, &ctx, iomap_fiemap_actor); /* inode with no (attribute) mapping will give ENOENT */ if (ret == -ENOENT) break; if (ret < 0) return ret; if (ret == 0) Loading
fs/xfs/xfs_iomap.c +49 −10 Original line number Diff line number Diff line Loading @@ -1041,20 +1041,14 @@ xfs_file_iomap_begin( return error; trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); xfs_bmbt_to_iomap(ip, iomap, &imap); } else if (nimaps) { xfs_iunlock(ip, XFS_ILOCK_EXCL); trace_xfs_iomap_found(ip, offset, length, 0, &imap); xfs_bmbt_to_iomap(ip, iomap, &imap); } else { ASSERT(nimaps); xfs_iunlock(ip, XFS_ILOCK_EXCL); trace_xfs_iomap_not_found(ip, offset, length, 0, &imap); iomap->blkno = IOMAP_NULL_BLOCK; iomap->type = IOMAP_HOLE; iomap->offset = offset; iomap->length = length; trace_xfs_iomap_found(ip, offset, length, 0, &imap); } xfs_bmbt_to_iomap(ip, iomap, &imap); return 0; } Loading Loading @@ -1116,3 +1110,48 @@ struct iomap_ops xfs_iomap_ops = { .iomap_begin = xfs_file_iomap_begin, .iomap_end = xfs_file_iomap_end, }; static int xfs_xattr_iomap_begin( struct inode *inode, loff_t offset, loff_t length, unsigned flags, struct iomap *iomap) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); struct xfs_bmbt_irec imap; int nimaps = 1, error = 0; unsigned lockmode; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; lockmode = xfs_ilock_data_map_shared(ip); /* if there are no attribute fork or extents, return ENOENT */ if (XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { error = -ENOENT; goto out_unlock; } ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, &nimaps, XFS_BMAPI_ENTIRE | XFS_BMAPI_ATTRFORK); out_unlock: xfs_iunlock(ip, lockmode); if (!error) { ASSERT(nimaps); xfs_bmbt_to_iomap(ip, iomap, &imap); } return error; } struct iomap_ops xfs_xattr_iomap_ops = { .iomap_begin = xfs_xattr_iomap_begin, };
fs/xfs/xfs_iomap.h +1 −0 Original line number Diff line number Diff line Loading @@ -35,5 +35,6 @@ void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, struct xfs_bmbt_irec *); extern struct iomap_ops xfs_iomap_ops; extern struct iomap_ops xfs_xattr_iomap_ops; #endif /* __XFS_IOMAP_H__*/
fs/xfs/xfs_iops.c +8 −1 Original line number Diff line number Diff line Loading @@ -1009,7 +1009,14 @@ xfs_vn_fiemap( int error; xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED); error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops); if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR; error = iomap_fiemap(inode, fieinfo, start, length, &xfs_xattr_iomap_ops); } else { error = iomap_fiemap(inode, fieinfo, start, length, &xfs_iomap_ops); } xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); return error; Loading
fs/xfs/xfs_trace.h +0 −1 Original line number Diff line number Diff line Loading @@ -1298,7 +1298,6 @@ DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); DEFINE_IOMAP_EVENT(xfs_iomap_alloc); DEFINE_IOMAP_EVENT(xfs_iomap_found); DEFINE_IOMAP_EVENT(xfs_iomap_not_found); DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), Loading