xfs_rmap.c 63 KB

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