xfs_ialloc_btree.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765
  1. /*
  2. * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it would be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write the Free Software Foundation,
  16. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "xfs.h"
  19. #include "xfs_fs.h"
  20. #include "xfs_types.h"
  21. #include "xfs_bit.h"
  22. #include "xfs_log.h"
  23. #include "xfs_inum.h"
  24. #include "xfs_trans.h"
  25. #include "xfs_sb.h"
  26. #include "xfs_ag.h"
  27. #include "xfs_dir2.h"
  28. #include "xfs_dmapi.h"
  29. #include "xfs_mount.h"
  30. #include "xfs_bmap_btree.h"
  31. #include "xfs_alloc_btree.h"
  32. #include "xfs_ialloc_btree.h"
  33. #include "xfs_dir2_sf.h"
  34. #include "xfs_attr_sf.h"
  35. #include "xfs_dinode.h"
  36. #include "xfs_inode.h"
  37. #include "xfs_btree.h"
  38. #include "xfs_ialloc.h"
  39. #include "xfs_alloc.h"
  40. #include "xfs_error.h"
  41. STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);
  42. STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
  43. STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
  44. STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
  45. STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *);
  46. STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
  47. STATIC int xfs_inobt_rshift(xfs_btree_cur_t *, int, int *);
  48. STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
  49. xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
  50. /*
  51. * Single level of the xfs_inobt_delete record deletion routine.
  52. * Delete record pointed to by cur/level.
  53. * Remove the record from its block then rebalance the tree.
  54. * Return 0 for error, 1 for done, 2 to go on to the next level.
  55. */
  56. STATIC int /* error */
  57. xfs_inobt_delrec(
  58. xfs_btree_cur_t *cur, /* btree cursor */
  59. int level, /* level removing record from */
  60. int *stat) /* fail/done/go-on */
  61. {
  62. xfs_buf_t *agbp; /* buffer for a.g. inode header */
  63. xfs_mount_t *mp; /* mount structure */
  64. xfs_agi_t *agi; /* allocation group inode header */
  65. xfs_inobt_block_t *block; /* btree block record/key lives in */
  66. xfs_agblock_t bno; /* btree block number */
  67. xfs_buf_t *bp; /* buffer for block */
  68. int error; /* error return value */
  69. int i; /* loop index */
  70. xfs_inobt_key_t key; /* kp points here if block is level 0 */
  71. xfs_inobt_key_t *kp = NULL; /* pointer to btree keys */
  72. xfs_agblock_t lbno; /* left block's block number */
  73. xfs_buf_t *lbp; /* left block's buffer pointer */
  74. xfs_inobt_block_t *left; /* left btree block */
  75. xfs_inobt_key_t *lkp; /* left block key pointer */
  76. xfs_inobt_ptr_t *lpp; /* left block address pointer */
  77. int lrecs = 0; /* number of records in left block */
  78. xfs_inobt_rec_t *lrp; /* left block record pointer */
  79. xfs_inobt_ptr_t *pp = NULL; /* pointer to btree addresses */
  80. int ptr; /* index in btree block for this rec */
  81. xfs_agblock_t rbno; /* right block's block number */
  82. xfs_buf_t *rbp; /* right block's buffer pointer */
  83. xfs_inobt_block_t *right; /* right btree block */
  84. xfs_inobt_key_t *rkp; /* right block key pointer */
  85. xfs_inobt_rec_t *rp; /* pointer to btree records */
  86. xfs_inobt_ptr_t *rpp; /* right block address pointer */
  87. int rrecs = 0; /* number of records in right block */
  88. int numrecs;
  89. xfs_inobt_rec_t *rrp; /* right block record pointer */
  90. xfs_btree_cur_t *tcur; /* temporary btree cursor */
  91. mp = cur->bc_mp;
  92. /*
  93. * Get the index of the entry being deleted, check for nothing there.
  94. */
  95. ptr = cur->bc_ptrs[level];
  96. if (ptr == 0) {
  97. *stat = 0;
  98. return 0;
  99. }
  100. /*
  101. * Get the buffer & block containing the record or key/ptr.
  102. */
  103. bp = cur->bc_bufs[level];
  104. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  105. #ifdef DEBUG
  106. if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
  107. return error;
  108. #endif
  109. /*
  110. * Fail if we're off the end of the block.
  111. */
  112. numrecs = be16_to_cpu(block->bb_numrecs);
  113. if (ptr > numrecs) {
  114. *stat = 0;
  115. return 0;
  116. }
  117. /*
  118. * It's a nonleaf. Excise the key and ptr being deleted, by
  119. * sliding the entries past them down one.
  120. * Log the changed areas of the block.
  121. */
  122. if (level > 0) {
  123. kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
  124. pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
  125. #ifdef DEBUG
  126. for (i = ptr; i < numrecs; i++) {
  127. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level)))
  128. return error;
  129. }
  130. #endif
  131. if (ptr < numrecs) {
  132. memmove(&kp[ptr - 1], &kp[ptr],
  133. (numrecs - ptr) * sizeof(*kp));
  134. memmove(&pp[ptr - 1], &pp[ptr],
  135. (numrecs - ptr) * sizeof(*kp));
  136. xfs_inobt_log_keys(cur, bp, ptr, numrecs - 1);
  137. xfs_inobt_log_ptrs(cur, bp, ptr, numrecs - 1);
  138. }
  139. }
  140. /*
  141. * It's a leaf. Excise the record being deleted, by sliding the
  142. * entries past it down one. Log the changed areas of the block.
  143. */
  144. else {
  145. rp = XFS_INOBT_REC_ADDR(block, 1, cur);
  146. if (ptr < numrecs) {
  147. memmove(&rp[ptr - 1], &rp[ptr],
  148. (numrecs - ptr) * sizeof(*rp));
  149. xfs_inobt_log_recs(cur, bp, ptr, numrecs - 1);
  150. }
  151. /*
  152. * If it's the first record in the block, we'll need a key
  153. * structure to pass up to the next level (updkey).
  154. */
  155. if (ptr == 1) {
  156. key.ir_startino = rp->ir_startino;
  157. kp = &key;
  158. }
  159. }
  160. /*
  161. * Decrement and log the number of entries in the block.
  162. */
  163. numrecs--;
  164. block->bb_numrecs = cpu_to_be16(numrecs);
  165. xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
  166. /*
  167. * Is this the root level? If so, we're almost done.
  168. */
  169. if (level == cur->bc_nlevels - 1) {
  170. /*
  171. * If this is the root level,
  172. * and there's only one entry left,
  173. * and it's NOT the leaf level,
  174. * then we can get rid of this level.
  175. */
  176. if (numrecs == 1 && level > 0) {
  177. agbp = cur->bc_private.a.agbp;
  178. agi = XFS_BUF_TO_AGI(agbp);
  179. /*
  180. * pp is still set to the first pointer in the block.
  181. * Make it the new root of the btree.
  182. */
  183. bno = be32_to_cpu(agi->agi_root);
  184. agi->agi_root = *pp;
  185. be32_add_cpu(&agi->agi_level, -1);
  186. /*
  187. * Free the block.
  188. */
  189. if ((error = xfs_free_extent(cur->bc_tp,
  190. XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, bno), 1)))
  191. return error;
  192. xfs_trans_binval(cur->bc_tp, bp);
  193. xfs_ialloc_log_agi(cur->bc_tp, agbp,
  194. XFS_AGI_ROOT | XFS_AGI_LEVEL);
  195. /*
  196. * Update the cursor so there's one fewer level.
  197. */
  198. cur->bc_bufs[level] = NULL;
  199. cur->bc_nlevels--;
  200. } else if (level > 0 &&
  201. (error = xfs_btree_decrement(cur, level, &i)))
  202. return error;
  203. *stat = 1;
  204. return 0;
  205. }
  206. /*
  207. * If we deleted the leftmost entry in the block, update the
  208. * key values above us in the tree.
  209. */
  210. if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1)))
  211. return error;
  212. /*
  213. * If the number of records remaining in the block is at least
  214. * the minimum, we're done.
  215. */
  216. if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) {
  217. if (level > 0 &&
  218. (error = xfs_btree_decrement(cur, level, &i)))
  219. return error;
  220. *stat = 1;
  221. return 0;
  222. }
  223. /*
  224. * Otherwise, we have to move some records around to keep the
  225. * tree balanced. Look at the left and right sibling blocks to
  226. * see if we can re-balance by moving only one record.
  227. */
  228. rbno = be32_to_cpu(block->bb_rightsib);
  229. lbno = be32_to_cpu(block->bb_leftsib);
  230. bno = NULLAGBLOCK;
  231. ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
  232. /*
  233. * Duplicate the cursor so our btree manipulations here won't
  234. * disrupt the next level up.
  235. */
  236. if ((error = xfs_btree_dup_cursor(cur, &tcur)))
  237. return error;
  238. /*
  239. * If there's a right sibling, see if it's ok to shift an entry
  240. * out of it.
  241. */
  242. if (rbno != NULLAGBLOCK) {
  243. /*
  244. * Move the temp cursor to the last entry in the next block.
  245. * Actually any entry but the first would suffice.
  246. */
  247. i = xfs_btree_lastrec(tcur, level);
  248. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  249. if ((error = xfs_btree_increment(tcur, level, &i)))
  250. goto error0;
  251. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  252. i = xfs_btree_lastrec(tcur, level);
  253. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  254. /*
  255. * Grab a pointer to the block.
  256. */
  257. rbp = tcur->bc_bufs[level];
  258. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  259. #ifdef DEBUG
  260. if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
  261. goto error0;
  262. #endif
  263. /*
  264. * Grab the current block number, for future use.
  265. */
  266. bno = be32_to_cpu(right->bb_leftsib);
  267. /*
  268. * If right block is full enough so that removing one entry
  269. * won't make it too empty, and left-shifting an entry out
  270. * of right to us works, we're done.
  271. */
  272. if (be16_to_cpu(right->bb_numrecs) - 1 >=
  273. XFS_INOBT_BLOCK_MINRECS(level, cur)) {
  274. if ((error = xfs_inobt_lshift(tcur, level, &i)))
  275. goto error0;
  276. if (i) {
  277. ASSERT(be16_to_cpu(block->bb_numrecs) >=
  278. XFS_INOBT_BLOCK_MINRECS(level, cur));
  279. xfs_btree_del_cursor(tcur,
  280. XFS_BTREE_NOERROR);
  281. if (level > 0 &&
  282. (error = xfs_btree_decrement(cur, level,
  283. &i)))
  284. return error;
  285. *stat = 1;
  286. return 0;
  287. }
  288. }
  289. /*
  290. * Otherwise, grab the number of records in right for
  291. * future reference, and fix up the temp cursor to point
  292. * to our block again (last record).
  293. */
  294. rrecs = be16_to_cpu(right->bb_numrecs);
  295. if (lbno != NULLAGBLOCK) {
  296. xfs_btree_firstrec(tcur, level);
  297. if ((error = xfs_btree_decrement(tcur, level, &i)))
  298. goto error0;
  299. }
  300. }
  301. /*
  302. * If there's a left sibling, see if it's ok to shift an entry
  303. * out of it.
  304. */
  305. if (lbno != NULLAGBLOCK) {
  306. /*
  307. * Move the temp cursor to the first entry in the
  308. * previous block.
  309. */
  310. xfs_btree_firstrec(tcur, level);
  311. if ((error = xfs_btree_decrement(tcur, level, &i)))
  312. goto error0;
  313. xfs_btree_firstrec(tcur, level);
  314. /*
  315. * Grab a pointer to the block.
  316. */
  317. lbp = tcur->bc_bufs[level];
  318. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  319. #ifdef DEBUG
  320. if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
  321. goto error0;
  322. #endif
  323. /*
  324. * Grab the current block number, for future use.
  325. */
  326. bno = be32_to_cpu(left->bb_rightsib);
  327. /*
  328. * If left block is full enough so that removing one entry
  329. * won't make it too empty, and right-shifting an entry out
  330. * of left to us works, we're done.
  331. */
  332. if (be16_to_cpu(left->bb_numrecs) - 1 >=
  333. XFS_INOBT_BLOCK_MINRECS(level, cur)) {
  334. if ((error = xfs_inobt_rshift(tcur, level, &i)))
  335. goto error0;
  336. if (i) {
  337. ASSERT(be16_to_cpu(block->bb_numrecs) >=
  338. XFS_INOBT_BLOCK_MINRECS(level, cur));
  339. xfs_btree_del_cursor(tcur,
  340. XFS_BTREE_NOERROR);
  341. if (level == 0)
  342. cur->bc_ptrs[0]++;
  343. *stat = 1;
  344. return 0;
  345. }
  346. }
  347. /*
  348. * Otherwise, grab the number of records in right for
  349. * future reference.
  350. */
  351. lrecs = be16_to_cpu(left->bb_numrecs);
  352. }
  353. /*
  354. * Delete the temp cursor, we're done with it.
  355. */
  356. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  357. /*
  358. * If here, we need to do a join to keep the tree balanced.
  359. */
  360. ASSERT(bno != NULLAGBLOCK);
  361. /*
  362. * See if we can join with the left neighbor block.
  363. */
  364. if (lbno != NULLAGBLOCK &&
  365. lrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
  366. /*
  367. * Set "right" to be the starting block,
  368. * "left" to be the left neighbor.
  369. */
  370. rbno = bno;
  371. right = block;
  372. rrecs = be16_to_cpu(right->bb_numrecs);
  373. rbp = bp;
  374. if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
  375. cur->bc_private.a.agno, lbno, 0, &lbp,
  376. XFS_INO_BTREE_REF)))
  377. return error;
  378. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  379. lrecs = be16_to_cpu(left->bb_numrecs);
  380. if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
  381. return error;
  382. }
  383. /*
  384. * If that won't work, see if we can join with the right neighbor block.
  385. */
  386. else if (rbno != NULLAGBLOCK &&
  387. rrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
  388. /*
  389. * Set "left" to be the starting block,
  390. * "right" to be the right neighbor.
  391. */
  392. lbno = bno;
  393. left = block;
  394. lrecs = be16_to_cpu(left->bb_numrecs);
  395. lbp = bp;
  396. if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
  397. cur->bc_private.a.agno, rbno, 0, &rbp,
  398. XFS_INO_BTREE_REF)))
  399. return error;
  400. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  401. rrecs = be16_to_cpu(right->bb_numrecs);
  402. if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
  403. return error;
  404. }
  405. /*
  406. * Otherwise, we can't fix the imbalance.
  407. * Just return. This is probably a logic error, but it's not fatal.
  408. */
  409. else {
  410. if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
  411. return error;
  412. *stat = 1;
  413. return 0;
  414. }
  415. /*
  416. * We're now going to join "left" and "right" by moving all the stuff
  417. * in "right" to "left" and deleting "right".
  418. */
  419. if (level > 0) {
  420. /*
  421. * It's a non-leaf. Move keys and pointers.
  422. */
  423. lkp = XFS_INOBT_KEY_ADDR(left, lrecs + 1, cur);
  424. lpp = XFS_INOBT_PTR_ADDR(left, lrecs + 1, cur);
  425. rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
  426. rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
  427. #ifdef DEBUG
  428. for (i = 0; i < rrecs; i++) {
  429. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
  430. return error;
  431. }
  432. #endif
  433. memcpy(lkp, rkp, rrecs * sizeof(*lkp));
  434. memcpy(lpp, rpp, rrecs * sizeof(*lpp));
  435. xfs_inobt_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
  436. xfs_inobt_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
  437. } else {
  438. /*
  439. * It's a leaf. Move records.
  440. */
  441. lrp = XFS_INOBT_REC_ADDR(left, lrecs + 1, cur);
  442. rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
  443. memcpy(lrp, rrp, rrecs * sizeof(*lrp));
  444. xfs_inobt_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
  445. }
  446. /*
  447. * If we joined with the left neighbor, set the buffer in the
  448. * cursor to the left block, and fix up the index.
  449. */
  450. if (bp != lbp) {
  451. xfs_btree_setbuf(cur, level, lbp);
  452. cur->bc_ptrs[level] += lrecs;
  453. }
  454. /*
  455. * If we joined with the right neighbor and there's a level above
  456. * us, increment the cursor at that level.
  457. */
  458. else if (level + 1 < cur->bc_nlevels &&
  459. (error = xfs_btree_increment(cur, level + 1, &i)))
  460. return error;
  461. /*
  462. * Fix up the number of records in the surviving block.
  463. */
  464. lrecs += rrecs;
  465. left->bb_numrecs = cpu_to_be16(lrecs);
  466. /*
  467. * Fix up the right block pointer in the surviving block, and log it.
  468. */
  469. left->bb_rightsib = right->bb_rightsib;
  470. xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
  471. /*
  472. * If there is a right sibling now, make it point to the
  473. * remaining block.
  474. */
  475. if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
  476. xfs_inobt_block_t *rrblock;
  477. xfs_buf_t *rrbp;
  478. if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
  479. cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
  480. &rrbp, XFS_INO_BTREE_REF)))
  481. return error;
  482. rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
  483. if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
  484. return error;
  485. rrblock->bb_leftsib = cpu_to_be32(lbno);
  486. xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
  487. }
  488. /*
  489. * Free the deleting block.
  490. */
  491. if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp,
  492. cur->bc_private.a.agno, rbno), 1)))
  493. return error;
  494. xfs_trans_binval(cur->bc_tp, rbp);
  495. /*
  496. * Readjust the ptr at this level if it's not a leaf, since it's
  497. * still pointing at the deletion point, which makes the cursor
  498. * inconsistent. If this makes the ptr 0, the caller fixes it up.
  499. * We can't use decrement because it would change the next level up.
  500. */
  501. if (level > 0)
  502. cur->bc_ptrs[level]--;
  503. /*
  504. * Return value means the next level up has something to do.
  505. */
  506. *stat = 2;
  507. return 0;
  508. error0:
  509. xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
  510. return error;
  511. }
  512. /*
  513. * Insert one record/level. Return information to the caller
  514. * allowing the next level up to proceed if necessary.
  515. */
  516. STATIC int /* error */
  517. xfs_inobt_insrec(
  518. xfs_btree_cur_t *cur, /* btree cursor */
  519. int level, /* level to insert record at */
  520. xfs_agblock_t *bnop, /* i/o: block number inserted */
  521. xfs_inobt_rec_t *recp, /* i/o: record data inserted */
  522. xfs_btree_cur_t **curp, /* output: new cursor replacing cur */
  523. int *stat) /* success/failure */
  524. {
  525. xfs_inobt_block_t *block; /* btree block record/key lives in */
  526. xfs_buf_t *bp; /* buffer for block */
  527. int error; /* error return value */
  528. int i; /* loop index */
  529. xfs_inobt_key_t key; /* key value being inserted */
  530. xfs_inobt_key_t *kp=NULL; /* pointer to btree keys */
  531. xfs_agblock_t nbno; /* block number of allocated block */
  532. xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
  533. xfs_inobt_key_t nkey; /* new key value, from split */
  534. xfs_inobt_rec_t nrec; /* new record value, for caller */
  535. int numrecs;
  536. int optr; /* old ptr value */
  537. xfs_inobt_ptr_t *pp; /* pointer to btree addresses */
  538. int ptr; /* index in btree block for this rec */
  539. xfs_inobt_rec_t *rp=NULL; /* pointer to btree records */
  540. /*
  541. * GCC doesn't understand the (arguably complex) control flow in
  542. * this function and complains about uninitialized structure fields
  543. * without this.
  544. */
  545. memset(&nrec, 0, sizeof(nrec));
  546. /*
  547. * If we made it to the root level, allocate a new root block
  548. * and we're done.
  549. */
  550. if (level >= cur->bc_nlevels) {
  551. error = xfs_inobt_newroot(cur, &i);
  552. *bnop = NULLAGBLOCK;
  553. *stat = i;
  554. return error;
  555. }
  556. /*
  557. * Make a key out of the record data to be inserted, and save it.
  558. */
  559. key.ir_startino = recp->ir_startino;
  560. optr = ptr = cur->bc_ptrs[level];
  561. /*
  562. * If we're off the left edge, return failure.
  563. */
  564. if (ptr == 0) {
  565. *stat = 0;
  566. return 0;
  567. }
  568. /*
  569. * Get pointers to the btree buffer and block.
  570. */
  571. bp = cur->bc_bufs[level];
  572. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  573. numrecs = be16_to_cpu(block->bb_numrecs);
  574. #ifdef DEBUG
  575. if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
  576. return error;
  577. /*
  578. * Check that the new entry is being inserted in the right place.
  579. */
  580. if (ptr <= numrecs) {
  581. if (level == 0) {
  582. rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
  583. xfs_btree_check_rec(cur->bc_btnum, recp, rp);
  584. } else {
  585. kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
  586. xfs_btree_check_key(cur->bc_btnum, &key, kp);
  587. }
  588. }
  589. #endif
  590. nbno = NULLAGBLOCK;
  591. ncur = NULL;
  592. /*
  593. * If the block is full, we can't insert the new entry until we
  594. * make the block un-full.
  595. */
  596. if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
  597. /*
  598. * First, try shifting an entry to the right neighbor.
  599. */
  600. if ((error = xfs_inobt_rshift(cur, level, &i)))
  601. return error;
  602. if (i) {
  603. /* nothing */
  604. }
  605. /*
  606. * Next, try shifting an entry to the left neighbor.
  607. */
  608. else {
  609. if ((error = xfs_inobt_lshift(cur, level, &i)))
  610. return error;
  611. if (i) {
  612. optr = ptr = cur->bc_ptrs[level];
  613. } else {
  614. /*
  615. * Next, try splitting the current block
  616. * in half. If this works we have to
  617. * re-set our variables because
  618. * we could be in a different block now.
  619. */
  620. if ((error = xfs_inobt_split(cur, level, &nbno,
  621. &nkey, &ncur, &i)))
  622. return error;
  623. if (i) {
  624. bp = cur->bc_bufs[level];
  625. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  626. #ifdef DEBUG
  627. if ((error = xfs_btree_check_sblock(cur,
  628. block, level, bp)))
  629. return error;
  630. #endif
  631. ptr = cur->bc_ptrs[level];
  632. nrec.ir_startino = nkey.ir_startino;
  633. } else {
  634. /*
  635. * Otherwise the insert fails.
  636. */
  637. *stat = 0;
  638. return 0;
  639. }
  640. }
  641. }
  642. }
  643. /*
  644. * At this point we know there's room for our new entry in the block
  645. * we're pointing at.
  646. */
  647. numrecs = be16_to_cpu(block->bb_numrecs);
  648. if (level > 0) {
  649. /*
  650. * It's a non-leaf entry. Make a hole for the new data
  651. * in the key and ptr regions of the block.
  652. */
  653. kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
  654. pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
  655. #ifdef DEBUG
  656. for (i = numrecs; i >= ptr; i--) {
  657. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
  658. return error;
  659. }
  660. #endif
  661. memmove(&kp[ptr], &kp[ptr - 1],
  662. (numrecs - ptr + 1) * sizeof(*kp));
  663. memmove(&pp[ptr], &pp[ptr - 1],
  664. (numrecs - ptr + 1) * sizeof(*pp));
  665. /*
  666. * Now stuff the new data in, bump numrecs and log the new data.
  667. */
  668. #ifdef DEBUG
  669. if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
  670. return error;
  671. #endif
  672. kp[ptr - 1] = key;
  673. pp[ptr - 1] = cpu_to_be32(*bnop);
  674. numrecs++;
  675. block->bb_numrecs = cpu_to_be16(numrecs);
  676. xfs_inobt_log_keys(cur, bp, ptr, numrecs);
  677. xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
  678. } else {
  679. /*
  680. * It's a leaf entry. Make a hole for the new record.
  681. */
  682. rp = XFS_INOBT_REC_ADDR(block, 1, cur);
  683. memmove(&rp[ptr], &rp[ptr - 1],
  684. (numrecs - ptr + 1) * sizeof(*rp));
  685. /*
  686. * Now stuff the new record in, bump numrecs
  687. * and log the new data.
  688. */
  689. rp[ptr - 1] = *recp;
  690. numrecs++;
  691. block->bb_numrecs = cpu_to_be16(numrecs);
  692. xfs_inobt_log_recs(cur, bp, ptr, numrecs);
  693. }
  694. /*
  695. * Log the new number of records in the btree header.
  696. */
  697. xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
  698. #ifdef DEBUG
  699. /*
  700. * Check that the key/record is in the right place, now.
  701. */
  702. if (ptr < numrecs) {
  703. if (level == 0)
  704. xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
  705. rp + ptr);
  706. else
  707. xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
  708. kp + ptr);
  709. }
  710. #endif
  711. /*
  712. * If we inserted at the start of a block, update the parents' keys.
  713. */
  714. if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
  715. return error;
  716. /*
  717. * Return the new block number, if any.
  718. * If there is one, give back a record value and a cursor too.
  719. */
  720. *bnop = nbno;
  721. if (nbno != NULLAGBLOCK) {
  722. *recp = nrec;
  723. *curp = ncur;
  724. }
  725. *stat = 1;
  726. return 0;
  727. }
  728. /*
  729. * Log header fields from a btree block.
  730. */
  731. STATIC void
  732. xfs_inobt_log_block(
  733. xfs_trans_t *tp, /* transaction pointer */
  734. xfs_buf_t *bp, /* buffer containing btree block */
  735. int fields) /* mask of fields: XFS_BB_... */
  736. {
  737. int first; /* first byte offset logged */
  738. int last; /* last byte offset logged */
  739. static const short offsets[] = { /* table of offsets */
  740. offsetof(xfs_inobt_block_t, bb_magic),
  741. offsetof(xfs_inobt_block_t, bb_level),
  742. offsetof(xfs_inobt_block_t, bb_numrecs),
  743. offsetof(xfs_inobt_block_t, bb_leftsib),
  744. offsetof(xfs_inobt_block_t, bb_rightsib),
  745. sizeof(xfs_inobt_block_t)
  746. };
  747. xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
  748. xfs_trans_log_buf(tp, bp, first, last);
  749. }
  750. /*
  751. * Log keys from a btree block (nonleaf).
  752. */
  753. STATIC void
  754. xfs_inobt_log_keys(
  755. xfs_btree_cur_t *cur, /* btree cursor */
  756. xfs_buf_t *bp, /* buffer containing btree block */
  757. int kfirst, /* index of first key to log */
  758. int klast) /* index of last key to log */
  759. {
  760. xfs_inobt_block_t *block; /* btree block to log from */
  761. int first; /* first byte offset logged */
  762. xfs_inobt_key_t *kp; /* key pointer in btree block */
  763. int last; /* last byte offset logged */
  764. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  765. kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
  766. first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
  767. last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
  768. xfs_trans_log_buf(cur->bc_tp, bp, first, last);
  769. }
  770. /*
  771. * Log block pointer fields from a btree block (nonleaf).
  772. */
  773. STATIC void
  774. xfs_inobt_log_ptrs(
  775. xfs_btree_cur_t *cur, /* btree cursor */
  776. xfs_buf_t *bp, /* buffer containing btree block */
  777. int pfirst, /* index of first pointer to log */
  778. int plast) /* index of last pointer to log */
  779. {
  780. xfs_inobt_block_t *block; /* btree block to log from */
  781. int first; /* first byte offset logged */
  782. int last; /* last byte offset logged */
  783. xfs_inobt_ptr_t *pp; /* block-pointer pointer in btree blk */
  784. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  785. pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
  786. first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
  787. last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
  788. xfs_trans_log_buf(cur->bc_tp, bp, first, last);
  789. }
  790. /*
  791. * Log records from a btree block (leaf).
  792. */
  793. STATIC void
  794. xfs_inobt_log_recs(
  795. xfs_btree_cur_t *cur, /* btree cursor */
  796. xfs_buf_t *bp, /* buffer containing btree block */
  797. int rfirst, /* index of first record to log */
  798. int rlast) /* index of last record to log */
  799. {
  800. xfs_inobt_block_t *block; /* btree block to log from */
  801. int first; /* first byte offset logged */
  802. int last; /* last byte offset logged */
  803. xfs_inobt_rec_t *rp; /* record pointer for btree block */
  804. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  805. rp = XFS_INOBT_REC_ADDR(block, 1, cur);
  806. first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
  807. last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
  808. xfs_trans_log_buf(cur->bc_tp, bp, first, last);
  809. }
  810. /*
  811. * Move 1 record left from cur/level if possible.
  812. * Update cur to reflect the new path.
  813. */
  814. STATIC int /* error */
  815. xfs_inobt_lshift(
  816. xfs_btree_cur_t *cur, /* btree cursor */
  817. int level, /* level to shift record on */
  818. int *stat) /* success/failure */
  819. {
  820. int error; /* error return value */
  821. #ifdef DEBUG
  822. int i; /* loop index */
  823. #endif
  824. xfs_inobt_key_t key; /* key value for leaf level upward */
  825. xfs_buf_t *lbp; /* buffer for left neighbor block */
  826. xfs_inobt_block_t *left; /* left neighbor btree block */
  827. xfs_inobt_key_t *lkp=NULL; /* key pointer for left block */
  828. xfs_inobt_ptr_t *lpp; /* address pointer for left block */
  829. xfs_inobt_rec_t *lrp=NULL; /* record pointer for left block */
  830. int nrec; /* new number of left block entries */
  831. xfs_buf_t *rbp; /* buffer for right (current) block */
  832. xfs_inobt_block_t *right; /* right (current) btree block */
  833. xfs_inobt_key_t *rkp=NULL; /* key pointer for right block */
  834. xfs_inobt_ptr_t *rpp=NULL; /* address pointer for right block */
  835. xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
  836. /*
  837. * Set up variables for this block as "right".
  838. */
  839. rbp = cur->bc_bufs[level];
  840. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  841. #ifdef DEBUG
  842. if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
  843. return error;
  844. #endif
  845. /*
  846. * If we've got no left sibling then we can't shift an entry left.
  847. */
  848. if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
  849. *stat = 0;
  850. return 0;
  851. }
  852. /*
  853. * If the cursor entry is the one that would be moved, don't
  854. * do it... it's too complicated.
  855. */
  856. if (cur->bc_ptrs[level] <= 1) {
  857. *stat = 0;
  858. return 0;
  859. }
  860. /*
  861. * Set up the left neighbor as "left".
  862. */
  863. if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
  864. cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
  865. 0, &lbp, XFS_INO_BTREE_REF)))
  866. return error;
  867. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  868. if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
  869. return error;
  870. /*
  871. * If it's full, it can't take another entry.
  872. */
  873. if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
  874. *stat = 0;
  875. return 0;
  876. }
  877. nrec = be16_to_cpu(left->bb_numrecs) + 1;
  878. /*
  879. * If non-leaf, copy a key and a ptr to the left block.
  880. */
  881. if (level > 0) {
  882. lkp = XFS_INOBT_KEY_ADDR(left, nrec, cur);
  883. rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
  884. *lkp = *rkp;
  885. xfs_inobt_log_keys(cur, lbp, nrec, nrec);
  886. lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
  887. rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
  888. #ifdef DEBUG
  889. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
  890. return error;
  891. #endif
  892. *lpp = *rpp;
  893. xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
  894. }
  895. /*
  896. * If leaf, copy a record to the left block.
  897. */
  898. else {
  899. lrp = XFS_INOBT_REC_ADDR(left, nrec, cur);
  900. rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
  901. *lrp = *rrp;
  902. xfs_inobt_log_recs(cur, lbp, nrec, nrec);
  903. }
  904. /*
  905. * Bump and log left's numrecs, decrement and log right's numrecs.
  906. */
  907. be16_add_cpu(&left->bb_numrecs, 1);
  908. xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
  909. #ifdef DEBUG
  910. if (level > 0)
  911. xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
  912. else
  913. xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
  914. #endif
  915. be16_add_cpu(&right->bb_numrecs, -1);
  916. xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
  917. /*
  918. * Slide the contents of right down one entry.
  919. */
  920. if (level > 0) {
  921. #ifdef DEBUG
  922. for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
  923. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
  924. level)))
  925. return error;
  926. }
  927. #endif
  928. memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
  929. memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
  930. xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  931. xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  932. } else {
  933. memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
  934. xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  935. key.ir_startino = rrp->ir_startino;
  936. rkp = &key;
  937. }
  938. /*
  939. * Update the parent key values of right.
  940. */
  941. if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
  942. return error;
  943. /*
  944. * Slide the cursor value left one.
  945. */
  946. cur->bc_ptrs[level]--;
  947. *stat = 1;
  948. return 0;
  949. }
  950. /*
  951. * Allocate a new root block, fill it in.
  952. */
  953. STATIC int /* error */
  954. xfs_inobt_newroot(
  955. xfs_btree_cur_t *cur, /* btree cursor */
  956. int *stat) /* success/failure */
  957. {
  958. xfs_agi_t *agi; /* a.g. inode header */
  959. xfs_alloc_arg_t args; /* allocation argument structure */
  960. xfs_inobt_block_t *block; /* one half of the old root block */
  961. xfs_buf_t *bp; /* buffer containing block */
  962. int error; /* error return value */
  963. xfs_inobt_key_t *kp; /* btree key pointer */
  964. xfs_agblock_t lbno; /* left block number */
  965. xfs_buf_t *lbp; /* left buffer pointer */
  966. xfs_inobt_block_t *left; /* left btree block */
  967. xfs_buf_t *nbp; /* new (root) buffer */
  968. xfs_inobt_block_t *new; /* new (root) btree block */
  969. int nptr; /* new value for key index, 1 or 2 */
  970. xfs_inobt_ptr_t *pp; /* btree address pointer */
  971. xfs_agblock_t rbno; /* right block number */
  972. xfs_buf_t *rbp; /* right buffer pointer */
  973. xfs_inobt_block_t *right; /* right btree block */
  974. xfs_inobt_rec_t *rp; /* btree record pointer */
  975. ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp));
  976. /*
  977. * Get a block & a buffer.
  978. */
  979. agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
  980. args.tp = cur->bc_tp;
  981. args.mp = cur->bc_mp;
  982. args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno,
  983. be32_to_cpu(agi->agi_root));
  984. args.mod = args.minleft = args.alignment = args.total = args.wasdel =
  985. args.isfl = args.userdata = args.minalignslop = 0;
  986. args.minlen = args.maxlen = args.prod = 1;
  987. args.type = XFS_ALLOCTYPE_NEAR_BNO;
  988. if ((error = xfs_alloc_vextent(&args)))
  989. return error;
  990. /*
  991. * None available, we fail.
  992. */
  993. if (args.fsbno == NULLFSBLOCK) {
  994. *stat = 0;
  995. return 0;
  996. }
  997. ASSERT(args.len == 1);
  998. nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
  999. new = XFS_BUF_TO_INOBT_BLOCK(nbp);
  1000. /*
  1001. * Set the root data in the a.g. inode structure.
  1002. */
  1003. agi->agi_root = cpu_to_be32(args.agbno);
  1004. be32_add_cpu(&agi->agi_level, 1);
  1005. xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp,
  1006. XFS_AGI_ROOT | XFS_AGI_LEVEL);
  1007. /*
  1008. * At the previous root level there are now two blocks: the old
  1009. * root, and the new block generated when it was split.
  1010. * We don't know which one the cursor is pointing at, so we
  1011. * set up variables "left" and "right" for each case.
  1012. */
  1013. bp = cur->bc_bufs[cur->bc_nlevels - 1];
  1014. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  1015. #ifdef DEBUG
  1016. if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
  1017. return error;
  1018. #endif
  1019. if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
  1020. /*
  1021. * Our block is left, pick up the right block.
  1022. */
  1023. lbp = bp;
  1024. lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
  1025. left = block;
  1026. rbno = be32_to_cpu(left->bb_rightsib);
  1027. if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
  1028. rbno, 0, &rbp, XFS_INO_BTREE_REF)))
  1029. return error;
  1030. bp = rbp;
  1031. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  1032. if ((error = xfs_btree_check_sblock(cur, right,
  1033. cur->bc_nlevels - 1, rbp)))
  1034. return error;
  1035. nptr = 1;
  1036. } else {
  1037. /*
  1038. * Our block is right, pick up the left block.
  1039. */
  1040. rbp = bp;
  1041. rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
  1042. right = block;
  1043. lbno = be32_to_cpu(right->bb_leftsib);
  1044. if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
  1045. lbno, 0, &lbp, XFS_INO_BTREE_REF)))
  1046. return error;
  1047. bp = lbp;
  1048. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  1049. if ((error = xfs_btree_check_sblock(cur, left,
  1050. cur->bc_nlevels - 1, lbp)))
  1051. return error;
  1052. nptr = 2;
  1053. }
  1054. /*
  1055. * Fill in the new block's btree header and log it.
  1056. */
  1057. new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
  1058. new->bb_level = cpu_to_be16(cur->bc_nlevels);
  1059. new->bb_numrecs = cpu_to_be16(2);
  1060. new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
  1061. new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
  1062. xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
  1063. ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
  1064. /*
  1065. * Fill in the key data in the new root.
  1066. */
  1067. kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
  1068. if (be16_to_cpu(left->bb_level) > 0) {
  1069. kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
  1070. kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
  1071. } else {
  1072. rp = XFS_INOBT_REC_ADDR(left, 1, cur);
  1073. kp[0].ir_startino = rp->ir_startino;
  1074. rp = XFS_INOBT_REC_ADDR(right, 1, cur);
  1075. kp[1].ir_startino = rp->ir_startino;
  1076. }
  1077. xfs_inobt_log_keys(cur, nbp, 1, 2);
  1078. /*
  1079. * Fill in the pointer data in the new root.
  1080. */
  1081. pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
  1082. pp[0] = cpu_to_be32(lbno);
  1083. pp[1] = cpu_to_be32(rbno);
  1084. xfs_inobt_log_ptrs(cur, nbp, 1, 2);
  1085. /*
  1086. * Fix up the cursor.
  1087. */
  1088. xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
  1089. cur->bc_ptrs[cur->bc_nlevels] = nptr;
  1090. cur->bc_nlevels++;
  1091. *stat = 1;
  1092. return 0;
  1093. }
  1094. /*
  1095. * Move 1 record right from cur/level if possible.
  1096. * Update cur to reflect the new path.
  1097. */
  1098. STATIC int /* error */
  1099. xfs_inobt_rshift(
  1100. xfs_btree_cur_t *cur, /* btree cursor */
  1101. int level, /* level to shift record on */
  1102. int *stat) /* success/failure */
  1103. {
  1104. int error; /* error return value */
  1105. int i; /* loop index */
  1106. xfs_inobt_key_t key; /* key value for leaf level upward */
  1107. xfs_buf_t *lbp; /* buffer for left (current) block */
  1108. xfs_inobt_block_t *left; /* left (current) btree block */
  1109. xfs_inobt_key_t *lkp; /* key pointer for left block */
  1110. xfs_inobt_ptr_t *lpp; /* address pointer for left block */
  1111. xfs_inobt_rec_t *lrp; /* record pointer for left block */
  1112. xfs_buf_t *rbp; /* buffer for right neighbor block */
  1113. xfs_inobt_block_t *right; /* right neighbor btree block */
  1114. xfs_inobt_key_t *rkp; /* key pointer for right block */
  1115. xfs_inobt_ptr_t *rpp; /* address pointer for right block */
  1116. xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
  1117. xfs_btree_cur_t *tcur; /* temporary cursor */
  1118. /*
  1119. * Set up variables for this block as "left".
  1120. */
  1121. lbp = cur->bc_bufs[level];
  1122. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  1123. #ifdef DEBUG
  1124. if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
  1125. return error;
  1126. #endif
  1127. /*
  1128. * If we've got no right sibling then we can't shift an entry right.
  1129. */
  1130. if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
  1131. *stat = 0;
  1132. return 0;
  1133. }
  1134. /*
  1135. * If the cursor entry is the one that would be moved, don't
  1136. * do it... it's too complicated.
  1137. */
  1138. if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
  1139. *stat = 0;
  1140. return 0;
  1141. }
  1142. /*
  1143. * Set up the right neighbor as "right".
  1144. */
  1145. if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
  1146. cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib),
  1147. 0, &rbp, XFS_INO_BTREE_REF)))
  1148. return error;
  1149. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  1150. if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
  1151. return error;
  1152. /*
  1153. * If it's full, it can't take another entry.
  1154. */
  1155. if (be16_to_cpu(right->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
  1156. *stat = 0;
  1157. return 0;
  1158. }
  1159. /*
  1160. * Make a hole at the start of the right neighbor block, then
  1161. * copy the last left block entry to the hole.
  1162. */
  1163. if (level > 0) {
  1164. lkp = XFS_INOBT_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1165. lpp = XFS_INOBT_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1166. rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
  1167. rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
  1168. #ifdef DEBUG
  1169. for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
  1170. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
  1171. return error;
  1172. }
  1173. #endif
  1174. memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
  1175. memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
  1176. #ifdef DEBUG
  1177. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
  1178. return error;
  1179. #endif
  1180. *rkp = *lkp;
  1181. *rpp = *lpp;
  1182. xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1183. xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1184. } else {
  1185. lrp = XFS_INOBT_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1186. rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
  1187. memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
  1188. *rrp = *lrp;
  1189. xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1190. key.ir_startino = rrp->ir_startino;
  1191. rkp = &key;
  1192. }
  1193. /*
  1194. * Decrement and log left's numrecs, bump and log right's numrecs.
  1195. */
  1196. be16_add_cpu(&left->bb_numrecs, -1);
  1197. xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
  1198. be16_add_cpu(&right->bb_numrecs, 1);
  1199. #ifdef DEBUG
  1200. if (level > 0)
  1201. xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
  1202. else
  1203. xfs_btree_check_rec(cur->bc_btnum, rrp, rrp + 1);
  1204. #endif
  1205. xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
  1206. /*
  1207. * Using a temporary cursor, update the parent key values of the
  1208. * block on the right.
  1209. */
  1210. if ((error = xfs_btree_dup_cursor(cur, &tcur)))
  1211. return error;
  1212. xfs_btree_lastrec(tcur, level);
  1213. if ((error = xfs_btree_increment(tcur, level, &i)) ||
  1214. (error = xfs_btree_updkey(tcur, (union xfs_btree_key *)rkp, level + 1))) {
  1215. xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
  1216. return error;
  1217. }
  1218. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  1219. *stat = 1;
  1220. return 0;
  1221. }
  1222. /*
  1223. * Split cur/level block in half.
  1224. * Return new block number and its first record (to be inserted into parent).
  1225. */
  1226. STATIC int /* error */
  1227. xfs_inobt_split(
  1228. xfs_btree_cur_t *cur, /* btree cursor */
  1229. int level, /* level to split */
  1230. xfs_agblock_t *bnop, /* output: block number allocated */
  1231. xfs_inobt_key_t *keyp, /* output: first key of new block */
  1232. xfs_btree_cur_t **curp, /* output: new cursor */
  1233. int *stat) /* success/failure */
  1234. {
  1235. xfs_alloc_arg_t args; /* allocation argument structure */
  1236. int error; /* error return value */
  1237. int i; /* loop index/record number */
  1238. xfs_agblock_t lbno; /* left (current) block number */
  1239. xfs_buf_t *lbp; /* buffer for left block */
  1240. xfs_inobt_block_t *left; /* left (current) btree block */
  1241. xfs_inobt_key_t *lkp; /* left btree key pointer */
  1242. xfs_inobt_ptr_t *lpp; /* left btree address pointer */
  1243. xfs_inobt_rec_t *lrp; /* left btree record pointer */
  1244. xfs_buf_t *rbp; /* buffer for right block */
  1245. xfs_inobt_block_t *right; /* right (new) btree block */
  1246. xfs_inobt_key_t *rkp; /* right btree key pointer */
  1247. xfs_inobt_ptr_t *rpp; /* right btree address pointer */
  1248. xfs_inobt_rec_t *rrp; /* right btree record pointer */
  1249. /*
  1250. * Set up left block (current one).
  1251. */
  1252. lbp = cur->bc_bufs[level];
  1253. args.tp = cur->bc_tp;
  1254. args.mp = cur->bc_mp;
  1255. lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
  1256. /*
  1257. * Allocate the new block.
  1258. * If we can't do it, we're toast. Give up.
  1259. */
  1260. args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno);
  1261. args.mod = args.minleft = args.alignment = args.total = args.wasdel =
  1262. args.isfl = args.userdata = args.minalignslop = 0;
  1263. args.minlen = args.maxlen = args.prod = 1;
  1264. args.type = XFS_ALLOCTYPE_NEAR_BNO;
  1265. if ((error = xfs_alloc_vextent(&args)))
  1266. return error;
  1267. if (args.fsbno == NULLFSBLOCK) {
  1268. *stat = 0;
  1269. return 0;
  1270. }
  1271. ASSERT(args.len == 1);
  1272. rbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
  1273. /*
  1274. * Set up the new block as "right".
  1275. */
  1276. right = XFS_BUF_TO_INOBT_BLOCK(rbp);
  1277. /*
  1278. * "Left" is the current (according to the cursor) block.
  1279. */
  1280. left = XFS_BUF_TO_INOBT_BLOCK(lbp);
  1281. #ifdef DEBUG
  1282. if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
  1283. return error;
  1284. #endif
  1285. /*
  1286. * Fill in the btree header for the new block.
  1287. */
  1288. right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
  1289. right->bb_level = left->bb_level;
  1290. right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
  1291. /*
  1292. * Make sure that if there's an odd number of entries now, that
  1293. * each new block will have the same number of entries.
  1294. */
  1295. if ((be16_to_cpu(left->bb_numrecs) & 1) &&
  1296. cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
  1297. be16_add_cpu(&right->bb_numrecs, 1);
  1298. i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
  1299. /*
  1300. * For non-leaf blocks, copy keys and addresses over to the new block.
  1301. */
  1302. if (level > 0) {
  1303. lkp = XFS_INOBT_KEY_ADDR(left, i, cur);
  1304. lpp = XFS_INOBT_PTR_ADDR(left, i, cur);
  1305. rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
  1306. rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
  1307. #ifdef DEBUG
  1308. for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
  1309. if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
  1310. return error;
  1311. }
  1312. #endif
  1313. memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
  1314. memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
  1315. xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1316. xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1317. *keyp = *rkp;
  1318. }
  1319. /*
  1320. * For leaf blocks, copy records over to the new block.
  1321. */
  1322. else {
  1323. lrp = XFS_INOBT_REC_ADDR(left, i, cur);
  1324. rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
  1325. memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
  1326. xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1327. keyp->ir_startino = rrp->ir_startino;
  1328. }
  1329. /*
  1330. * Find the left block number by looking in the buffer.
  1331. * Adjust numrecs, sibling pointers.
  1332. */
  1333. be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
  1334. right->bb_rightsib = left->bb_rightsib;
  1335. left->bb_rightsib = cpu_to_be32(args.agbno);
  1336. right->bb_leftsib = cpu_to_be32(lbno);
  1337. xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);
  1338. xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
  1339. /*
  1340. * If there's a block to the new block's right, make that block
  1341. * point back to right instead of to left.
  1342. */
  1343. if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
  1344. xfs_inobt_block_t *rrblock; /* rr btree block */
  1345. xfs_buf_t *rrbp; /* buffer for rrblock */
  1346. if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
  1347. be32_to_cpu(right->bb_rightsib), 0, &rrbp,
  1348. XFS_INO_BTREE_REF)))
  1349. return error;
  1350. rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
  1351. if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
  1352. return error;
  1353. rrblock->bb_leftsib = cpu_to_be32(args.agbno);
  1354. xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);
  1355. }
  1356. /*
  1357. * If the cursor is really in the right block, move it there.
  1358. * If it's just pointing past the last entry in left, then we'll
  1359. * insert there, so don't change anything in that case.
  1360. */
  1361. if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
  1362. xfs_btree_setbuf(cur, level, rbp);
  1363. cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
  1364. }
  1365. /*
  1366. * If there are more levels, we'll need another cursor which refers
  1367. * the right block, no matter where this cursor was.
  1368. */
  1369. if (level + 1 < cur->bc_nlevels) {
  1370. if ((error = xfs_btree_dup_cursor(cur, curp)))
  1371. return error;
  1372. (*curp)->bc_ptrs[level + 1]++;
  1373. }
  1374. *bnop = args.agbno;
  1375. *stat = 1;
  1376. return 0;
  1377. }
  1378. /*
  1379. * Externally visible routines.
  1380. */
  1381. /*
  1382. * Delete the record pointed to by cur.
  1383. * The cursor refers to the place where the record was (could be inserted)
  1384. * when the operation returns.
  1385. */
  1386. int /* error */
  1387. xfs_inobt_delete(
  1388. xfs_btree_cur_t *cur, /* btree cursor */
  1389. int *stat) /* success/failure */
  1390. {
  1391. int error;
  1392. int i; /* result code */
  1393. int level; /* btree level */
  1394. /*
  1395. * Go up the tree, starting at leaf level.
  1396. * If 2 is returned then a join was done; go to the next level.
  1397. * Otherwise we are done.
  1398. */
  1399. for (level = 0, i = 2; i == 2; level++) {
  1400. if ((error = xfs_inobt_delrec(cur, level, &i)))
  1401. return error;
  1402. }
  1403. if (i == 0) {
  1404. for (level = 1; level < cur->bc_nlevels; level++) {
  1405. if (cur->bc_ptrs[level] == 0) {
  1406. if ((error = xfs_btree_decrement(cur, level, &i)))
  1407. return error;
  1408. break;
  1409. }
  1410. }
  1411. }
  1412. *stat = i;
  1413. return 0;
  1414. }
  1415. /*
  1416. * Get the data from the pointed-to record.
  1417. */
  1418. int /* error */
  1419. xfs_inobt_get_rec(
  1420. xfs_btree_cur_t *cur, /* btree cursor */
  1421. xfs_agino_t *ino, /* output: starting inode of chunk */
  1422. __int32_t *fcnt, /* output: number of free inodes */
  1423. xfs_inofree_t *free, /* output: free inode mask */
  1424. int *stat) /* output: success/failure */
  1425. {
  1426. xfs_inobt_block_t *block; /* btree block */
  1427. xfs_buf_t *bp; /* buffer containing btree block */
  1428. #ifdef DEBUG
  1429. int error; /* error return value */
  1430. #endif
  1431. int ptr; /* record number */
  1432. xfs_inobt_rec_t *rec; /* record data */
  1433. bp = cur->bc_bufs[0];
  1434. ptr = cur->bc_ptrs[0];
  1435. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  1436. #ifdef DEBUG
  1437. if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
  1438. return error;
  1439. #endif
  1440. /*
  1441. * Off the right end or left end, return failure.
  1442. */
  1443. if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
  1444. *stat = 0;
  1445. return 0;
  1446. }
  1447. /*
  1448. * Point to the record and extract its data.
  1449. */
  1450. rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
  1451. *ino = be32_to_cpu(rec->ir_startino);
  1452. *fcnt = be32_to_cpu(rec->ir_freecount);
  1453. *free = be64_to_cpu(rec->ir_free);
  1454. *stat = 1;
  1455. return 0;
  1456. }
  1457. /*
  1458. * Insert the current record at the point referenced by cur.
  1459. * The cursor may be inconsistent on return if splits have been done.
  1460. */
  1461. int /* error */
  1462. xfs_inobt_insert(
  1463. xfs_btree_cur_t *cur, /* btree cursor */
  1464. int *stat) /* success/failure */
  1465. {
  1466. int error; /* error return value */
  1467. int i; /* result value, 0 for failure */
  1468. int level; /* current level number in btree */
  1469. xfs_agblock_t nbno; /* new block number (split result) */
  1470. xfs_btree_cur_t *ncur; /* new cursor (split result) */
  1471. xfs_inobt_rec_t nrec; /* record being inserted this level */
  1472. xfs_btree_cur_t *pcur; /* previous level's cursor */
  1473. level = 0;
  1474. nbno = NULLAGBLOCK;
  1475. nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
  1476. nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
  1477. nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
  1478. ncur = NULL;
  1479. pcur = cur;
  1480. /*
  1481. * Loop going up the tree, starting at the leaf level.
  1482. * Stop when we don't get a split block, that must mean that
  1483. * the insert is finished with this level.
  1484. */
  1485. do {
  1486. /*
  1487. * Insert nrec/nbno into this level of the tree.
  1488. * Note if we fail, nbno will be null.
  1489. */
  1490. if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur,
  1491. &i))) {
  1492. if (pcur != cur)
  1493. xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
  1494. return error;
  1495. }
  1496. /*
  1497. * See if the cursor we just used is trash.
  1498. * Can't trash the caller's cursor, but otherwise we should
  1499. * if ncur is a new cursor or we're about to be done.
  1500. */
  1501. if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
  1502. cur->bc_nlevels = pcur->bc_nlevels;
  1503. xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
  1504. }
  1505. /*
  1506. * If we got a new cursor, switch to it.
  1507. */
  1508. if (ncur) {
  1509. pcur = ncur;
  1510. ncur = NULL;
  1511. }
  1512. } while (nbno != NULLAGBLOCK);
  1513. *stat = i;
  1514. return 0;
  1515. }
  1516. /*
  1517. * Update the record referred to by cur, to the value given
  1518. * by [ino, fcnt, free].
  1519. * This either works (return 0) or gets an EFSCORRUPTED error.
  1520. */
  1521. int /* error */
  1522. xfs_inobt_update(
  1523. xfs_btree_cur_t *cur, /* btree cursor */
  1524. xfs_agino_t ino, /* starting inode of chunk */
  1525. __int32_t fcnt, /* free inode count */
  1526. xfs_inofree_t free) /* free inode mask */
  1527. {
  1528. xfs_inobt_block_t *block; /* btree block to update */
  1529. xfs_buf_t *bp; /* buffer containing btree block */
  1530. int error; /* error return value */
  1531. int ptr; /* current record number (updating) */
  1532. xfs_inobt_rec_t *rp; /* pointer to updated record */
  1533. /*
  1534. * Pick up the current block.
  1535. */
  1536. bp = cur->bc_bufs[0];
  1537. block = XFS_BUF_TO_INOBT_BLOCK(bp);
  1538. #ifdef DEBUG
  1539. if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
  1540. return error;
  1541. #endif
  1542. /*
  1543. * Get the address of the rec to be updated.
  1544. */
  1545. ptr = cur->bc_ptrs[0];
  1546. rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
  1547. /*
  1548. * Fill in the new contents and log them.
  1549. */
  1550. rp->ir_startino = cpu_to_be32(ino);
  1551. rp->ir_freecount = cpu_to_be32(fcnt);
  1552. rp->ir_free = cpu_to_be64(free);
  1553. xfs_inobt_log_recs(cur, bp, ptr, ptr);
  1554. /*
  1555. * Updating first record in leaf. Pass new key value up to our parent.
  1556. */
  1557. if (ptr == 1) {
  1558. xfs_inobt_key_t key; /* key containing [ino] */
  1559. key.ir_startino = cpu_to_be32(ino);
  1560. if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1)))
  1561. return error;
  1562. }
  1563. return 0;
  1564. }
  1565. STATIC struct xfs_btree_cur *
  1566. xfs_inobt_dup_cursor(
  1567. struct xfs_btree_cur *cur)
  1568. {
  1569. return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
  1570. cur->bc_private.a.agbp, cur->bc_private.a.agno);
  1571. }
  1572. STATIC int
  1573. xfs_inobt_get_maxrecs(
  1574. struct xfs_btree_cur *cur,
  1575. int level)
  1576. {
  1577. return cur->bc_mp->m_inobt_mxr[level != 0];
  1578. }
  1579. STATIC void
  1580. xfs_inobt_init_key_from_rec(
  1581. union xfs_btree_key *key,
  1582. union xfs_btree_rec *rec)
  1583. {
  1584. key->inobt.ir_startino = rec->inobt.ir_startino;
  1585. }
  1586. /*
  1587. * intial value of ptr for lookup
  1588. */
  1589. STATIC void
  1590. xfs_inobt_init_ptr_from_cur(
  1591. struct xfs_btree_cur *cur,
  1592. union xfs_btree_ptr *ptr)
  1593. {
  1594. struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
  1595. ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
  1596. ptr->s = agi->agi_root;
  1597. }
  1598. STATIC __int64_t
  1599. xfs_inobt_key_diff(
  1600. struct xfs_btree_cur *cur,
  1601. union xfs_btree_key *key)
  1602. {
  1603. return (__int64_t)be32_to_cpu(key->inobt.ir_startino) -
  1604. cur->bc_rec.i.ir_startino;
  1605. }
  1606. #ifdef XFS_BTREE_TRACE
  1607. ktrace_t *xfs_inobt_trace_buf;
  1608. STATIC void
  1609. xfs_inobt_trace_enter(
  1610. struct xfs_btree_cur *cur,
  1611. const char *func,
  1612. char *s,
  1613. int type,
  1614. int line,
  1615. __psunsigned_t a0,
  1616. __psunsigned_t a1,
  1617. __psunsigned_t a2,
  1618. __psunsigned_t a3,
  1619. __psunsigned_t a4,
  1620. __psunsigned_t a5,
  1621. __psunsigned_t a6,
  1622. __psunsigned_t a7,
  1623. __psunsigned_t a8,
  1624. __psunsigned_t a9,
  1625. __psunsigned_t a10)
  1626. {
  1627. ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type,
  1628. (void *)func, (void *)s, NULL, (void *)cur,
  1629. (void *)a0, (void *)a1, (void *)a2, (void *)a3,
  1630. (void *)a4, (void *)a5, (void *)a6, (void *)a7,
  1631. (void *)a8, (void *)a9, (void *)a10);
  1632. }
  1633. STATIC void
  1634. xfs_inobt_trace_cursor(
  1635. struct xfs_btree_cur *cur,
  1636. __uint32_t *s0,
  1637. __uint64_t *l0,
  1638. __uint64_t *l1)
  1639. {
  1640. *s0 = cur->bc_private.a.agno;
  1641. *l0 = cur->bc_rec.i.ir_startino;
  1642. *l1 = cur->bc_rec.i.ir_free;
  1643. }
  1644. STATIC void
  1645. xfs_inobt_trace_key(
  1646. struct xfs_btree_cur *cur,
  1647. union xfs_btree_key *key,
  1648. __uint64_t *l0,
  1649. __uint64_t *l1)
  1650. {
  1651. *l0 = be32_to_cpu(key->inobt.ir_startino);
  1652. *l1 = 0;
  1653. }
  1654. STATIC void
  1655. xfs_inobt_trace_record(
  1656. struct xfs_btree_cur *cur,
  1657. union xfs_btree_rec *rec,
  1658. __uint64_t *l0,
  1659. __uint64_t *l1,
  1660. __uint64_t *l2)
  1661. {
  1662. *l0 = be32_to_cpu(rec->inobt.ir_startino);
  1663. *l1 = be32_to_cpu(rec->inobt.ir_freecount);
  1664. *l2 = be64_to_cpu(rec->inobt.ir_free);
  1665. }
  1666. #endif /* XFS_BTREE_TRACE */
  1667. static const struct xfs_btree_ops xfs_inobt_ops = {
  1668. .rec_len = sizeof(xfs_inobt_rec_t),
  1669. .key_len = sizeof(xfs_inobt_key_t),
  1670. .dup_cursor = xfs_inobt_dup_cursor,
  1671. .get_maxrecs = xfs_inobt_get_maxrecs,
  1672. .init_key_from_rec = xfs_inobt_init_key_from_rec,
  1673. .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
  1674. .key_diff = xfs_inobt_key_diff,
  1675. #ifdef XFS_BTREE_TRACE
  1676. .trace_enter = xfs_inobt_trace_enter,
  1677. .trace_cursor = xfs_inobt_trace_cursor,
  1678. .trace_key = xfs_inobt_trace_key,
  1679. .trace_record = xfs_inobt_trace_record,
  1680. #endif
  1681. };
  1682. /*
  1683. * Allocate a new inode btree cursor.
  1684. */
  1685. struct xfs_btree_cur * /* new inode btree cursor */
  1686. xfs_inobt_init_cursor(
  1687. struct xfs_mount *mp, /* file system mount point */
  1688. struct xfs_trans *tp, /* transaction pointer */
  1689. struct xfs_buf *agbp, /* buffer for agi structure */
  1690. xfs_agnumber_t agno) /* allocation group number */
  1691. {
  1692. struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
  1693. struct xfs_btree_cur *cur;
  1694. cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
  1695. cur->bc_tp = tp;
  1696. cur->bc_mp = mp;
  1697. cur->bc_nlevels = be32_to_cpu(agi->agi_level);
  1698. cur->bc_btnum = XFS_BTNUM_INO;
  1699. cur->bc_blocklog = mp->m_sb.sb_blocklog;
  1700. cur->bc_ops = &xfs_inobt_ops;
  1701. cur->bc_private.a.agbp = agbp;
  1702. cur->bc_private.a.agno = agno;
  1703. return cur;
  1704. }