xfs_rtbitmap.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_bit.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_inode.h"
  15. #include "xfs_bmap.h"
  16. #include "xfs_bmap_btree.h"
  17. #include "xfs_trans_space.h"
  18. #include "xfs_trans.h"
  19. #include "xfs_rtalloc.h"
  20. #include "xfs_error.h"
  21. #include "xfs_rtbitmap.h"
  22. #include "xfs_health.h"
  23. /*
  24. * Realtime allocator bitmap functions shared with userspace.
  25. */
  26. /*
  27. * Real time buffers need verifiers to avoid runtime warnings during IO.
  28. * We don't have anything to verify, however, so these are just dummy
  29. * operations.
  30. */
  31. static void
  32. xfs_rtbuf_verify_read(
  33. struct xfs_buf *bp)
  34. {
  35. return;
  36. }
  37. static void
  38. xfs_rtbuf_verify_write(
  39. struct xfs_buf *bp)
  40. {
  41. return;
  42. }
  43. const struct xfs_buf_ops xfs_rtbuf_ops = {
  44. .name = "rtbuf",
  45. .verify_read = xfs_rtbuf_verify_read,
  46. .verify_write = xfs_rtbuf_verify_write,
  47. };
  48. /* Release cached rt bitmap and summary buffers. */
  49. void
  50. xfs_rtbuf_cache_relse(
  51. struct xfs_rtalloc_args *args)
  52. {
  53. if (args->rbmbp) {
  54. xfs_trans_brelse(args->tp, args->rbmbp);
  55. args->rbmbp = NULL;
  56. args->rbmoff = NULLFILEOFF;
  57. }
  58. if (args->sumbp) {
  59. xfs_trans_brelse(args->tp, args->sumbp);
  60. args->sumbp = NULL;
  61. args->sumoff = NULLFILEOFF;
  62. }
  63. }
  64. /*
  65. * Get a buffer for the bitmap or summary file block specified.
  66. * The buffer is returned read and locked.
  67. */
  68. static int
  69. xfs_rtbuf_get(
  70. struct xfs_rtalloc_args *args,
  71. xfs_fileoff_t block, /* block number in bitmap or summary */
  72. int issum) /* is summary not bitmap */
  73. {
  74. struct xfs_mount *mp = args->mp;
  75. struct xfs_buf **cbpp; /* cached block buffer */
  76. xfs_fileoff_t *coffp; /* cached block number */
  77. struct xfs_buf *bp; /* block buffer, result */
  78. struct xfs_inode *ip; /* bitmap or summary inode */
  79. struct xfs_bmbt_irec map;
  80. enum xfs_blft type;
  81. int nmap = 1;
  82. int error;
  83. if (issum) {
  84. cbpp = &args->sumbp;
  85. coffp = &args->sumoff;
  86. ip = mp->m_rsumip;
  87. type = XFS_BLFT_RTSUMMARY_BUF;
  88. } else {
  89. cbpp = &args->rbmbp;
  90. coffp = &args->rbmoff;
  91. ip = mp->m_rbmip;
  92. type = XFS_BLFT_RTBITMAP_BUF;
  93. }
  94. /*
  95. * If we have a cached buffer, and the block number matches, use that.
  96. */
  97. if (*cbpp && *coffp == block)
  98. return 0;
  99. /*
  100. * Otherwise we have to have to get the buffer. If there was an old
  101. * one, get rid of it first.
  102. */
  103. if (*cbpp) {
  104. xfs_trans_brelse(args->tp, *cbpp);
  105. *cbpp = NULL;
  106. }
  107. error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
  108. if (error)
  109. return error;
  110. if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
  111. xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
  112. XFS_SICK_RT_BITMAP);
  113. return -EFSCORRUPTED;
  114. }
  115. ASSERT(map.br_startblock != NULLFSBLOCK);
  116. error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp,
  117. XFS_FSB_TO_DADDR(mp, map.br_startblock),
  118. mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
  119. if (xfs_metadata_is_sick(error))
  120. xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
  121. XFS_SICK_RT_BITMAP);
  122. if (error)
  123. return error;
  124. xfs_trans_buf_set_type(args->tp, bp, type);
  125. *cbpp = bp;
  126. *coffp = block;
  127. return 0;
  128. }
  129. int
  130. xfs_rtbitmap_read_buf(
  131. struct xfs_rtalloc_args *args,
  132. xfs_fileoff_t block)
  133. {
  134. struct xfs_mount *mp = args->mp;
  135. if (XFS_IS_CORRUPT(mp, block >= mp->m_sb.sb_rbmblocks)) {
  136. xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP);
  137. return -EFSCORRUPTED;
  138. }
  139. return xfs_rtbuf_get(args, block, 0);
  140. }
  141. int
  142. xfs_rtsummary_read_buf(
  143. struct xfs_rtalloc_args *args,
  144. xfs_fileoff_t block)
  145. {
  146. struct xfs_mount *mp = args->mp;
  147. if (XFS_IS_CORRUPT(mp, block >= mp->m_rsumblocks)) {
  148. xfs_rt_mark_sick(args->mp, XFS_SICK_RT_SUMMARY);
  149. return -EFSCORRUPTED;
  150. }
  151. return xfs_rtbuf_get(args, block, 1);
  152. }
  153. /*
  154. * Searching backward from start find the first block whose allocated/free state
  155. * is different from start's.
  156. */
  157. int
  158. xfs_rtfind_back(
  159. struct xfs_rtalloc_args *args,
  160. xfs_rtxnum_t start, /* starting rtext to look at */
  161. xfs_rtxnum_t *rtx) /* out: start rtext found */
  162. {
  163. struct xfs_mount *mp = args->mp;
  164. int bit; /* bit number in the word */
  165. xfs_fileoff_t block; /* bitmap block number */
  166. int error; /* error value */
  167. xfs_rtxnum_t firstbit; /* first useful bit in the word */
  168. xfs_rtxnum_t i; /* current bit number rel. to start */
  169. xfs_rtxnum_t len; /* length of inspected area */
  170. xfs_rtword_t mask; /* mask of relevant bits for value */
  171. xfs_rtword_t want; /* mask for "good" values */
  172. xfs_rtword_t wdiff; /* difference from wanted value */
  173. xfs_rtword_t incore;
  174. unsigned int word; /* word number in the buffer */
  175. /*
  176. * Compute and read in starting bitmap block for starting block.
  177. */
  178. block = xfs_rtx_to_rbmblock(mp, start);
  179. error = xfs_rtbitmap_read_buf(args, block);
  180. if (error)
  181. return error;
  182. /*
  183. * Get the first word's index & point to it.
  184. */
  185. word = xfs_rtx_to_rbmword(mp, start);
  186. bit = (int)(start & (XFS_NBWORD - 1));
  187. len = start + 1;
  188. /*
  189. * Compute match value, based on the bit at start: if 1 (free)
  190. * then all-ones, else all-zeroes.
  191. */
  192. incore = xfs_rtbitmap_getword(args, word);
  193. want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
  194. /*
  195. * If the starting position is not word-aligned, deal with the
  196. * partial word.
  197. */
  198. if (bit < XFS_NBWORD - 1) {
  199. /*
  200. * Calculate first (leftmost) bit number to look at,
  201. * and mask for all the relevant bits in this word.
  202. */
  203. firstbit = max_t(xfs_srtblock_t, bit - len + 1, 0);
  204. mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
  205. firstbit;
  206. /*
  207. * Calculate the difference between the value there
  208. * and what we're looking for.
  209. */
  210. if ((wdiff = (incore ^ want) & mask)) {
  211. /*
  212. * Different. Mark where we are and return.
  213. */
  214. i = bit - xfs_highbit32(wdiff);
  215. *rtx = start - i + 1;
  216. return 0;
  217. }
  218. i = bit - firstbit + 1;
  219. /*
  220. * Go on to previous block if that's where the previous word is
  221. * and we need the previous word.
  222. */
  223. if (--word == -1 && i < len) {
  224. /*
  225. * If done with this block, get the previous one.
  226. */
  227. error = xfs_rtbitmap_read_buf(args, --block);
  228. if (error)
  229. return error;
  230. word = mp->m_blockwsize - 1;
  231. }
  232. } else {
  233. /*
  234. * Starting on a word boundary, no partial word.
  235. */
  236. i = 0;
  237. }
  238. /*
  239. * Loop over whole words in buffers. When we use up one buffer
  240. * we move on to the previous one.
  241. */
  242. while (len - i >= XFS_NBWORD) {
  243. /*
  244. * Compute difference between actual and desired value.
  245. */
  246. incore = xfs_rtbitmap_getword(args, word);
  247. if ((wdiff = incore ^ want)) {
  248. /*
  249. * Different, mark where we are and return.
  250. */
  251. i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
  252. *rtx = start - i + 1;
  253. return 0;
  254. }
  255. i += XFS_NBWORD;
  256. /*
  257. * Go on to previous block if that's where the previous word is
  258. * and we need the previous word.
  259. */
  260. if (--word == -1 && i < len) {
  261. /*
  262. * If done with this block, get the previous one.
  263. */
  264. error = xfs_rtbitmap_read_buf(args, --block);
  265. if (error)
  266. return error;
  267. word = mp->m_blockwsize - 1;
  268. }
  269. }
  270. /*
  271. * If not ending on a word boundary, deal with the last
  272. * (partial) word.
  273. */
  274. if (len - i) {
  275. /*
  276. * Calculate first (leftmost) bit number to look at,
  277. * and mask for all the relevant bits in this word.
  278. */
  279. firstbit = XFS_NBWORD - (len - i);
  280. mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
  281. /*
  282. * Compute difference between actual and desired value.
  283. */
  284. incore = xfs_rtbitmap_getword(args, word);
  285. if ((wdiff = (incore ^ want) & mask)) {
  286. /*
  287. * Different, mark where we are and return.
  288. */
  289. i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
  290. *rtx = start - i + 1;
  291. return 0;
  292. } else
  293. i = len;
  294. }
  295. /*
  296. * No match, return that we scanned the whole area.
  297. */
  298. *rtx = start - i + 1;
  299. return 0;
  300. }
  301. /*
  302. * Searching forward from start to limit, find the first block whose
  303. * allocated/free state is different from start's.
  304. */
  305. int
  306. xfs_rtfind_forw(
  307. struct xfs_rtalloc_args *args,
  308. xfs_rtxnum_t start, /* starting rtext to look at */
  309. xfs_rtxnum_t limit, /* last rtext to look at */
  310. xfs_rtxnum_t *rtx) /* out: start rtext found */
  311. {
  312. struct xfs_mount *mp = args->mp;
  313. int bit; /* bit number in the word */
  314. xfs_fileoff_t block; /* bitmap block number */
  315. int error;
  316. xfs_rtxnum_t i; /* current bit number rel. to start */
  317. xfs_rtxnum_t lastbit;/* last useful bit in the word */
  318. xfs_rtxnum_t len; /* length of inspected area */
  319. xfs_rtword_t mask; /* mask of relevant bits for value */
  320. xfs_rtword_t want; /* mask for "good" values */
  321. xfs_rtword_t wdiff; /* difference from wanted value */
  322. xfs_rtword_t incore;
  323. unsigned int word; /* word number in the buffer */
  324. ASSERT(start <= limit);
  325. /*
  326. * Compute and read in starting bitmap block for starting block.
  327. */
  328. block = xfs_rtx_to_rbmblock(mp, start);
  329. error = xfs_rtbitmap_read_buf(args, block);
  330. if (error)
  331. return error;
  332. /*
  333. * Get the first word's index & point to it.
  334. */
  335. word = xfs_rtx_to_rbmword(mp, start);
  336. bit = (int)(start & (XFS_NBWORD - 1));
  337. len = limit - start + 1;
  338. /*
  339. * Compute match value, based on the bit at start: if 1 (free)
  340. * then all-ones, else all-zeroes.
  341. */
  342. incore = xfs_rtbitmap_getword(args, word);
  343. want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
  344. /*
  345. * If the starting position is not word-aligned, deal with the
  346. * partial word.
  347. */
  348. if (bit) {
  349. /*
  350. * Calculate last (rightmost) bit number to look at,
  351. * and mask for all the relevant bits in this word.
  352. */
  353. lastbit = min(bit + len, XFS_NBWORD);
  354. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  355. /*
  356. * Calculate the difference between the value there
  357. * and what we're looking for.
  358. */
  359. if ((wdiff = (incore ^ want) & mask)) {
  360. /*
  361. * Different. Mark where we are and return.
  362. */
  363. i = xfs_lowbit32(wdiff) - bit;
  364. *rtx = start + i - 1;
  365. return 0;
  366. }
  367. i = lastbit - bit;
  368. /*
  369. * Go on to next block if that's where the next word is
  370. * and we need the next word.
  371. */
  372. if (++word == mp->m_blockwsize && i < len) {
  373. /*
  374. * If done with this block, get the previous one.
  375. */
  376. error = xfs_rtbitmap_read_buf(args, ++block);
  377. if (error)
  378. return error;
  379. word = 0;
  380. }
  381. } else {
  382. /*
  383. * Starting on a word boundary, no partial word.
  384. */
  385. i = 0;
  386. }
  387. /*
  388. * Loop over whole words in buffers. When we use up one buffer
  389. * we move on to the next one.
  390. */
  391. while (len - i >= XFS_NBWORD) {
  392. /*
  393. * Compute difference between actual and desired value.
  394. */
  395. incore = xfs_rtbitmap_getword(args, word);
  396. if ((wdiff = incore ^ want)) {
  397. /*
  398. * Different, mark where we are and return.
  399. */
  400. i += xfs_lowbit32(wdiff);
  401. *rtx = start + i - 1;
  402. return 0;
  403. }
  404. i += XFS_NBWORD;
  405. /*
  406. * Go on to next block if that's where the next word is
  407. * and we need the next word.
  408. */
  409. if (++word == mp->m_blockwsize && i < len) {
  410. /*
  411. * If done with this block, get the next one.
  412. */
  413. error = xfs_rtbitmap_read_buf(args, ++block);
  414. if (error)
  415. return error;
  416. word = 0;
  417. }
  418. }
  419. /*
  420. * If not ending on a word boundary, deal with the last
  421. * (partial) word.
  422. */
  423. if ((lastbit = len - i)) {
  424. /*
  425. * Calculate mask for all the relevant bits in this word.
  426. */
  427. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  428. /*
  429. * Compute difference between actual and desired value.
  430. */
  431. incore = xfs_rtbitmap_getword(args, word);
  432. if ((wdiff = (incore ^ want) & mask)) {
  433. /*
  434. * Different, mark where we are and return.
  435. */
  436. i += xfs_lowbit32(wdiff);
  437. *rtx = start + i - 1;
  438. return 0;
  439. } else
  440. i = len;
  441. }
  442. /*
  443. * No match, return that we scanned the whole area.
  444. */
  445. *rtx = start + i - 1;
  446. return 0;
  447. }
  448. /* Log rtsummary counter at @infoword. */
  449. static inline void
  450. xfs_trans_log_rtsummary(
  451. struct xfs_rtalloc_args *args,
  452. unsigned int infoword)
  453. {
  454. struct xfs_buf *bp = args->sumbp;
  455. size_t first, last;
  456. first = (void *)xfs_rsumblock_infoptr(args, infoword) - bp->b_addr;
  457. last = first + sizeof(xfs_suminfo_t) - 1;
  458. xfs_trans_log_buf(args->tp, bp, first, last);
  459. }
  460. /*
  461. * Modify the summary information for a given extent size, bitmap block
  462. * combination.
  463. */
  464. int
  465. xfs_rtmodify_summary(
  466. struct xfs_rtalloc_args *args,
  467. int log, /* log2 of extent size */
  468. xfs_fileoff_t bbno, /* bitmap block number */
  469. int delta) /* in/out: summary block number */
  470. {
  471. struct xfs_mount *mp = args->mp;
  472. xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
  473. unsigned int infoword;
  474. xfs_suminfo_t val;
  475. int error;
  476. error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
  477. if (error)
  478. return error;
  479. infoword = xfs_rtsumoffs_to_infoword(mp, so);
  480. val = xfs_suminfo_add(args, infoword, delta);
  481. if (mp->m_rsum_cache) {
  482. if (val == 0 && log + 1 == mp->m_rsum_cache[bbno])
  483. mp->m_rsum_cache[bbno] = log;
  484. if (val != 0 && log >= mp->m_rsum_cache[bbno])
  485. mp->m_rsum_cache[bbno] = log + 1;
  486. }
  487. xfs_trans_log_rtsummary(args, infoword);
  488. return 0;
  489. }
  490. /*
  491. * Read and return the summary information for a given extent size, bitmap block
  492. * combination.
  493. */
  494. int
  495. xfs_rtget_summary(
  496. struct xfs_rtalloc_args *args,
  497. int log, /* log2 of extent size */
  498. xfs_fileoff_t bbno, /* bitmap block number */
  499. xfs_suminfo_t *sum) /* out: summary info for this block */
  500. {
  501. struct xfs_mount *mp = args->mp;
  502. xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
  503. int error;
  504. error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
  505. if (!error)
  506. *sum = xfs_suminfo_get(args, xfs_rtsumoffs_to_infoword(mp, so));
  507. return error;
  508. }
  509. /* Log rtbitmap block from the word @from to the byte before @next. */
  510. static inline void
  511. xfs_trans_log_rtbitmap(
  512. struct xfs_rtalloc_args *args,
  513. unsigned int from,
  514. unsigned int next)
  515. {
  516. struct xfs_buf *bp = args->rbmbp;
  517. size_t first, last;
  518. first = (void *)xfs_rbmblock_wordptr(args, from) - bp->b_addr;
  519. last = ((void *)xfs_rbmblock_wordptr(args, next) - 1) - bp->b_addr;
  520. xfs_trans_log_buf(args->tp, bp, first, last);
  521. }
  522. /*
  523. * Set the given range of bitmap bits to the given value.
  524. * Do whatever I/O and logging is required.
  525. */
  526. int
  527. xfs_rtmodify_range(
  528. struct xfs_rtalloc_args *args,
  529. xfs_rtxnum_t start, /* starting rtext to modify */
  530. xfs_rtxlen_t len, /* length of extent to modify */
  531. int val) /* 1 for free, 0 for allocated */
  532. {
  533. struct xfs_mount *mp = args->mp;
  534. int bit; /* bit number in the word */
  535. xfs_fileoff_t block; /* bitmap block number */
  536. int error;
  537. int i; /* current bit number rel. to start */
  538. int lastbit; /* last useful bit in word */
  539. xfs_rtword_t mask; /* mask of relevant bits for value */
  540. xfs_rtword_t incore;
  541. unsigned int firstword; /* first word used in the buffer */
  542. unsigned int word; /* word number in the buffer */
  543. /*
  544. * Compute starting bitmap block number.
  545. */
  546. block = xfs_rtx_to_rbmblock(mp, start);
  547. /*
  548. * Read the bitmap block, and point to its data.
  549. */
  550. error = xfs_rtbitmap_read_buf(args, block);
  551. if (error)
  552. return error;
  553. /*
  554. * Compute the starting word's address, and starting bit.
  555. */
  556. firstword = word = xfs_rtx_to_rbmword(mp, start);
  557. bit = (int)(start & (XFS_NBWORD - 1));
  558. /*
  559. * 0 (allocated) => all zeroes; 1 (free) => all ones.
  560. */
  561. val = -val;
  562. /*
  563. * If not starting on a word boundary, deal with the first
  564. * (partial) word.
  565. */
  566. if (bit) {
  567. /*
  568. * Compute first bit not changed and mask of relevant bits.
  569. */
  570. lastbit = min(bit + len, XFS_NBWORD);
  571. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  572. /*
  573. * Set/clear the active bits.
  574. */
  575. incore = xfs_rtbitmap_getword(args, word);
  576. if (val)
  577. incore |= mask;
  578. else
  579. incore &= ~mask;
  580. xfs_rtbitmap_setword(args, word, incore);
  581. i = lastbit - bit;
  582. /*
  583. * Go on to the next block if that's where the next word is
  584. * and we need the next word.
  585. */
  586. if (++word == mp->m_blockwsize && i < len) {
  587. /*
  588. * Log the changed part of this block.
  589. * Get the next one.
  590. */
  591. xfs_trans_log_rtbitmap(args, firstword, word);
  592. error = xfs_rtbitmap_read_buf(args, ++block);
  593. if (error)
  594. return error;
  595. firstword = word = 0;
  596. }
  597. } else {
  598. /*
  599. * Starting on a word boundary, no partial word.
  600. */
  601. i = 0;
  602. }
  603. /*
  604. * Loop over whole words in buffers. When we use up one buffer
  605. * we move on to the next one.
  606. */
  607. while (len - i >= XFS_NBWORD) {
  608. /*
  609. * Set the word value correctly.
  610. */
  611. xfs_rtbitmap_setword(args, word, val);
  612. i += XFS_NBWORD;
  613. /*
  614. * Go on to the next block if that's where the next word is
  615. * and we need the next word.
  616. */
  617. if (++word == mp->m_blockwsize && i < len) {
  618. /*
  619. * Log the changed part of this block.
  620. * Get the next one.
  621. */
  622. xfs_trans_log_rtbitmap(args, firstword, word);
  623. error = xfs_rtbitmap_read_buf(args, ++block);
  624. if (error)
  625. return error;
  626. firstword = word = 0;
  627. }
  628. }
  629. /*
  630. * If not ending on a word boundary, deal with the last
  631. * (partial) word.
  632. */
  633. if ((lastbit = len - i)) {
  634. /*
  635. * Compute a mask of relevant bits.
  636. */
  637. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  638. /*
  639. * Set/clear the active bits.
  640. */
  641. incore = xfs_rtbitmap_getword(args, word);
  642. if (val)
  643. incore |= mask;
  644. else
  645. incore &= ~mask;
  646. xfs_rtbitmap_setword(args, word, incore);
  647. word++;
  648. }
  649. /*
  650. * Log any remaining changed bytes.
  651. */
  652. if (word > firstword)
  653. xfs_trans_log_rtbitmap(args, firstword, word);
  654. return 0;
  655. }
  656. /*
  657. * Mark an extent specified by start and len freed.
  658. * Updates all the summary information as well as the bitmap.
  659. */
  660. int
  661. xfs_rtfree_range(
  662. struct xfs_rtalloc_args *args,
  663. xfs_rtxnum_t start, /* starting rtext to free */
  664. xfs_rtxlen_t len) /* in/out: summary block number */
  665. {
  666. struct xfs_mount *mp = args->mp;
  667. xfs_rtxnum_t end; /* end of the freed extent */
  668. int error; /* error value */
  669. xfs_rtxnum_t postblock; /* first rtext freed > end */
  670. xfs_rtxnum_t preblock; /* first rtext freed < start */
  671. end = start + len - 1;
  672. /*
  673. * Modify the bitmap to mark this extent freed.
  674. */
  675. error = xfs_rtmodify_range(args, start, len, 1);
  676. if (error) {
  677. return error;
  678. }
  679. /*
  680. * Assume we're freeing out of the middle of an allocated extent.
  681. * We need to find the beginning and end of the extent so we can
  682. * properly update the summary.
  683. */
  684. error = xfs_rtfind_back(args, start, &preblock);
  685. if (error) {
  686. return error;
  687. }
  688. /*
  689. * Find the next allocated block (end of allocated extent).
  690. */
  691. error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1,
  692. &postblock);
  693. if (error)
  694. return error;
  695. /*
  696. * If there are blocks not being freed at the front of the
  697. * old extent, add summary data for them to be allocated.
  698. */
  699. if (preblock < start) {
  700. error = xfs_rtmodify_summary(args,
  701. xfs_highbit64(start - preblock),
  702. xfs_rtx_to_rbmblock(mp, preblock), -1);
  703. if (error) {
  704. return error;
  705. }
  706. }
  707. /*
  708. * If there are blocks not being freed at the end of the
  709. * old extent, add summary data for them to be allocated.
  710. */
  711. if (postblock > end) {
  712. error = xfs_rtmodify_summary(args,
  713. xfs_highbit64(postblock - end),
  714. xfs_rtx_to_rbmblock(mp, end + 1), -1);
  715. if (error) {
  716. return error;
  717. }
  718. }
  719. /*
  720. * Increment the summary information corresponding to the entire
  721. * (new) free extent.
  722. */
  723. return xfs_rtmodify_summary(args,
  724. xfs_highbit64(postblock + 1 - preblock),
  725. xfs_rtx_to_rbmblock(mp, preblock), 1);
  726. }
  727. /*
  728. * Check that the given range is either all allocated (val = 0) or
  729. * all free (val = 1).
  730. */
  731. int
  732. xfs_rtcheck_range(
  733. struct xfs_rtalloc_args *args,
  734. xfs_rtxnum_t start, /* starting rtext number of extent */
  735. xfs_rtxlen_t len, /* length of extent */
  736. int val, /* 1 for free, 0 for allocated */
  737. xfs_rtxnum_t *new, /* out: first rtext not matching */
  738. int *stat) /* out: 1 for matches, 0 for not */
  739. {
  740. struct xfs_mount *mp = args->mp;
  741. int bit; /* bit number in the word */
  742. xfs_fileoff_t block; /* bitmap block number */
  743. int error;
  744. xfs_rtxnum_t i; /* current bit number rel. to start */
  745. xfs_rtxnum_t lastbit; /* last useful bit in word */
  746. xfs_rtword_t mask; /* mask of relevant bits for value */
  747. xfs_rtword_t wdiff; /* difference from wanted value */
  748. xfs_rtword_t incore;
  749. unsigned int word; /* word number in the buffer */
  750. /*
  751. * Compute starting bitmap block number
  752. */
  753. block = xfs_rtx_to_rbmblock(mp, start);
  754. /*
  755. * Read the bitmap block.
  756. */
  757. error = xfs_rtbitmap_read_buf(args, block);
  758. if (error)
  759. return error;
  760. /*
  761. * Compute the starting word's address, and starting bit.
  762. */
  763. word = xfs_rtx_to_rbmword(mp, start);
  764. bit = (int)(start & (XFS_NBWORD - 1));
  765. /*
  766. * 0 (allocated) => all zero's; 1 (free) => all one's.
  767. */
  768. val = -val;
  769. /*
  770. * If not starting on a word boundary, deal with the first
  771. * (partial) word.
  772. */
  773. if (bit) {
  774. /*
  775. * Compute first bit not examined.
  776. */
  777. lastbit = min(bit + len, XFS_NBWORD);
  778. /*
  779. * Mask of relevant bits.
  780. */
  781. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  782. /*
  783. * Compute difference between actual and desired value.
  784. */
  785. incore = xfs_rtbitmap_getword(args, word);
  786. if ((wdiff = (incore ^ val) & mask)) {
  787. /*
  788. * Different, compute first wrong bit and return.
  789. */
  790. i = xfs_lowbit32(wdiff) - bit;
  791. *new = start + i;
  792. *stat = 0;
  793. return 0;
  794. }
  795. i = lastbit - bit;
  796. /*
  797. * Go on to next block if that's where the next word is
  798. * and we need the next word.
  799. */
  800. if (++word == mp->m_blockwsize && i < len) {
  801. /*
  802. * If done with this block, get the next one.
  803. */
  804. error = xfs_rtbitmap_read_buf(args, ++block);
  805. if (error)
  806. return error;
  807. word = 0;
  808. }
  809. } else {
  810. /*
  811. * Starting on a word boundary, no partial word.
  812. */
  813. i = 0;
  814. }
  815. /*
  816. * Loop over whole words in buffers. When we use up one buffer
  817. * we move on to the next one.
  818. */
  819. while (len - i >= XFS_NBWORD) {
  820. /*
  821. * Compute difference between actual and desired value.
  822. */
  823. incore = xfs_rtbitmap_getword(args, word);
  824. if ((wdiff = incore ^ val)) {
  825. /*
  826. * Different, compute first wrong bit and return.
  827. */
  828. i += xfs_lowbit32(wdiff);
  829. *new = start + i;
  830. *stat = 0;
  831. return 0;
  832. }
  833. i += XFS_NBWORD;
  834. /*
  835. * Go on to next block if that's where the next word is
  836. * and we need the next word.
  837. */
  838. if (++word == mp->m_blockwsize && i < len) {
  839. /*
  840. * If done with this block, get the next one.
  841. */
  842. error = xfs_rtbitmap_read_buf(args, ++block);
  843. if (error)
  844. return error;
  845. word = 0;
  846. }
  847. }
  848. /*
  849. * If not ending on a word boundary, deal with the last
  850. * (partial) word.
  851. */
  852. if ((lastbit = len - i)) {
  853. /*
  854. * Mask of relevant bits.
  855. */
  856. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  857. /*
  858. * Compute difference between actual and desired value.
  859. */
  860. incore = xfs_rtbitmap_getword(args, word);
  861. if ((wdiff = (incore ^ val) & mask)) {
  862. /*
  863. * Different, compute first wrong bit and return.
  864. */
  865. i += xfs_lowbit32(wdiff);
  866. *new = start + i;
  867. *stat = 0;
  868. return 0;
  869. } else
  870. i = len;
  871. }
  872. /*
  873. * Successful, return.
  874. */
  875. *new = start + i;
  876. *stat = 1;
  877. return 0;
  878. }
  879. #ifdef DEBUG
  880. /*
  881. * Check that the given extent (block range) is allocated already.
  882. */
  883. STATIC int
  884. xfs_rtcheck_alloc_range(
  885. struct xfs_rtalloc_args *args,
  886. xfs_rtxnum_t start, /* starting rtext number of extent */
  887. xfs_rtxlen_t len) /* length of extent */
  888. {
  889. xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */
  890. int stat;
  891. int error;
  892. error = xfs_rtcheck_range(args, start, len, 0, &new, &stat);
  893. if (error)
  894. return error;
  895. ASSERT(stat);
  896. return 0;
  897. }
  898. #else
  899. #define xfs_rtcheck_alloc_range(a,b,l) (0)
  900. #endif
  901. /*
  902. * Free an extent in the realtime subvolume. Length is expressed in
  903. * realtime extents, as is the block number.
  904. */
  905. int
  906. xfs_rtfree_extent(
  907. struct xfs_trans *tp, /* transaction pointer */
  908. xfs_rtxnum_t start, /* starting rtext number to free */
  909. xfs_rtxlen_t len) /* length of extent freed */
  910. {
  911. struct xfs_mount *mp = tp->t_mountp;
  912. struct xfs_rtalloc_args args = {
  913. .mp = mp,
  914. .tp = tp,
  915. };
  916. int error;
  917. struct timespec64 atime;
  918. ASSERT(mp->m_rbmip->i_itemp != NULL);
  919. xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL);
  920. error = xfs_rtcheck_alloc_range(&args, start, len);
  921. if (error)
  922. return error;
  923. /*
  924. * Free the range of realtime blocks.
  925. */
  926. error = xfs_rtfree_range(&args, start, len);
  927. if (error)
  928. goto out;
  929. /*
  930. * Mark more blocks free in the superblock.
  931. */
  932. xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
  933. /*
  934. * If we've now freed all the blocks, reset the file sequence
  935. * number to 0.
  936. */
  937. if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
  938. mp->m_sb.sb_rextents) {
  939. if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
  940. mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
  941. atime = inode_get_atime(VFS_I(mp->m_rbmip));
  942. atime.tv_sec = 0;
  943. inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime);
  944. xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
  945. }
  946. error = 0;
  947. out:
  948. xfs_rtbuf_cache_relse(&args);
  949. return error;
  950. }
  951. /*
  952. * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
  953. * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
  954. * cannot exceed XFS_MAX_BMBT_EXTLEN.
  955. */
  956. int
  957. xfs_rtfree_blocks(
  958. struct xfs_trans *tp,
  959. xfs_fsblock_t rtbno,
  960. xfs_filblks_t rtlen)
  961. {
  962. struct xfs_mount *mp = tp->t_mountp;
  963. xfs_extlen_t mod;
  964. ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
  965. mod = xfs_rtb_to_rtxoff(mp, rtlen);
  966. if (mod) {
  967. ASSERT(mod == 0);
  968. return -EIO;
  969. }
  970. mod = xfs_rtb_to_rtxoff(mp, rtbno);
  971. if (mod) {
  972. ASSERT(mod == 0);
  973. return -EIO;
  974. }
  975. return xfs_rtfree_extent(tp, xfs_rtb_to_rtx(mp, rtbno),
  976. xfs_rtb_to_rtx(mp, rtlen));
  977. }
  978. /* Find all the free records within a given range. */
  979. int
  980. xfs_rtalloc_query_range(
  981. struct xfs_mount *mp,
  982. struct xfs_trans *tp,
  983. xfs_rtxnum_t start,
  984. xfs_rtxnum_t end,
  985. xfs_rtalloc_query_range_fn fn,
  986. void *priv)
  987. {
  988. struct xfs_rtalloc_args args = {
  989. .mp = mp,
  990. .tp = tp,
  991. };
  992. int error = 0;
  993. if (start > end)
  994. return -EINVAL;
  995. if (start == end || start >= mp->m_sb.sb_rextents)
  996. return 0;
  997. end = min(end, mp->m_sb.sb_rextents - 1);
  998. /* Iterate the bitmap, looking for discrepancies. */
  999. while (start <= end) {
  1000. struct xfs_rtalloc_rec rec;
  1001. int is_free;
  1002. xfs_rtxnum_t rtend;
  1003. /* Is the first block free? */
  1004. error = xfs_rtcheck_range(&args, start, 1, 1, &rtend,
  1005. &is_free);
  1006. if (error)
  1007. break;
  1008. /* How long does the extent go for? */
  1009. error = xfs_rtfind_forw(&args, start, end, &rtend);
  1010. if (error)
  1011. break;
  1012. if (is_free) {
  1013. rec.ar_startext = start;
  1014. rec.ar_extcount = rtend - start + 1;
  1015. error = fn(mp, tp, &rec, priv);
  1016. if (error)
  1017. break;
  1018. }
  1019. start = rtend + 1;
  1020. }
  1021. xfs_rtbuf_cache_relse(&args);
  1022. return error;
  1023. }
  1024. /* Find all the free records. */
  1025. int
  1026. xfs_rtalloc_query_all(
  1027. struct xfs_mount *mp,
  1028. struct xfs_trans *tp,
  1029. xfs_rtalloc_query_range_fn fn,
  1030. void *priv)
  1031. {
  1032. return xfs_rtalloc_query_range(mp, tp, 0, mp->m_sb.sb_rextents - 1, fn,
  1033. priv);
  1034. }
  1035. /* Is the given extent all free? */
  1036. int
  1037. xfs_rtalloc_extent_is_free(
  1038. struct xfs_mount *mp,
  1039. struct xfs_trans *tp,
  1040. xfs_rtxnum_t start,
  1041. xfs_rtxlen_t len,
  1042. bool *is_free)
  1043. {
  1044. struct xfs_rtalloc_args args = {
  1045. .mp = mp,
  1046. .tp = tp,
  1047. };
  1048. xfs_rtxnum_t end;
  1049. int matches;
  1050. int error;
  1051. error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches);
  1052. xfs_rtbuf_cache_relse(&args);
  1053. if (error)
  1054. return error;
  1055. *is_free = matches;
  1056. return 0;
  1057. }
  1058. /*
  1059. * Compute the number of rtbitmap blocks needed to track the given number of rt
  1060. * extents.
  1061. */
  1062. xfs_filblks_t
  1063. xfs_rtbitmap_blockcount(
  1064. struct xfs_mount *mp,
  1065. xfs_rtbxlen_t rtextents)
  1066. {
  1067. return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize);
  1068. }
  1069. /* Compute the number of rtsummary blocks needed to track the given rt space. */
  1070. xfs_filblks_t
  1071. xfs_rtsummary_blockcount(
  1072. struct xfs_mount *mp,
  1073. unsigned int rsumlevels,
  1074. xfs_extlen_t rbmblocks)
  1075. {
  1076. unsigned long long rsumwords;
  1077. rsumwords = (unsigned long long)rsumlevels * rbmblocks;
  1078. return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
  1079. }
  1080. /* Lock both realtime free space metadata inodes for a freespace update. */
  1081. void
  1082. xfs_rtbitmap_lock(
  1083. struct xfs_mount *mp)
  1084. {
  1085. xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
  1086. xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
  1087. }
  1088. /*
  1089. * Join both realtime free space metadata inodes to the transaction. The
  1090. * ILOCKs will be released on transaction commit.
  1091. */
  1092. void
  1093. xfs_rtbitmap_trans_join(
  1094. struct xfs_trans *tp)
  1095. {
  1096. xfs_trans_ijoin(tp, tp->t_mountp->m_rbmip, XFS_ILOCK_EXCL);
  1097. xfs_trans_ijoin(tp, tp->t_mountp->m_rsumip, XFS_ILOCK_EXCL);
  1098. }
  1099. /* Unlock both realtime free space metadata inodes after a freespace update. */
  1100. void
  1101. xfs_rtbitmap_unlock(
  1102. struct xfs_mount *mp)
  1103. {
  1104. xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
  1105. xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
  1106. }
  1107. /*
  1108. * Lock the realtime free space metadata inodes for a freespace scan. Callers
  1109. * must walk metadata blocks in order of increasing file offset.
  1110. */
  1111. void
  1112. xfs_rtbitmap_lock_shared(
  1113. struct xfs_mount *mp,
  1114. unsigned int rbmlock_flags)
  1115. {
  1116. if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
  1117. xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
  1118. if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
  1119. xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
  1120. }
  1121. /* Unlock the realtime free space metadata inodes after a freespace scan. */
  1122. void
  1123. xfs_rtbitmap_unlock_shared(
  1124. struct xfs_mount *mp,
  1125. unsigned int rbmlock_flags)
  1126. {
  1127. if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
  1128. xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
  1129. if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
  1130. xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
  1131. }
  1132. static int
  1133. xfs_rtfile_alloc_blocks(
  1134. struct xfs_inode *ip,
  1135. xfs_fileoff_t offset_fsb,
  1136. xfs_filblks_t count_fsb,
  1137. struct xfs_bmbt_irec *map)
  1138. {
  1139. struct xfs_mount *mp = ip->i_mount;
  1140. struct xfs_trans *tp;
  1141. int nmap = 1;
  1142. int error;
  1143. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc,
  1144. XFS_GROWFSRT_SPACE_RES(mp, count_fsb), 0, 0, &tp);
  1145. if (error)
  1146. return error;
  1147. xfs_ilock(ip, XFS_ILOCK_EXCL);
  1148. xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
  1149. error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK,
  1150. XFS_IEXT_ADD_NOSPLIT_CNT);
  1151. if (error)
  1152. goto out_trans_cancel;
  1153. error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
  1154. XFS_BMAPI_METADATA, 0, map, &nmap);
  1155. if (error)
  1156. goto out_trans_cancel;
  1157. return xfs_trans_commit(tp);
  1158. out_trans_cancel:
  1159. xfs_trans_cancel(tp);
  1160. return error;
  1161. }
  1162. /* Get a buffer for the block. */
  1163. static int
  1164. xfs_rtfile_initialize_block(
  1165. struct xfs_inode *ip,
  1166. xfs_fsblock_t fsbno,
  1167. void *data)
  1168. {
  1169. struct xfs_mount *mp = ip->i_mount;
  1170. struct xfs_trans *tp;
  1171. struct xfs_buf *bp;
  1172. const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
  1173. enum xfs_blft buf_type;
  1174. int error;
  1175. if (ip == mp->m_rsumip)
  1176. buf_type = XFS_BLFT_RTSUMMARY_BUF;
  1177. else
  1178. buf_type = XFS_BLFT_RTBITMAP_BUF;
  1179. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp);
  1180. if (error)
  1181. return error;
  1182. xfs_ilock(ip, XFS_ILOCK_EXCL);
  1183. xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
  1184. error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
  1185. XFS_FSB_TO_DADDR(mp, fsbno), mp->m_bsize, 0, &bp);
  1186. if (error) {
  1187. xfs_trans_cancel(tp);
  1188. return error;
  1189. }
  1190. xfs_trans_buf_set_type(tp, bp, buf_type);
  1191. bp->b_ops = &xfs_rtbuf_ops;
  1192. if (data)
  1193. memcpy(bp->b_addr, data, copylen);
  1194. else
  1195. memset(bp->b_addr, 0, copylen);
  1196. xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
  1197. return xfs_trans_commit(tp);
  1198. }
  1199. /*
  1200. * Allocate space to the bitmap or summary file, and zero it, for growfs.
  1201. * @data must be a contiguous buffer large enough to fill all blocks in the
  1202. * file; or NULL to initialize the contents to zeroes.
  1203. */
  1204. int
  1205. xfs_rtfile_initialize_blocks(
  1206. struct xfs_inode *ip, /* inode (bitmap/summary) */
  1207. xfs_fileoff_t offset_fsb, /* offset to start from */
  1208. xfs_fileoff_t end_fsb, /* offset to allocate to */
  1209. void *data) /* data to fill the blocks */
  1210. {
  1211. struct xfs_mount *mp = ip->i_mount;
  1212. const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
  1213. while (offset_fsb < end_fsb) {
  1214. struct xfs_bmbt_irec map;
  1215. xfs_filblks_t i;
  1216. int error;
  1217. error = xfs_rtfile_alloc_blocks(ip, offset_fsb,
  1218. end_fsb - offset_fsb, &map);
  1219. if (error)
  1220. return error;
  1221. /*
  1222. * Now we need to clear the allocated blocks.
  1223. *
  1224. * Do this one block per transaction, to keep it simple.
  1225. */
  1226. for (i = 0; i < map.br_blockcount; i++) {
  1227. error = xfs_rtfile_initialize_block(ip,
  1228. map.br_startblock + i, data);
  1229. if (error)
  1230. return error;
  1231. if (data)
  1232. data += copylen;
  1233. }
  1234. offset_fsb = map.br_startoff + map.br_blockcount;
  1235. }
  1236. return 0;
  1237. }