xfs: make xfs_bmbt_to_iomap more useful
Move checking for invalid zero blocks and setting of various iomap flags into this helper. Also make it deal with "raw" delalloc extents to avoid clutter in the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
15baadf72c
commit
16be143373
|
@ -35,18 +35,40 @@
|
||||||
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
|
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
|
||||||
<< mp->m_writeio_log)
|
<< mp->m_writeio_log)
|
||||||
|
|
||||||
void
|
static int
|
||||||
|
xfs_alert_fsblock_zero(
|
||||||
|
xfs_inode_t *ip,
|
||||||
|
xfs_bmbt_irec_t *imap)
|
||||||
|
{
|
||||||
|
xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
|
||||||
|
"Access to block zero in inode %llu "
|
||||||
|
"start_block: %llx start_off: %llx "
|
||||||
|
"blkcnt: %llx extent-state: %x",
|
||||||
|
(unsigned long long)ip->i_ino,
|
||||||
|
(unsigned long long)imap->br_startblock,
|
||||||
|
(unsigned long long)imap->br_startoff,
|
||||||
|
(unsigned long long)imap->br_blockcount,
|
||||||
|
imap->br_state);
|
||||||
|
return -EFSCORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
xfs_bmbt_to_iomap(
|
xfs_bmbt_to_iomap(
|
||||||
struct xfs_inode *ip,
|
struct xfs_inode *ip,
|
||||||
struct iomap *iomap,
|
struct iomap *iomap,
|
||||||
struct xfs_bmbt_irec *imap)
|
struct xfs_bmbt_irec *imap,
|
||||||
|
bool shared)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
|
|
||||||
|
if (unlikely(!imap->br_startblock && !XFS_IS_REALTIME_INODE(ip)))
|
||||||
|
return xfs_alert_fsblock_zero(ip, imap);
|
||||||
|
|
||||||
if (imap->br_startblock == HOLESTARTBLOCK) {
|
if (imap->br_startblock == HOLESTARTBLOCK) {
|
||||||
iomap->addr = IOMAP_NULL_ADDR;
|
iomap->addr = IOMAP_NULL_ADDR;
|
||||||
iomap->type = IOMAP_HOLE;
|
iomap->type = IOMAP_HOLE;
|
||||||
} else if (imap->br_startblock == DELAYSTARTBLOCK) {
|
} else if (imap->br_startblock == DELAYSTARTBLOCK ||
|
||||||
|
isnullstartblock(imap->br_startblock)) {
|
||||||
iomap->addr = IOMAP_NULL_ADDR;
|
iomap->addr = IOMAP_NULL_ADDR;
|
||||||
iomap->type = IOMAP_DELALLOC;
|
iomap->type = IOMAP_DELALLOC;
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,6 +82,13 @@ xfs_bmbt_to_iomap(
|
||||||
iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
|
iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
|
||||||
iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
|
iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
|
||||||
iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
|
iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
|
||||||
|
|
||||||
|
if (xfs_ipincount(ip) &&
|
||||||
|
(ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP))
|
||||||
|
iomap->flags |= IOMAP_F_DIRTY;
|
||||||
|
if (shared)
|
||||||
|
iomap->flags |= IOMAP_F_SHARED;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -138,23 +167,6 @@ xfs_iomap_eof_align_last_fsb(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
|
||||||
xfs_alert_fsblock_zero(
|
|
||||||
xfs_inode_t *ip,
|
|
||||||
xfs_bmbt_irec_t *imap)
|
|
||||||
{
|
|
||||||
xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO,
|
|
||||||
"Access to block zero in inode %llu "
|
|
||||||
"start_block: %llx start_off: %llx "
|
|
||||||
"blkcnt: %llx extent-state: %x",
|
|
||||||
(unsigned long long)ip->i_ino,
|
|
||||||
(unsigned long long)imap->br_startblock,
|
|
||||||
(unsigned long long)imap->br_startoff,
|
|
||||||
(unsigned long long)imap->br_blockcount,
|
|
||||||
imap->br_state);
|
|
||||||
return -EFSCORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
xfs_iomap_write_direct(
|
xfs_iomap_write_direct(
|
||||||
xfs_inode_t *ip,
|
xfs_inode_t *ip,
|
||||||
|
@ -649,17 +661,7 @@ retry:
|
||||||
iomap->flags |= IOMAP_F_NEW;
|
iomap->flags |= IOMAP_F_NEW;
|
||||||
trace_xfs_iomap_alloc(ip, offset, count, XFS_DATA_FORK, &got);
|
trace_xfs_iomap_alloc(ip, offset, count, XFS_DATA_FORK, &got);
|
||||||
done:
|
done:
|
||||||
if (isnullstartblock(got.br_startblock))
|
error = xfs_bmbt_to_iomap(ip, iomap, &got, false);
|
||||||
got.br_startblock = DELAYSTARTBLOCK;
|
|
||||||
|
|
||||||
if (!got.br_startblock) {
|
|
||||||
error = xfs_alert_fsblock_zero(ip, &got);
|
|
||||||
if (error)
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfs_bmbt_to_iomap(ip, iomap, &got);
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||||
return error;
|
return error;
|
||||||
|
@ -976,15 +978,7 @@ xfs_file_iomap_begin(
|
||||||
trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap);
|
trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap);
|
||||||
|
|
||||||
out_finish:
|
out_finish:
|
||||||
if (xfs_ipincount(ip) && (ip->i_itemp->ili_fsync_fields
|
return xfs_bmbt_to_iomap(ip, iomap, &imap, shared);
|
||||||
& ~XFS_ILOG_TIMESTAMP))
|
|
||||||
iomap->flags |= IOMAP_F_DIRTY;
|
|
||||||
|
|
||||||
xfs_bmbt_to_iomap(ip, iomap, &imap);
|
|
||||||
|
|
||||||
if (shared)
|
|
||||||
iomap->flags |= IOMAP_F_SHARED;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_found:
|
out_found:
|
||||||
ASSERT(nimaps);
|
ASSERT(nimaps);
|
||||||
|
@ -1107,12 +1101,10 @@ xfs_xattr_iomap_begin(
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock(ip, lockmode);
|
xfs_iunlock(ip, lockmode);
|
||||||
|
|
||||||
if (!error) {
|
if (error)
|
||||||
ASSERT(nimaps);
|
return error;
|
||||||
xfs_bmbt_to_iomap(ip, iomap, &imap);
|
ASSERT(nimaps);
|
||||||
}
|
return xfs_bmbt_to_iomap(ip, iomap, &imap, false);
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct iomap_ops xfs_xattr_iomap_ops = {
|
const struct iomap_ops xfs_xattr_iomap_ops = {
|
||||||
|
|
|
@ -15,8 +15,8 @@ int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t,
|
||||||
struct xfs_bmbt_irec *, int);
|
struct xfs_bmbt_irec *, int);
|
||||||
int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
|
int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
|
||||||
|
|
||||||
void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
|
int xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *,
|
||||||
struct xfs_bmbt_irec *);
|
struct xfs_bmbt_irec *, bool shared);
|
||||||
xfs_extlen_t xfs_eof_alignment(struct xfs_inode *ip, xfs_extlen_t extsize);
|
xfs_extlen_t xfs_eof_alignment(struct xfs_inode *ip, xfs_extlen_t extsize);
|
||||||
|
|
||||||
static inline xfs_filblks_t
|
static inline xfs_filblks_t
|
||||||
|
|
|
@ -185,7 +185,7 @@ xfs_fs_map_blocks(
|
||||||
}
|
}
|
||||||
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
|
||||||
|
|
||||||
xfs_bmbt_to_iomap(ip, iomap, &imap);
|
error = xfs_bmbt_to_iomap(ip, iomap, &imap, false);
|
||||||
*device_generation = mp->m_generation;
|
*device_generation = mp->m_generation;
|
||||||
return error;
|
return error;
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
|
Loading…
Reference in New Issue