aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-04-24 02:00:53 -0400
committerDave Chinner <david@fromorbit.com>2014-04-24 02:00:53 -0400
commit0aa0a756ec255cfc8b733fe0d8993c1758b1240c (patch)
treec9d25258ab96046dd3e594cb4d6ded335878c2da /fs/xfs/xfs_ialloc.c
parent9d43b180af67cccd4bd1342f7f54f8131515b0a1 (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.c93
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 */
117STATIC int
118xfs_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 */
132STATIC int
133xfs_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 */