diff options
author | Brian Foster <bfoster@redhat.com> | 2014-04-24 02:00:53 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-04-24 02:00:53 -0400 |
commit | 0aa0a756ec255cfc8b733fe0d8993c1758b1240c (patch) | |
tree | c9d25258ab96046dd3e594cb4d6ded335878c2da /fs/xfs/xfs_ialloc.c | |
parent | 9d43b180af67cccd4bd1342f7f54f8131515b0a1 (diff) |
xfs: insert newly allocated inode chunks into the finobt
A newly allocated inode chunk, by definition, has at least one
free inode, so a record is always inserted into the finobt.
Create the xfs_inobt_insert() helper from existing code to insert
a record in an inobt based on the provided BTNUM. Update
xfs_ialloc_ag_alloc() to invoke the helper for the existing
XFS_BTNUM_INO tree and XFS_BTNUM_FINO tree, if enabled.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 93 |
1 files changed, 70 insertions, 23 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index a0aead57a341..203db98f0bc9 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -112,6 +112,66 @@ xfs_inobt_get_rec( | |||
112 | } | 112 | } |
113 | 113 | ||
114 | /* | 114 | /* |
115 | * Insert a single inobt record. Cursor must already point to desired location. | ||
116 | */ | ||
117 | STATIC int | ||
118 | xfs_inobt_insert_rec( | ||
119 | struct xfs_btree_cur *cur, | ||
120 | __int32_t freecount, | ||
121 | xfs_inofree_t free, | ||
122 | int *stat) | ||
123 | { | ||
124 | cur->bc_rec.i.ir_freecount = freecount; | ||
125 | cur->bc_rec.i.ir_free = free; | ||
126 | return xfs_btree_insert(cur, stat); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Insert records describing a newly allocated inode chunk into the inobt. | ||
131 | */ | ||
132 | STATIC int | ||
133 | xfs_inobt_insert( | ||
134 | struct xfs_mount *mp, | ||
135 | struct xfs_trans *tp, | ||
136 | struct xfs_buf *agbp, | ||
137 | xfs_agino_t newino, | ||
138 | xfs_agino_t newlen, | ||
139 | xfs_btnum_t btnum) | ||
140 | { | ||
141 | struct xfs_btree_cur *cur; | ||
142 | struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); | ||
143 | xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno); | ||
144 | xfs_agino_t thisino; | ||
145 | int i; | ||
146 | int error; | ||
147 | |||
148 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); | ||
149 | |||
150 | for (thisino = newino; | ||
151 | thisino < newino + newlen; | ||
152 | thisino += XFS_INODES_PER_CHUNK) { | ||
153 | error = xfs_inobt_lookup(cur, thisino, XFS_LOOKUP_EQ, &i); | ||
154 | if (error) { | ||
155 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
156 | return error; | ||
157 | } | ||
158 | ASSERT(i == 0); | ||
159 | |||
160 | error = xfs_inobt_insert_rec(cur, XFS_INODES_PER_CHUNK, | ||
161 | XFS_INOBT_ALL_FREE, &i); | ||
162 | if (error) { | ||
163 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
164 | return error; | ||
165 | } | ||
166 | ASSERT(i == 1); | ||
167 | } | ||
168 | |||
169 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* | ||
115 | * Verify that the number of free inodes in the AGI is correct. | 175 | * Verify that the number of free inodes in the AGI is correct. |
116 | */ | 176 | */ |
117 | #ifdef DEBUG | 177 | #ifdef DEBUG |
@@ -303,13 +363,10 @@ xfs_ialloc_ag_alloc( | |||
303 | { | 363 | { |
304 | xfs_agi_t *agi; /* allocation group header */ | 364 | xfs_agi_t *agi; /* allocation group header */ |
305 | xfs_alloc_arg_t args; /* allocation argument structure */ | 365 | xfs_alloc_arg_t args; /* allocation argument structure */ |
306 | xfs_btree_cur_t *cur; /* inode btree cursor */ | ||
307 | xfs_agnumber_t agno; | 366 | xfs_agnumber_t agno; |
308 | int error; | 367 | int error; |
309 | int i; | ||
310 | xfs_agino_t newino; /* new first inode's number */ | 368 | xfs_agino_t newino; /* new first inode's number */ |
311 | xfs_agino_t newlen; /* new number of inodes */ | 369 | xfs_agino_t newlen; /* new number of inodes */ |
312 | xfs_agino_t thisino; /* current inode number, for loop */ | ||
313 | int isaligned = 0; /* inode allocation at stripe unit */ | 370 | int isaligned = 0; /* inode allocation at stripe unit */ |
314 | /* boundary */ | 371 | /* boundary */ |
315 | struct xfs_perag *pag; | 372 | struct xfs_perag *pag; |
@@ -459,29 +516,19 @@ xfs_ialloc_ag_alloc( | |||
459 | agi->agi_newino = cpu_to_be32(newino); | 516 | agi->agi_newino = cpu_to_be32(newino); |
460 | 517 | ||
461 | /* | 518 | /* |
462 | * Insert records describing the new inode chunk into the btree. | 519 | * Insert records describing the new inode chunk into the btrees. |
463 | */ | 520 | */ |
464 | cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno, XFS_BTNUM_INO); | 521 | error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen, |
465 | for (thisino = newino; | 522 | XFS_BTNUM_INO); |
466 | thisino < newino + newlen; | 523 | if (error) |
467 | thisino += XFS_INODES_PER_CHUNK) { | 524 | return error; |
468 | cur->bc_rec.i.ir_startino = thisino; | 525 | |
469 | cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK; | 526 | if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) { |
470 | cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE; | 527 | error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen, |
471 | error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i); | 528 | XFS_BTNUM_FINO); |
472 | if (error) { | 529 | if (error) |
473 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
474 | return error; | ||
475 | } | ||
476 | ASSERT(i == 0); | ||
477 | error = xfs_btree_insert(cur, &i); | ||
478 | if (error) { | ||
479 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | ||
480 | return error; | 530 | return error; |
481 | } | ||
482 | ASSERT(i == 1); | ||
483 | } | 531 | } |
484 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | ||
485 | /* | 532 | /* |
486 | * Log allocation group header fields | 533 | * Log allocation group header fields |
487 | */ | 534 | */ |