aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c132
1 files changed, 112 insertions, 20 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index aad8c5da38af..c8a56c529642 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -119,6 +119,102 @@ xfs_ialloc_cluster_alignment(
119} 119}
120 120
121/* 121/*
122 * Lookup the record equal to ino in the btree given by cur.
123 */
124STATIC int /* error */
125xfs_inobt_lookup_eq(
126 struct xfs_btree_cur *cur, /* btree cursor */
127 xfs_agino_t ino, /* starting inode of chunk */
128 __int32_t fcnt, /* free inode count */
129 xfs_inofree_t free, /* free inode mask */
130 int *stat) /* success/failure */
131{
132 cur->bc_rec.i.ir_startino = ino;
133 cur->bc_rec.i.ir_freecount = fcnt;
134 cur->bc_rec.i.ir_free = free;
135 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
136}
137
138/*
139 * Lookup the first record greater than or equal to ino
140 * in the btree given by cur.
141 */
142int /* error */
143xfs_inobt_lookup_ge(
144 struct xfs_btree_cur *cur, /* btree cursor */
145 xfs_agino_t ino, /* starting inode of chunk */
146 __int32_t fcnt, /* free inode count */
147 xfs_inofree_t free, /* free inode mask */
148 int *stat) /* success/failure */
149{
150 cur->bc_rec.i.ir_startino = ino;
151 cur->bc_rec.i.ir_freecount = fcnt;
152 cur->bc_rec.i.ir_free = free;
153 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
154}
155
156/*
157 * Lookup the first record less than or equal to ino
158 * in the btree given by cur.
159 */
160int /* error */
161xfs_inobt_lookup_le(
162 struct xfs_btree_cur *cur, /* btree cursor */
163 xfs_agino_t ino, /* starting inode of chunk */
164 __int32_t fcnt, /* free inode count */
165 xfs_inofree_t free, /* free inode mask */
166 int *stat) /* success/failure */
167{
168 cur->bc_rec.i.ir_startino = ino;
169 cur->bc_rec.i.ir_freecount = fcnt;
170 cur->bc_rec.i.ir_free = free;
171 return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
172}
173
174/*
175 * Update the record referred to by cur to the value given
176 * by [ino, fcnt, free].
177 * This either works (return 0) or gets an EFSCORRUPTED error.
178 */
179STATIC int /* error */
180xfs_inobt_update(
181 struct xfs_btree_cur *cur, /* btree cursor */
182 xfs_agino_t ino, /* starting inode of chunk */
183 __int32_t fcnt, /* free inode count */
184 xfs_inofree_t free) /* free inode mask */
185{
186 union xfs_btree_rec rec;
187
188 rec.inobt.ir_startino = cpu_to_be32(ino);
189 rec.inobt.ir_freecount = cpu_to_be32(fcnt);
190 rec.inobt.ir_free = cpu_to_be64(free);
191 return xfs_btree_update(cur, &rec);
192}
193
194/*
195 * Get the data from the pointed-to record.
196 */
197int /* error */
198xfs_inobt_get_rec(
199 struct xfs_btree_cur *cur, /* btree cursor */
200 xfs_agino_t *ino, /* output: starting inode of chunk */
201 __int32_t *fcnt, /* output: number of free inodes */
202 xfs_inofree_t *free, /* output: free inode mask */
203 int *stat) /* output: success/failure */
204{
205 union xfs_btree_rec *rec;
206 int error;
207
208 error = xfs_btree_get_rec(cur, &rec, stat);
209 if (!error && *stat == 1) {
210 *ino = be32_to_cpu(rec->inobt.ir_startino);
211 *fcnt = be32_to_cpu(rec->inobt.ir_freecount);
212 *free = be64_to_cpu(rec->inobt.ir_free);
213 }
214 return error;
215}
216
217/*
122 * Allocate new inodes in the allocation group specified by agbp. 218 * Allocate new inodes in the allocation group specified by agbp.
123 * Return 0 for success, else error code. 219 * Return 0 for success, else error code.
124 */ 220 */
@@ -335,8 +431,7 @@ xfs_ialloc_ag_alloc(
335 /* 431 /*
336 * Insert records describing the new inode chunk into the btree. 432 * Insert records describing the new inode chunk into the btree.
337 */ 433 */
338 cur = xfs_btree_init_cursor(args.mp, tp, agbp, agno, 434 cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno);
339 XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
340 for (thisino = newino; 435 for (thisino = newino;
341 thisino < newino + newlen; 436 thisino < newino + newlen;
342 thisino += XFS_INODES_PER_CHUNK) { 437 thisino += XFS_INODES_PER_CHUNK) {
@@ -346,7 +441,7 @@ xfs_ialloc_ag_alloc(
346 return error; 441 return error;
347 } 442 }
348 ASSERT(i == 0); 443 ASSERT(i == 0);
349 if ((error = xfs_inobt_insert(cur, &i))) { 444 if ((error = xfs_btree_insert(cur, &i))) {
350 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 445 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
351 return error; 446 return error;
352 } 447 }
@@ -676,8 +771,7 @@ nextag:
676 */ 771 */
677 agno = tagno; 772 agno = tagno;
678 *IO_agbp = NULL; 773 *IO_agbp = NULL;
679 cur = xfs_btree_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno), 774 cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
680 XFS_BTNUM_INO, (xfs_inode_t *)0, 0);
681 /* 775 /*
682 * If pagino is 0 (this is the root inode allocation) use newino. 776 * If pagino is 0 (this is the root inode allocation) use newino.
683 * This must work because we've just allocated some. 777 * This must work because we've just allocated some.
@@ -697,7 +791,7 @@ nextag:
697 goto error0; 791 goto error0;
698 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 792 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
699 freecount += rec.ir_freecount; 793 freecount += rec.ir_freecount;
700 if ((error = xfs_inobt_increment(cur, 0, &i))) 794 if ((error = xfs_btree_increment(cur, 0, &i)))
701 goto error0; 795 goto error0;
702 } while (i == 1); 796 } while (i == 1);
703 797
@@ -741,7 +835,7 @@ nextag:
741 /* 835 /*
742 * Search left with tcur, back up 1 record. 836 * Search left with tcur, back up 1 record.
743 */ 837 */
744 if ((error = xfs_inobt_decrement(tcur, 0, &i))) 838 if ((error = xfs_btree_decrement(tcur, 0, &i)))
745 goto error1; 839 goto error1;
746 doneleft = !i; 840 doneleft = !i;
747 if (!doneleft) { 841 if (!doneleft) {
@@ -755,7 +849,7 @@ nextag:
755 /* 849 /*
756 * Search right with cur, go forward 1 record. 850 * Search right with cur, go forward 1 record.
757 */ 851 */
758 if ((error = xfs_inobt_increment(cur, 0, &i))) 852 if ((error = xfs_btree_increment(cur, 0, &i)))
759 goto error1; 853 goto error1;
760 doneright = !i; 854 doneright = !i;
761 if (!doneright) { 855 if (!doneright) {
@@ -817,7 +911,7 @@ nextag:
817 * further left. 911 * further left.
818 */ 912 */
819 if (useleft) { 913 if (useleft) {
820 if ((error = xfs_inobt_decrement(tcur, 0, 914 if ((error = xfs_btree_decrement(tcur, 0,
821 &i))) 915 &i)))
822 goto error1; 916 goto error1;
823 doneleft = !i; 917 doneleft = !i;
@@ -837,7 +931,7 @@ nextag:
837 * further right. 931 * further right.
838 */ 932 */
839 else { 933 else {
840 if ((error = xfs_inobt_increment(cur, 0, 934 if ((error = xfs_btree_increment(cur, 0,
841 &i))) 935 &i)))
842 goto error1; 936 goto error1;
843 doneright = !i; 937 doneright = !i;
@@ -892,7 +986,7 @@ nextag:
892 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 986 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
893 if (rec.ir_freecount > 0) 987 if (rec.ir_freecount > 0)
894 break; 988 break;
895 if ((error = xfs_inobt_increment(cur, 0, &i))) 989 if ((error = xfs_btree_increment(cur, 0, &i)))
896 goto error0; 990 goto error0;
897 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 991 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
898 } 992 }
@@ -926,7 +1020,7 @@ nextag:
926 goto error0; 1020 goto error0;
927 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1021 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
928 freecount += rec.ir_freecount; 1022 freecount += rec.ir_freecount;
929 if ((error = xfs_inobt_increment(cur, 0, &i))) 1023 if ((error = xfs_btree_increment(cur, 0, &i)))
930 goto error0; 1024 goto error0;
931 } while (i == 1); 1025 } while (i == 1);
932 ASSERT(freecount == be32_to_cpu(agi->agi_freecount) || 1026 ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
@@ -1022,8 +1116,7 @@ xfs_difree(
1022 /* 1116 /*
1023 * Initialize the cursor. 1117 * Initialize the cursor.
1024 */ 1118 */
1025 cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO, 1119 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
1026 (xfs_inode_t *)0, 0);
1027#ifdef DEBUG 1120#ifdef DEBUG
1028 if (cur->bc_nlevels == 1) { 1121 if (cur->bc_nlevels == 1) {
1029 int freecount = 0; 1122 int freecount = 0;
@@ -1036,7 +1129,7 @@ xfs_difree(
1036 goto error0; 1129 goto error0;
1037 if (i) { 1130 if (i) {
1038 freecount += rec.ir_freecount; 1131 freecount += rec.ir_freecount;
1039 if ((error = xfs_inobt_increment(cur, 0, &i))) 1132 if ((error = xfs_btree_increment(cur, 0, &i)))
1040 goto error0; 1133 goto error0;
1041 } 1134 }
1042 } while (i == 1); 1135 } while (i == 1);
@@ -1098,8 +1191,8 @@ xfs_difree(
1098 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); 1191 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
1099 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); 1192 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
1100 1193
1101 if ((error = xfs_inobt_delete(cur, &i))) { 1194 if ((error = xfs_btree_delete(cur, &i))) {
1102 cmn_err(CE_WARN, "xfs_difree: xfs_inobt_delete returned an error %d on %s.\n", 1195 cmn_err(CE_WARN, "xfs_difree: xfs_btree_delete returned an error %d on %s.\n",
1103 error, mp->m_fsname); 1196 error, mp->m_fsname);
1104 goto error0; 1197 goto error0;
1105 } 1198 }
@@ -1141,7 +1234,7 @@ xfs_difree(
1141 goto error0; 1234 goto error0;
1142 if (i) { 1235 if (i) {
1143 freecount += rec.ir_freecount; 1236 freecount += rec.ir_freecount;
1144 if ((error = xfs_inobt_increment(cur, 0, &i))) 1237 if ((error = xfs_btree_increment(cur, 0, &i)))
1145 goto error0; 1238 goto error0;
1146 } 1239 }
1147 } while (i == 1); 1240 } while (i == 1);
@@ -1259,8 +1352,7 @@ xfs_dilocate(
1259#endif /* DEBUG */ 1352#endif /* DEBUG */
1260 return error; 1353 return error;
1261 } 1354 }
1262 cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO, 1355 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
1263 (xfs_inode_t *)0, 0);
1264 if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) { 1356 if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
1265#ifdef DEBUG 1357#ifdef DEBUG
1266 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: " 1358 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_dilocate: "