xfs_rmap.c 79 KB

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