diff options
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 132 |
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 | */ | ||
124 | STATIC int /* error */ | ||
125 | xfs_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 | */ | ||
142 | int /* error */ | ||
143 | xfs_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 | */ | ||
160 | int /* error */ | ||
161 | xfs_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 | */ | ||
179 | STATIC int /* error */ | ||
180 | xfs_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 | */ | ||
197 | int /* error */ | ||
198 | xfs_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: " |