xfs_rmap.c 66 KB

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