diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc_btree.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 0fd086d03d41..7c471881c9a6 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -82,11 +82,12 @@ xfs_finobt_set_root( | |||
82 | } | 82 | } |
83 | 83 | ||
84 | STATIC int | 84 | STATIC int |
85 | xfs_inobt_alloc_block( | 85 | __xfs_inobt_alloc_block( |
86 | struct xfs_btree_cur *cur, | 86 | struct xfs_btree_cur *cur, |
87 | union xfs_btree_ptr *start, | 87 | union xfs_btree_ptr *start, |
88 | union xfs_btree_ptr *new, | 88 | union xfs_btree_ptr *new, |
89 | int *stat) | 89 | int *stat, |
90 | enum xfs_ag_resv_type resv) | ||
90 | { | 91 | { |
91 | xfs_alloc_arg_t args; /* block allocation args */ | 92 | xfs_alloc_arg_t args; /* block allocation args */ |
92 | int error; /* error return value */ | 93 | int error; /* error return value */ |
@@ -103,6 +104,7 @@ xfs_inobt_alloc_block( | |||
103 | args.maxlen = 1; | 104 | args.maxlen = 1; |
104 | args.prod = 1; | 105 | args.prod = 1; |
105 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 106 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
107 | args.resv = resv; | ||
106 | 108 | ||
107 | error = xfs_alloc_vextent(&args); | 109 | error = xfs_alloc_vextent(&args); |
108 | if (error) { | 110 | if (error) { |
@@ -123,6 +125,27 @@ xfs_inobt_alloc_block( | |||
123 | } | 125 | } |
124 | 126 | ||
125 | STATIC int | 127 | STATIC int |
128 | xfs_inobt_alloc_block( | ||
129 | struct xfs_btree_cur *cur, | ||
130 | union xfs_btree_ptr *start, | ||
131 | union xfs_btree_ptr *new, | ||
132 | int *stat) | ||
133 | { | ||
134 | return __xfs_inobt_alloc_block(cur, start, new, stat, XFS_AG_RESV_NONE); | ||
135 | } | ||
136 | |||
137 | STATIC int | ||
138 | xfs_finobt_alloc_block( | ||
139 | struct xfs_btree_cur *cur, | ||
140 | union xfs_btree_ptr *start, | ||
141 | union xfs_btree_ptr *new, | ||
142 | int *stat) | ||
143 | { | ||
144 | return __xfs_inobt_alloc_block(cur, start, new, stat, | ||
145 | XFS_AG_RESV_METADATA); | ||
146 | } | ||
147 | |||
148 | STATIC int | ||
126 | xfs_inobt_free_block( | 149 | xfs_inobt_free_block( |
127 | struct xfs_btree_cur *cur, | 150 | struct xfs_btree_cur *cur, |
128 | struct xfs_buf *bp) | 151 | struct xfs_buf *bp) |
@@ -328,7 +351,7 @@ static const struct xfs_btree_ops xfs_finobt_ops = { | |||
328 | 351 | ||
329 | .dup_cursor = xfs_inobt_dup_cursor, | 352 | .dup_cursor = xfs_inobt_dup_cursor, |
330 | .set_root = xfs_finobt_set_root, | 353 | .set_root = xfs_finobt_set_root, |
331 | .alloc_block = xfs_inobt_alloc_block, | 354 | .alloc_block = xfs_finobt_alloc_block, |
332 | .free_block = xfs_inobt_free_block, | 355 | .free_block = xfs_inobt_free_block, |
333 | .get_minrecs = xfs_inobt_get_minrecs, | 356 | .get_minrecs = xfs_inobt_get_minrecs, |
334 | .get_maxrecs = xfs_inobt_get_maxrecs, | 357 | .get_maxrecs = xfs_inobt_get_maxrecs, |
@@ -480,3 +503,64 @@ xfs_inobt_rec_check_count( | |||
480 | return 0; | 503 | return 0; |
481 | } | 504 | } |
482 | #endif /* DEBUG */ | 505 | #endif /* DEBUG */ |
506 | |||
507 | static xfs_extlen_t | ||
508 | xfs_inobt_max_size( | ||
509 | struct xfs_mount *mp) | ||
510 | { | ||
511 | /* Bail out if we're uninitialized, which can happen in mkfs. */ | ||
512 | if (mp->m_inobt_mxr[0] == 0) | ||
513 | return 0; | ||
514 | |||
515 | return xfs_btree_calc_size(mp, mp->m_inobt_mnr, | ||
516 | (uint64_t)mp->m_sb.sb_agblocks * mp->m_sb.sb_inopblock / | ||
517 | XFS_INODES_PER_CHUNK); | ||
518 | } | ||
519 | |||
520 | static int | ||
521 | xfs_inobt_count_blocks( | ||
522 | struct xfs_mount *mp, | ||
523 | xfs_agnumber_t agno, | ||
524 | xfs_btnum_t btnum, | ||
525 | xfs_extlen_t *tree_blocks) | ||
526 | { | ||
527 | struct xfs_buf *agbp; | ||
528 | struct xfs_btree_cur *cur; | ||
529 | int error; | ||
530 | |||
531 | error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); | ||
532 | if (error) | ||
533 | return error; | ||
534 | |||
535 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); | ||
536 | error = xfs_btree_count_blocks(cur, tree_blocks); | ||
537 | xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); | ||
538 | xfs_buf_relse(agbp); | ||
539 | |||
540 | return error; | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * Figure out how many blocks to reserve and how many are used by this btree. | ||
545 | */ | ||
546 | int | ||
547 | xfs_finobt_calc_reserves( | ||
548 | struct xfs_mount *mp, | ||
549 | xfs_agnumber_t agno, | ||
550 | xfs_extlen_t *ask, | ||
551 | xfs_extlen_t *used) | ||
552 | { | ||
553 | xfs_extlen_t tree_len = 0; | ||
554 | int error; | ||
555 | |||
556 | if (!xfs_sb_version_hasfinobt(&mp->m_sb)) | ||
557 | return 0; | ||
558 | |||
559 | error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len); | ||
560 | if (error) | ||
561 | return error; | ||
562 | |||
563 | *ask += xfs_inobt_max_size(mp); | ||
564 | *used += tree_len; | ||
565 | return 0; | ||
566 | } | ||