diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-02-19 17:02:39 -0800 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-06-01 21:16:42 -0700 |
commit | 2b35e21e18baaf5564038098894683a1e6798af3 (patch) | |
tree | 095412d4f87e74b140e882aee7404b037db8c236 /fs | |
parent | 51dce91c6b60a35aed7b6d4eeadb2d779c01dc71 (diff) |
xfs: create transaction reservations for metadata inode operations
Create transaction reservation types and block reservation helpers to
help us calculate transaction requirements.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_imeta.c | 20 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_imeta.h | 3 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_trans_resv.c | 61 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_trans_resv.h | 2 |
4 files changed, 86 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_imeta.c b/fs/xfs/libxfs/xfs_imeta.c index f21b0a81c9fb..71b5cf4872cf 100644 --- a/fs/xfs/libxfs/xfs_imeta.c +++ b/fs/xfs/libxfs/xfs_imeta.c @@ -17,6 +17,10 @@ #include "xfs_imeta.h" #include "xfs_trace.h" #include "xfs_inode.h" +#include "xfs_bmap_btree.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_trans_space.h" /* * Metadata Inode Number Management @@ -378,3 +382,19 @@ xfs_imeta_mount( { return 0; } + +/* Calculate the log block reservation to create a metadata inode. */ +unsigned int +xfs_imeta_create_space_res( + struct xfs_mount *mp) +{ + return XFS_IALLOC_SPACE_RES(mp); +} + +/* Calculate the log block reservation to unlink a metadata inode. */ +unsigned int +xfs_imeta_unlink_space_res( + struct xfs_mount *mp) +{ + return XFS_REMOVE_SPACE_RES(mp); +} diff --git a/fs/xfs/libxfs/xfs_imeta.h b/fs/xfs/libxfs/xfs_imeta.h index 7b6ed6760f38..ce3382948ba0 100644 --- a/fs/xfs/libxfs/xfs_imeta.h +++ b/fs/xfs/libxfs/xfs_imeta.h @@ -40,4 +40,7 @@ void xfs_imeta_end_update(struct xfs_mount *mp, struct xfs_imeta_end *cleanup, bool xfs_is_static_meta_ino(struct xfs_mount *mp, xfs_ino_t ino); int xfs_imeta_mount(struct xfs_mount *mp); +unsigned int xfs_imeta_create_space_res(struct xfs_mount *mp); +unsigned int xfs_imeta_unlink_space_res(struct xfs_mount *mp); + #endif /* __XFS_IMETA_H__ */ diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index d1a0848cb52e..4eeafa7b9647 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -832,6 +832,56 @@ xfs_calc_sb_reservation( return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); } +/* + * Metadata inode creation needs enough space to create or mkdir a directory, + * plus logging the superblock. + */ +static unsigned int +xfs_calc_imeta_create_resv( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret; + + ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); + ret += resp->tr_create.tr_logres; + return ret; +} + +/* Metadata inode creation needs enough rounds to create or mkdir a directory */ +static int +xfs_calc_imeta_create_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + return resp->tr_create.tr_logcount; +} + +/* + * Metadata inode unlink needs enough space to remove a file plus logging the + * superblock. + */ +static unsigned int +xfs_calc_imeta_unlink_resv( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret; + + ret = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); + ret += resp->tr_remove.tr_logres; + return ret; +} + +/* Metadata inode creation needs enough rounds to remove a file. */ +static int +xfs_calc_imeta_unlink_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + return resp->tr_remove.tr_logcount; +} + void xfs_trans_resv_calc( struct xfs_mount *mp, @@ -946,4 +996,15 @@ xfs_trans_resv_calc( resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp); resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp); resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp); + + /* metadata inode creation and unlink */ + resp->tr_imeta_create.tr_logres = xfs_calc_imeta_create_resv(mp, resp); + resp->tr_imeta_create.tr_logcount = + xfs_calc_imeta_create_count(mp, resp); + resp->tr_imeta_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_imeta_unlink.tr_logres = xfs_calc_imeta_unlink_resv(mp, resp); + resp->tr_imeta_unlink.tr_logcount = + xfs_calc_imeta_unlink_count(mp, resp); + resp->tr_imeta_unlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; } diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h index 7241ab28cf84..7f7d86671319 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.h +++ b/fs/xfs/libxfs/xfs_trans_resv.h @@ -50,6 +50,8 @@ struct xfs_trans_resv { struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */ struct xfs_trans_res tr_sb; /* modify superblock */ struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */ + struct xfs_trans_res tr_imeta_create; /* create metadata inode */ + struct xfs_trans_res tr_imeta_unlink; /* unlink metadata inode */ }; /* shorthand way of accessing reservation structure */ |