xfs_rmap.c 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2014 Red Hat, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_bit.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_sb.h"
  15. #include "xfs_defer.h"
  16. #include "xfs_btree.h"
  17. #include "xfs_trans.h"
  18. #include "xfs_alloc.h"
  19. #include "xfs_rmap.h"
  20. #include "xfs_rmap_btree.h"
  21. #include "xfs_trace.h"
  22. #include "xfs_errortag.h"
  23. #include "xfs_error.h"
  24. #include "xfs_inode.h"
  25. #include "xfs_ag.h"
  26. struct kmem_cache *xfs_rmap_intent_cache;
  27. /*
  28. * Lookup the first record less than or equal to [bno, len, owner, offset]
  29. * in the btree given by cur.
  30. */
  31. int
  32. xfs_rmap_lookup_le(
  33. struct xfs_btree_cur *cur,
  34. xfs_agblock_t bno,
  35. uint64_t owner,
  36. uint64_t offset,
  37. unsigned int flags,
  38. struct xfs_rmap_irec *irec,
  39. int *stat)
  40. {
  41. int get_stat = 0;
  42. int error;
  43. cur->bc_rec.r.rm_startblock = bno;
  44. cur->bc_rec.r.rm_blockcount = 0;
  45. cur->bc_rec.r.rm_owner = owner;
  46. cur->bc_rec.r.rm_offset = offset;
  47. cur->bc_rec.r.rm_flags = flags;
  48. error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
  49. if (error || !(*stat) || !irec)
  50. return error;
  51. error = xfs_rmap_get_rec(cur, irec, &get_stat);
  52. if (error)
  53. return error;
  54. if (!get_stat)
  55. return -EFSCORRUPTED;
  56. return 0;
  57. }
  58. /*
  59. * Lookup the record exactly matching [bno, len, owner, offset]
  60. * in the btree given by cur.
  61. */
  62. int
  63. xfs_rmap_lookup_eq(
  64. struct xfs_btree_cur *cur,
  65. xfs_agblock_t bno,
  66. xfs_extlen_t len,
  67. uint64_t owner,
  68. uint64_t offset,
  69. unsigned int flags,
  70. int *stat)
  71. {
  72. cur->bc_rec.r.rm_startblock = bno;
  73. cur->bc_rec.r.rm_blockcount = len;
  74. cur->bc_rec.r.rm_owner = owner;
  75. cur->bc_rec.r.rm_offset = offset;
  76. cur->bc_rec.r.rm_flags = flags;
  77. return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
  78. }
  79. /*
  80. * Update the record referred to by cur to the value given
  81. * by [bno, len, owner, offset].
  82. * This either works (return 0) or gets an EFSCORRUPTED error.
  83. */
  84. STATIC int
  85. xfs_rmap_update(
  86. struct xfs_btree_cur *cur,
  87. struct xfs_rmap_irec *irec)
  88. {
  89. union xfs_btree_rec rec;
  90. int error;
  91. trace_xfs_rmap_update(cur->bc_mp, cur->bc_ag.pag->pag_agno,
  92. irec->rm_startblock, irec->rm_blockcount,
  93. irec->rm_owner, irec->rm_offset, irec->rm_flags);
  94. rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
  95. rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
  96. rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
  97. rec.rmap.rm_offset = cpu_to_be64(
  98. xfs_rmap_irec_offset_pack(irec));
  99. error = xfs_btree_update(cur, &rec);
  100. if (error)
  101. trace_xfs_rmap_update_error(cur->bc_mp,
  102. cur->bc_ag.pag->pag_agno, error, _RET_IP_);
  103. return error;
  104. }
  105. int
  106. xfs_rmap_insert(
  107. struct xfs_btree_cur *rcur,
  108. xfs_agblock_t agbno,
  109. xfs_extlen_t len,
  110. uint64_t owner,
  111. uint64_t offset,
  112. unsigned int flags)
  113. {
  114. int i;
  115. int error;
  116. trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
  117. len, owner, offset, flags);
  118. error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
  119. if (error)
  120. goto done;
  121. if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
  122. error = -EFSCORRUPTED;
  123. goto done;
  124. }
  125. rcur->bc_rec.r.rm_startblock = agbno;
  126. rcur->bc_rec.r.rm_blockcount = len;
  127. rcur->bc_rec.r.rm_owner = owner;
  128. rcur->bc_rec.r.rm_offset = offset;
  129. rcur->bc_rec.r.rm_flags = flags;
  130. error = xfs_btree_insert(rcur, &i);
  131. if (error)
  132. goto done;
  133. if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
  134. error = -EFSCORRUPTED;
  135. goto done;
  136. }
  137. done:
  138. if (error)
  139. trace_xfs_rmap_insert_error(rcur->bc_mp,
  140. rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
  141. return error;
  142. }
  143. STATIC int
  144. xfs_rmap_delete(
  145. struct xfs_btree_cur *rcur,
  146. xfs_agblock_t agbno,
  147. xfs_extlen_t len,
  148. uint64_t owner,
  149. uint64_t offset,
  150. unsigned int flags)
  151. {
  152. int i;
  153. int error;
  154. trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
  155. len, owner, offset, flags);
  156. error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
  157. if (error)
  158. goto done;
  159. if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
  160. error = -EFSCORRUPTED;
  161. goto done;
  162. }
  163. error = xfs_btree_delete(rcur, &i);
  164. if (error)
  165. goto done;
  166. if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
  167. error = -EFSCORRUPTED;
  168. goto done;
  169. }
  170. done:
  171. if (error)
  172. trace_xfs_rmap_delete_error(rcur->bc_mp,
  173. rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
  174. return error;
  175. }
  176. /* Convert an internal btree record to an rmap record. */
  177. int
  178. xfs_rmap_btrec_to_irec(
  179. const union xfs_btree_rec *rec,
  180. struct xfs_rmap_irec *irec)
  181. {
  182. irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
  183. irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
  184. irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
  185. return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
  186. irec);
  187. }
  188. /*
  189. * Get the data from the pointed-to record.
  190. */
  191. int
  192. xfs_rmap_get_rec(
  193. struct xfs_btree_cur *cur,
  194. struct xfs_rmap_irec *irec,
  195. int *stat)
  196. {
  197. struct xfs_mount *mp = cur->bc_mp;
  198. struct xfs_perag *pag = cur->bc_ag.pag;
  199. union xfs_btree_rec *rec;
  200. int error;
  201. error = xfs_btree_get_rec(cur, &rec, stat);
  202. if (error || !*stat)
  203. return error;
  204. if (xfs_rmap_btrec_to_irec(rec, irec))
  205. goto out_bad_rec;
  206. if (irec->rm_blockcount == 0)
  207. goto out_bad_rec;
  208. if (irec->rm_startblock <= XFS_AGFL_BLOCK(mp)) {
  209. if (irec->rm_owner != XFS_RMAP_OWN_FS)
  210. goto out_bad_rec;
  211. if (irec->rm_blockcount != XFS_AGFL_BLOCK(mp) + 1)
  212. goto out_bad_rec;
  213. } else {
  214. /* check for valid extent range, including overflow */
  215. if (!xfs_verify_agbext(pag, irec->rm_startblock,
  216. irec->rm_blockcount))
  217. goto out_bad_rec;
  218. }
  219. if (!(xfs_verify_ino(mp, irec->rm_owner) ||
  220. (irec->rm_owner <= XFS_RMAP_OWN_FS &&
  221. irec->rm_owner >= XFS_RMAP_OWN_MIN)))
  222. goto out_bad_rec;
  223. return 0;
  224. out_bad_rec:
  225. xfs_warn(mp,
  226. "Reverse Mapping BTree record corruption in AG %d detected!",
  227. pag->pag_agno);
  228. xfs_warn(mp,
  229. "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
  230. irec->rm_owner, irec->rm_flags, irec->rm_startblock,
  231. irec->rm_blockcount);
  232. return -EFSCORRUPTED;
  233. }
  234. struct xfs_find_left_neighbor_info {
  235. struct xfs_rmap_irec high;
  236. struct xfs_rmap_irec *irec;
  237. };
  238. /* For each rmap given, figure out if it matches the key we want. */
  239. STATIC int
  240. xfs_rmap_find_left_neighbor_helper(
  241. struct xfs_btree_cur *cur,
  242. const struct xfs_rmap_irec *rec,
  243. void *priv)
  244. {
  245. struct xfs_find_left_neighbor_info *info = priv;
  246. trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
  247. cur->bc_ag.pag->pag_agno, rec->rm_startblock,
  248. rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
  249. rec->rm_flags);
  250. if (rec->rm_owner != info->high.rm_owner)
  251. return 0;
  252. if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
  253. !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
  254. rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
  255. return 0;
  256. *info->irec = *rec;
  257. return -ECANCELED;
  258. }
  259. /*
  260. * Find the record to the left of the given extent, being careful only to
  261. * return a match with the same owner and adjacent physical and logical
  262. * block ranges.
  263. */
  264. STATIC int
  265. xfs_rmap_find_left_neighbor(
  266. struct xfs_btree_cur *cur,
  267. xfs_agblock_t bno,
  268. uint64_t owner,
  269. uint64_t offset,
  270. unsigned int flags,
  271. struct xfs_rmap_irec *irec,
  272. int *stat)
  273. {
  274. struct xfs_find_left_neighbor_info info;
  275. int found = 0;
  276. int error;
  277. *stat = 0;
  278. if (bno == 0)
  279. return 0;
  280. info.high.rm_startblock = bno - 1;
  281. info.high.rm_owner = owner;
  282. if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
  283. !(flags & XFS_RMAP_BMBT_BLOCK)) {
  284. if (offset == 0)
  285. return 0;
  286. info.high.rm_offset = offset - 1;
  287. } else
  288. info.high.rm_offset = 0;
  289. info.high.rm_flags = flags;
  290. info.high.rm_blockcount = 0;
  291. info.irec = irec;
  292. trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
  293. cur->bc_ag.pag->pag_agno, bno, 0, owner, offset, flags);
  294. /*
  295. * Historically, we always used the range query to walk every reverse
  296. * mapping that could possibly overlap the key that the caller asked
  297. * for, and filter out the ones that don't. That is very slow when
  298. * there are a lot of records.
  299. *
  300. * However, there are two scenarios where the classic btree search can
  301. * produce correct results -- if the index contains a record that is an
  302. * exact match for the lookup key; and if there are no other records
  303. * between the record we want and the key we supplied.
  304. *
  305. * As an optimization, try a non-overlapped lookup first. This makes
  306. * extent conversion and remap operations run a bit faster if the
  307. * physical extents aren't being shared. If we don't find what we
  308. * want, we fall back to the overlapped query.
  309. */
  310. error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
  311. &found);
  312. if (error)
  313. return error;
  314. if (found)
  315. error = xfs_rmap_find_left_neighbor_helper(cur, irec, &info);
  316. if (!error)
  317. error = xfs_rmap_query_range(cur, &info.high, &info.high,
  318. xfs_rmap_find_left_neighbor_helper, &info);
  319. if (error != -ECANCELED)
  320. return error;
  321. *stat = 1;
  322. trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
  323. cur->bc_ag.pag->pag_agno, irec->rm_startblock,
  324. irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
  325. irec->rm_flags);
  326. return 0;
  327. }
  328. /* For each rmap given, figure out if it matches the key we want. */
  329. STATIC int
  330. xfs_rmap_lookup_le_range_helper(
  331. struct xfs_btree_cur *cur,
  332. const struct xfs_rmap_irec *rec,
  333. void *priv)
  334. {
  335. struct xfs_find_left_neighbor_info *info = priv;
  336. trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
  337. cur->bc_ag.pag->pag_agno, rec->rm_startblock,
  338. rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
  339. rec->rm_flags);
  340. if (rec->rm_owner != info->high.rm_owner)
  341. return 0;
  342. if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
  343. !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
  344. (rec->rm_offset > info->high.rm_offset ||
  345. rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
  346. return 0;
  347. *info->irec = *rec;
  348. return -ECANCELED;
  349. }
  350. /*
  351. * Find the record to the left of the given extent, being careful only to
  352. * return a match with the same owner and overlapping physical and logical
  353. * block ranges. This is the overlapping-interval version of
  354. * xfs_rmap_lookup_le.
  355. */
  356. int
  357. xfs_rmap_lookup_le_range(
  358. struct xfs_btree_cur *cur,
  359. xfs_agblock_t bno,
  360. uint64_t owner,
  361. uint64_t offset,
  362. unsigned int flags,
  363. struct xfs_rmap_irec *irec,
  364. int *stat)
  365. {
  366. struct xfs_find_left_neighbor_info info;
  367. int found = 0;
  368. int error;
  369. info.high.rm_startblock = bno;
  370. info.high.rm_owner = owner;
  371. if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
  372. info.high.rm_offset = offset;
  373. else
  374. info.high.rm_offset = 0;
  375. info.high.rm_flags = flags;
  376. info.high.rm_blockcount = 0;
  377. *stat = 0;
  378. info.irec = irec;
  379. trace_xfs_rmap_lookup_le_range(cur->bc_mp, cur->bc_ag.pag->pag_agno,
  380. bno, 0, owner, offset, flags);
  381. /*
  382. * Historically, we always used the range query to walk every reverse
  383. * mapping that could possibly overlap the key that the caller asked
  384. * for, and filter out the ones that don't. That is very slow when
  385. * there are a lot of records.
  386. *
  387. * However, there are two scenarios where the classic btree search can
  388. * produce correct results -- if the index contains a record that is an
  389. * exact match for the lookup key; and if there are no other records
  390. * between the record we want and the key we supplied.
  391. *
  392. * As an optimization, try a non-overlapped lookup first. This makes
  393. * scrub run much faster on most filesystems because bmbt records are
  394. * usually an exact match for rmap records. If we don't find what we
  395. * want, we fall back to the overlapped query.
  396. */
  397. error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
  398. &found);
  399. if (error)
  400. return error;
  401. if (found)
  402. error = xfs_rmap_lookup_le_range_helper(cur, irec, &info);
  403. if (!error)
  404. error = xfs_rmap_query_range(cur, &info.high, &info.high,
  405. xfs_rmap_lookup_le_range_helper, &info);
  406. if (error != -ECANCELED)
  407. return error;
  408. *stat = 1;
  409. trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
  410. cur->bc_ag.pag->pag_agno, irec->rm_startblock,
  411. irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
  412. irec->rm_flags);
  413. return 0;
  414. }
  415. /*
  416. * Perform all the relevant owner checks for a removal op. If we're doing an
  417. * unknown-owner removal then we have no owner information to check.
  418. */
  419. static int
  420. xfs_rmap_free_check_owner(
  421. struct xfs_mount *mp,
  422. uint64_t ltoff,
  423. struct xfs_rmap_irec *rec,
  424. xfs_filblks_t len,
  425. uint64_t owner,
  426. uint64_t offset,
  427. unsigned int flags)
  428. {
  429. int error = 0;
  430. if (owner == XFS_RMAP_OWN_UNKNOWN)
  431. return 0;
  432. /* Make sure the unwritten flag matches. */
  433. if (XFS_IS_CORRUPT(mp,
  434. (flags & XFS_RMAP_UNWRITTEN) !=
  435. (rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
  436. error = -EFSCORRUPTED;
  437. goto out;
  438. }
  439. /* Make sure the owner matches what we expect to find in the tree. */
  440. if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
  441. error = -EFSCORRUPTED;
  442. goto out;
  443. }
  444. /* Check the offset, if necessary. */
  445. if (XFS_RMAP_NON_INODE_OWNER(owner))
  446. goto out;
  447. if (flags & XFS_RMAP_BMBT_BLOCK) {
  448. if (XFS_IS_CORRUPT(mp,
  449. !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
  450. error = -EFSCORRUPTED;
  451. goto out;
  452. }
  453. } else {
  454. if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
  455. error = -EFSCORRUPTED;
  456. goto out;
  457. }
  458. if (XFS_IS_CORRUPT(mp,
  459. offset + len > ltoff + rec->rm_blockcount)) {
  460. error = -EFSCORRUPTED;
  461. goto out;
  462. }
  463. }
  464. out:
  465. return error;
  466. }
  467. /*
  468. * Find the extent in the rmap btree and remove it.
  469. *
  470. * The record we find should always be an exact match for the extent that we're
  471. * looking for, since we insert them into the btree without modification.
  472. *
  473. * Special Case #1: when growing the filesystem, we "free" an extent when
  474. * growing the last AG. This extent is new space and so it is not tracked as
  475. * used space in the btree. The growfs code will pass in an owner of
  476. * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
  477. * extent. We verify that - the extent lookup result in a record that does not
  478. * overlap.
  479. *
  480. * Special Case #2: EFIs do not record the owner of the extent, so when
  481. * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
  482. * btree to ignore the owner (i.e. wildcard match) so we don't trigger
  483. * corruption checks during log recovery.
  484. */
  485. STATIC int
  486. xfs_rmap_unmap(
  487. struct xfs_btree_cur *cur,
  488. xfs_agblock_t bno,
  489. xfs_extlen_t len,
  490. bool unwritten,
  491. const struct xfs_owner_info *oinfo)
  492. {
  493. struct xfs_mount *mp = cur->bc_mp;
  494. struct xfs_rmap_irec ltrec;
  495. uint64_t ltoff;
  496. int error = 0;
  497. int i;
  498. uint64_t owner;
  499. uint64_t offset;
  500. unsigned int flags;
  501. bool ignore_off;
  502. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  503. ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
  504. (flags & XFS_RMAP_BMBT_BLOCK);
  505. if (unwritten)
  506. flags |= XFS_RMAP_UNWRITTEN;
  507. trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
  508. unwritten, oinfo);
  509. /*
  510. * We should always have a left record because there's a static record
  511. * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
  512. * will not ever be removed from the tree.
  513. */
  514. error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec, &i);
  515. if (error)
  516. goto out_error;
  517. if (XFS_IS_CORRUPT(mp, i != 1)) {
  518. error = -EFSCORRUPTED;
  519. goto out_error;
  520. }
  521. trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
  522. cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
  523. ltrec.rm_blockcount, ltrec.rm_owner,
  524. ltrec.rm_offset, ltrec.rm_flags);
  525. ltoff = ltrec.rm_offset;
  526. /*
  527. * For growfs, the incoming extent must be beyond the left record we
  528. * just found as it is new space and won't be used by anyone. This is
  529. * just a corruption check as we don't actually do anything with this
  530. * extent. Note that we need to use >= instead of > because it might
  531. * be the case that the "left" extent goes all the way to EOFS.
  532. */
  533. if (owner == XFS_RMAP_OWN_NULL) {
  534. if (XFS_IS_CORRUPT(mp,
  535. bno <
  536. ltrec.rm_startblock + ltrec.rm_blockcount)) {
  537. error = -EFSCORRUPTED;
  538. goto out_error;
  539. }
  540. goto out_done;
  541. }
  542. /*
  543. * If we're doing an unknown-owner removal for EFI recovery, we expect
  544. * to find the full range in the rmapbt or nothing at all. If we
  545. * don't find any rmaps overlapping either end of the range, we're
  546. * done. Hopefully this means that the EFI creator already queued
  547. * (and finished) a RUI to remove the rmap.
  548. */
  549. if (owner == XFS_RMAP_OWN_UNKNOWN &&
  550. ltrec.rm_startblock + ltrec.rm_blockcount <= bno) {
  551. struct xfs_rmap_irec rtrec;
  552. error = xfs_btree_increment(cur, 0, &i);
  553. if (error)
  554. goto out_error;
  555. if (i == 0)
  556. goto out_done;
  557. error = xfs_rmap_get_rec(cur, &rtrec, &i);
  558. if (error)
  559. goto out_error;
  560. if (XFS_IS_CORRUPT(mp, i != 1)) {
  561. error = -EFSCORRUPTED;
  562. goto out_error;
  563. }
  564. if (rtrec.rm_startblock >= bno + len)
  565. goto out_done;
  566. }
  567. /* Make sure the extent we found covers the entire freeing range. */
  568. if (XFS_IS_CORRUPT(mp,
  569. ltrec.rm_startblock > bno ||
  570. ltrec.rm_startblock + ltrec.rm_blockcount <
  571. bno + len)) {
  572. error = -EFSCORRUPTED;
  573. goto out_error;
  574. }
  575. /* Check owner information. */
  576. error = xfs_rmap_free_check_owner(mp, ltoff, &ltrec, len, owner,
  577. offset, flags);
  578. if (error)
  579. goto out_error;
  580. if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
  581. /* exact match, simply remove the record from rmap tree */
  582. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  583. ltrec.rm_startblock, ltrec.rm_blockcount,
  584. ltrec.rm_owner, ltrec.rm_offset,
  585. ltrec.rm_flags);
  586. error = xfs_btree_delete(cur, &i);
  587. if (error)
  588. goto out_error;
  589. if (XFS_IS_CORRUPT(mp, i != 1)) {
  590. error = -EFSCORRUPTED;
  591. goto out_error;
  592. }
  593. } else if (ltrec.rm_startblock == bno) {
  594. /*
  595. * overlap left hand side of extent: move the start, trim the
  596. * length and update the current record.
  597. *
  598. * ltbno ltlen
  599. * Orig: |oooooooooooooooooooo|
  600. * Freeing: |fffffffff|
  601. * Result: |rrrrrrrrrr|
  602. * bno len
  603. */
  604. ltrec.rm_startblock += len;
  605. ltrec.rm_blockcount -= len;
  606. if (!ignore_off)
  607. ltrec.rm_offset += len;
  608. error = xfs_rmap_update(cur, &ltrec);
  609. if (error)
  610. goto out_error;
  611. } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
  612. /*
  613. * overlap right hand side of extent: trim the length and update
  614. * the current record.
  615. *
  616. * ltbno ltlen
  617. * Orig: |oooooooooooooooooooo|
  618. * Freeing: |fffffffff|
  619. * Result: |rrrrrrrrrr|
  620. * bno len
  621. */
  622. ltrec.rm_blockcount -= len;
  623. error = xfs_rmap_update(cur, &ltrec);
  624. if (error)
  625. goto out_error;
  626. } else {
  627. /*
  628. * overlap middle of extent: trim the length of the existing
  629. * record to the length of the new left-extent size, increment
  630. * the insertion position so we can insert a new record
  631. * containing the remaining right-extent space.
  632. *
  633. * ltbno ltlen
  634. * Orig: |oooooooooooooooooooo|
  635. * Freeing: |fffffffff|
  636. * Result: |rrrrr| |rrrr|
  637. * bno len
  638. */
  639. xfs_extlen_t orig_len = ltrec.rm_blockcount;
  640. ltrec.rm_blockcount = bno - ltrec.rm_startblock;
  641. error = xfs_rmap_update(cur, &ltrec);
  642. if (error)
  643. goto out_error;
  644. error = xfs_btree_increment(cur, 0, &i);
  645. if (error)
  646. goto out_error;
  647. cur->bc_rec.r.rm_startblock = bno + len;
  648. cur->bc_rec.r.rm_blockcount = orig_len - len -
  649. ltrec.rm_blockcount;
  650. cur->bc_rec.r.rm_owner = ltrec.rm_owner;
  651. if (ignore_off)
  652. cur->bc_rec.r.rm_offset = 0;
  653. else
  654. cur->bc_rec.r.rm_offset = offset + len;
  655. cur->bc_rec.r.rm_flags = flags;
  656. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
  657. cur->bc_rec.r.rm_startblock,
  658. cur->bc_rec.r.rm_blockcount,
  659. cur->bc_rec.r.rm_owner,
  660. cur->bc_rec.r.rm_offset,
  661. cur->bc_rec.r.rm_flags);
  662. error = xfs_btree_insert(cur, &i);
  663. if (error)
  664. goto out_error;
  665. }
  666. out_done:
  667. trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  668. unwritten, oinfo);
  669. out_error:
  670. if (error)
  671. trace_xfs_rmap_unmap_error(mp, cur->bc_ag.pag->pag_agno,
  672. error, _RET_IP_);
  673. return error;
  674. }
  675. /*
  676. * Remove a reference to an extent in the rmap btree.
  677. */
  678. int
  679. xfs_rmap_free(
  680. struct xfs_trans *tp,
  681. struct xfs_buf *agbp,
  682. struct xfs_perag *pag,
  683. xfs_agblock_t bno,
  684. xfs_extlen_t len,
  685. const struct xfs_owner_info *oinfo)
  686. {
  687. struct xfs_mount *mp = tp->t_mountp;
  688. struct xfs_btree_cur *cur;
  689. int error;
  690. if (!xfs_has_rmapbt(mp))
  691. return 0;
  692. cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
  693. error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
  694. xfs_btree_del_cursor(cur, error);
  695. return error;
  696. }
  697. /*
  698. * A mergeable rmap must have the same owner and the same values for
  699. * the unwritten, attr_fork, and bmbt flags. The startblock and
  700. * offset are checked separately.
  701. */
  702. static bool
  703. xfs_rmap_is_mergeable(
  704. struct xfs_rmap_irec *irec,
  705. uint64_t owner,
  706. unsigned int flags)
  707. {
  708. if (irec->rm_owner == XFS_RMAP_OWN_NULL)
  709. return false;
  710. if (irec->rm_owner != owner)
  711. return false;
  712. if ((flags & XFS_RMAP_UNWRITTEN) ^
  713. (irec->rm_flags & XFS_RMAP_UNWRITTEN))
  714. return false;
  715. if ((flags & XFS_RMAP_ATTR_FORK) ^
  716. (irec->rm_flags & XFS_RMAP_ATTR_FORK))
  717. return false;
  718. if ((flags & XFS_RMAP_BMBT_BLOCK) ^
  719. (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
  720. return false;
  721. return true;
  722. }
  723. /*
  724. * When we allocate a new block, the first thing we do is add a reference to
  725. * the extent in the rmap btree. This takes the form of a [agbno, length,
  726. * owner, offset] record. Flags are encoded in the high bits of the offset
  727. * field.
  728. */
  729. STATIC int
  730. xfs_rmap_map(
  731. struct xfs_btree_cur *cur,
  732. xfs_agblock_t bno,
  733. xfs_extlen_t len,
  734. bool unwritten,
  735. const struct xfs_owner_info *oinfo)
  736. {
  737. struct xfs_mount *mp = cur->bc_mp;
  738. struct xfs_rmap_irec ltrec;
  739. struct xfs_rmap_irec gtrec;
  740. int have_gt;
  741. int have_lt;
  742. int error = 0;
  743. int i;
  744. uint64_t owner;
  745. uint64_t offset;
  746. unsigned int flags = 0;
  747. bool ignore_off;
  748. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  749. ASSERT(owner != 0);
  750. ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
  751. (flags & XFS_RMAP_BMBT_BLOCK);
  752. if (unwritten)
  753. flags |= XFS_RMAP_UNWRITTEN;
  754. trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
  755. unwritten, oinfo);
  756. ASSERT(!xfs_rmap_should_skip_owner_update(oinfo));
  757. /*
  758. * For the initial lookup, look for an exact match or the left-adjacent
  759. * record for our insertion point. This will also give us the record for
  760. * start block contiguity tests.
  761. */
  762. error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec,
  763. &have_lt);
  764. if (error)
  765. goto out_error;
  766. if (have_lt) {
  767. trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
  768. cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
  769. ltrec.rm_blockcount, ltrec.rm_owner,
  770. ltrec.rm_offset, ltrec.rm_flags);
  771. if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
  772. have_lt = 0;
  773. }
  774. if (XFS_IS_CORRUPT(mp,
  775. have_lt != 0 &&
  776. ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
  777. error = -EFSCORRUPTED;
  778. goto out_error;
  779. }
  780. /*
  781. * Increment the cursor to see if we have a right-adjacent record to our
  782. * insertion point. This will give us the record for end block
  783. * contiguity tests.
  784. */
  785. error = xfs_btree_increment(cur, 0, &have_gt);
  786. if (error)
  787. goto out_error;
  788. if (have_gt) {
  789. error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
  790. if (error)
  791. goto out_error;
  792. if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
  793. error = -EFSCORRUPTED;
  794. goto out_error;
  795. }
  796. if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
  797. error = -EFSCORRUPTED;
  798. goto out_error;
  799. }
  800. trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
  801. cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
  802. gtrec.rm_blockcount, gtrec.rm_owner,
  803. gtrec.rm_offset, gtrec.rm_flags);
  804. if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
  805. have_gt = 0;
  806. }
  807. /*
  808. * Note: cursor currently points one record to the right of ltrec, even
  809. * if there is no record in the tree to the right.
  810. */
  811. if (have_lt &&
  812. ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
  813. (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
  814. /*
  815. * left edge contiguous, merge into left record.
  816. *
  817. * ltbno ltlen
  818. * orig: |ooooooooo|
  819. * adding: |aaaaaaaaa|
  820. * result: |rrrrrrrrrrrrrrrrrrr|
  821. * bno len
  822. */
  823. ltrec.rm_blockcount += len;
  824. if (have_gt &&
  825. bno + len == gtrec.rm_startblock &&
  826. (ignore_off || offset + len == gtrec.rm_offset) &&
  827. (unsigned long)ltrec.rm_blockcount + len +
  828. gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
  829. /*
  830. * right edge also contiguous, delete right record
  831. * and merge into left record.
  832. *
  833. * ltbno ltlen gtbno gtlen
  834. * orig: |ooooooooo| |ooooooooo|
  835. * adding: |aaaaaaaaa|
  836. * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
  837. */
  838. ltrec.rm_blockcount += gtrec.rm_blockcount;
  839. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  840. gtrec.rm_startblock,
  841. gtrec.rm_blockcount,
  842. gtrec.rm_owner,
  843. gtrec.rm_offset,
  844. gtrec.rm_flags);
  845. error = xfs_btree_delete(cur, &i);
  846. if (error)
  847. goto out_error;
  848. if (XFS_IS_CORRUPT(mp, i != 1)) {
  849. error = -EFSCORRUPTED;
  850. goto out_error;
  851. }
  852. }
  853. /* point the cursor back to the left record and update */
  854. error = xfs_btree_decrement(cur, 0, &have_gt);
  855. if (error)
  856. goto out_error;
  857. error = xfs_rmap_update(cur, &ltrec);
  858. if (error)
  859. goto out_error;
  860. } else if (have_gt &&
  861. bno + len == gtrec.rm_startblock &&
  862. (ignore_off || offset + len == gtrec.rm_offset)) {
  863. /*
  864. * right edge contiguous, merge into right record.
  865. *
  866. * gtbno gtlen
  867. * Orig: |ooooooooo|
  868. * adding: |aaaaaaaaa|
  869. * Result: |rrrrrrrrrrrrrrrrrrr|
  870. * bno len
  871. */
  872. gtrec.rm_startblock = bno;
  873. gtrec.rm_blockcount += len;
  874. if (!ignore_off)
  875. gtrec.rm_offset = offset;
  876. error = xfs_rmap_update(cur, &gtrec);
  877. if (error)
  878. goto out_error;
  879. } else {
  880. /*
  881. * no contiguous edge with identical owner, insert
  882. * new record at current cursor position.
  883. */
  884. cur->bc_rec.r.rm_startblock = bno;
  885. cur->bc_rec.r.rm_blockcount = len;
  886. cur->bc_rec.r.rm_owner = owner;
  887. cur->bc_rec.r.rm_offset = offset;
  888. cur->bc_rec.r.rm_flags = flags;
  889. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
  890. owner, offset, flags);
  891. error = xfs_btree_insert(cur, &i);
  892. if (error)
  893. goto out_error;
  894. if (XFS_IS_CORRUPT(mp, i != 1)) {
  895. error = -EFSCORRUPTED;
  896. goto out_error;
  897. }
  898. }
  899. trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  900. unwritten, oinfo);
  901. out_error:
  902. if (error)
  903. trace_xfs_rmap_map_error(mp, cur->bc_ag.pag->pag_agno,
  904. error, _RET_IP_);
  905. return error;
  906. }
  907. /*
  908. * Add a reference to an extent in the rmap btree.
  909. */
  910. int
  911. xfs_rmap_alloc(
  912. struct xfs_trans *tp,
  913. struct xfs_buf *agbp,
  914. struct xfs_perag *pag,
  915. xfs_agblock_t bno,
  916. xfs_extlen_t len,
  917. const struct xfs_owner_info *oinfo)
  918. {
  919. struct xfs_mount *mp = tp->t_mountp;
  920. struct xfs_btree_cur *cur;
  921. int error;
  922. if (!xfs_has_rmapbt(mp))
  923. return 0;
  924. cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
  925. error = xfs_rmap_map(cur, bno, len, false, oinfo);
  926. xfs_btree_del_cursor(cur, error);
  927. return error;
  928. }
  929. #define RMAP_LEFT_CONTIG (1 << 0)
  930. #define RMAP_RIGHT_CONTIG (1 << 1)
  931. #define RMAP_LEFT_FILLING (1 << 2)
  932. #define RMAP_RIGHT_FILLING (1 << 3)
  933. #define RMAP_LEFT_VALID (1 << 6)
  934. #define RMAP_RIGHT_VALID (1 << 7)
  935. #define LEFT r[0]
  936. #define RIGHT r[1]
  937. #define PREV r[2]
  938. #define NEW r[3]
  939. /*
  940. * Convert an unwritten extent to a real extent or vice versa.
  941. * Does not handle overlapping extents.
  942. */
  943. STATIC int
  944. xfs_rmap_convert(
  945. struct xfs_btree_cur *cur,
  946. xfs_agblock_t bno,
  947. xfs_extlen_t len,
  948. bool unwritten,
  949. const struct xfs_owner_info *oinfo)
  950. {
  951. struct xfs_mount *mp = cur->bc_mp;
  952. struct xfs_rmap_irec r[4]; /* neighbor extent entries */
  953. /* left is 0, right is 1, */
  954. /* prev is 2, new is 3 */
  955. uint64_t owner;
  956. uint64_t offset;
  957. uint64_t new_endoff;
  958. unsigned int oldext;
  959. unsigned int newext;
  960. unsigned int flags = 0;
  961. int i;
  962. int state = 0;
  963. int error;
  964. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  965. ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
  966. (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
  967. oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
  968. new_endoff = offset + len;
  969. trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
  970. unwritten, oinfo);
  971. /*
  972. * For the initial lookup, look for an exact match or the left-adjacent
  973. * record for our insertion point. This will also give us the record for
  974. * start block contiguity tests.
  975. */
  976. error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, &PREV, &i);
  977. if (error)
  978. goto done;
  979. if (XFS_IS_CORRUPT(mp, i != 1)) {
  980. error = -EFSCORRUPTED;
  981. goto done;
  982. }
  983. trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
  984. cur->bc_ag.pag->pag_agno, PREV.rm_startblock,
  985. PREV.rm_blockcount, PREV.rm_owner,
  986. PREV.rm_offset, PREV.rm_flags);
  987. ASSERT(PREV.rm_offset <= offset);
  988. ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
  989. ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
  990. newext = ~oldext & XFS_RMAP_UNWRITTEN;
  991. /*
  992. * Set flags determining what part of the previous oldext allocation
  993. * extent is being replaced by a newext allocation.
  994. */
  995. if (PREV.rm_offset == offset)
  996. state |= RMAP_LEFT_FILLING;
  997. if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
  998. state |= RMAP_RIGHT_FILLING;
  999. /*
  1000. * Decrement the cursor to see if we have a left-adjacent record to our
  1001. * insertion point. This will give us the record for end block
  1002. * contiguity tests.
  1003. */
  1004. error = xfs_btree_decrement(cur, 0, &i);
  1005. if (error)
  1006. goto done;
  1007. if (i) {
  1008. state |= RMAP_LEFT_VALID;
  1009. error = xfs_rmap_get_rec(cur, &LEFT, &i);
  1010. if (error)
  1011. goto done;
  1012. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1013. error = -EFSCORRUPTED;
  1014. goto done;
  1015. }
  1016. if (XFS_IS_CORRUPT(mp,
  1017. LEFT.rm_startblock + LEFT.rm_blockcount >
  1018. bno)) {
  1019. error = -EFSCORRUPTED;
  1020. goto done;
  1021. }
  1022. trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
  1023. cur->bc_ag.pag->pag_agno, LEFT.rm_startblock,
  1024. LEFT.rm_blockcount, LEFT.rm_owner,
  1025. LEFT.rm_offset, LEFT.rm_flags);
  1026. if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
  1027. LEFT.rm_offset + LEFT.rm_blockcount == offset &&
  1028. xfs_rmap_is_mergeable(&LEFT, owner, newext))
  1029. state |= RMAP_LEFT_CONTIG;
  1030. }
  1031. /*
  1032. * Increment the cursor to see if we have a right-adjacent record to our
  1033. * insertion point. This will give us the record for end block
  1034. * contiguity tests.
  1035. */
  1036. error = xfs_btree_increment(cur, 0, &i);
  1037. if (error)
  1038. goto done;
  1039. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1040. error = -EFSCORRUPTED;
  1041. goto done;
  1042. }
  1043. error = xfs_btree_increment(cur, 0, &i);
  1044. if (error)
  1045. goto done;
  1046. if (i) {
  1047. state |= RMAP_RIGHT_VALID;
  1048. error = xfs_rmap_get_rec(cur, &RIGHT, &i);
  1049. if (error)
  1050. goto done;
  1051. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1052. error = -EFSCORRUPTED;
  1053. goto done;
  1054. }
  1055. if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
  1056. error = -EFSCORRUPTED;
  1057. goto done;
  1058. }
  1059. trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
  1060. cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
  1061. RIGHT.rm_blockcount, RIGHT.rm_owner,
  1062. RIGHT.rm_offset, RIGHT.rm_flags);
  1063. if (bno + len == RIGHT.rm_startblock &&
  1064. offset + len == RIGHT.rm_offset &&
  1065. xfs_rmap_is_mergeable(&RIGHT, owner, newext))
  1066. state |= RMAP_RIGHT_CONTIG;
  1067. }
  1068. /* check that left + prev + right is not too long */
  1069. if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1070. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
  1071. (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1072. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
  1073. (unsigned long)LEFT.rm_blockcount + len +
  1074. RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
  1075. state &= ~RMAP_RIGHT_CONTIG;
  1076. trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
  1077. _RET_IP_);
  1078. /* reset the cursor back to PREV */
  1079. error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, NULL, &i);
  1080. if (error)
  1081. goto done;
  1082. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1083. error = -EFSCORRUPTED;
  1084. goto done;
  1085. }
  1086. /*
  1087. * Switch out based on the FILLING and CONTIG state bits.
  1088. */
  1089. switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1090. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
  1091. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1092. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1093. /*
  1094. * Setting all of a previous oldext extent to newext.
  1095. * The left and right neighbors are both contiguous with new.
  1096. */
  1097. error = xfs_btree_increment(cur, 0, &i);
  1098. if (error)
  1099. goto done;
  1100. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1101. error = -EFSCORRUPTED;
  1102. goto done;
  1103. }
  1104. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  1105. RIGHT.rm_startblock, RIGHT.rm_blockcount,
  1106. RIGHT.rm_owner, RIGHT.rm_offset,
  1107. RIGHT.rm_flags);
  1108. error = xfs_btree_delete(cur, &i);
  1109. if (error)
  1110. goto done;
  1111. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1112. error = -EFSCORRUPTED;
  1113. goto done;
  1114. }
  1115. error = xfs_btree_decrement(cur, 0, &i);
  1116. if (error)
  1117. goto done;
  1118. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1119. error = -EFSCORRUPTED;
  1120. goto done;
  1121. }
  1122. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  1123. PREV.rm_startblock, PREV.rm_blockcount,
  1124. PREV.rm_owner, PREV.rm_offset,
  1125. PREV.rm_flags);
  1126. error = xfs_btree_delete(cur, &i);
  1127. if (error)
  1128. goto done;
  1129. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1130. error = -EFSCORRUPTED;
  1131. goto done;
  1132. }
  1133. error = xfs_btree_decrement(cur, 0, &i);
  1134. if (error)
  1135. goto done;
  1136. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1137. error = -EFSCORRUPTED;
  1138. goto done;
  1139. }
  1140. NEW = LEFT;
  1141. NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
  1142. error = xfs_rmap_update(cur, &NEW);
  1143. if (error)
  1144. goto done;
  1145. break;
  1146. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
  1147. /*
  1148. * Setting all of a previous oldext extent to newext.
  1149. * The left neighbor is contiguous, the right is not.
  1150. */
  1151. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  1152. PREV.rm_startblock, PREV.rm_blockcount,
  1153. PREV.rm_owner, PREV.rm_offset,
  1154. PREV.rm_flags);
  1155. error = xfs_btree_delete(cur, &i);
  1156. if (error)
  1157. goto done;
  1158. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1159. error = -EFSCORRUPTED;
  1160. goto done;
  1161. }
  1162. error = xfs_btree_decrement(cur, 0, &i);
  1163. if (error)
  1164. goto done;
  1165. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1166. error = -EFSCORRUPTED;
  1167. goto done;
  1168. }
  1169. NEW = LEFT;
  1170. NEW.rm_blockcount += PREV.rm_blockcount;
  1171. error = xfs_rmap_update(cur, &NEW);
  1172. if (error)
  1173. goto done;
  1174. break;
  1175. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1176. /*
  1177. * Setting all of a previous oldext extent to newext.
  1178. * The right neighbor is contiguous, the left is not.
  1179. */
  1180. error = xfs_btree_increment(cur, 0, &i);
  1181. if (error)
  1182. goto done;
  1183. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1184. error = -EFSCORRUPTED;
  1185. goto done;
  1186. }
  1187. trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
  1188. RIGHT.rm_startblock, RIGHT.rm_blockcount,
  1189. RIGHT.rm_owner, RIGHT.rm_offset,
  1190. RIGHT.rm_flags);
  1191. error = xfs_btree_delete(cur, &i);
  1192. if (error)
  1193. goto done;
  1194. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1195. error = -EFSCORRUPTED;
  1196. goto done;
  1197. }
  1198. error = xfs_btree_decrement(cur, 0, &i);
  1199. if (error)
  1200. goto done;
  1201. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1202. error = -EFSCORRUPTED;
  1203. goto done;
  1204. }
  1205. NEW = PREV;
  1206. NEW.rm_blockcount = len + RIGHT.rm_blockcount;
  1207. NEW.rm_flags = newext;
  1208. error = xfs_rmap_update(cur, &NEW);
  1209. if (error)
  1210. goto done;
  1211. break;
  1212. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
  1213. /*
  1214. * Setting all of a previous oldext extent to newext.
  1215. * Neither the left nor right neighbors are contiguous with
  1216. * the new one.
  1217. */
  1218. NEW = PREV;
  1219. NEW.rm_flags = newext;
  1220. error = xfs_rmap_update(cur, &NEW);
  1221. if (error)
  1222. goto done;
  1223. break;
  1224. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
  1225. /*
  1226. * Setting the first part of a previous oldext extent to newext.
  1227. * The left neighbor is contiguous.
  1228. */
  1229. NEW = PREV;
  1230. NEW.rm_offset += len;
  1231. NEW.rm_startblock += len;
  1232. NEW.rm_blockcount -= len;
  1233. error = xfs_rmap_update(cur, &NEW);
  1234. if (error)
  1235. goto done;
  1236. error = xfs_btree_decrement(cur, 0, &i);
  1237. if (error)
  1238. goto done;
  1239. NEW = LEFT;
  1240. NEW.rm_blockcount += len;
  1241. error = xfs_rmap_update(cur, &NEW);
  1242. if (error)
  1243. goto done;
  1244. break;
  1245. case RMAP_LEFT_FILLING:
  1246. /*
  1247. * Setting the first part of a previous oldext extent to newext.
  1248. * The left neighbor is not contiguous.
  1249. */
  1250. NEW = PREV;
  1251. NEW.rm_startblock += len;
  1252. NEW.rm_offset += len;
  1253. NEW.rm_blockcount -= len;
  1254. error = xfs_rmap_update(cur, &NEW);
  1255. if (error)
  1256. goto done;
  1257. NEW.rm_startblock = bno;
  1258. NEW.rm_owner = owner;
  1259. NEW.rm_offset = offset;
  1260. NEW.rm_blockcount = len;
  1261. NEW.rm_flags = newext;
  1262. cur->bc_rec.r = NEW;
  1263. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
  1264. len, owner, offset, newext);
  1265. error = xfs_btree_insert(cur, &i);
  1266. if (error)
  1267. goto done;
  1268. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1269. error = -EFSCORRUPTED;
  1270. goto done;
  1271. }
  1272. break;
  1273. case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1274. /*
  1275. * Setting the last part of a previous oldext extent to newext.
  1276. * The right neighbor is contiguous with the new allocation.
  1277. */
  1278. NEW = PREV;
  1279. NEW.rm_blockcount -= len;
  1280. error = xfs_rmap_update(cur, &NEW);
  1281. if (error)
  1282. goto done;
  1283. error = xfs_btree_increment(cur, 0, &i);
  1284. if (error)
  1285. goto done;
  1286. NEW = RIGHT;
  1287. NEW.rm_offset = offset;
  1288. NEW.rm_startblock = bno;
  1289. NEW.rm_blockcount += len;
  1290. error = xfs_rmap_update(cur, &NEW);
  1291. if (error)
  1292. goto done;
  1293. break;
  1294. case RMAP_RIGHT_FILLING:
  1295. /*
  1296. * Setting the last part of a previous oldext extent to newext.
  1297. * The right neighbor is not contiguous.
  1298. */
  1299. NEW = PREV;
  1300. NEW.rm_blockcount -= len;
  1301. error = xfs_rmap_update(cur, &NEW);
  1302. if (error)
  1303. goto done;
  1304. error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
  1305. oldext, &i);
  1306. if (error)
  1307. goto done;
  1308. if (XFS_IS_CORRUPT(mp, i != 0)) {
  1309. error = -EFSCORRUPTED;
  1310. goto done;
  1311. }
  1312. NEW.rm_startblock = bno;
  1313. NEW.rm_owner = owner;
  1314. NEW.rm_offset = offset;
  1315. NEW.rm_blockcount = len;
  1316. NEW.rm_flags = newext;
  1317. cur->bc_rec.r = NEW;
  1318. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
  1319. len, owner, offset, newext);
  1320. error = xfs_btree_insert(cur, &i);
  1321. if (error)
  1322. goto done;
  1323. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1324. error = -EFSCORRUPTED;
  1325. goto done;
  1326. }
  1327. break;
  1328. case 0:
  1329. /*
  1330. * Setting the middle part of a previous oldext extent to
  1331. * newext. Contiguity is impossible here.
  1332. * One extent becomes three extents.
  1333. */
  1334. /* new right extent - oldext */
  1335. NEW.rm_startblock = bno + len;
  1336. NEW.rm_owner = owner;
  1337. NEW.rm_offset = new_endoff;
  1338. NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
  1339. new_endoff;
  1340. NEW.rm_flags = PREV.rm_flags;
  1341. error = xfs_rmap_update(cur, &NEW);
  1342. if (error)
  1343. goto done;
  1344. /* new left extent - oldext */
  1345. NEW = PREV;
  1346. NEW.rm_blockcount = offset - PREV.rm_offset;
  1347. cur->bc_rec.r = NEW;
  1348. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
  1349. NEW.rm_startblock, NEW.rm_blockcount,
  1350. NEW.rm_owner, NEW.rm_offset,
  1351. NEW.rm_flags);
  1352. error = xfs_btree_insert(cur, &i);
  1353. if (error)
  1354. goto done;
  1355. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1356. error = -EFSCORRUPTED;
  1357. goto done;
  1358. }
  1359. /*
  1360. * Reset the cursor to the position of the new extent
  1361. * we are about to insert as we can't trust it after
  1362. * the previous insert.
  1363. */
  1364. error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
  1365. oldext, &i);
  1366. if (error)
  1367. goto done;
  1368. if (XFS_IS_CORRUPT(mp, i != 0)) {
  1369. error = -EFSCORRUPTED;
  1370. goto done;
  1371. }
  1372. /* new middle extent - newext */
  1373. cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
  1374. cur->bc_rec.r.rm_flags |= newext;
  1375. trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1376. owner, offset, newext);
  1377. error = xfs_btree_insert(cur, &i);
  1378. if (error)
  1379. goto done;
  1380. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1381. error = -EFSCORRUPTED;
  1382. goto done;
  1383. }
  1384. break;
  1385. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1386. case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1387. case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
  1388. case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
  1389. case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1390. case RMAP_LEFT_CONTIG:
  1391. case RMAP_RIGHT_CONTIG:
  1392. /*
  1393. * These cases are all impossible.
  1394. */
  1395. ASSERT(0);
  1396. }
  1397. trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1398. unwritten, oinfo);
  1399. done:
  1400. if (error)
  1401. trace_xfs_rmap_convert_error(cur->bc_mp,
  1402. cur->bc_ag.pag->pag_agno, error, _RET_IP_);
  1403. return error;
  1404. }
  1405. /*
  1406. * Convert an unwritten extent to a real extent or vice versa. If there is no
  1407. * possibility of overlapping extents, delegate to the simpler convert
  1408. * function.
  1409. */
  1410. STATIC int
  1411. xfs_rmap_convert_shared(
  1412. struct xfs_btree_cur *cur,
  1413. xfs_agblock_t bno,
  1414. xfs_extlen_t len,
  1415. bool unwritten,
  1416. const struct xfs_owner_info *oinfo)
  1417. {
  1418. struct xfs_mount *mp = cur->bc_mp;
  1419. struct xfs_rmap_irec r[4]; /* neighbor extent entries */
  1420. /* left is 0, right is 1, */
  1421. /* prev is 2, new is 3 */
  1422. uint64_t owner;
  1423. uint64_t offset;
  1424. uint64_t new_endoff;
  1425. unsigned int oldext;
  1426. unsigned int newext;
  1427. unsigned int flags = 0;
  1428. int i;
  1429. int state = 0;
  1430. int error;
  1431. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  1432. ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
  1433. (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
  1434. oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
  1435. new_endoff = offset + len;
  1436. trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1437. unwritten, oinfo);
  1438. /*
  1439. * For the initial lookup, look for and exact match or the left-adjacent
  1440. * record for our insertion point. This will also give us the record for
  1441. * start block contiguity tests.
  1442. */
  1443. error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
  1444. &PREV, &i);
  1445. if (error)
  1446. goto done;
  1447. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1448. error = -EFSCORRUPTED;
  1449. goto done;
  1450. }
  1451. ASSERT(PREV.rm_offset <= offset);
  1452. ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
  1453. ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
  1454. newext = ~oldext & XFS_RMAP_UNWRITTEN;
  1455. /*
  1456. * Set flags determining what part of the previous oldext allocation
  1457. * extent is being replaced by a newext allocation.
  1458. */
  1459. if (PREV.rm_offset == offset)
  1460. state |= RMAP_LEFT_FILLING;
  1461. if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
  1462. state |= RMAP_RIGHT_FILLING;
  1463. /* Is there a left record that abuts our range? */
  1464. error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
  1465. &LEFT, &i);
  1466. if (error)
  1467. goto done;
  1468. if (i) {
  1469. state |= RMAP_LEFT_VALID;
  1470. if (XFS_IS_CORRUPT(mp,
  1471. LEFT.rm_startblock + LEFT.rm_blockcount >
  1472. bno)) {
  1473. error = -EFSCORRUPTED;
  1474. goto done;
  1475. }
  1476. if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
  1477. state |= RMAP_LEFT_CONTIG;
  1478. }
  1479. /* Is there a right record that abuts our range? */
  1480. error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
  1481. newext, &i);
  1482. if (error)
  1483. goto done;
  1484. if (i) {
  1485. state |= RMAP_RIGHT_VALID;
  1486. error = xfs_rmap_get_rec(cur, &RIGHT, &i);
  1487. if (error)
  1488. goto done;
  1489. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1490. error = -EFSCORRUPTED;
  1491. goto done;
  1492. }
  1493. if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
  1494. error = -EFSCORRUPTED;
  1495. goto done;
  1496. }
  1497. trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
  1498. cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
  1499. RIGHT.rm_blockcount, RIGHT.rm_owner,
  1500. RIGHT.rm_offset, RIGHT.rm_flags);
  1501. if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
  1502. state |= RMAP_RIGHT_CONTIG;
  1503. }
  1504. /* check that left + prev + right is not too long */
  1505. if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1506. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
  1507. (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1508. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
  1509. (unsigned long)LEFT.rm_blockcount + len +
  1510. RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
  1511. state &= ~RMAP_RIGHT_CONTIG;
  1512. trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
  1513. _RET_IP_);
  1514. /*
  1515. * Switch out based on the FILLING and CONTIG state bits.
  1516. */
  1517. switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1518. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
  1519. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
  1520. RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1521. /*
  1522. * Setting all of a previous oldext extent to newext.
  1523. * The left and right neighbors are both contiguous with new.
  1524. */
  1525. error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
  1526. RIGHT.rm_blockcount, RIGHT.rm_owner,
  1527. RIGHT.rm_offset, RIGHT.rm_flags);
  1528. if (error)
  1529. goto done;
  1530. error = xfs_rmap_delete(cur, PREV.rm_startblock,
  1531. PREV.rm_blockcount, PREV.rm_owner,
  1532. PREV.rm_offset, PREV.rm_flags);
  1533. if (error)
  1534. goto done;
  1535. NEW = LEFT;
  1536. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1537. NEW.rm_blockcount, NEW.rm_owner,
  1538. NEW.rm_offset, NEW.rm_flags, &i);
  1539. if (error)
  1540. goto done;
  1541. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1542. error = -EFSCORRUPTED;
  1543. goto done;
  1544. }
  1545. NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
  1546. error = xfs_rmap_update(cur, &NEW);
  1547. if (error)
  1548. goto done;
  1549. break;
  1550. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
  1551. /*
  1552. * Setting all of a previous oldext extent to newext.
  1553. * The left neighbor is contiguous, the right is not.
  1554. */
  1555. error = xfs_rmap_delete(cur, PREV.rm_startblock,
  1556. PREV.rm_blockcount, PREV.rm_owner,
  1557. PREV.rm_offset, PREV.rm_flags);
  1558. if (error)
  1559. goto done;
  1560. NEW = LEFT;
  1561. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1562. NEW.rm_blockcount, NEW.rm_owner,
  1563. NEW.rm_offset, NEW.rm_flags, &i);
  1564. if (error)
  1565. goto done;
  1566. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1567. error = -EFSCORRUPTED;
  1568. goto done;
  1569. }
  1570. NEW.rm_blockcount += PREV.rm_blockcount;
  1571. error = xfs_rmap_update(cur, &NEW);
  1572. if (error)
  1573. goto done;
  1574. break;
  1575. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1576. /*
  1577. * Setting all of a previous oldext extent to newext.
  1578. * The right neighbor is contiguous, the left is not.
  1579. */
  1580. error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
  1581. RIGHT.rm_blockcount, RIGHT.rm_owner,
  1582. RIGHT.rm_offset, RIGHT.rm_flags);
  1583. if (error)
  1584. goto done;
  1585. NEW = PREV;
  1586. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1587. NEW.rm_blockcount, NEW.rm_owner,
  1588. NEW.rm_offset, NEW.rm_flags, &i);
  1589. if (error)
  1590. goto done;
  1591. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1592. error = -EFSCORRUPTED;
  1593. goto done;
  1594. }
  1595. NEW.rm_blockcount += RIGHT.rm_blockcount;
  1596. NEW.rm_flags = RIGHT.rm_flags;
  1597. error = xfs_rmap_update(cur, &NEW);
  1598. if (error)
  1599. goto done;
  1600. break;
  1601. case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
  1602. /*
  1603. * Setting all of a previous oldext extent to newext.
  1604. * Neither the left nor right neighbors are contiguous with
  1605. * the new one.
  1606. */
  1607. NEW = PREV;
  1608. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1609. NEW.rm_blockcount, NEW.rm_owner,
  1610. NEW.rm_offset, NEW.rm_flags, &i);
  1611. if (error)
  1612. goto done;
  1613. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1614. error = -EFSCORRUPTED;
  1615. goto done;
  1616. }
  1617. NEW.rm_flags = newext;
  1618. error = xfs_rmap_update(cur, &NEW);
  1619. if (error)
  1620. goto done;
  1621. break;
  1622. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
  1623. /*
  1624. * Setting the first part of a previous oldext extent to newext.
  1625. * The left neighbor is contiguous.
  1626. */
  1627. NEW = PREV;
  1628. error = xfs_rmap_delete(cur, NEW.rm_startblock,
  1629. NEW.rm_blockcount, NEW.rm_owner,
  1630. NEW.rm_offset, NEW.rm_flags);
  1631. if (error)
  1632. goto done;
  1633. NEW.rm_offset += len;
  1634. NEW.rm_startblock += len;
  1635. NEW.rm_blockcount -= len;
  1636. error = xfs_rmap_insert(cur, NEW.rm_startblock,
  1637. NEW.rm_blockcount, NEW.rm_owner,
  1638. NEW.rm_offset, NEW.rm_flags);
  1639. if (error)
  1640. goto done;
  1641. NEW = LEFT;
  1642. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1643. NEW.rm_blockcount, NEW.rm_owner,
  1644. NEW.rm_offset, NEW.rm_flags, &i);
  1645. if (error)
  1646. goto done;
  1647. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1648. error = -EFSCORRUPTED;
  1649. goto done;
  1650. }
  1651. NEW.rm_blockcount += len;
  1652. error = xfs_rmap_update(cur, &NEW);
  1653. if (error)
  1654. goto done;
  1655. break;
  1656. case RMAP_LEFT_FILLING:
  1657. /*
  1658. * Setting the first part of a previous oldext extent to newext.
  1659. * The left neighbor is not contiguous.
  1660. */
  1661. NEW = PREV;
  1662. error = xfs_rmap_delete(cur, NEW.rm_startblock,
  1663. NEW.rm_blockcount, NEW.rm_owner,
  1664. NEW.rm_offset, NEW.rm_flags);
  1665. if (error)
  1666. goto done;
  1667. NEW.rm_offset += len;
  1668. NEW.rm_startblock += len;
  1669. NEW.rm_blockcount -= len;
  1670. error = xfs_rmap_insert(cur, NEW.rm_startblock,
  1671. NEW.rm_blockcount, NEW.rm_owner,
  1672. NEW.rm_offset, NEW.rm_flags);
  1673. if (error)
  1674. goto done;
  1675. error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
  1676. if (error)
  1677. goto done;
  1678. break;
  1679. case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
  1680. /*
  1681. * Setting the last part of a previous oldext extent to newext.
  1682. * The right neighbor is contiguous with the new allocation.
  1683. */
  1684. NEW = PREV;
  1685. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1686. NEW.rm_blockcount, NEW.rm_owner,
  1687. NEW.rm_offset, NEW.rm_flags, &i);
  1688. if (error)
  1689. goto done;
  1690. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1691. error = -EFSCORRUPTED;
  1692. goto done;
  1693. }
  1694. NEW.rm_blockcount = offset - NEW.rm_offset;
  1695. error = xfs_rmap_update(cur, &NEW);
  1696. if (error)
  1697. goto done;
  1698. NEW = RIGHT;
  1699. error = xfs_rmap_delete(cur, NEW.rm_startblock,
  1700. NEW.rm_blockcount, NEW.rm_owner,
  1701. NEW.rm_offset, NEW.rm_flags);
  1702. if (error)
  1703. goto done;
  1704. NEW.rm_offset = offset;
  1705. NEW.rm_startblock = bno;
  1706. NEW.rm_blockcount += len;
  1707. error = xfs_rmap_insert(cur, NEW.rm_startblock,
  1708. NEW.rm_blockcount, NEW.rm_owner,
  1709. NEW.rm_offset, NEW.rm_flags);
  1710. if (error)
  1711. goto done;
  1712. break;
  1713. case RMAP_RIGHT_FILLING:
  1714. /*
  1715. * Setting the last part of a previous oldext extent to newext.
  1716. * The right neighbor is not contiguous.
  1717. */
  1718. NEW = PREV;
  1719. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1720. NEW.rm_blockcount, NEW.rm_owner,
  1721. NEW.rm_offset, NEW.rm_flags, &i);
  1722. if (error)
  1723. goto done;
  1724. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1725. error = -EFSCORRUPTED;
  1726. goto done;
  1727. }
  1728. NEW.rm_blockcount -= len;
  1729. error = xfs_rmap_update(cur, &NEW);
  1730. if (error)
  1731. goto done;
  1732. error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
  1733. if (error)
  1734. goto done;
  1735. break;
  1736. case 0:
  1737. /*
  1738. * Setting the middle part of a previous oldext extent to
  1739. * newext. Contiguity is impossible here.
  1740. * One extent becomes three extents.
  1741. */
  1742. /* new right extent - oldext */
  1743. NEW.rm_startblock = bno + len;
  1744. NEW.rm_owner = owner;
  1745. NEW.rm_offset = new_endoff;
  1746. NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
  1747. new_endoff;
  1748. NEW.rm_flags = PREV.rm_flags;
  1749. error = xfs_rmap_insert(cur, NEW.rm_startblock,
  1750. NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
  1751. NEW.rm_flags);
  1752. if (error)
  1753. goto done;
  1754. /* new left extent - oldext */
  1755. NEW = PREV;
  1756. error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
  1757. NEW.rm_blockcount, NEW.rm_owner,
  1758. NEW.rm_offset, NEW.rm_flags, &i);
  1759. if (error)
  1760. goto done;
  1761. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1762. error = -EFSCORRUPTED;
  1763. goto done;
  1764. }
  1765. NEW.rm_blockcount = offset - NEW.rm_offset;
  1766. error = xfs_rmap_update(cur, &NEW);
  1767. if (error)
  1768. goto done;
  1769. /* new middle extent - newext */
  1770. NEW.rm_startblock = bno;
  1771. NEW.rm_blockcount = len;
  1772. NEW.rm_owner = owner;
  1773. NEW.rm_offset = offset;
  1774. NEW.rm_flags = newext;
  1775. error = xfs_rmap_insert(cur, NEW.rm_startblock,
  1776. NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
  1777. NEW.rm_flags);
  1778. if (error)
  1779. goto done;
  1780. break;
  1781. case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1782. case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1783. case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
  1784. case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
  1785. case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
  1786. case RMAP_LEFT_CONTIG:
  1787. case RMAP_RIGHT_CONTIG:
  1788. /*
  1789. * These cases are all impossible.
  1790. */
  1791. ASSERT(0);
  1792. }
  1793. trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1794. unwritten, oinfo);
  1795. done:
  1796. if (error)
  1797. trace_xfs_rmap_convert_error(cur->bc_mp,
  1798. cur->bc_ag.pag->pag_agno, error, _RET_IP_);
  1799. return error;
  1800. }
  1801. #undef NEW
  1802. #undef LEFT
  1803. #undef RIGHT
  1804. #undef PREV
  1805. /*
  1806. * Find an extent in the rmap btree and unmap it. For rmap extent types that
  1807. * can overlap (data fork rmaps on reflink filesystems) we must be careful
  1808. * that the prev/next records in the btree might belong to another owner.
  1809. * Therefore we must use delete+insert to alter any of the key fields.
  1810. *
  1811. * For every other situation there can only be one owner for a given extent,
  1812. * so we can call the regular _free function.
  1813. */
  1814. STATIC int
  1815. xfs_rmap_unmap_shared(
  1816. struct xfs_btree_cur *cur,
  1817. xfs_agblock_t bno,
  1818. xfs_extlen_t len,
  1819. bool unwritten,
  1820. const struct xfs_owner_info *oinfo)
  1821. {
  1822. struct xfs_mount *mp = cur->bc_mp;
  1823. struct xfs_rmap_irec ltrec;
  1824. uint64_t ltoff;
  1825. int error = 0;
  1826. int i;
  1827. uint64_t owner;
  1828. uint64_t offset;
  1829. unsigned int flags;
  1830. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  1831. if (unwritten)
  1832. flags |= XFS_RMAP_UNWRITTEN;
  1833. trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1834. unwritten, oinfo);
  1835. /*
  1836. * We should always have a left record because there's a static record
  1837. * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
  1838. * will not ever be removed from the tree.
  1839. */
  1840. error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
  1841. &ltrec, &i);
  1842. if (error)
  1843. goto out_error;
  1844. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1845. error = -EFSCORRUPTED;
  1846. goto out_error;
  1847. }
  1848. ltoff = ltrec.rm_offset;
  1849. /* Make sure the extent we found covers the entire freeing range. */
  1850. if (XFS_IS_CORRUPT(mp,
  1851. ltrec.rm_startblock > bno ||
  1852. ltrec.rm_startblock + ltrec.rm_blockcount <
  1853. bno + len)) {
  1854. error = -EFSCORRUPTED;
  1855. goto out_error;
  1856. }
  1857. /* Make sure the owner matches what we expect to find in the tree. */
  1858. if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
  1859. error = -EFSCORRUPTED;
  1860. goto out_error;
  1861. }
  1862. /* Make sure the unwritten flag matches. */
  1863. if (XFS_IS_CORRUPT(mp,
  1864. (flags & XFS_RMAP_UNWRITTEN) !=
  1865. (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
  1866. error = -EFSCORRUPTED;
  1867. goto out_error;
  1868. }
  1869. /* Check the offset. */
  1870. if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
  1871. error = -EFSCORRUPTED;
  1872. goto out_error;
  1873. }
  1874. if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
  1875. error = -EFSCORRUPTED;
  1876. goto out_error;
  1877. }
  1878. if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
  1879. /* Exact match, simply remove the record from rmap tree. */
  1880. error = xfs_rmap_delete(cur, ltrec.rm_startblock,
  1881. ltrec.rm_blockcount, ltrec.rm_owner,
  1882. ltrec.rm_offset, ltrec.rm_flags);
  1883. if (error)
  1884. goto out_error;
  1885. } else if (ltrec.rm_startblock == bno) {
  1886. /*
  1887. * Overlap left hand side of extent: move the start, trim the
  1888. * length and update the current record.
  1889. *
  1890. * ltbno ltlen
  1891. * Orig: |oooooooooooooooooooo|
  1892. * Freeing: |fffffffff|
  1893. * Result: |rrrrrrrrrr|
  1894. * bno len
  1895. */
  1896. /* Delete prev rmap. */
  1897. error = xfs_rmap_delete(cur, ltrec.rm_startblock,
  1898. ltrec.rm_blockcount, ltrec.rm_owner,
  1899. ltrec.rm_offset, ltrec.rm_flags);
  1900. if (error)
  1901. goto out_error;
  1902. /* Add an rmap at the new offset. */
  1903. ltrec.rm_startblock += len;
  1904. ltrec.rm_blockcount -= len;
  1905. ltrec.rm_offset += len;
  1906. error = xfs_rmap_insert(cur, ltrec.rm_startblock,
  1907. ltrec.rm_blockcount, ltrec.rm_owner,
  1908. ltrec.rm_offset, ltrec.rm_flags);
  1909. if (error)
  1910. goto out_error;
  1911. } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
  1912. /*
  1913. * Overlap right hand side of extent: trim the length and
  1914. * update the current record.
  1915. *
  1916. * ltbno ltlen
  1917. * Orig: |oooooooooooooooooooo|
  1918. * Freeing: |fffffffff|
  1919. * Result: |rrrrrrrrrr|
  1920. * bno len
  1921. */
  1922. error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
  1923. ltrec.rm_blockcount, ltrec.rm_owner,
  1924. ltrec.rm_offset, ltrec.rm_flags, &i);
  1925. if (error)
  1926. goto out_error;
  1927. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1928. error = -EFSCORRUPTED;
  1929. goto out_error;
  1930. }
  1931. ltrec.rm_blockcount -= len;
  1932. error = xfs_rmap_update(cur, &ltrec);
  1933. if (error)
  1934. goto out_error;
  1935. } else {
  1936. /*
  1937. * Overlap middle of extent: trim the length of the existing
  1938. * record to the length of the new left-extent size, increment
  1939. * the insertion position so we can insert a new record
  1940. * containing the remaining right-extent space.
  1941. *
  1942. * ltbno ltlen
  1943. * Orig: |oooooooooooooooooooo|
  1944. * Freeing: |fffffffff|
  1945. * Result: |rrrrr| |rrrr|
  1946. * bno len
  1947. */
  1948. xfs_extlen_t orig_len = ltrec.rm_blockcount;
  1949. /* Shrink the left side of the rmap */
  1950. error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
  1951. ltrec.rm_blockcount, ltrec.rm_owner,
  1952. ltrec.rm_offset, ltrec.rm_flags, &i);
  1953. if (error)
  1954. goto out_error;
  1955. if (XFS_IS_CORRUPT(mp, i != 1)) {
  1956. error = -EFSCORRUPTED;
  1957. goto out_error;
  1958. }
  1959. ltrec.rm_blockcount = bno - ltrec.rm_startblock;
  1960. error = xfs_rmap_update(cur, &ltrec);
  1961. if (error)
  1962. goto out_error;
  1963. /* Add an rmap at the new offset */
  1964. error = xfs_rmap_insert(cur, bno + len,
  1965. orig_len - len - ltrec.rm_blockcount,
  1966. ltrec.rm_owner, offset + len,
  1967. ltrec.rm_flags);
  1968. if (error)
  1969. goto out_error;
  1970. }
  1971. trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  1972. unwritten, oinfo);
  1973. out_error:
  1974. if (error)
  1975. trace_xfs_rmap_unmap_error(cur->bc_mp,
  1976. cur->bc_ag.pag->pag_agno, error, _RET_IP_);
  1977. return error;
  1978. }
  1979. /*
  1980. * Find an extent in the rmap btree and map it. For rmap extent types that
  1981. * can overlap (data fork rmaps on reflink filesystems) we must be careful
  1982. * that the prev/next records in the btree might belong to another owner.
  1983. * Therefore we must use delete+insert to alter any of the key fields.
  1984. *
  1985. * For every other situation there can only be one owner for a given extent,
  1986. * so we can call the regular _alloc function.
  1987. */
  1988. STATIC int
  1989. xfs_rmap_map_shared(
  1990. struct xfs_btree_cur *cur,
  1991. xfs_agblock_t bno,
  1992. xfs_extlen_t len,
  1993. bool unwritten,
  1994. const struct xfs_owner_info *oinfo)
  1995. {
  1996. struct xfs_mount *mp = cur->bc_mp;
  1997. struct xfs_rmap_irec ltrec;
  1998. struct xfs_rmap_irec gtrec;
  1999. int have_gt;
  2000. int have_lt;
  2001. int error = 0;
  2002. int i;
  2003. uint64_t owner;
  2004. uint64_t offset;
  2005. unsigned int flags = 0;
  2006. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  2007. if (unwritten)
  2008. flags |= XFS_RMAP_UNWRITTEN;
  2009. trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
  2010. unwritten, oinfo);
  2011. /* Is there a left record that abuts our range? */
  2012. error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
  2013. &ltrec, &have_lt);
  2014. if (error)
  2015. goto out_error;
  2016. if (have_lt &&
  2017. !xfs_rmap_is_mergeable(&ltrec, owner, flags))
  2018. have_lt = 0;
  2019. /* Is there a right record that abuts our range? */
  2020. error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
  2021. flags, &have_gt);
  2022. if (error)
  2023. goto out_error;
  2024. if (have_gt) {
  2025. error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
  2026. if (error)
  2027. goto out_error;
  2028. if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
  2029. error = -EFSCORRUPTED;
  2030. goto out_error;
  2031. }
  2032. trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
  2033. cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
  2034. gtrec.rm_blockcount, gtrec.rm_owner,
  2035. gtrec.rm_offset, gtrec.rm_flags);
  2036. if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
  2037. have_gt = 0;
  2038. }
  2039. if (have_lt &&
  2040. ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
  2041. ltrec.rm_offset + ltrec.rm_blockcount == offset) {
  2042. /*
  2043. * Left edge contiguous, merge into left record.
  2044. *
  2045. * ltbno ltlen
  2046. * orig: |ooooooooo|
  2047. * adding: |aaaaaaaaa|
  2048. * result: |rrrrrrrrrrrrrrrrrrr|
  2049. * bno len
  2050. */
  2051. ltrec.rm_blockcount += len;
  2052. if (have_gt &&
  2053. bno + len == gtrec.rm_startblock &&
  2054. offset + len == gtrec.rm_offset) {
  2055. /*
  2056. * Right edge also contiguous, delete right record
  2057. * and merge into left record.
  2058. *
  2059. * ltbno ltlen gtbno gtlen
  2060. * orig: |ooooooooo| |ooooooooo|
  2061. * adding: |aaaaaaaaa|
  2062. * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
  2063. */
  2064. ltrec.rm_blockcount += gtrec.rm_blockcount;
  2065. error = xfs_rmap_delete(cur, gtrec.rm_startblock,
  2066. gtrec.rm_blockcount, gtrec.rm_owner,
  2067. gtrec.rm_offset, gtrec.rm_flags);
  2068. if (error)
  2069. goto out_error;
  2070. }
  2071. /* Point the cursor back to the left record and update. */
  2072. error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
  2073. ltrec.rm_blockcount, ltrec.rm_owner,
  2074. ltrec.rm_offset, ltrec.rm_flags, &i);
  2075. if (error)
  2076. goto out_error;
  2077. if (XFS_IS_CORRUPT(mp, i != 1)) {
  2078. error = -EFSCORRUPTED;
  2079. goto out_error;
  2080. }
  2081. error = xfs_rmap_update(cur, &ltrec);
  2082. if (error)
  2083. goto out_error;
  2084. } else if (have_gt &&
  2085. bno + len == gtrec.rm_startblock &&
  2086. offset + len == gtrec.rm_offset) {
  2087. /*
  2088. * Right edge contiguous, merge into right record.
  2089. *
  2090. * gtbno gtlen
  2091. * Orig: |ooooooooo|
  2092. * adding: |aaaaaaaaa|
  2093. * Result: |rrrrrrrrrrrrrrrrrrr|
  2094. * bno len
  2095. */
  2096. /* Delete the old record. */
  2097. error = xfs_rmap_delete(cur, gtrec.rm_startblock,
  2098. gtrec.rm_blockcount, gtrec.rm_owner,
  2099. gtrec.rm_offset, gtrec.rm_flags);
  2100. if (error)
  2101. goto out_error;
  2102. /* Move the start and re-add it. */
  2103. gtrec.rm_startblock = bno;
  2104. gtrec.rm_blockcount += len;
  2105. gtrec.rm_offset = offset;
  2106. error = xfs_rmap_insert(cur, gtrec.rm_startblock,
  2107. gtrec.rm_blockcount, gtrec.rm_owner,
  2108. gtrec.rm_offset, gtrec.rm_flags);
  2109. if (error)
  2110. goto out_error;
  2111. } else {
  2112. /*
  2113. * No contiguous edge with identical owner, insert
  2114. * new record at current cursor position.
  2115. */
  2116. error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
  2117. if (error)
  2118. goto out_error;
  2119. }
  2120. trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
  2121. unwritten, oinfo);
  2122. out_error:
  2123. if (error)
  2124. trace_xfs_rmap_map_error(cur->bc_mp,
  2125. cur->bc_ag.pag->pag_agno, error, _RET_IP_);
  2126. return error;
  2127. }
  2128. /* Insert a raw rmap into the rmapbt. */
  2129. int
  2130. xfs_rmap_map_raw(
  2131. struct xfs_btree_cur *cur,
  2132. struct xfs_rmap_irec *rmap)
  2133. {
  2134. struct xfs_owner_info oinfo;
  2135. oinfo.oi_owner = rmap->rm_owner;
  2136. oinfo.oi_offset = rmap->rm_offset;
  2137. oinfo.oi_flags = 0;
  2138. if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
  2139. oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
  2140. if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
  2141. oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
  2142. if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
  2143. return xfs_rmap_map(cur, rmap->rm_startblock,
  2144. rmap->rm_blockcount,
  2145. rmap->rm_flags & XFS_RMAP_UNWRITTEN,
  2146. &oinfo);
  2147. return xfs_rmap_map_shared(cur, rmap->rm_startblock,
  2148. rmap->rm_blockcount,
  2149. rmap->rm_flags & XFS_RMAP_UNWRITTEN,
  2150. &oinfo);
  2151. }
  2152. struct xfs_rmap_query_range_info {
  2153. xfs_rmap_query_range_fn fn;
  2154. void *priv;
  2155. };
  2156. /* Format btree record and pass to our callback. */
  2157. STATIC int
  2158. xfs_rmap_query_range_helper(
  2159. struct xfs_btree_cur *cur,
  2160. const union xfs_btree_rec *rec,
  2161. void *priv)
  2162. {
  2163. struct xfs_rmap_query_range_info *query = priv;
  2164. struct xfs_rmap_irec irec;
  2165. int error;
  2166. error = xfs_rmap_btrec_to_irec(rec, &irec);
  2167. if (error)
  2168. return error;
  2169. return query->fn(cur, &irec, query->priv);
  2170. }
  2171. /* Find all rmaps between two keys. */
  2172. int
  2173. xfs_rmap_query_range(
  2174. struct xfs_btree_cur *cur,
  2175. const struct xfs_rmap_irec *low_rec,
  2176. const struct xfs_rmap_irec *high_rec,
  2177. xfs_rmap_query_range_fn fn,
  2178. void *priv)
  2179. {
  2180. union xfs_btree_irec low_brec;
  2181. union xfs_btree_irec high_brec;
  2182. struct xfs_rmap_query_range_info query;
  2183. low_brec.r = *low_rec;
  2184. high_brec.r = *high_rec;
  2185. query.priv = priv;
  2186. query.fn = fn;
  2187. return xfs_btree_query_range(cur, &low_brec, &high_brec,
  2188. xfs_rmap_query_range_helper, &query);
  2189. }
  2190. /* Find all rmaps. */
  2191. int
  2192. xfs_rmap_query_all(
  2193. struct xfs_btree_cur *cur,
  2194. xfs_rmap_query_range_fn fn,
  2195. void *priv)
  2196. {
  2197. struct xfs_rmap_query_range_info query;
  2198. query.priv = priv;
  2199. query.fn = fn;
  2200. return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
  2201. }
  2202. /* Clean up after calling xfs_rmap_finish_one. */
  2203. void
  2204. xfs_rmap_finish_one_cleanup(
  2205. struct xfs_trans *tp,
  2206. struct xfs_btree_cur *rcur,
  2207. int error)
  2208. {
  2209. struct xfs_buf *agbp;
  2210. if (rcur == NULL)
  2211. return;
  2212. agbp = rcur->bc_ag.agbp;
  2213. xfs_btree_del_cursor(rcur, error);
  2214. if (error)
  2215. xfs_trans_brelse(tp, agbp);
  2216. }
  2217. /*
  2218. * Process one of the deferred rmap operations. We pass back the
  2219. * btree cursor to maintain our lock on the rmapbt between calls.
  2220. * This saves time and eliminates a buffer deadlock between the
  2221. * superblock and the AGF because we'll always grab them in the same
  2222. * order.
  2223. */
  2224. int
  2225. xfs_rmap_finish_one(
  2226. struct xfs_trans *tp,
  2227. enum xfs_rmap_intent_type type,
  2228. uint64_t owner,
  2229. int whichfork,
  2230. xfs_fileoff_t startoff,
  2231. xfs_fsblock_t startblock,
  2232. xfs_filblks_t blockcount,
  2233. xfs_exntst_t state,
  2234. struct xfs_btree_cur **pcur)
  2235. {
  2236. struct xfs_mount *mp = tp->t_mountp;
  2237. struct xfs_perag *pag;
  2238. struct xfs_btree_cur *rcur;
  2239. struct xfs_buf *agbp = NULL;
  2240. int error = 0;
  2241. struct xfs_owner_info oinfo;
  2242. xfs_agblock_t bno;
  2243. bool unwritten;
  2244. pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
  2245. bno = XFS_FSB_TO_AGBNO(mp, startblock);
  2246. trace_xfs_rmap_deferred(mp, pag->pag_agno, type, bno, owner, whichfork,
  2247. startoff, blockcount, state);
  2248. if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE)) {
  2249. error = -EIO;
  2250. goto out_drop;
  2251. }
  2252. /*
  2253. * If we haven't gotten a cursor or the cursor AG doesn't match
  2254. * the startblock, get one now.
  2255. */
  2256. rcur = *pcur;
  2257. if (rcur != NULL && rcur->bc_ag.pag != pag) {
  2258. xfs_rmap_finish_one_cleanup(tp, rcur, 0);
  2259. rcur = NULL;
  2260. *pcur = NULL;
  2261. }
  2262. if (rcur == NULL) {
  2263. /*
  2264. * Refresh the freelist before we start changing the
  2265. * rmapbt, because a shape change could cause us to
  2266. * allocate blocks.
  2267. */
  2268. error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
  2269. if (error)
  2270. goto out_drop;
  2271. if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
  2272. error = -EFSCORRUPTED;
  2273. goto out_drop;
  2274. }
  2275. rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
  2276. }
  2277. *pcur = rcur;
  2278. xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
  2279. unwritten = state == XFS_EXT_UNWRITTEN;
  2280. bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
  2281. switch (type) {
  2282. case XFS_RMAP_ALLOC:
  2283. case XFS_RMAP_MAP:
  2284. error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
  2285. break;
  2286. case XFS_RMAP_MAP_SHARED:
  2287. error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
  2288. &oinfo);
  2289. break;
  2290. case XFS_RMAP_FREE:
  2291. case XFS_RMAP_UNMAP:
  2292. error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
  2293. &oinfo);
  2294. break;
  2295. case XFS_RMAP_UNMAP_SHARED:
  2296. error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
  2297. &oinfo);
  2298. break;
  2299. case XFS_RMAP_CONVERT:
  2300. error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
  2301. &oinfo);
  2302. break;
  2303. case XFS_RMAP_CONVERT_SHARED:
  2304. error = xfs_rmap_convert_shared(rcur, bno, blockcount,
  2305. !unwritten, &oinfo);
  2306. break;
  2307. default:
  2308. ASSERT(0);
  2309. error = -EFSCORRUPTED;
  2310. }
  2311. out_drop:
  2312. xfs_perag_put(pag);
  2313. return error;
  2314. }
  2315. /*
  2316. * Don't defer an rmap if we aren't an rmap filesystem.
  2317. */
  2318. static bool
  2319. xfs_rmap_update_is_needed(
  2320. struct xfs_mount *mp,
  2321. int whichfork)
  2322. {
  2323. return xfs_has_rmapbt(mp) && whichfork != XFS_COW_FORK;
  2324. }
  2325. /*
  2326. * Record a rmap intent; the list is kept sorted first by AG and then by
  2327. * increasing age.
  2328. */
  2329. static void
  2330. __xfs_rmap_add(
  2331. struct xfs_trans *tp,
  2332. enum xfs_rmap_intent_type type,
  2333. uint64_t owner,
  2334. int whichfork,
  2335. struct xfs_bmbt_irec *bmap)
  2336. {
  2337. struct xfs_rmap_intent *ri;
  2338. trace_xfs_rmap_defer(tp->t_mountp,
  2339. XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
  2340. type,
  2341. XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
  2342. owner, whichfork,
  2343. bmap->br_startoff,
  2344. bmap->br_blockcount,
  2345. bmap->br_state);
  2346. ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
  2347. INIT_LIST_HEAD(&ri->ri_list);
  2348. ri->ri_type = type;
  2349. ri->ri_owner = owner;
  2350. ri->ri_whichfork = whichfork;
  2351. ri->ri_bmap = *bmap;
  2352. xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
  2353. }
  2354. /* Map an extent into a file. */
  2355. void
  2356. xfs_rmap_map_extent(
  2357. struct xfs_trans *tp,
  2358. struct xfs_inode *ip,
  2359. int whichfork,
  2360. struct xfs_bmbt_irec *PREV)
  2361. {
  2362. enum xfs_rmap_intent_type type = XFS_RMAP_MAP;
  2363. if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
  2364. return;
  2365. if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
  2366. type = XFS_RMAP_MAP_SHARED;
  2367. __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
  2368. }
  2369. /* Unmap an extent out of a file. */
  2370. void
  2371. xfs_rmap_unmap_extent(
  2372. struct xfs_trans *tp,
  2373. struct xfs_inode *ip,
  2374. int whichfork,
  2375. struct xfs_bmbt_irec *PREV)
  2376. {
  2377. enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP;
  2378. if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
  2379. return;
  2380. if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
  2381. type = XFS_RMAP_UNMAP_SHARED;
  2382. __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
  2383. }
  2384. /*
  2385. * Convert a data fork extent from unwritten to real or vice versa.
  2386. *
  2387. * Note that tp can be NULL here as no transaction is used for COW fork
  2388. * unwritten conversion.
  2389. */
  2390. void
  2391. xfs_rmap_convert_extent(
  2392. struct xfs_mount *mp,
  2393. struct xfs_trans *tp,
  2394. struct xfs_inode *ip,
  2395. int whichfork,
  2396. struct xfs_bmbt_irec *PREV)
  2397. {
  2398. enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT;
  2399. if (!xfs_rmap_update_is_needed(mp, whichfork))
  2400. return;
  2401. if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
  2402. type = XFS_RMAP_CONVERT_SHARED;
  2403. __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
  2404. }
  2405. /* Schedule the creation of an rmap for non-file data. */
  2406. void
  2407. xfs_rmap_alloc_extent(
  2408. struct xfs_trans *tp,
  2409. xfs_agnumber_t agno,
  2410. xfs_agblock_t bno,
  2411. xfs_extlen_t len,
  2412. uint64_t owner)
  2413. {
  2414. struct xfs_bmbt_irec bmap;
  2415. if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
  2416. return;
  2417. bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
  2418. bmap.br_blockcount = len;
  2419. bmap.br_startoff = 0;
  2420. bmap.br_state = XFS_EXT_NORM;
  2421. __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap);
  2422. }
  2423. /* Schedule the deletion of an rmap for non-file data. */
  2424. void
  2425. xfs_rmap_free_extent(
  2426. struct xfs_trans *tp,
  2427. xfs_agnumber_t agno,
  2428. xfs_agblock_t bno,
  2429. xfs_extlen_t len,
  2430. uint64_t owner)
  2431. {
  2432. struct xfs_bmbt_irec bmap;
  2433. if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
  2434. return;
  2435. bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
  2436. bmap.br_blockcount = len;
  2437. bmap.br_startoff = 0;
  2438. bmap.br_state = XFS_EXT_NORM;
  2439. __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap);
  2440. }
  2441. /* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */
  2442. int
  2443. xfs_rmap_compare(
  2444. const struct xfs_rmap_irec *a,
  2445. const struct xfs_rmap_irec *b)
  2446. {
  2447. __u64 oa;
  2448. __u64 ob;
  2449. oa = xfs_rmap_irec_offset_pack(a);
  2450. ob = xfs_rmap_irec_offset_pack(b);
  2451. if (a->rm_startblock < b->rm_startblock)
  2452. return -1;
  2453. else if (a->rm_startblock > b->rm_startblock)
  2454. return 1;
  2455. else if (a->rm_owner < b->rm_owner)
  2456. return -1;
  2457. else if (a->rm_owner > b->rm_owner)
  2458. return 1;
  2459. else if (oa < ob)
  2460. return -1;
  2461. else if (oa > ob)
  2462. return 1;
  2463. else
  2464. return 0;
  2465. }
  2466. /* Is there a record covering a given extent? */
  2467. int
  2468. xfs_rmap_has_record(
  2469. struct xfs_btree_cur *cur,
  2470. xfs_agblock_t bno,
  2471. xfs_extlen_t len,
  2472. bool *exists)
  2473. {
  2474. union xfs_btree_irec low;
  2475. union xfs_btree_irec high;
  2476. memset(&low, 0, sizeof(low));
  2477. low.r.rm_startblock = bno;
  2478. memset(&high, 0xFF, sizeof(high));
  2479. high.r.rm_startblock = bno + len - 1;
  2480. return xfs_btree_has_record(cur, &low, &high, exists);
  2481. }
  2482. /*
  2483. * Is there a record for this owner completely covering a given physical
  2484. * extent? If so, *has_rmap will be set to true. If there is no record
  2485. * or the record only covers part of the range, we set *has_rmap to false.
  2486. * This function doesn't perform range lookups or offset checks, so it is
  2487. * not suitable for checking data fork blocks.
  2488. */
  2489. int
  2490. xfs_rmap_record_exists(
  2491. struct xfs_btree_cur *cur,
  2492. xfs_agblock_t bno,
  2493. xfs_extlen_t len,
  2494. const struct xfs_owner_info *oinfo,
  2495. bool *has_rmap)
  2496. {
  2497. uint64_t owner;
  2498. uint64_t offset;
  2499. unsigned int flags;
  2500. int has_record;
  2501. struct xfs_rmap_irec irec;
  2502. int error;
  2503. xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
  2504. ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) ||
  2505. (flags & XFS_RMAP_BMBT_BLOCK));
  2506. error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &irec,
  2507. &has_record);
  2508. if (error)
  2509. return error;
  2510. if (!has_record) {
  2511. *has_rmap = false;
  2512. return 0;
  2513. }
  2514. *has_rmap = (irec.rm_owner == owner && irec.rm_startblock <= bno &&
  2515. irec.rm_startblock + irec.rm_blockcount >= bno + len);
  2516. return 0;
  2517. }
  2518. struct xfs_rmap_key_state {
  2519. uint64_t owner;
  2520. uint64_t offset;
  2521. unsigned int flags;
  2522. };
  2523. /* For each rmap given, figure out if it doesn't match the key we want. */
  2524. STATIC int
  2525. xfs_rmap_has_other_keys_helper(
  2526. struct xfs_btree_cur *cur,
  2527. const struct xfs_rmap_irec *rec,
  2528. void *priv)
  2529. {
  2530. struct xfs_rmap_key_state *rks = priv;
  2531. if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset &&
  2532. ((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags)
  2533. return 0;
  2534. return -ECANCELED;
  2535. }
  2536. /*
  2537. * Given an extent and some owner info, can we find records overlapping
  2538. * the extent whose owner info does not match the given owner?
  2539. */
  2540. int
  2541. xfs_rmap_has_other_keys(
  2542. struct xfs_btree_cur *cur,
  2543. xfs_agblock_t bno,
  2544. xfs_extlen_t len,
  2545. const struct xfs_owner_info *oinfo,
  2546. bool *has_rmap)
  2547. {
  2548. struct xfs_rmap_irec low = {0};
  2549. struct xfs_rmap_irec high;
  2550. struct xfs_rmap_key_state rks;
  2551. int error;
  2552. xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags);
  2553. *has_rmap = false;
  2554. low.rm_startblock = bno;
  2555. memset(&high, 0xFF, sizeof(high));
  2556. high.rm_startblock = bno + len - 1;
  2557. error = xfs_rmap_query_range(cur, &low, &high,
  2558. xfs_rmap_has_other_keys_helper, &rks);
  2559. if (error == -ECANCELED) {
  2560. *has_rmap = true;
  2561. return 0;
  2562. }
  2563. return error;
  2564. }
  2565. const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = {
  2566. .oi_owner = XFS_RMAP_OWN_NULL,
  2567. };
  2568. const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = {
  2569. .oi_owner = XFS_RMAP_OWN_UNKNOWN,
  2570. };
  2571. const struct xfs_owner_info XFS_RMAP_OINFO_FS = {
  2572. .oi_owner = XFS_RMAP_OWN_FS,
  2573. };
  2574. const struct xfs_owner_info XFS_RMAP_OINFO_LOG = {
  2575. .oi_owner = XFS_RMAP_OWN_LOG,
  2576. };
  2577. const struct xfs_owner_info XFS_RMAP_OINFO_AG = {
  2578. .oi_owner = XFS_RMAP_OWN_AG,
  2579. };
  2580. const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = {
  2581. .oi_owner = XFS_RMAP_OWN_INOBT,
  2582. };
  2583. const struct xfs_owner_info XFS_RMAP_OINFO_INODES = {
  2584. .oi_owner = XFS_RMAP_OWN_INODES,
  2585. };
  2586. const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
  2587. .oi_owner = XFS_RMAP_OWN_REFC,
  2588. };
  2589. const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
  2590. .oi_owner = XFS_RMAP_OWN_COW,
  2591. };
  2592. int __init
  2593. xfs_rmap_intent_init_cache(void)
  2594. {
  2595. xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
  2596. sizeof(struct xfs_rmap_intent),
  2597. 0, 0, NULL);
  2598. return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
  2599. }
  2600. void
  2601. xfs_rmap_intent_destroy_cache(void)
  2602. {
  2603. kmem_cache_destroy(xfs_rmap_intent_cache);
  2604. xfs_rmap_intent_cache = NULL;
  2605. }