xfs_rmap.c 66 KB

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