|
@@ -82,11 +82,12 @@ xfs_finobt_set_root(
|
|
}
|
|
}
|
|
|
|
|
|
STATIC int
|
|
STATIC int
|
|
-xfs_inobt_alloc_block(
|
|
|
|
|
|
+__xfs_inobt_alloc_block(
|
|
struct xfs_btree_cur *cur,
|
|
struct xfs_btree_cur *cur,
|
|
union xfs_btree_ptr *start,
|
|
union xfs_btree_ptr *start,
|
|
union xfs_btree_ptr *new,
|
|
union xfs_btree_ptr *new,
|
|
- int *stat)
|
|
|
|
|
|
+ int *stat,
|
|
|
|
+ enum xfs_ag_resv_type resv)
|
|
{
|
|
{
|
|
xfs_alloc_arg_t args; /* block allocation args */
|
|
xfs_alloc_arg_t args; /* block allocation args */
|
|
int error; /* error return value */
|
|
int error; /* error return value */
|
|
@@ -103,6 +104,7 @@ xfs_inobt_alloc_block(
|
|
args.maxlen = 1;
|
|
args.maxlen = 1;
|
|
args.prod = 1;
|
|
args.prod = 1;
|
|
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
|
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
|
|
|
+ args.resv = resv;
|
|
|
|
|
|
error = xfs_alloc_vextent(&args);
|
|
error = xfs_alloc_vextent(&args);
|
|
if (error) {
|
|
if (error) {
|
|
@@ -122,6 +124,27 @@ xfs_inobt_alloc_block(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+STATIC int
|
|
|
|
+xfs_inobt_alloc_block(
|
|
|
|
+ struct xfs_btree_cur *cur,
|
|
|
|
+ union xfs_btree_ptr *start,
|
|
|
|
+ union xfs_btree_ptr *new,
|
|
|
|
+ int *stat)
|
|
|
|
+{
|
|
|
|
+ return __xfs_inobt_alloc_block(cur, start, new, stat, XFS_AG_RESV_NONE);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+STATIC int
|
|
|
|
+xfs_finobt_alloc_block(
|
|
|
|
+ struct xfs_btree_cur *cur,
|
|
|
|
+ union xfs_btree_ptr *start,
|
|
|
|
+ union xfs_btree_ptr *new,
|
|
|
|
+ int *stat)
|
|
|
|
+{
|
|
|
|
+ return __xfs_inobt_alloc_block(cur, start, new, stat,
|
|
|
|
+ XFS_AG_RESV_METADATA);
|
|
|
|
+}
|
|
|
|
+
|
|
STATIC int
|
|
STATIC int
|
|
xfs_inobt_free_block(
|
|
xfs_inobt_free_block(
|
|
struct xfs_btree_cur *cur,
|
|
struct xfs_btree_cur *cur,
|
|
@@ -328,7 +351,7 @@ static const struct xfs_btree_ops xfs_finobt_ops = {
|
|
|
|
|
|
.dup_cursor = xfs_inobt_dup_cursor,
|
|
.dup_cursor = xfs_inobt_dup_cursor,
|
|
.set_root = xfs_finobt_set_root,
|
|
.set_root = xfs_finobt_set_root,
|
|
- .alloc_block = xfs_inobt_alloc_block,
|
|
|
|
|
|
+ .alloc_block = xfs_finobt_alloc_block,
|
|
.free_block = xfs_inobt_free_block,
|
|
.free_block = xfs_inobt_free_block,
|
|
.get_minrecs = xfs_inobt_get_minrecs,
|
|
.get_minrecs = xfs_inobt_get_minrecs,
|
|
.get_maxrecs = xfs_inobt_get_maxrecs,
|
|
.get_maxrecs = xfs_inobt_get_maxrecs,
|
|
@@ -480,3 +503,64 @@ xfs_inobt_rec_check_count(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
#endif /* DEBUG */
|
|
#endif /* DEBUG */
|
|
|
|
+
|
|
|
|
+static xfs_extlen_t
|
|
|
|
+xfs_inobt_max_size(
|
|
|
|
+ struct xfs_mount *mp)
|
|
|
|
+{
|
|
|
|
+ /* Bail out if we're uninitialized, which can happen in mkfs. */
|
|
|
|
+ if (mp->m_inobt_mxr[0] == 0)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return xfs_btree_calc_size(mp, mp->m_inobt_mnr,
|
|
|
|
+ (uint64_t)mp->m_sb.sb_agblocks * mp->m_sb.sb_inopblock /
|
|
|
|
+ XFS_INODES_PER_CHUNK);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+xfs_inobt_count_blocks(
|
|
|
|
+ struct xfs_mount *mp,
|
|
|
|
+ xfs_agnumber_t agno,
|
|
|
|
+ xfs_btnum_t btnum,
|
|
|
|
+ xfs_extlen_t *tree_blocks)
|
|
|
|
+{
|
|
|
|
+ struct xfs_buf *agbp;
|
|
|
|
+ struct xfs_btree_cur *cur;
|
|
|
|
+ int error;
|
|
|
|
+
|
|
|
|
+ error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
|
|
|
|
+ if (error)
|
|
|
|
+ return error;
|
|
|
|
+
|
|
|
|
+ cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum);
|
|
|
|
+ error = xfs_btree_count_blocks(cur, tree_blocks);
|
|
|
|
+ xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
|
|
|
|
+ xfs_buf_relse(agbp);
|
|
|
|
+
|
|
|
|
+ return error;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Figure out how many blocks to reserve and how many are used by this btree.
|
|
|
|
+ */
|
|
|
|
+int
|
|
|
|
+xfs_finobt_calc_reserves(
|
|
|
|
+ struct xfs_mount *mp,
|
|
|
|
+ xfs_agnumber_t agno,
|
|
|
|
+ xfs_extlen_t *ask,
|
|
|
|
+ xfs_extlen_t *used)
|
|
|
|
+{
|
|
|
|
+ xfs_extlen_t tree_len = 0;
|
|
|
|
+ int error;
|
|
|
|
+
|
|
|
|
+ if (!xfs_sb_version_hasfinobt(&mp->m_sb))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len);
|
|
|
|
+ if (error)
|
|
|
|
+ return error;
|
|
|
|
+
|
|
|
|
+ *ask += xfs_inobt_max_size(mp);
|
|
|
|
+ *used += tree_len;
|
|
|
|
+ return 0;
|
|
|
|
+}
|