xfs_rmap.c 63 KB

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