xfs_bmap_btree.c 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692
  1. /*
  2. * Copyright (c) 2000-2003,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_inode_item.h"
  38. #include "xfs_alloc.h"
  39. #include "xfs_btree.h"
  40. #include "xfs_ialloc.h"
  41. #include "xfs_itable.h"
  42. #include "xfs_bmap.h"
  43. #include "xfs_error.h"
  44. #include "xfs_quota.h"
  45. #if defined(XFS_BMBT_TRACE)
  46. ktrace_t *xfs_bmbt_trace_buf;
  47. #endif
  48. /*
  49. * Prototypes for internal btree functions.
  50. */
  51. STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *);
  52. STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
  53. STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
  54. STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
  55. STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
  56. STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
  57. __uint64_t *, xfs_btree_cur_t **, int *);
  58. STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);
  59. #if defined(XFS_BMBT_TRACE)
  60. static char ARGS[] = "args";
  61. static char ENTRY[] = "entry";
  62. static char ERROR[] = "error";
  63. #undef EXIT
  64. static char EXIT[] = "exit";
  65. /*
  66. * Add a trace buffer entry for the arguments given to the routine,
  67. * generic form.
  68. */
  69. STATIC void
  70. xfs_bmbt_trace_enter(
  71. char *func,
  72. xfs_btree_cur_t *cur,
  73. char *s,
  74. int type,
  75. int line,
  76. __psunsigned_t a0,
  77. __psunsigned_t a1,
  78. __psunsigned_t a2,
  79. __psunsigned_t a3,
  80. __psunsigned_t a4,
  81. __psunsigned_t a5,
  82. __psunsigned_t a6,
  83. __psunsigned_t a7,
  84. __psunsigned_t a8,
  85. __psunsigned_t a9,
  86. __psunsigned_t a10)
  87. {
  88. xfs_inode_t *ip;
  89. int whichfork;
  90. ip = cur->bc_private.b.ip;
  91. whichfork = cur->bc_private.b.whichfork;
  92. ktrace_enter(xfs_bmbt_trace_buf,
  93. (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
  94. (void *)func, (void *)s, (void *)ip, (void *)cur,
  95. (void *)a0, (void *)a1, (void *)a2, (void *)a3,
  96. (void *)a4, (void *)a5, (void *)a6, (void *)a7,
  97. (void *)a8, (void *)a9, (void *)a10);
  98. ASSERT(ip->i_btrace);
  99. ktrace_enter(ip->i_btrace,
  100. (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
  101. (void *)func, (void *)s, (void *)ip, (void *)cur,
  102. (void *)a0, (void *)a1, (void *)a2, (void *)a3,
  103. (void *)a4, (void *)a5, (void *)a6, (void *)a7,
  104. (void *)a8, (void *)a9, (void *)a10);
  105. }
  106. /*
  107. * Add a trace buffer entry for arguments, for a buffer & 1 integer arg.
  108. */
  109. STATIC void
  110. xfs_bmbt_trace_argbi(
  111. char *func,
  112. xfs_btree_cur_t *cur,
  113. xfs_buf_t *b,
  114. int i,
  115. int line)
  116. {
  117. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGBI, line,
  118. (__psunsigned_t)b, i, 0, 0,
  119. 0, 0, 0, 0,
  120. 0, 0, 0);
  121. }
  122. /*
  123. * Add a trace buffer entry for arguments, for a buffer & 2 integer args.
  124. */
  125. STATIC void
  126. xfs_bmbt_trace_argbii(
  127. char *func,
  128. xfs_btree_cur_t *cur,
  129. xfs_buf_t *b,
  130. int i0,
  131. int i1,
  132. int line)
  133. {
  134. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGBII, line,
  135. (__psunsigned_t)b, i0, i1, 0,
  136. 0, 0, 0, 0,
  137. 0, 0, 0);
  138. }
  139. /*
  140. * Add a trace buffer entry for arguments, for 3 block-length args
  141. * and an integer arg.
  142. */
  143. STATIC void
  144. xfs_bmbt_trace_argfffi(
  145. char *func,
  146. xfs_btree_cur_t *cur,
  147. xfs_dfiloff_t o,
  148. xfs_dfsbno_t b,
  149. xfs_dfilblks_t i,
  150. int j,
  151. int line)
  152. {
  153. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGFFFI, line,
  154. o >> 32, (int)o, b >> 32, (int)b,
  155. i >> 32, (int)i, (int)j, 0,
  156. 0, 0, 0);
  157. }
  158. /*
  159. * Add a trace buffer entry for arguments, for one integer arg.
  160. */
  161. STATIC void
  162. xfs_bmbt_trace_argi(
  163. char *func,
  164. xfs_btree_cur_t *cur,
  165. int i,
  166. int line)
  167. {
  168. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGI, line,
  169. i, 0, 0, 0,
  170. 0, 0, 0, 0,
  171. 0, 0, 0);
  172. }
  173. /*
  174. * Add a trace buffer entry for arguments, for int, fsblock, key.
  175. */
  176. STATIC void
  177. xfs_bmbt_trace_argifk(
  178. char *func,
  179. xfs_btree_cur_t *cur,
  180. int i,
  181. xfs_fsblock_t f,
  182. xfs_dfiloff_t o,
  183. int line)
  184. {
  185. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
  186. i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32,
  187. (int)o, 0, 0, 0,
  188. 0, 0, 0);
  189. }
  190. /*
  191. * Add a trace buffer entry for arguments, for int, fsblock, rec.
  192. */
  193. STATIC void
  194. xfs_bmbt_trace_argifr(
  195. char *func,
  196. xfs_btree_cur_t *cur,
  197. int i,
  198. xfs_fsblock_t f,
  199. xfs_bmbt_rec_t *r,
  200. int line)
  201. {
  202. xfs_dfsbno_t b;
  203. xfs_dfilblks_t c;
  204. xfs_dfsbno_t d;
  205. xfs_dfiloff_t o;
  206. xfs_bmbt_irec_t s;
  207. d = (xfs_dfsbno_t)f;
  208. xfs_bmbt_disk_get_all(r, &s);
  209. o = (xfs_dfiloff_t)s.br_startoff;
  210. b = (xfs_dfsbno_t)s.br_startblock;
  211. c = s.br_blockcount;
  212. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFR, line,
  213. i, d >> 32, (int)d, o >> 32,
  214. (int)o, b >> 32, (int)b, c >> 32,
  215. (int)c, 0, 0);
  216. }
  217. /*
  218. * Add a trace buffer entry for arguments, for int, key.
  219. */
  220. STATIC void
  221. xfs_bmbt_trace_argik(
  222. char *func,
  223. xfs_btree_cur_t *cur,
  224. int i,
  225. xfs_bmbt_key_t *k,
  226. int line)
  227. {
  228. xfs_dfiloff_t o;
  229. o = be64_to_cpu(k->br_startoff);
  230. xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
  231. i, o >> 32, (int)o, 0,
  232. 0, 0, 0, 0,
  233. 0, 0, 0);
  234. }
  235. /*
  236. * Add a trace buffer entry for the cursor/operation.
  237. */
  238. STATIC void
  239. xfs_bmbt_trace_cursor(
  240. char *func,
  241. xfs_btree_cur_t *cur,
  242. char *s,
  243. int line)
  244. {
  245. xfs_bmbt_rec_t r;
  246. xfs_bmbt_set_all(&r, &cur->bc_rec.b);
  247. xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line,
  248. (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) |
  249. cur->bc_private.b.allocated,
  250. INT_GET(r.l0, ARCH_CONVERT) >> 32, (int)INT_GET(r.l0, ARCH_CONVERT), INT_GET(r.l1, ARCH_CONVERT) >> 32, (int)INT_GET(r.l1, ARCH_CONVERT),
  251. (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1],
  252. (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3],
  253. (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1],
  254. (cur->bc_ptrs[2] << 16) | cur->bc_ptrs[3]);
  255. }
  256. #define XFS_BMBT_TRACE_ARGBI(c,b,i) \
  257. xfs_bmbt_trace_argbi(fname, c, b, i, __LINE__)
  258. #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \
  259. xfs_bmbt_trace_argbii(fname, c, b, i, j, __LINE__)
  260. #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \
  261. xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__)
  262. #define XFS_BMBT_TRACE_ARGI(c,i) \
  263. xfs_bmbt_trace_argi(fname, c, i, __LINE__)
  264. #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \
  265. xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__)
  266. #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \
  267. xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__)
  268. #define XFS_BMBT_TRACE_ARGIK(c,i,k) \
  269. xfs_bmbt_trace_argik(fname, c, i, k, __LINE__)
  270. #define XFS_BMBT_TRACE_CURSOR(c,s) \
  271. xfs_bmbt_trace_cursor(fname, c, s, __LINE__)
  272. #else
  273. #define XFS_BMBT_TRACE_ARGBI(c,b,i)
  274. #define XFS_BMBT_TRACE_ARGBII(c,b,i,j)
  275. #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j)
  276. #define XFS_BMBT_TRACE_ARGI(c,i)
  277. #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s)
  278. #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r)
  279. #define XFS_BMBT_TRACE_ARGIK(c,i,k)
  280. #define XFS_BMBT_TRACE_CURSOR(c,s)
  281. #endif /* XFS_BMBT_TRACE */
  282. /*
  283. * Internal functions.
  284. */
  285. /*
  286. * Delete record pointed to by cur/level.
  287. */
  288. STATIC int /* error */
  289. xfs_bmbt_delrec(
  290. xfs_btree_cur_t *cur,
  291. int level,
  292. int *stat) /* success/failure */
  293. {
  294. xfs_bmbt_block_t *block; /* bmap btree block */
  295. xfs_fsblock_t bno; /* fs-relative block number */
  296. xfs_buf_t *bp; /* buffer for block */
  297. int error; /* error return value */
  298. #ifdef XFS_BMBT_TRACE
  299. static char fname[] = "xfs_bmbt_delrec";
  300. #endif
  301. int i; /* loop counter */
  302. int j; /* temp state */
  303. xfs_bmbt_key_t key; /* bmap btree key */
  304. xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
  305. xfs_fsblock_t lbno; /* left sibling block number */
  306. xfs_buf_t *lbp; /* left buffer pointer */
  307. xfs_bmbt_block_t *left; /* left btree block */
  308. xfs_bmbt_key_t *lkp; /* left btree key */
  309. xfs_bmbt_ptr_t *lpp; /* left address pointer */
  310. int lrecs=0; /* left record count */
  311. xfs_bmbt_rec_t *lrp; /* left record pointer */
  312. xfs_mount_t *mp; /* file system mount point */
  313. xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
  314. int ptr; /* key/record index */
  315. xfs_fsblock_t rbno; /* right sibling block number */
  316. xfs_buf_t *rbp; /* right buffer pointer */
  317. xfs_bmbt_block_t *right; /* right btree block */
  318. xfs_bmbt_key_t *rkp; /* right btree key */
  319. xfs_bmbt_rec_t *rp; /* pointer to bmap btree rec */
  320. xfs_bmbt_ptr_t *rpp; /* right address pointer */
  321. xfs_bmbt_block_t *rrblock; /* right-right btree block */
  322. xfs_buf_t *rrbp; /* right-right buffer pointer */
  323. int rrecs=0; /* right record count */
  324. xfs_bmbt_rec_t *rrp; /* right record pointer */
  325. xfs_btree_cur_t *tcur; /* temporary btree cursor */
  326. int numrecs; /* temporary numrec count */
  327. int numlrecs, numrrecs;
  328. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  329. XFS_BMBT_TRACE_ARGI(cur, level);
  330. ptr = cur->bc_ptrs[level];
  331. tcur = NULL;
  332. if (ptr == 0) {
  333. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  334. *stat = 0;
  335. return 0;
  336. }
  337. block = xfs_bmbt_get_block(cur, level, &bp);
  338. numrecs = be16_to_cpu(block->bb_numrecs);
  339. #ifdef DEBUG
  340. if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
  341. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  342. goto error0;
  343. }
  344. #endif
  345. if (ptr > numrecs) {
  346. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  347. *stat = 0;
  348. return 0;
  349. }
  350. XFS_STATS_INC(xs_bmbt_delrec);
  351. if (level > 0) {
  352. kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
  353. pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
  354. #ifdef DEBUG
  355. for (i = ptr; i < numrecs; i++) {
  356. if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
  357. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  358. goto error0;
  359. }
  360. }
  361. #endif
  362. if (ptr < numrecs) {
  363. memmove(&kp[ptr - 1], &kp[ptr],
  364. (numrecs - ptr) * sizeof(*kp));
  365. memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */
  366. (numrecs - ptr) * sizeof(*pp));
  367. xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
  368. xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
  369. }
  370. } else {
  371. rp = XFS_BMAP_REC_IADDR(block, 1, cur);
  372. if (ptr < numrecs) {
  373. memmove(&rp[ptr - 1], &rp[ptr],
  374. (numrecs - ptr) * sizeof(*rp));
  375. xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
  376. }
  377. if (ptr == 1) {
  378. key.br_startoff =
  379. cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
  380. kp = &key;
  381. }
  382. }
  383. numrecs--;
  384. block->bb_numrecs = cpu_to_be16(numrecs);
  385. xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
  386. /*
  387. * We're at the root level.
  388. * First, shrink the root block in-memory.
  389. * Try to get rid of the next level down.
  390. * If we can't then there's nothing left to do.
  391. */
  392. if (level == cur->bc_nlevels - 1) {
  393. xfs_iroot_realloc(cur->bc_private.b.ip, -1,
  394. cur->bc_private.b.whichfork);
  395. if ((error = xfs_bmbt_killroot(cur))) {
  396. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  397. goto error0;
  398. }
  399. if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) {
  400. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  401. goto error0;
  402. }
  403. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  404. *stat = 1;
  405. return 0;
  406. }
  407. if (ptr == 1 && (error = xfs_bmbt_updkey(cur, kp, level + 1))) {
  408. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  409. goto error0;
  410. }
  411. if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
  412. if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) {
  413. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  414. goto error0;
  415. }
  416. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  417. *stat = 1;
  418. return 0;
  419. }
  420. rbno = be64_to_cpu(block->bb_rightsib);
  421. lbno = be64_to_cpu(block->bb_leftsib);
  422. /*
  423. * One child of root, need to get a chance to copy its contents
  424. * into the root and delete it. Can't go up to next level,
  425. * there's nothing to delete there.
  426. */
  427. if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
  428. level == cur->bc_nlevels - 2) {
  429. if ((error = xfs_bmbt_killroot(cur))) {
  430. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  431. goto error0;
  432. }
  433. if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) {
  434. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  435. goto error0;
  436. }
  437. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  438. *stat = 1;
  439. return 0;
  440. }
  441. ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK);
  442. if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
  443. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  444. goto error0;
  445. }
  446. bno = NULLFSBLOCK;
  447. if (rbno != NULLFSBLOCK) {
  448. i = xfs_btree_lastrec(tcur, level);
  449. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  450. if ((error = xfs_bmbt_increment(tcur, level, &i))) {
  451. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  452. goto error0;
  453. }
  454. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  455. i = xfs_btree_lastrec(tcur, level);
  456. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  457. rbp = tcur->bc_bufs[level];
  458. right = XFS_BUF_TO_BMBT_BLOCK(rbp);
  459. #ifdef DEBUG
  460. if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
  461. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  462. goto error0;
  463. }
  464. #endif
  465. bno = be64_to_cpu(right->bb_leftsib);
  466. if (be16_to_cpu(right->bb_numrecs) - 1 >=
  467. XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
  468. if ((error = xfs_bmbt_lshift(tcur, level, &i))) {
  469. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  470. goto error0;
  471. }
  472. if (i) {
  473. ASSERT(be16_to_cpu(block->bb_numrecs) >=
  474. XFS_BMAP_BLOCK_IMINRECS(level, tcur));
  475. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  476. tcur = NULL;
  477. if (level > 0) {
  478. if ((error = xfs_bmbt_decrement(cur,
  479. level, &i))) {
  480. XFS_BMBT_TRACE_CURSOR(cur,
  481. ERROR);
  482. goto error0;
  483. }
  484. }
  485. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  486. *stat = 1;
  487. return 0;
  488. }
  489. }
  490. rrecs = be16_to_cpu(right->bb_numrecs);
  491. if (lbno != NULLFSBLOCK) {
  492. i = xfs_btree_firstrec(tcur, level);
  493. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  494. if ((error = xfs_bmbt_decrement(tcur, level, &i))) {
  495. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  496. goto error0;
  497. }
  498. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  499. }
  500. }
  501. if (lbno != NULLFSBLOCK) {
  502. i = xfs_btree_firstrec(tcur, level);
  503. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  504. /*
  505. * decrement to last in block
  506. */
  507. if ((error = xfs_bmbt_decrement(tcur, level, &i))) {
  508. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  509. goto error0;
  510. }
  511. i = xfs_btree_firstrec(tcur, level);
  512. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  513. lbp = tcur->bc_bufs[level];
  514. left = XFS_BUF_TO_BMBT_BLOCK(lbp);
  515. #ifdef DEBUG
  516. if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
  517. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  518. goto error0;
  519. }
  520. #endif
  521. bno = be64_to_cpu(left->bb_rightsib);
  522. if (be16_to_cpu(left->bb_numrecs) - 1 >=
  523. XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
  524. if ((error = xfs_bmbt_rshift(tcur, level, &i))) {
  525. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  526. goto error0;
  527. }
  528. if (i) {
  529. ASSERT(be16_to_cpu(block->bb_numrecs) >=
  530. XFS_BMAP_BLOCK_IMINRECS(level, tcur));
  531. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  532. tcur = NULL;
  533. if (level == 0)
  534. cur->bc_ptrs[0]++;
  535. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  536. *stat = 1;
  537. return 0;
  538. }
  539. }
  540. lrecs = be16_to_cpu(left->bb_numrecs);
  541. }
  542. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  543. tcur = NULL;
  544. mp = cur->bc_mp;
  545. ASSERT(bno != NULLFSBLOCK);
  546. if (lbno != NULLFSBLOCK &&
  547. lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
  548. rbno = bno;
  549. right = block;
  550. rbp = bp;
  551. if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp,
  552. XFS_BMAP_BTREE_REF))) {
  553. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  554. goto error0;
  555. }
  556. left = XFS_BUF_TO_BMBT_BLOCK(lbp);
  557. if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
  558. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  559. goto error0;
  560. }
  561. } else if (rbno != NULLFSBLOCK &&
  562. rrecs + be16_to_cpu(block->bb_numrecs) <=
  563. XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
  564. lbno = bno;
  565. left = block;
  566. lbp = bp;
  567. if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp,
  568. XFS_BMAP_BTREE_REF))) {
  569. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  570. goto error0;
  571. }
  572. right = XFS_BUF_TO_BMBT_BLOCK(rbp);
  573. if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
  574. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  575. goto error0;
  576. }
  577. lrecs = be16_to_cpu(left->bb_numrecs);
  578. } else {
  579. if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) {
  580. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  581. goto error0;
  582. }
  583. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  584. *stat = 1;
  585. return 0;
  586. }
  587. numlrecs = be16_to_cpu(left->bb_numrecs);
  588. numrrecs = be16_to_cpu(right->bb_numrecs);
  589. if (level > 0) {
  590. lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
  591. lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
  592. rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
  593. rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
  594. #ifdef DEBUG
  595. for (i = 0; i < numrrecs; i++) {
  596. if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
  597. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  598. goto error0;
  599. }
  600. }
  601. #endif
  602. memcpy(lkp, rkp, numrrecs * sizeof(*lkp));
  603. memcpy(lpp, rpp, numrrecs * sizeof(*lpp));
  604. xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
  605. xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
  606. } else {
  607. lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur);
  608. rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
  609. memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
  610. xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
  611. }
  612. be16_add(&left->bb_numrecs, numrrecs);
  613. left->bb_rightsib = right->bb_rightsib;
  614. xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
  615. if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
  616. if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
  617. be64_to_cpu(left->bb_rightsib),
  618. 0, &rrbp, XFS_BMAP_BTREE_REF))) {
  619. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  620. goto error0;
  621. }
  622. rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
  623. if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
  624. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  625. goto error0;
  626. }
  627. rrblock->bb_leftsib = cpu_to_be64(lbno);
  628. xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
  629. }
  630. xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
  631. cur->bc_private.b.flist, mp);
  632. cur->bc_private.b.ip->i_d.di_nblocks--;
  633. xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
  634. XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
  635. XFS_TRANS_DQ_BCOUNT, -1L);
  636. xfs_trans_binval(cur->bc_tp, rbp);
  637. if (bp != lbp) {
  638. cur->bc_bufs[level] = lbp;
  639. cur->bc_ptrs[level] += lrecs;
  640. cur->bc_ra[level] = 0;
  641. } else if ((error = xfs_bmbt_increment(cur, level + 1, &i))) {
  642. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  643. goto error0;
  644. }
  645. if (level > 0)
  646. cur->bc_ptrs[level]--;
  647. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  648. *stat = 2;
  649. return 0;
  650. error0:
  651. if (tcur)
  652. xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
  653. return error;
  654. }
  655. /*
  656. * Insert one record/level. Return information to the caller
  657. * allowing the next level up to proceed if necessary.
  658. */
  659. STATIC int /* error */
  660. xfs_bmbt_insrec(
  661. xfs_btree_cur_t *cur,
  662. int level,
  663. xfs_fsblock_t *bnop,
  664. xfs_bmbt_rec_t *recp,
  665. xfs_btree_cur_t **curp,
  666. int *stat) /* no-go/done/continue */
  667. {
  668. xfs_bmbt_block_t *block; /* bmap btree block */
  669. xfs_buf_t *bp; /* buffer for block */
  670. int error; /* error return value */
  671. #ifdef XFS_BMBT_TRACE
  672. static char fname[] = "xfs_bmbt_insrec";
  673. #endif
  674. int i; /* loop index */
  675. xfs_bmbt_key_t key; /* bmap btree key */
  676. xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
  677. int logflags; /* inode logging flags */
  678. xfs_fsblock_t nbno; /* new block number */
  679. struct xfs_btree_cur *ncur; /* new btree cursor */
  680. __uint64_t startoff; /* new btree key value */
  681. xfs_bmbt_rec_t nrec; /* new record count */
  682. int optr; /* old key/record index */
  683. xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
  684. int ptr; /* key/record index */
  685. xfs_bmbt_rec_t *rp=NULL; /* pointer to bmap btree rec */
  686. int numrecs;
  687. ASSERT(level < cur->bc_nlevels);
  688. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  689. XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
  690. ncur = NULL;
  691. key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp));
  692. optr = ptr = cur->bc_ptrs[level];
  693. if (ptr == 0) {
  694. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  695. *stat = 0;
  696. return 0;
  697. }
  698. XFS_STATS_INC(xs_bmbt_insrec);
  699. block = xfs_bmbt_get_block(cur, level, &bp);
  700. numrecs = be16_to_cpu(block->bb_numrecs);
  701. #ifdef DEBUG
  702. if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
  703. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  704. return error;
  705. }
  706. if (ptr <= numrecs) {
  707. if (level == 0) {
  708. rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
  709. xfs_btree_check_rec(XFS_BTNUM_BMAP, recp, rp);
  710. } else {
  711. kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
  712. xfs_btree_check_key(XFS_BTNUM_BMAP, &key, kp);
  713. }
  714. }
  715. #endif
  716. nbno = NULLFSBLOCK;
  717. if (numrecs == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
  718. if (numrecs < XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
  719. /*
  720. * A root block, that can be made bigger.
  721. */
  722. xfs_iroot_realloc(cur->bc_private.b.ip, 1,
  723. cur->bc_private.b.whichfork);
  724. block = xfs_bmbt_get_block(cur, level, &bp);
  725. } else if (level == cur->bc_nlevels - 1) {
  726. if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) ||
  727. *stat == 0) {
  728. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  729. return error;
  730. }
  731. xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
  732. logflags);
  733. block = xfs_bmbt_get_block(cur, level, &bp);
  734. } else {
  735. if ((error = xfs_bmbt_rshift(cur, level, &i))) {
  736. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  737. return error;
  738. }
  739. if (i) {
  740. /* nothing */
  741. } else {
  742. if ((error = xfs_bmbt_lshift(cur, level, &i))) {
  743. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  744. return error;
  745. }
  746. if (i) {
  747. optr = ptr = cur->bc_ptrs[level];
  748. } else {
  749. if ((error = xfs_bmbt_split(cur, level,
  750. &nbno, &startoff, &ncur,
  751. &i))) {
  752. XFS_BMBT_TRACE_CURSOR(cur,
  753. ERROR);
  754. return error;
  755. }
  756. if (i) {
  757. block = xfs_bmbt_get_block(
  758. cur, level, &bp);
  759. #ifdef DEBUG
  760. if ((error =
  761. xfs_btree_check_lblock(cur,
  762. block, level, bp))) {
  763. XFS_BMBT_TRACE_CURSOR(
  764. cur, ERROR);
  765. return error;
  766. }
  767. #endif
  768. ptr = cur->bc_ptrs[level];
  769. xfs_bmbt_disk_set_allf(&nrec,
  770. startoff, 0, 0,
  771. XFS_EXT_NORM);
  772. } else {
  773. XFS_BMBT_TRACE_CURSOR(cur,
  774. EXIT);
  775. *stat = 0;
  776. return 0;
  777. }
  778. }
  779. }
  780. }
  781. }
  782. numrecs = be16_to_cpu(block->bb_numrecs);
  783. if (level > 0) {
  784. kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
  785. pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
  786. #ifdef DEBUG
  787. for (i = numrecs; i >= ptr; i--) {
  788. if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1],
  789. level))) {
  790. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  791. return error;
  792. }
  793. }
  794. #endif
  795. memmove(&kp[ptr], &kp[ptr - 1],
  796. (numrecs - ptr + 1) * sizeof(*kp));
  797. memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
  798. (numrecs - ptr + 1) * sizeof(*pp));
  799. #ifdef DEBUG
  800. if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
  801. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  802. return error;
  803. }
  804. #endif
  805. kp[ptr - 1] = key;
  806. pp[ptr - 1] = cpu_to_be64(*bnop);
  807. numrecs++;
  808. block->bb_numrecs = cpu_to_be16(numrecs);
  809. xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
  810. xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs);
  811. } else {
  812. rp = XFS_BMAP_REC_IADDR(block, 1, cur);
  813. memmove(&rp[ptr], &rp[ptr - 1],
  814. (numrecs - ptr + 1) * sizeof(*rp));
  815. rp[ptr - 1] = *recp;
  816. numrecs++;
  817. block->bb_numrecs = cpu_to_be16(numrecs);
  818. xfs_bmbt_log_recs(cur, bp, ptr, numrecs);
  819. }
  820. xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
  821. #ifdef DEBUG
  822. if (ptr < numrecs) {
  823. if (level == 0)
  824. xfs_btree_check_rec(XFS_BTNUM_BMAP, rp + ptr - 1,
  825. rp + ptr);
  826. else
  827. xfs_btree_check_key(XFS_BTNUM_BMAP, kp + ptr - 1,
  828. kp + ptr);
  829. }
  830. #endif
  831. if (optr == 1 && (error = xfs_bmbt_updkey(cur, &key, level + 1))) {
  832. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  833. return error;
  834. }
  835. *bnop = nbno;
  836. if (nbno != NULLFSBLOCK) {
  837. *recp = nrec;
  838. *curp = ncur;
  839. }
  840. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  841. *stat = 1;
  842. return 0;
  843. }
  844. STATIC int
  845. xfs_bmbt_killroot(
  846. xfs_btree_cur_t *cur)
  847. {
  848. xfs_bmbt_block_t *block;
  849. xfs_bmbt_block_t *cblock;
  850. xfs_buf_t *cbp;
  851. xfs_bmbt_key_t *ckp;
  852. xfs_bmbt_ptr_t *cpp;
  853. #ifdef DEBUG
  854. int error;
  855. #endif
  856. #ifdef XFS_BMBT_TRACE
  857. static char fname[] = "xfs_bmbt_killroot";
  858. #endif
  859. int i;
  860. xfs_bmbt_key_t *kp;
  861. xfs_inode_t *ip;
  862. xfs_ifork_t *ifp;
  863. int level;
  864. xfs_bmbt_ptr_t *pp;
  865. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  866. level = cur->bc_nlevels - 1;
  867. ASSERT(level >= 1);
  868. /*
  869. * Don't deal with the root block needs to be a leaf case.
  870. * We're just going to turn the thing back into extents anyway.
  871. */
  872. if (level == 1) {
  873. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  874. return 0;
  875. }
  876. block = xfs_bmbt_get_block(cur, level, &cbp);
  877. /*
  878. * Give up if the root has multiple children.
  879. */
  880. if (be16_to_cpu(block->bb_numrecs) != 1) {
  881. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  882. return 0;
  883. }
  884. /*
  885. * Only do this if the next level will fit.
  886. * Then the data must be copied up to the inode,
  887. * instead of freeing the root you free the next level.
  888. */
  889. cbp = cur->bc_bufs[level - 1];
  890. cblock = XFS_BUF_TO_BMBT_BLOCK(cbp);
  891. if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
  892. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  893. return 0;
  894. }
  895. ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO);
  896. ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO);
  897. ip = cur->bc_private.b.ip;
  898. ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork);
  899. ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) ==
  900. XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes));
  901. i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur));
  902. if (i) {
  903. xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
  904. block = ifp->if_broot;
  905. }
  906. be16_add(&block->bb_numrecs, i);
  907. ASSERT(block->bb_numrecs == cblock->bb_numrecs);
  908. kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
  909. ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
  910. memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp));
  911. pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
  912. cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
  913. #ifdef DEBUG
  914. for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
  915. if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) {
  916. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  917. return error;
  918. }
  919. }
  920. #endif
  921. memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp));
  922. xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
  923. cur->bc_private.b.flist, cur->bc_mp);
  924. ip->i_d.di_nblocks--;
  925. XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip,
  926. XFS_TRANS_DQ_BCOUNT, -1L);
  927. xfs_trans_binval(cur->bc_tp, cbp);
  928. cur->bc_bufs[level - 1] = NULL;
  929. be16_add(&block->bb_level, -1);
  930. xfs_trans_log_inode(cur->bc_tp, ip,
  931. XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
  932. cur->bc_nlevels--;
  933. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  934. return 0;
  935. }
  936. /*
  937. * Log key values from the btree block.
  938. */
  939. STATIC void
  940. xfs_bmbt_log_keys(
  941. xfs_btree_cur_t *cur,
  942. xfs_buf_t *bp,
  943. int kfirst,
  944. int klast)
  945. {
  946. #ifdef XFS_BMBT_TRACE
  947. static char fname[] = "xfs_bmbt_log_keys";
  948. #endif
  949. xfs_trans_t *tp;
  950. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  951. XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast);
  952. tp = cur->bc_tp;
  953. if (bp) {
  954. xfs_bmbt_block_t *block;
  955. int first;
  956. xfs_bmbt_key_t *kp;
  957. int last;
  958. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  959. kp = XFS_BMAP_KEY_DADDR(block, 1, cur);
  960. first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
  961. last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
  962. xfs_trans_log_buf(tp, bp, first, last);
  963. } else {
  964. xfs_inode_t *ip;
  965. ip = cur->bc_private.b.ip;
  966. xfs_trans_log_inode(tp, ip,
  967. XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
  968. }
  969. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  970. }
  971. /*
  972. * Log pointer values from the btree block.
  973. */
  974. STATIC void
  975. xfs_bmbt_log_ptrs(
  976. xfs_btree_cur_t *cur,
  977. xfs_buf_t *bp,
  978. int pfirst,
  979. int plast)
  980. {
  981. #ifdef XFS_BMBT_TRACE
  982. static char fname[] = "xfs_bmbt_log_ptrs";
  983. #endif
  984. xfs_trans_t *tp;
  985. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  986. XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast);
  987. tp = cur->bc_tp;
  988. if (bp) {
  989. xfs_bmbt_block_t *block;
  990. int first;
  991. int last;
  992. xfs_bmbt_ptr_t *pp;
  993. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  994. pp = XFS_BMAP_PTR_DADDR(block, 1, cur);
  995. first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
  996. last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
  997. xfs_trans_log_buf(tp, bp, first, last);
  998. } else {
  999. xfs_inode_t *ip;
  1000. ip = cur->bc_private.b.ip;
  1001. xfs_trans_log_inode(tp, ip,
  1002. XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
  1003. }
  1004. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1005. }
  1006. /*
  1007. * Lookup the record. The cursor is made to point to it, based on dir.
  1008. */
  1009. STATIC int /* error */
  1010. xfs_bmbt_lookup(
  1011. xfs_btree_cur_t *cur,
  1012. xfs_lookup_t dir,
  1013. int *stat) /* success/failure */
  1014. {
  1015. xfs_bmbt_block_t *block=NULL;
  1016. xfs_buf_t *bp;
  1017. xfs_daddr_t d;
  1018. xfs_sfiloff_t diff;
  1019. int error; /* error return value */
  1020. #ifdef XFS_BMBT_TRACE
  1021. static char fname[] = "xfs_bmbt_lookup";
  1022. #endif
  1023. xfs_fsblock_t fsbno=0;
  1024. int high;
  1025. int i;
  1026. int keyno=0;
  1027. xfs_bmbt_key_t *kkbase=NULL;
  1028. xfs_bmbt_key_t *kkp;
  1029. xfs_bmbt_rec_t *krbase=NULL;
  1030. xfs_bmbt_rec_t *krp;
  1031. int level;
  1032. int low;
  1033. xfs_mount_t *mp;
  1034. xfs_bmbt_ptr_t *pp;
  1035. xfs_bmbt_irec_t *rp;
  1036. xfs_fileoff_t startoff;
  1037. xfs_trans_t *tp;
  1038. XFS_STATS_INC(xs_bmbt_lookup);
  1039. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1040. XFS_BMBT_TRACE_ARGI(cur, (int)dir);
  1041. tp = cur->bc_tp;
  1042. mp = cur->bc_mp;
  1043. rp = &cur->bc_rec.b;
  1044. for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
  1045. if (level < cur->bc_nlevels - 1) {
  1046. d = XFS_FSB_TO_DADDR(mp, fsbno);
  1047. bp = cur->bc_bufs[level];
  1048. if (bp && XFS_BUF_ADDR(bp) != d)
  1049. bp = NULL;
  1050. if (!bp) {
  1051. if ((error = xfs_btree_read_bufl(mp, tp, fsbno,
  1052. 0, &bp, XFS_BMAP_BTREE_REF))) {
  1053. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1054. return error;
  1055. }
  1056. xfs_btree_setbuf(cur, level, bp);
  1057. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  1058. if ((error = xfs_btree_check_lblock(cur, block,
  1059. level, bp))) {
  1060. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1061. return error;
  1062. }
  1063. } else
  1064. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  1065. } else
  1066. block = xfs_bmbt_get_block(cur, level, &bp);
  1067. if (diff == 0)
  1068. keyno = 1;
  1069. else {
  1070. if (level > 0)
  1071. kkbase = XFS_BMAP_KEY_IADDR(block, 1, cur);
  1072. else
  1073. krbase = XFS_BMAP_REC_IADDR(block, 1, cur);
  1074. low = 1;
  1075. if (!(high = be16_to_cpu(block->bb_numrecs))) {
  1076. ASSERT(level == 0);
  1077. cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
  1078. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1079. *stat = 0;
  1080. return 0;
  1081. }
  1082. while (low <= high) {
  1083. XFS_STATS_INC(xs_bmbt_compare);
  1084. keyno = (low + high) >> 1;
  1085. if (level > 0) {
  1086. kkp = kkbase + keyno - 1;
  1087. startoff = be64_to_cpu(kkp->br_startoff);
  1088. } else {
  1089. krp = krbase + keyno - 1;
  1090. startoff = xfs_bmbt_disk_get_startoff(krp);
  1091. }
  1092. diff = (xfs_sfiloff_t)
  1093. (startoff - rp->br_startoff);
  1094. if (diff < 0)
  1095. low = keyno + 1;
  1096. else if (diff > 0)
  1097. high = keyno - 1;
  1098. else
  1099. break;
  1100. }
  1101. }
  1102. if (level > 0) {
  1103. if (diff > 0 && --keyno < 1)
  1104. keyno = 1;
  1105. pp = XFS_BMAP_PTR_IADDR(block, keyno, cur);
  1106. fsbno = be64_to_cpu(*pp);
  1107. #ifdef DEBUG
  1108. if ((error = xfs_btree_check_lptr(cur, fsbno, level))) {
  1109. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1110. return error;
  1111. }
  1112. #endif
  1113. cur->bc_ptrs[level] = keyno;
  1114. }
  1115. }
  1116. if (dir != XFS_LOOKUP_LE && diff < 0) {
  1117. keyno++;
  1118. /*
  1119. * If ge search and we went off the end of the block, but it's
  1120. * not the last block, we're in the wrong block.
  1121. */
  1122. if (dir == XFS_LOOKUP_GE && keyno > be16_to_cpu(block->bb_numrecs) &&
  1123. be64_to_cpu(block->bb_rightsib) != NULLDFSBNO) {
  1124. cur->bc_ptrs[0] = keyno;
  1125. if ((error = xfs_bmbt_increment(cur, 0, &i))) {
  1126. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1127. return error;
  1128. }
  1129. XFS_WANT_CORRUPTED_RETURN(i == 1);
  1130. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1131. *stat = 1;
  1132. return 0;
  1133. }
  1134. }
  1135. else if (dir == XFS_LOOKUP_LE && diff > 0)
  1136. keyno--;
  1137. cur->bc_ptrs[0] = keyno;
  1138. if (keyno == 0 || keyno > be16_to_cpu(block->bb_numrecs)) {
  1139. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1140. *stat = 0;
  1141. } else {
  1142. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1143. *stat = ((dir != XFS_LOOKUP_EQ) || (diff == 0));
  1144. }
  1145. return 0;
  1146. }
  1147. /*
  1148. * Move 1 record left from cur/level if possible.
  1149. * Update cur to reflect the new path.
  1150. */
  1151. STATIC int /* error */
  1152. xfs_bmbt_lshift(
  1153. xfs_btree_cur_t *cur,
  1154. int level,
  1155. int *stat) /* success/failure */
  1156. {
  1157. int error; /* error return value */
  1158. #ifdef XFS_BMBT_TRACE
  1159. static char fname[] = "xfs_bmbt_lshift";
  1160. #endif
  1161. #ifdef DEBUG
  1162. int i; /* loop counter */
  1163. #endif
  1164. xfs_bmbt_key_t key; /* bmap btree key */
  1165. xfs_buf_t *lbp; /* left buffer pointer */
  1166. xfs_bmbt_block_t *left; /* left btree block */
  1167. xfs_bmbt_key_t *lkp=NULL; /* left btree key */
  1168. xfs_bmbt_ptr_t *lpp; /* left address pointer */
  1169. int lrecs; /* left record count */
  1170. xfs_bmbt_rec_t *lrp=NULL; /* left record pointer */
  1171. xfs_mount_t *mp; /* file system mount point */
  1172. xfs_buf_t *rbp; /* right buffer pointer */
  1173. xfs_bmbt_block_t *right; /* right btree block */
  1174. xfs_bmbt_key_t *rkp=NULL; /* right btree key */
  1175. xfs_bmbt_ptr_t *rpp=NULL; /* right address pointer */
  1176. xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
  1177. int rrecs; /* right record count */
  1178. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1179. XFS_BMBT_TRACE_ARGI(cur, level);
  1180. if (level == cur->bc_nlevels - 1) {
  1181. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1182. *stat = 0;
  1183. return 0;
  1184. }
  1185. rbp = cur->bc_bufs[level];
  1186. right = XFS_BUF_TO_BMBT_BLOCK(rbp);
  1187. #ifdef DEBUG
  1188. if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
  1189. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1190. return error;
  1191. }
  1192. #endif
  1193. if (be64_to_cpu(right->bb_leftsib) == NULLDFSBNO) {
  1194. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1195. *stat = 0;
  1196. return 0;
  1197. }
  1198. if (cur->bc_ptrs[level] <= 1) {
  1199. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1200. *stat = 0;
  1201. return 0;
  1202. }
  1203. mp = cur->bc_mp;
  1204. if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(right->bb_leftsib), 0,
  1205. &lbp, XFS_BMAP_BTREE_REF))) {
  1206. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1207. return error;
  1208. }
  1209. left = XFS_BUF_TO_BMBT_BLOCK(lbp);
  1210. if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
  1211. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1212. return error;
  1213. }
  1214. if (be16_to_cpu(left->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
  1215. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1216. *stat = 0;
  1217. return 0;
  1218. }
  1219. lrecs = be16_to_cpu(left->bb_numrecs) + 1;
  1220. if (level > 0) {
  1221. lkp = XFS_BMAP_KEY_IADDR(left, lrecs, cur);
  1222. rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
  1223. *lkp = *rkp;
  1224. xfs_bmbt_log_keys(cur, lbp, lrecs, lrecs);
  1225. lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
  1226. rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
  1227. #ifdef DEBUG
  1228. if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
  1229. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1230. return error;
  1231. }
  1232. #endif
  1233. *lpp = *rpp; /* INT_: direct copy */
  1234. xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
  1235. } else {
  1236. lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
  1237. rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
  1238. *lrp = *rrp;
  1239. xfs_bmbt_log_recs(cur, lbp, lrecs, lrecs);
  1240. }
  1241. left->bb_numrecs = cpu_to_be16(lrecs);
  1242. xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
  1243. #ifdef DEBUG
  1244. if (level > 0)
  1245. xfs_btree_check_key(XFS_BTNUM_BMAP, lkp - 1, lkp);
  1246. else
  1247. xfs_btree_check_rec(XFS_BTNUM_BMAP, lrp - 1, lrp);
  1248. #endif
  1249. rrecs = be16_to_cpu(right->bb_numrecs) - 1;
  1250. right->bb_numrecs = cpu_to_be16(rrecs);
  1251. xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
  1252. if (level > 0) {
  1253. #ifdef DEBUG
  1254. for (i = 0; i < rrecs; i++) {
  1255. if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
  1256. level))) {
  1257. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1258. return error;
  1259. }
  1260. }
  1261. #endif
  1262. memmove(rkp, rkp + 1, rrecs * sizeof(*rkp));
  1263. memmove(rpp, rpp + 1, rrecs * sizeof(*rpp));
  1264. xfs_bmbt_log_keys(cur, rbp, 1, rrecs);
  1265. xfs_bmbt_log_ptrs(cur, rbp, 1, rrecs);
  1266. } else {
  1267. memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
  1268. xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
  1269. key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
  1270. rkp = &key;
  1271. }
  1272. if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
  1273. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1274. return error;
  1275. }
  1276. cur->bc_ptrs[level]--;
  1277. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1278. *stat = 1;
  1279. return 0;
  1280. }
  1281. /*
  1282. * Move 1 record right from cur/level if possible.
  1283. * Update cur to reflect the new path.
  1284. */
  1285. STATIC int /* error */
  1286. xfs_bmbt_rshift(
  1287. xfs_btree_cur_t *cur,
  1288. int level,
  1289. int *stat) /* success/failure */
  1290. {
  1291. int error; /* error return value */
  1292. #ifdef XFS_BMBT_TRACE
  1293. static char fname[] = "xfs_bmbt_rshift";
  1294. #endif
  1295. int i; /* loop counter */
  1296. xfs_bmbt_key_t key; /* bmap btree key */
  1297. xfs_buf_t *lbp; /* left buffer pointer */
  1298. xfs_bmbt_block_t *left; /* left btree block */
  1299. xfs_bmbt_key_t *lkp; /* left btree key */
  1300. xfs_bmbt_ptr_t *lpp; /* left address pointer */
  1301. xfs_bmbt_rec_t *lrp; /* left record pointer */
  1302. xfs_mount_t *mp; /* file system mount point */
  1303. xfs_buf_t *rbp; /* right buffer pointer */
  1304. xfs_bmbt_block_t *right; /* right btree block */
  1305. xfs_bmbt_key_t *rkp; /* right btree key */
  1306. xfs_bmbt_ptr_t *rpp; /* right address pointer */
  1307. xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
  1308. struct xfs_btree_cur *tcur; /* temporary btree cursor */
  1309. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1310. XFS_BMBT_TRACE_ARGI(cur, level);
  1311. if (level == cur->bc_nlevels - 1) {
  1312. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1313. *stat = 0;
  1314. return 0;
  1315. }
  1316. lbp = cur->bc_bufs[level];
  1317. left = XFS_BUF_TO_BMBT_BLOCK(lbp);
  1318. #ifdef DEBUG
  1319. if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
  1320. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1321. return error;
  1322. }
  1323. #endif
  1324. if (be64_to_cpu(left->bb_rightsib) == NULLDFSBNO) {
  1325. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1326. *stat = 0;
  1327. return 0;
  1328. }
  1329. if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
  1330. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1331. *stat = 0;
  1332. return 0;
  1333. }
  1334. mp = cur->bc_mp;
  1335. if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(left->bb_rightsib), 0,
  1336. &rbp, XFS_BMAP_BTREE_REF))) {
  1337. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1338. return error;
  1339. }
  1340. right = XFS_BUF_TO_BMBT_BLOCK(rbp);
  1341. if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
  1342. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1343. return error;
  1344. }
  1345. if (be16_to_cpu(right->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
  1346. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1347. *stat = 0;
  1348. return 0;
  1349. }
  1350. if (level > 0) {
  1351. lkp = XFS_BMAP_KEY_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1352. lpp = XFS_BMAP_PTR_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1353. rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
  1354. rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
  1355. #ifdef DEBUG
  1356. for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
  1357. if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
  1358. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1359. return error;
  1360. }
  1361. }
  1362. #endif
  1363. memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
  1364. memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
  1365. #ifdef DEBUG
  1366. if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) {
  1367. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1368. return error;
  1369. }
  1370. #endif
  1371. *rkp = *lkp;
  1372. *rpp = *lpp; /* INT_: direct copy */
  1373. xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1374. xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1375. } else {
  1376. lrp = XFS_BMAP_REC_IADDR(left, be16_to_cpu(left->bb_numrecs), cur);
  1377. rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
  1378. memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
  1379. *rrp = *lrp;
  1380. xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
  1381. key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
  1382. rkp = &key;
  1383. }
  1384. be16_add(&left->bb_numrecs, -1);
  1385. xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
  1386. be16_add(&right->bb_numrecs, 1);
  1387. #ifdef DEBUG
  1388. if (level > 0)
  1389. xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
  1390. else
  1391. xfs_btree_check_rec(XFS_BTNUM_BMAP, rrp, rrp + 1);
  1392. #endif
  1393. xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
  1394. if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
  1395. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1396. return error;
  1397. }
  1398. i = xfs_btree_lastrec(tcur, level);
  1399. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  1400. if ((error = xfs_bmbt_increment(tcur, level, &i))) {
  1401. XFS_BMBT_TRACE_CURSOR(tcur, ERROR);
  1402. goto error1;
  1403. }
  1404. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  1405. if ((error = xfs_bmbt_updkey(tcur, rkp, level + 1))) {
  1406. XFS_BMBT_TRACE_CURSOR(tcur, ERROR);
  1407. goto error1;
  1408. }
  1409. xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
  1410. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1411. *stat = 1;
  1412. return 0;
  1413. error0:
  1414. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1415. error1:
  1416. xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
  1417. return error;
  1418. }
  1419. /*
  1420. * Determine the extent state.
  1421. */
  1422. /* ARGSUSED */
  1423. STATIC xfs_exntst_t
  1424. xfs_extent_state(
  1425. xfs_filblks_t blks,
  1426. int extent_flag)
  1427. {
  1428. if (extent_flag) {
  1429. ASSERT(blks != 0); /* saved for DMIG */
  1430. return XFS_EXT_UNWRITTEN;
  1431. }
  1432. return XFS_EXT_NORM;
  1433. }
  1434. /*
  1435. * Split cur/level block in half.
  1436. * Return new block number and its first record (to be inserted into parent).
  1437. */
  1438. STATIC int /* error */
  1439. xfs_bmbt_split(
  1440. xfs_btree_cur_t *cur,
  1441. int level,
  1442. xfs_fsblock_t *bnop,
  1443. __uint64_t *startoff,
  1444. xfs_btree_cur_t **curp,
  1445. int *stat) /* success/failure */
  1446. {
  1447. xfs_alloc_arg_t args; /* block allocation args */
  1448. int error; /* error return value */
  1449. #ifdef XFS_BMBT_TRACE
  1450. static char fname[] = "xfs_bmbt_split";
  1451. #endif
  1452. int i; /* loop counter */
  1453. xfs_fsblock_t lbno; /* left sibling block number */
  1454. xfs_buf_t *lbp; /* left buffer pointer */
  1455. xfs_bmbt_block_t *left; /* left btree block */
  1456. xfs_bmbt_key_t *lkp; /* left btree key */
  1457. xfs_bmbt_ptr_t *lpp; /* left address pointer */
  1458. xfs_bmbt_rec_t *lrp; /* left record pointer */
  1459. xfs_buf_t *rbp; /* right buffer pointer */
  1460. xfs_bmbt_block_t *right; /* right btree block */
  1461. xfs_bmbt_key_t *rkp; /* right btree key */
  1462. xfs_bmbt_ptr_t *rpp; /* right address pointer */
  1463. xfs_bmbt_block_t *rrblock; /* right-right btree block */
  1464. xfs_buf_t *rrbp; /* right-right buffer pointer */
  1465. xfs_bmbt_rec_t *rrp; /* right record pointer */
  1466. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1467. XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff);
  1468. args.tp = cur->bc_tp;
  1469. args.mp = cur->bc_mp;
  1470. lbp = cur->bc_bufs[level];
  1471. lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
  1472. left = XFS_BUF_TO_BMBT_BLOCK(lbp);
  1473. args.fsbno = cur->bc_private.b.firstblock;
  1474. args.firstblock = args.fsbno;
  1475. if (args.fsbno == NULLFSBLOCK) {
  1476. args.fsbno = lbno;
  1477. args.type = XFS_ALLOCTYPE_START_BNO;
  1478. } else
  1479. args.type = XFS_ALLOCTYPE_NEAR_BNO;
  1480. args.mod = args.minleft = args.alignment = args.total = args.isfl =
  1481. args.userdata = args.minalignslop = 0;
  1482. args.minlen = args.maxlen = args.prod = 1;
  1483. args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
  1484. if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) {
  1485. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1486. return XFS_ERROR(ENOSPC);
  1487. }
  1488. if ((error = xfs_alloc_vextent(&args))) {
  1489. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1490. return error;
  1491. }
  1492. if (args.fsbno == NULLFSBLOCK) {
  1493. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1494. *stat = 0;
  1495. return 0;
  1496. }
  1497. ASSERT(args.len == 1);
  1498. cur->bc_private.b.firstblock = args.fsbno;
  1499. cur->bc_private.b.allocated++;
  1500. cur->bc_private.b.ip->i_d.di_nblocks++;
  1501. xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
  1502. XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
  1503. XFS_TRANS_DQ_BCOUNT, 1L);
  1504. rbp = xfs_btree_get_bufl(args.mp, args.tp, args.fsbno, 0);
  1505. right = XFS_BUF_TO_BMBT_BLOCK(rbp);
  1506. #ifdef DEBUG
  1507. if ((error = xfs_btree_check_lblock(cur, left, level, rbp))) {
  1508. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1509. return error;
  1510. }
  1511. #endif
  1512. right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
  1513. right->bb_level = left->bb_level;
  1514. right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
  1515. if ((be16_to_cpu(left->bb_numrecs) & 1) &&
  1516. cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
  1517. be16_add(&right->bb_numrecs, 1);
  1518. i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
  1519. if (level > 0) {
  1520. lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
  1521. lpp = XFS_BMAP_PTR_IADDR(left, i, cur);
  1522. rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
  1523. rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
  1524. #ifdef DEBUG
  1525. for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
  1526. if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) {
  1527. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1528. return error;
  1529. }
  1530. }
  1531. #endif
  1532. memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
  1533. memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
  1534. xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1535. xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1536. *startoff = be64_to_cpu(rkp->br_startoff);
  1537. } else {
  1538. lrp = XFS_BMAP_REC_IADDR(left, i, cur);
  1539. rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
  1540. memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
  1541. xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
  1542. *startoff = xfs_bmbt_disk_get_startoff(rrp);
  1543. }
  1544. be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
  1545. right->bb_rightsib = left->bb_rightsib;
  1546. left->bb_rightsib = cpu_to_be64(args.fsbno);
  1547. right->bb_leftsib = cpu_to_be64(lbno);
  1548. xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS);
  1549. xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
  1550. if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) {
  1551. if ((error = xfs_btree_read_bufl(args.mp, args.tp,
  1552. be64_to_cpu(right->bb_rightsib), 0, &rrbp,
  1553. XFS_BMAP_BTREE_REF))) {
  1554. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1555. return error;
  1556. }
  1557. rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
  1558. if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
  1559. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1560. return error;
  1561. }
  1562. rrblock->bb_leftsib = cpu_to_be64(args.fsbno);
  1563. xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
  1564. }
  1565. if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
  1566. xfs_btree_setbuf(cur, level, rbp);
  1567. cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
  1568. }
  1569. if (level + 1 < cur->bc_nlevels) {
  1570. if ((error = xfs_btree_dup_cursor(cur, curp))) {
  1571. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1572. return error;
  1573. }
  1574. (*curp)->bc_ptrs[level + 1]++;
  1575. }
  1576. *bnop = args.fsbno;
  1577. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1578. *stat = 1;
  1579. return 0;
  1580. }
  1581. /*
  1582. * Update keys for the record.
  1583. */
  1584. STATIC int
  1585. xfs_bmbt_updkey(
  1586. xfs_btree_cur_t *cur,
  1587. xfs_bmbt_key_t *keyp, /* on-disk format */
  1588. int level)
  1589. {
  1590. xfs_bmbt_block_t *block;
  1591. xfs_buf_t *bp;
  1592. #ifdef DEBUG
  1593. int error;
  1594. #endif
  1595. #ifdef XFS_BMBT_TRACE
  1596. static char fname[] = "xfs_bmbt_updkey";
  1597. #endif
  1598. xfs_bmbt_key_t *kp;
  1599. int ptr;
  1600. ASSERT(level >= 1);
  1601. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1602. XFS_BMBT_TRACE_ARGIK(cur, level, keyp);
  1603. for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
  1604. block = xfs_bmbt_get_block(cur, level, &bp);
  1605. #ifdef DEBUG
  1606. if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
  1607. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1608. return error;
  1609. }
  1610. #endif
  1611. ptr = cur->bc_ptrs[level];
  1612. kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
  1613. *kp = *keyp;
  1614. xfs_bmbt_log_keys(cur, bp, ptr, ptr);
  1615. }
  1616. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1617. return 0;
  1618. }
  1619. /*
  1620. * Convert on-disk form of btree root to in-memory form.
  1621. */
  1622. void
  1623. xfs_bmdr_to_bmbt(
  1624. xfs_bmdr_block_t *dblock,
  1625. int dblocklen,
  1626. xfs_bmbt_block_t *rblock,
  1627. int rblocklen)
  1628. {
  1629. int dmxr;
  1630. xfs_bmbt_key_t *fkp;
  1631. __be64 *fpp;
  1632. xfs_bmbt_key_t *tkp;
  1633. __be64 *tpp;
  1634. rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
  1635. rblock->bb_level = dblock->bb_level;
  1636. ASSERT(be16_to_cpu(rblock->bb_level) > 0);
  1637. rblock->bb_numrecs = dblock->bb_numrecs;
  1638. rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
  1639. rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
  1640. dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
  1641. fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1);
  1642. tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
  1643. fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr);
  1644. tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
  1645. dmxr = be16_to_cpu(dblock->bb_numrecs);
  1646. memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
  1647. memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
  1648. }
  1649. /*
  1650. * Decrement cursor by one record at the level.
  1651. * For nonzero levels the leaf-ward information is untouched.
  1652. */
  1653. int /* error */
  1654. xfs_bmbt_decrement(
  1655. xfs_btree_cur_t *cur,
  1656. int level,
  1657. int *stat) /* success/failure */
  1658. {
  1659. xfs_bmbt_block_t *block;
  1660. xfs_buf_t *bp;
  1661. int error; /* error return value */
  1662. #ifdef XFS_BMBT_TRACE
  1663. static char fname[] = "xfs_bmbt_decrement";
  1664. #endif
  1665. xfs_fsblock_t fsbno;
  1666. int lev;
  1667. xfs_mount_t *mp;
  1668. xfs_trans_t *tp;
  1669. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1670. XFS_BMBT_TRACE_ARGI(cur, level);
  1671. ASSERT(level < cur->bc_nlevels);
  1672. if (level < cur->bc_nlevels - 1)
  1673. xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
  1674. if (--cur->bc_ptrs[level] > 0) {
  1675. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1676. *stat = 1;
  1677. return 0;
  1678. }
  1679. block = xfs_bmbt_get_block(cur, level, &bp);
  1680. #ifdef DEBUG
  1681. if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
  1682. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1683. return error;
  1684. }
  1685. #endif
  1686. if (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO) {
  1687. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1688. *stat = 0;
  1689. return 0;
  1690. }
  1691. for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
  1692. if (--cur->bc_ptrs[lev] > 0)
  1693. break;
  1694. if (lev < cur->bc_nlevels - 1)
  1695. xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
  1696. }
  1697. if (lev == cur->bc_nlevels) {
  1698. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1699. *stat = 0;
  1700. return 0;
  1701. }
  1702. tp = cur->bc_tp;
  1703. mp = cur->bc_mp;
  1704. for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
  1705. fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
  1706. if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
  1707. XFS_BMAP_BTREE_REF))) {
  1708. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1709. return error;
  1710. }
  1711. lev--;
  1712. xfs_btree_setbuf(cur, lev, bp);
  1713. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  1714. if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
  1715. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1716. return error;
  1717. }
  1718. cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
  1719. }
  1720. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1721. *stat = 1;
  1722. return 0;
  1723. }
  1724. /*
  1725. * Delete the record pointed to by cur.
  1726. */
  1727. int /* error */
  1728. xfs_bmbt_delete(
  1729. xfs_btree_cur_t *cur,
  1730. int *stat) /* success/failure */
  1731. {
  1732. int error; /* error return value */
  1733. #ifdef XFS_BMBT_TRACE
  1734. static char fname[] = "xfs_bmbt_delete";
  1735. #endif
  1736. int i;
  1737. int level;
  1738. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1739. for (level = 0, i = 2; i == 2; level++) {
  1740. if ((error = xfs_bmbt_delrec(cur, level, &i))) {
  1741. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1742. return error;
  1743. }
  1744. }
  1745. if (i == 0) {
  1746. for (level = 1; level < cur->bc_nlevels; level++) {
  1747. if (cur->bc_ptrs[level] == 0) {
  1748. if ((error = xfs_bmbt_decrement(cur, level,
  1749. &i))) {
  1750. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1751. return error;
  1752. }
  1753. break;
  1754. }
  1755. }
  1756. }
  1757. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1758. *stat = i;
  1759. return 0;
  1760. }
  1761. /*
  1762. * Convert a compressed bmap extent record to an uncompressed form.
  1763. * This code must be in sync with the routines xfs_bmbt_get_startoff,
  1764. * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
  1765. */
  1766. STATIC_INLINE void
  1767. __xfs_bmbt_get_all(
  1768. __uint64_t l0,
  1769. __uint64_t l1,
  1770. xfs_bmbt_irec_t *s)
  1771. {
  1772. int ext_flag;
  1773. xfs_exntst_t st;
  1774. ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
  1775. s->br_startoff = ((xfs_fileoff_t)l0 &
  1776. XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
  1777. #if XFS_BIG_BLKNOS
  1778. s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) |
  1779. (((xfs_fsblock_t)l1) >> 21);
  1780. #else
  1781. #ifdef DEBUG
  1782. {
  1783. xfs_dfsbno_t b;
  1784. b = (((xfs_dfsbno_t)l0 & XFS_MASK64LO(9)) << 43) |
  1785. (((xfs_dfsbno_t)l1) >> 21);
  1786. ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
  1787. s->br_startblock = (xfs_fsblock_t)b;
  1788. }
  1789. #else /* !DEBUG */
  1790. s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
  1791. #endif /* DEBUG */
  1792. #endif /* XFS_BIG_BLKNOS */
  1793. s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21));
  1794. /* This is xfs_extent_state() in-line */
  1795. if (ext_flag) {
  1796. ASSERT(s->br_blockcount != 0); /* saved for DMIG */
  1797. st = XFS_EXT_UNWRITTEN;
  1798. } else
  1799. st = XFS_EXT_NORM;
  1800. s->br_state = st;
  1801. }
  1802. void
  1803. xfs_bmbt_get_all(
  1804. xfs_bmbt_rec_t *r,
  1805. xfs_bmbt_irec_t *s)
  1806. {
  1807. __xfs_bmbt_get_all(r->l0, r->l1, s);
  1808. }
  1809. /*
  1810. * Get the block pointer for the given level of the cursor.
  1811. * Fill in the buffer pointer, if applicable.
  1812. */
  1813. xfs_bmbt_block_t *
  1814. xfs_bmbt_get_block(
  1815. xfs_btree_cur_t *cur,
  1816. int level,
  1817. xfs_buf_t **bpp)
  1818. {
  1819. xfs_ifork_t *ifp;
  1820. xfs_bmbt_block_t *rval;
  1821. if (level < cur->bc_nlevels - 1) {
  1822. *bpp = cur->bc_bufs[level];
  1823. rval = XFS_BUF_TO_BMBT_BLOCK(*bpp);
  1824. } else {
  1825. *bpp = NULL;
  1826. ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
  1827. cur->bc_private.b.whichfork);
  1828. rval = ifp->if_broot;
  1829. }
  1830. return rval;
  1831. }
  1832. /*
  1833. * Extract the blockcount field from an in memory bmap extent record.
  1834. */
  1835. xfs_filblks_t
  1836. xfs_bmbt_get_blockcount(
  1837. xfs_bmbt_rec_t *r)
  1838. {
  1839. return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21));
  1840. }
  1841. /*
  1842. * Extract the startblock field from an in memory bmap extent record.
  1843. */
  1844. xfs_fsblock_t
  1845. xfs_bmbt_get_startblock(
  1846. xfs_bmbt_rec_t *r)
  1847. {
  1848. #if XFS_BIG_BLKNOS
  1849. return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
  1850. (((xfs_fsblock_t)r->l1) >> 21);
  1851. #else
  1852. #ifdef DEBUG
  1853. xfs_dfsbno_t b;
  1854. b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) |
  1855. (((xfs_dfsbno_t)r->l1) >> 21);
  1856. ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
  1857. return (xfs_fsblock_t)b;
  1858. #else /* !DEBUG */
  1859. return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
  1860. #endif /* DEBUG */
  1861. #endif /* XFS_BIG_BLKNOS */
  1862. }
  1863. /*
  1864. * Extract the startoff field from an in memory bmap extent record.
  1865. */
  1866. xfs_fileoff_t
  1867. xfs_bmbt_get_startoff(
  1868. xfs_bmbt_rec_t *r)
  1869. {
  1870. return ((xfs_fileoff_t)r->l0 &
  1871. XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
  1872. }
  1873. xfs_exntst_t
  1874. xfs_bmbt_get_state(
  1875. xfs_bmbt_rec_t *r)
  1876. {
  1877. int ext_flag;
  1878. ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));
  1879. return xfs_extent_state(xfs_bmbt_get_blockcount(r),
  1880. ext_flag);
  1881. }
  1882. #ifndef XFS_NATIVE_HOST
  1883. /* Endian flipping versions of the bmbt extraction functions */
  1884. void
  1885. xfs_bmbt_disk_get_all(
  1886. xfs_bmbt_rec_t *r,
  1887. xfs_bmbt_irec_t *s)
  1888. {
  1889. __uint64_t l0, l1;
  1890. l0 = INT_GET(r->l0, ARCH_CONVERT);
  1891. l1 = INT_GET(r->l1, ARCH_CONVERT);
  1892. __xfs_bmbt_get_all(l0, l1, s);
  1893. }
  1894. /*
  1895. * Extract the blockcount field from an on disk bmap extent record.
  1896. */
  1897. xfs_filblks_t
  1898. xfs_bmbt_disk_get_blockcount(
  1899. xfs_bmbt_rec_t *r)
  1900. {
  1901. return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21));
  1902. }
  1903. /*
  1904. * Extract the startoff field from a disk format bmap extent record.
  1905. */
  1906. xfs_fileoff_t
  1907. xfs_bmbt_disk_get_startoff(
  1908. xfs_bmbt_rec_t *r)
  1909. {
  1910. return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) &
  1911. XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
  1912. }
  1913. #endif /* XFS_NATIVE_HOST */
  1914. /*
  1915. * Increment cursor by one record at the level.
  1916. * For nonzero levels the leaf-ward information is untouched.
  1917. */
  1918. int /* error */
  1919. xfs_bmbt_increment(
  1920. xfs_btree_cur_t *cur,
  1921. int level,
  1922. int *stat) /* success/failure */
  1923. {
  1924. xfs_bmbt_block_t *block;
  1925. xfs_buf_t *bp;
  1926. int error; /* error return value */
  1927. #ifdef XFS_BMBT_TRACE
  1928. static char fname[] = "xfs_bmbt_increment";
  1929. #endif
  1930. xfs_fsblock_t fsbno;
  1931. int lev;
  1932. xfs_mount_t *mp;
  1933. xfs_trans_t *tp;
  1934. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  1935. XFS_BMBT_TRACE_ARGI(cur, level);
  1936. ASSERT(level < cur->bc_nlevels);
  1937. if (level < cur->bc_nlevels - 1)
  1938. xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
  1939. block = xfs_bmbt_get_block(cur, level, &bp);
  1940. #ifdef DEBUG
  1941. if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
  1942. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1943. return error;
  1944. }
  1945. #endif
  1946. if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) {
  1947. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1948. *stat = 1;
  1949. return 0;
  1950. }
  1951. if (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO) {
  1952. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1953. *stat = 0;
  1954. return 0;
  1955. }
  1956. for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
  1957. block = xfs_bmbt_get_block(cur, lev, &bp);
  1958. #ifdef DEBUG
  1959. if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
  1960. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1961. return error;
  1962. }
  1963. #endif
  1964. if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs))
  1965. break;
  1966. if (lev < cur->bc_nlevels - 1)
  1967. xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
  1968. }
  1969. if (lev == cur->bc_nlevels) {
  1970. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1971. *stat = 0;
  1972. return 0;
  1973. }
  1974. tp = cur->bc_tp;
  1975. mp = cur->bc_mp;
  1976. for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
  1977. fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
  1978. if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
  1979. XFS_BMAP_BTREE_REF))) {
  1980. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1981. return error;
  1982. }
  1983. lev--;
  1984. xfs_btree_setbuf(cur, lev, bp);
  1985. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  1986. if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
  1987. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  1988. return error;
  1989. }
  1990. cur->bc_ptrs[lev] = 1;
  1991. }
  1992. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  1993. *stat = 1;
  1994. return 0;
  1995. }
  1996. /*
  1997. * Insert the current record at the point referenced by cur.
  1998. */
  1999. int /* error */
  2000. xfs_bmbt_insert(
  2001. xfs_btree_cur_t *cur,
  2002. int *stat) /* success/failure */
  2003. {
  2004. int error; /* error return value */
  2005. #ifdef XFS_BMBT_TRACE
  2006. static char fname[] = "xfs_bmbt_insert";
  2007. #endif
  2008. int i;
  2009. int level;
  2010. xfs_fsblock_t nbno;
  2011. xfs_btree_cur_t *ncur;
  2012. xfs_bmbt_rec_t nrec;
  2013. xfs_btree_cur_t *pcur;
  2014. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  2015. level = 0;
  2016. nbno = NULLFSBLOCK;
  2017. xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
  2018. ncur = NULL;
  2019. pcur = cur;
  2020. do {
  2021. if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
  2022. &i))) {
  2023. if (pcur != cur)
  2024. xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
  2025. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2026. return error;
  2027. }
  2028. XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
  2029. if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) {
  2030. cur->bc_nlevels = pcur->bc_nlevels;
  2031. cur->bc_private.b.allocated +=
  2032. pcur->bc_private.b.allocated;
  2033. pcur->bc_private.b.allocated = 0;
  2034. ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) ||
  2035. (cur->bc_private.b.ip->i_d.di_flags &
  2036. XFS_DIFLAG_REALTIME));
  2037. cur->bc_private.b.firstblock =
  2038. pcur->bc_private.b.firstblock;
  2039. ASSERT(cur->bc_private.b.flist ==
  2040. pcur->bc_private.b.flist);
  2041. xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
  2042. }
  2043. if (ncur) {
  2044. pcur = ncur;
  2045. ncur = NULL;
  2046. }
  2047. } while (nbno != NULLFSBLOCK);
  2048. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2049. *stat = i;
  2050. return 0;
  2051. error0:
  2052. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2053. return error;
  2054. }
  2055. /*
  2056. * Log fields from the btree block header.
  2057. */
  2058. void
  2059. xfs_bmbt_log_block(
  2060. xfs_btree_cur_t *cur,
  2061. xfs_buf_t *bp,
  2062. int fields)
  2063. {
  2064. int first;
  2065. #ifdef XFS_BMBT_TRACE
  2066. static char fname[] = "xfs_bmbt_log_block";
  2067. #endif
  2068. int last;
  2069. xfs_trans_t *tp;
  2070. static const short offsets[] = {
  2071. offsetof(xfs_bmbt_block_t, bb_magic),
  2072. offsetof(xfs_bmbt_block_t, bb_level),
  2073. offsetof(xfs_bmbt_block_t, bb_numrecs),
  2074. offsetof(xfs_bmbt_block_t, bb_leftsib),
  2075. offsetof(xfs_bmbt_block_t, bb_rightsib),
  2076. sizeof(xfs_bmbt_block_t)
  2077. };
  2078. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  2079. XFS_BMBT_TRACE_ARGBI(cur, bp, fields);
  2080. tp = cur->bc_tp;
  2081. if (bp) {
  2082. xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first,
  2083. &last);
  2084. xfs_trans_log_buf(tp, bp, first, last);
  2085. } else
  2086. xfs_trans_log_inode(tp, cur->bc_private.b.ip,
  2087. XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
  2088. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2089. }
  2090. /*
  2091. * Log record values from the btree block.
  2092. */
  2093. void
  2094. xfs_bmbt_log_recs(
  2095. xfs_btree_cur_t *cur,
  2096. xfs_buf_t *bp,
  2097. int rfirst,
  2098. int rlast)
  2099. {
  2100. xfs_bmbt_block_t *block;
  2101. int first;
  2102. #ifdef XFS_BMBT_TRACE
  2103. static char fname[] = "xfs_bmbt_log_recs";
  2104. #endif
  2105. int last;
  2106. xfs_bmbt_rec_t *rp;
  2107. xfs_trans_t *tp;
  2108. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  2109. XFS_BMBT_TRACE_ARGBII(cur, bp, rfirst, rlast);
  2110. ASSERT(bp);
  2111. tp = cur->bc_tp;
  2112. block = XFS_BUF_TO_BMBT_BLOCK(bp);
  2113. rp = XFS_BMAP_REC_DADDR(block, 1, cur);
  2114. first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
  2115. last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
  2116. xfs_trans_log_buf(tp, bp, first, last);
  2117. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2118. }
  2119. int /* error */
  2120. xfs_bmbt_lookup_eq(
  2121. xfs_btree_cur_t *cur,
  2122. xfs_fileoff_t off,
  2123. xfs_fsblock_t bno,
  2124. xfs_filblks_t len,
  2125. int *stat) /* success/failure */
  2126. {
  2127. cur->bc_rec.b.br_startoff = off;
  2128. cur->bc_rec.b.br_startblock = bno;
  2129. cur->bc_rec.b.br_blockcount = len;
  2130. return xfs_bmbt_lookup(cur, XFS_LOOKUP_EQ, stat);
  2131. }
  2132. int /* error */
  2133. xfs_bmbt_lookup_ge(
  2134. xfs_btree_cur_t *cur,
  2135. xfs_fileoff_t off,
  2136. xfs_fsblock_t bno,
  2137. xfs_filblks_t len,
  2138. int *stat) /* success/failure */
  2139. {
  2140. cur->bc_rec.b.br_startoff = off;
  2141. cur->bc_rec.b.br_startblock = bno;
  2142. cur->bc_rec.b.br_blockcount = len;
  2143. return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);
  2144. }
  2145. /*
  2146. * Give the bmap btree a new root block. Copy the old broot contents
  2147. * down into a real block and make the broot point to it.
  2148. */
  2149. int /* error */
  2150. xfs_bmbt_newroot(
  2151. xfs_btree_cur_t *cur, /* btree cursor */
  2152. int *logflags, /* logging flags for inode */
  2153. int *stat) /* return status - 0 fail */
  2154. {
  2155. xfs_alloc_arg_t args; /* allocation arguments */
  2156. xfs_bmbt_block_t *block; /* bmap btree block */
  2157. xfs_buf_t *bp; /* buffer for block */
  2158. xfs_bmbt_block_t *cblock; /* child btree block */
  2159. xfs_bmbt_key_t *ckp; /* child key pointer */
  2160. xfs_bmbt_ptr_t *cpp; /* child ptr pointer */
  2161. int error; /* error return code */
  2162. #ifdef XFS_BMBT_TRACE
  2163. static char fname[] = "xfs_bmbt_newroot";
  2164. #endif
  2165. #ifdef DEBUG
  2166. int i; /* loop counter */
  2167. #endif
  2168. xfs_bmbt_key_t *kp; /* pointer to bmap btree key */
  2169. int level; /* btree level */
  2170. xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
  2171. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  2172. level = cur->bc_nlevels - 1;
  2173. block = xfs_bmbt_get_block(cur, level, &bp);
  2174. /*
  2175. * Copy the root into a real block.
  2176. */
  2177. args.mp = cur->bc_mp;
  2178. pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
  2179. args.tp = cur->bc_tp;
  2180. args.fsbno = cur->bc_private.b.firstblock;
  2181. args.mod = args.minleft = args.alignment = args.total = args.isfl =
  2182. args.userdata = args.minalignslop = 0;
  2183. args.minlen = args.maxlen = args.prod = 1;
  2184. args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
  2185. args.firstblock = args.fsbno;
  2186. if (args.fsbno == NULLFSBLOCK) {
  2187. #ifdef DEBUG
  2188. if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {
  2189. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2190. return error;
  2191. }
  2192. #endif
  2193. args.fsbno = be64_to_cpu(*pp);
  2194. args.type = XFS_ALLOCTYPE_START_BNO;
  2195. } else
  2196. args.type = XFS_ALLOCTYPE_NEAR_BNO;
  2197. if ((error = xfs_alloc_vextent(&args))) {
  2198. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2199. return error;
  2200. }
  2201. if (args.fsbno == NULLFSBLOCK) {
  2202. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2203. *stat = 0;
  2204. return 0;
  2205. }
  2206. ASSERT(args.len == 1);
  2207. cur->bc_private.b.firstblock = args.fsbno;
  2208. cur->bc_private.b.allocated++;
  2209. cur->bc_private.b.ip->i_d.di_nblocks++;
  2210. XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
  2211. XFS_TRANS_DQ_BCOUNT, 1L);
  2212. bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
  2213. cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
  2214. *cblock = *block;
  2215. be16_add(&block->bb_level, 1);
  2216. block->bb_numrecs = cpu_to_be16(1);
  2217. cur->bc_nlevels++;
  2218. cur->bc_ptrs[level + 1] = 1;
  2219. kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
  2220. ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
  2221. memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp));
  2222. cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
  2223. #ifdef DEBUG
  2224. for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
  2225. if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
  2226. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2227. return error;
  2228. }
  2229. }
  2230. #endif
  2231. memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
  2232. #ifdef DEBUG
  2233. if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {
  2234. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2235. return error;
  2236. }
  2237. #endif
  2238. *pp = cpu_to_be64(args.fsbno);
  2239. xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
  2240. cur->bc_private.b.whichfork);
  2241. xfs_btree_setbuf(cur, level, bp);
  2242. /*
  2243. * Do all this logging at the end so that
  2244. * the root is at the right level.
  2245. */
  2246. xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS);
  2247. xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
  2248. xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
  2249. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2250. *logflags |=
  2251. XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);
  2252. *stat = 1;
  2253. return 0;
  2254. }
  2255. /*
  2256. * Set all the fields in a bmap extent record from the uncompressed form.
  2257. */
  2258. void
  2259. xfs_bmbt_set_all(
  2260. xfs_bmbt_rec_t *r,
  2261. xfs_bmbt_irec_t *s)
  2262. {
  2263. int extent_flag;
  2264. ASSERT((s->br_state == XFS_EXT_NORM) ||
  2265. (s->br_state == XFS_EXT_UNWRITTEN));
  2266. extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
  2267. ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
  2268. ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
  2269. #if XFS_BIG_BLKNOS
  2270. ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
  2271. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2272. ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
  2273. ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
  2274. r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2275. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2276. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2277. #else /* !XFS_BIG_BLKNOS */
  2278. if (ISNULLSTARTBLOCK(s->br_startblock)) {
  2279. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2280. ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
  2281. (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
  2282. r->l1 = XFS_MASK64HI(11) |
  2283. ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2284. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2285. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2286. } else {
  2287. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2288. ((xfs_bmbt_rec_base_t)s->br_startoff << 9);
  2289. r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2290. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2291. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2292. }
  2293. #endif /* XFS_BIG_BLKNOS */
  2294. }
  2295. /*
  2296. * Set all the fields in a bmap extent record from the arguments.
  2297. */
  2298. void
  2299. xfs_bmbt_set_allf(
  2300. xfs_bmbt_rec_t *r,
  2301. xfs_fileoff_t o,
  2302. xfs_fsblock_t b,
  2303. xfs_filblks_t c,
  2304. xfs_exntst_t v)
  2305. {
  2306. int extent_flag;
  2307. ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
  2308. extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
  2309. ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
  2310. ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
  2311. #if XFS_BIG_BLKNOS
  2312. ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
  2313. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2314. ((xfs_bmbt_rec_base_t)o << 9) |
  2315. ((xfs_bmbt_rec_base_t)b >> 43);
  2316. r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
  2317. ((xfs_bmbt_rec_base_t)c &
  2318. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2319. #else /* !XFS_BIG_BLKNOS */
  2320. if (ISNULLSTARTBLOCK(b)) {
  2321. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2322. ((xfs_bmbt_rec_base_t)o << 9) |
  2323. (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
  2324. r->l1 = XFS_MASK64HI(11) |
  2325. ((xfs_bmbt_rec_base_t)b << 21) |
  2326. ((xfs_bmbt_rec_base_t)c &
  2327. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2328. } else {
  2329. r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2330. ((xfs_bmbt_rec_base_t)o << 9);
  2331. r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
  2332. ((xfs_bmbt_rec_base_t)c &
  2333. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2334. }
  2335. #endif /* XFS_BIG_BLKNOS */
  2336. }
  2337. #ifndef XFS_NATIVE_HOST
  2338. /*
  2339. * Set all the fields in a bmap extent record from the uncompressed form.
  2340. */
  2341. void
  2342. xfs_bmbt_disk_set_all(
  2343. xfs_bmbt_rec_t *r,
  2344. xfs_bmbt_irec_t *s)
  2345. {
  2346. int extent_flag;
  2347. ASSERT((s->br_state == XFS_EXT_NORM) ||
  2348. (s->br_state == XFS_EXT_UNWRITTEN));
  2349. extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
  2350. ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
  2351. ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
  2352. #if XFS_BIG_BLKNOS
  2353. ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
  2354. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2355. ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
  2356. ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
  2357. INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2358. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2359. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2360. #else /* !XFS_BIG_BLKNOS */
  2361. if (ISNULLSTARTBLOCK(s->br_startblock)) {
  2362. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2363. ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
  2364. (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
  2365. INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
  2366. ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2367. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2368. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2369. } else {
  2370. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2371. ((xfs_bmbt_rec_base_t)s->br_startoff << 9));
  2372. INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
  2373. ((xfs_bmbt_rec_base_t)s->br_blockcount &
  2374. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2375. }
  2376. #endif /* XFS_BIG_BLKNOS */
  2377. }
  2378. /*
  2379. * Set all the fields in a disk format bmap extent record from the arguments.
  2380. */
  2381. void
  2382. xfs_bmbt_disk_set_allf(
  2383. xfs_bmbt_rec_t *r,
  2384. xfs_fileoff_t o,
  2385. xfs_fsblock_t b,
  2386. xfs_filblks_t c,
  2387. xfs_exntst_t v)
  2388. {
  2389. int extent_flag;
  2390. ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
  2391. extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
  2392. ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
  2393. ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
  2394. #if XFS_BIG_BLKNOS
  2395. ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
  2396. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2397. ((xfs_bmbt_rec_base_t)o << 9) |
  2398. ((xfs_bmbt_rec_base_t)b >> 43));
  2399. INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
  2400. ((xfs_bmbt_rec_base_t)c &
  2401. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2402. #else /* !XFS_BIG_BLKNOS */
  2403. if (ISNULLSTARTBLOCK(b)) {
  2404. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2405. ((xfs_bmbt_rec_base_t)o << 9) |
  2406. (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
  2407. INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
  2408. ((xfs_bmbt_rec_base_t)b << 21) |
  2409. ((xfs_bmbt_rec_base_t)c &
  2410. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2411. } else {
  2412. INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
  2413. ((xfs_bmbt_rec_base_t)o << 9));
  2414. INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
  2415. ((xfs_bmbt_rec_base_t)c &
  2416. (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
  2417. }
  2418. #endif /* XFS_BIG_BLKNOS */
  2419. }
  2420. #endif /* XFS_NATIVE_HOST */
  2421. /*
  2422. * Set the blockcount field in a bmap extent record.
  2423. */
  2424. void
  2425. xfs_bmbt_set_blockcount(
  2426. xfs_bmbt_rec_t *r,
  2427. xfs_filblks_t v)
  2428. {
  2429. ASSERT((v & XFS_MASK64HI(43)) == 0);
  2430. r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) |
  2431. (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21));
  2432. }
  2433. /*
  2434. * Set the startblock field in a bmap extent record.
  2435. */
  2436. void
  2437. xfs_bmbt_set_startblock(
  2438. xfs_bmbt_rec_t *r,
  2439. xfs_fsblock_t v)
  2440. {
  2441. #if XFS_BIG_BLKNOS
  2442. ASSERT((v & XFS_MASK64HI(12)) == 0);
  2443. r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
  2444. (xfs_bmbt_rec_base_t)(v >> 43);
  2445. r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
  2446. (xfs_bmbt_rec_base_t)(v << 21);
  2447. #else /* !XFS_BIG_BLKNOS */
  2448. if (ISNULLSTARTBLOCK(v)) {
  2449. r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
  2450. r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) |
  2451. ((xfs_bmbt_rec_base_t)v << 21) |
  2452. (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2453. } else {
  2454. r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
  2455. r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
  2456. (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
  2457. }
  2458. #endif /* XFS_BIG_BLKNOS */
  2459. }
  2460. /*
  2461. * Set the startoff field in a bmap extent record.
  2462. */
  2463. void
  2464. xfs_bmbt_set_startoff(
  2465. xfs_bmbt_rec_t *r,
  2466. xfs_fileoff_t v)
  2467. {
  2468. ASSERT((v & XFS_MASK64HI(9)) == 0);
  2469. r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) |
  2470. ((xfs_bmbt_rec_base_t)v << 9) |
  2471. (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
  2472. }
  2473. /*
  2474. * Set the extent state field in a bmap extent record.
  2475. */
  2476. void
  2477. xfs_bmbt_set_state(
  2478. xfs_bmbt_rec_t *r,
  2479. xfs_exntst_t v)
  2480. {
  2481. ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
  2482. if (v == XFS_EXT_NORM)
  2483. r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN);
  2484. else
  2485. r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN);
  2486. }
  2487. /*
  2488. * Convert in-memory form of btree root to on-disk form.
  2489. */
  2490. void
  2491. xfs_bmbt_to_bmdr(
  2492. xfs_bmbt_block_t *rblock,
  2493. int rblocklen,
  2494. xfs_bmdr_block_t *dblock,
  2495. int dblocklen)
  2496. {
  2497. int dmxr;
  2498. xfs_bmbt_key_t *fkp;
  2499. __be64 *fpp;
  2500. xfs_bmbt_key_t *tkp;
  2501. __be64 *tpp;
  2502. ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
  2503. ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
  2504. ASSERT(be64_to_cpu(rblock->bb_rightsib) == NULLDFSBNO);
  2505. ASSERT(be16_to_cpu(rblock->bb_level) > 0);
  2506. dblock->bb_level = rblock->bb_level;
  2507. dblock->bb_numrecs = rblock->bb_numrecs;
  2508. dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
  2509. fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
  2510. tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1);
  2511. fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
  2512. tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr);
  2513. dmxr = be16_to_cpu(dblock->bb_numrecs);
  2514. memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
  2515. memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
  2516. }
  2517. /*
  2518. * Update the record to the passed values.
  2519. */
  2520. int
  2521. xfs_bmbt_update(
  2522. xfs_btree_cur_t *cur,
  2523. xfs_fileoff_t off,
  2524. xfs_fsblock_t bno,
  2525. xfs_filblks_t len,
  2526. xfs_exntst_t state)
  2527. {
  2528. xfs_bmbt_block_t *block;
  2529. xfs_buf_t *bp;
  2530. int error;
  2531. #ifdef XFS_BMBT_TRACE
  2532. static char fname[] = "xfs_bmbt_update";
  2533. #endif
  2534. xfs_bmbt_key_t key;
  2535. int ptr;
  2536. xfs_bmbt_rec_t *rp;
  2537. XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
  2538. XFS_BMBT_TRACE_ARGFFFI(cur, (xfs_dfiloff_t)off, (xfs_dfsbno_t)bno,
  2539. (xfs_dfilblks_t)len, (int)state);
  2540. block = xfs_bmbt_get_block(cur, 0, &bp);
  2541. #ifdef DEBUG
  2542. if ((error = xfs_btree_check_lblock(cur, block, 0, bp))) {
  2543. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2544. return error;
  2545. }
  2546. #endif
  2547. ptr = cur->bc_ptrs[0];
  2548. rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
  2549. xfs_bmbt_disk_set_allf(rp, off, bno, len, state);
  2550. xfs_bmbt_log_recs(cur, bp, ptr, ptr);
  2551. if (ptr > 1) {
  2552. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2553. return 0;
  2554. }
  2555. key.br_startoff = cpu_to_be64(off);
  2556. if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
  2557. XFS_BMBT_TRACE_CURSOR(cur, ERROR);
  2558. return error;
  2559. }
  2560. XFS_BMBT_TRACE_CURSOR(cur, EXIT);
  2561. return 0;
  2562. }
  2563. /*
  2564. * Check extent records, which have just been read, for
  2565. * any bit in the extent flag field. ASSERT on debug
  2566. * kernels, as this condition should not occur.
  2567. * Return an error condition (1) if any flags found,
  2568. * otherwise return 0.
  2569. */
  2570. int
  2571. xfs_check_nostate_extents(
  2572. xfs_ifork_t *ifp,
  2573. xfs_extnum_t idx,
  2574. xfs_extnum_t num)
  2575. {
  2576. xfs_bmbt_rec_t *ep;
  2577. for (; num > 0; num--, idx++) {
  2578. ep = xfs_iext_get_ext(ifp, idx);
  2579. if ((ep->l0 >>
  2580. (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
  2581. ASSERT(0);
  2582. return 1;
  2583. }
  2584. }
  2585. return 0;
  2586. }