xfs_rtbitmap.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  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_trans.h"
  17. #include "xfs_rtalloc.h"
  18. #include "xfs_error.h"
  19. /*
  20. * Realtime allocator bitmap functions shared with userspace.
  21. */
  22. /*
  23. * Real time buffers need verifiers to avoid runtime warnings during IO.
  24. * We don't have anything to verify, however, so these are just dummy
  25. * operations.
  26. */
  27. static void
  28. xfs_rtbuf_verify_read(
  29. struct xfs_buf *bp)
  30. {
  31. return;
  32. }
  33. static void
  34. xfs_rtbuf_verify_write(
  35. struct xfs_buf *bp)
  36. {
  37. return;
  38. }
  39. const struct xfs_buf_ops xfs_rtbuf_ops = {
  40. .name = "rtbuf",
  41. .verify_read = xfs_rtbuf_verify_read,
  42. .verify_write = xfs_rtbuf_verify_write,
  43. };
  44. /*
  45. * Get a buffer for the bitmap or summary file block specified.
  46. * The buffer is returned read and locked.
  47. */
  48. int
  49. xfs_rtbuf_get(
  50. xfs_mount_t *mp, /* file system mount structure */
  51. xfs_trans_t *tp, /* transaction pointer */
  52. xfs_rtblock_t block, /* block number in bitmap or summary */
  53. int issum, /* is summary not bitmap */
  54. struct xfs_buf **bpp) /* output: buffer for the block */
  55. {
  56. struct xfs_buf *bp; /* block buffer, result */
  57. xfs_inode_t *ip; /* bitmap or summary inode */
  58. xfs_bmbt_irec_t map;
  59. int nmap = 1;
  60. int error; /* error value */
  61. ip = issum ? mp->m_rsumip : mp->m_rbmip;
  62. error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
  63. if (error)
  64. return error;
  65. if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map)))
  66. return -EFSCORRUPTED;
  67. ASSERT(map.br_startblock != NULLFSBLOCK);
  68. error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
  69. XFS_FSB_TO_DADDR(mp, map.br_startblock),
  70. mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
  71. if (error)
  72. return error;
  73. xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
  74. : XFS_BLFT_RTBITMAP_BUF);
  75. *bpp = bp;
  76. return 0;
  77. }
  78. /*
  79. * Searching backward from start to limit, find the first block whose
  80. * allocated/free state is different from start's.
  81. */
  82. int
  83. xfs_rtfind_back(
  84. xfs_mount_t *mp, /* file system mount point */
  85. xfs_trans_t *tp, /* transaction pointer */
  86. xfs_rtblock_t start, /* starting block to look at */
  87. xfs_rtblock_t limit, /* last block to look at */
  88. xfs_rtblock_t *rtblock) /* out: start block found */
  89. {
  90. xfs_rtword_t *b; /* current word in buffer */
  91. int bit; /* bit number in the word */
  92. xfs_rtblock_t block; /* bitmap block number */
  93. struct xfs_buf *bp; /* buf for the block */
  94. xfs_rtword_t *bufp; /* starting word in buffer */
  95. int error; /* error value */
  96. xfs_rtblock_t firstbit; /* first useful bit in the word */
  97. xfs_rtblock_t i; /* current bit number rel. to start */
  98. xfs_rtblock_t len; /* length of inspected area */
  99. xfs_rtword_t mask; /* mask of relevant bits for value */
  100. xfs_rtword_t want; /* mask for "good" values */
  101. xfs_rtword_t wdiff; /* difference from wanted value */
  102. int word; /* word number in the buffer */
  103. /*
  104. * Compute and read in starting bitmap block for starting block.
  105. */
  106. block = XFS_BITTOBLOCK(mp, start);
  107. error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
  108. if (error) {
  109. return error;
  110. }
  111. bufp = bp->b_addr;
  112. /*
  113. * Get the first word's index & point to it.
  114. */
  115. word = XFS_BITTOWORD(mp, start);
  116. b = &bufp[word];
  117. bit = (int)(start & (XFS_NBWORD - 1));
  118. len = start - limit + 1;
  119. /*
  120. * Compute match value, based on the bit at start: if 1 (free)
  121. * then all-ones, else all-zeroes.
  122. */
  123. want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
  124. /*
  125. * If the starting position is not word-aligned, deal with the
  126. * partial word.
  127. */
  128. if (bit < XFS_NBWORD - 1) {
  129. /*
  130. * Calculate first (leftmost) bit number to look at,
  131. * and mask for all the relevant bits in this word.
  132. */
  133. firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
  134. mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
  135. firstbit;
  136. /*
  137. * Calculate the difference between the value there
  138. * and what we're looking for.
  139. */
  140. if ((wdiff = (*b ^ want) & mask)) {
  141. /*
  142. * Different. Mark where we are and return.
  143. */
  144. xfs_trans_brelse(tp, bp);
  145. i = bit - XFS_RTHIBIT(wdiff);
  146. *rtblock = start - i + 1;
  147. return 0;
  148. }
  149. i = bit - firstbit + 1;
  150. /*
  151. * Go on to previous block if that's where the previous word is
  152. * and we need the previous word.
  153. */
  154. if (--word == -1 && i < len) {
  155. /*
  156. * If done with this block, get the previous one.
  157. */
  158. xfs_trans_brelse(tp, bp);
  159. error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
  160. if (error) {
  161. return error;
  162. }
  163. bufp = bp->b_addr;
  164. word = XFS_BLOCKWMASK(mp);
  165. b = &bufp[word];
  166. } else {
  167. /*
  168. * Go on to the previous word in the buffer.
  169. */
  170. b--;
  171. }
  172. } else {
  173. /*
  174. * Starting on a word boundary, no partial word.
  175. */
  176. i = 0;
  177. }
  178. /*
  179. * Loop over whole words in buffers. When we use up one buffer
  180. * we move on to the previous one.
  181. */
  182. while (len - i >= XFS_NBWORD) {
  183. /*
  184. * Compute difference between actual and desired value.
  185. */
  186. if ((wdiff = *b ^ want)) {
  187. /*
  188. * Different, mark where we are and return.
  189. */
  190. xfs_trans_brelse(tp, bp);
  191. i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
  192. *rtblock = start - i + 1;
  193. return 0;
  194. }
  195. i += XFS_NBWORD;
  196. /*
  197. * Go on to previous block if that's where the previous word is
  198. * and we need the previous word.
  199. */
  200. if (--word == -1 && i < len) {
  201. /*
  202. * If done with this block, get the previous one.
  203. */
  204. xfs_trans_brelse(tp, bp);
  205. error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
  206. if (error) {
  207. return error;
  208. }
  209. bufp = bp->b_addr;
  210. word = XFS_BLOCKWMASK(mp);
  211. b = &bufp[word];
  212. } else {
  213. /*
  214. * Go on to the previous word in the buffer.
  215. */
  216. b--;
  217. }
  218. }
  219. /*
  220. * If not ending on a word boundary, deal with the last
  221. * (partial) word.
  222. */
  223. if (len - i) {
  224. /*
  225. * Calculate first (leftmost) bit number to look at,
  226. * and mask for all the relevant bits in this word.
  227. */
  228. firstbit = XFS_NBWORD - (len - i);
  229. mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
  230. /*
  231. * Compute difference between actual and desired value.
  232. */
  233. if ((wdiff = (*b ^ want) & mask)) {
  234. /*
  235. * Different, mark where we are and return.
  236. */
  237. xfs_trans_brelse(tp, bp);
  238. i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
  239. *rtblock = start - i + 1;
  240. return 0;
  241. } else
  242. i = len;
  243. }
  244. /*
  245. * No match, return that we scanned the whole area.
  246. */
  247. xfs_trans_brelse(tp, bp);
  248. *rtblock = start - i + 1;
  249. return 0;
  250. }
  251. /*
  252. * Searching forward from start to limit, find the first block whose
  253. * allocated/free state is different from start's.
  254. */
  255. int
  256. xfs_rtfind_forw(
  257. xfs_mount_t *mp, /* file system mount point */
  258. xfs_trans_t *tp, /* transaction pointer */
  259. xfs_rtblock_t start, /* starting block to look at */
  260. xfs_rtblock_t limit, /* last block to look at */
  261. xfs_rtblock_t *rtblock) /* out: start block found */
  262. {
  263. xfs_rtword_t *b; /* current word in buffer */
  264. int bit; /* bit number in the word */
  265. xfs_rtblock_t block; /* bitmap block number */
  266. struct xfs_buf *bp; /* buf for the block */
  267. xfs_rtword_t *bufp; /* starting word in buffer */
  268. int error; /* error value */
  269. xfs_rtblock_t i; /* current bit number rel. to start */
  270. xfs_rtblock_t lastbit; /* last useful bit in the word */
  271. xfs_rtblock_t len; /* length of inspected area */
  272. xfs_rtword_t mask; /* mask of relevant bits for value */
  273. xfs_rtword_t want; /* mask for "good" values */
  274. xfs_rtword_t wdiff; /* difference from wanted value */
  275. int word; /* word number in the buffer */
  276. /*
  277. * Compute and read in starting bitmap block for starting block.
  278. */
  279. block = XFS_BITTOBLOCK(mp, start);
  280. error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
  281. if (error) {
  282. return error;
  283. }
  284. bufp = bp->b_addr;
  285. /*
  286. * Get the first word's index & point to it.
  287. */
  288. word = XFS_BITTOWORD(mp, start);
  289. b = &bufp[word];
  290. bit = (int)(start & (XFS_NBWORD - 1));
  291. len = limit - start + 1;
  292. /*
  293. * Compute match value, based on the bit at start: if 1 (free)
  294. * then all-ones, else all-zeroes.
  295. */
  296. want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
  297. /*
  298. * If the starting position is not word-aligned, deal with the
  299. * partial word.
  300. */
  301. if (bit) {
  302. /*
  303. * Calculate last (rightmost) bit number to look at,
  304. * and mask for all the relevant bits in this word.
  305. */
  306. lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
  307. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  308. /*
  309. * Calculate the difference between the value there
  310. * and what we're looking for.
  311. */
  312. if ((wdiff = (*b ^ want) & mask)) {
  313. /*
  314. * Different. Mark where we are and return.
  315. */
  316. xfs_trans_brelse(tp, bp);
  317. i = XFS_RTLOBIT(wdiff) - bit;
  318. *rtblock = start + i - 1;
  319. return 0;
  320. }
  321. i = lastbit - bit;
  322. /*
  323. * Go on to next block if that's where the next word is
  324. * and we need the next word.
  325. */
  326. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  327. /*
  328. * If done with this block, get the previous one.
  329. */
  330. xfs_trans_brelse(tp, bp);
  331. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  332. if (error) {
  333. return error;
  334. }
  335. b = bufp = bp->b_addr;
  336. word = 0;
  337. } else {
  338. /*
  339. * Go on to the previous word in the buffer.
  340. */
  341. b++;
  342. }
  343. } else {
  344. /*
  345. * Starting on a word boundary, no partial word.
  346. */
  347. i = 0;
  348. }
  349. /*
  350. * Loop over whole words in buffers. When we use up one buffer
  351. * we move on to the next one.
  352. */
  353. while (len - i >= XFS_NBWORD) {
  354. /*
  355. * Compute difference between actual and desired value.
  356. */
  357. if ((wdiff = *b ^ want)) {
  358. /*
  359. * Different, mark where we are and return.
  360. */
  361. xfs_trans_brelse(tp, bp);
  362. i += XFS_RTLOBIT(wdiff);
  363. *rtblock = start + i - 1;
  364. return 0;
  365. }
  366. i += XFS_NBWORD;
  367. /*
  368. * Go on to next block if that's where the next word is
  369. * and we need the next word.
  370. */
  371. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  372. /*
  373. * If done with this block, get the next one.
  374. */
  375. xfs_trans_brelse(tp, bp);
  376. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  377. if (error) {
  378. return error;
  379. }
  380. b = bufp = bp->b_addr;
  381. word = 0;
  382. } else {
  383. /*
  384. * Go on to the next word in the buffer.
  385. */
  386. b++;
  387. }
  388. }
  389. /*
  390. * If not ending on a word boundary, deal with the last
  391. * (partial) word.
  392. */
  393. if ((lastbit = len - i)) {
  394. /*
  395. * Calculate mask for all the relevant bits in this word.
  396. */
  397. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  398. /*
  399. * Compute difference between actual and desired value.
  400. */
  401. if ((wdiff = (*b ^ want) & mask)) {
  402. /*
  403. * Different, mark where we are and return.
  404. */
  405. xfs_trans_brelse(tp, bp);
  406. i += XFS_RTLOBIT(wdiff);
  407. *rtblock = start + i - 1;
  408. return 0;
  409. } else
  410. i = len;
  411. }
  412. /*
  413. * No match, return that we scanned the whole area.
  414. */
  415. xfs_trans_brelse(tp, bp);
  416. *rtblock = start + i - 1;
  417. return 0;
  418. }
  419. /*
  420. * Read and/or modify the summary information for a given extent size,
  421. * bitmap block combination.
  422. * Keeps track of a current summary block, so we don't keep reading
  423. * it from the buffer cache.
  424. *
  425. * Summary information is returned in *sum if specified.
  426. * If no delta is specified, returns summary only.
  427. */
  428. int
  429. xfs_rtmodify_summary_int(
  430. xfs_mount_t *mp, /* file system mount structure */
  431. xfs_trans_t *tp, /* transaction pointer */
  432. int log, /* log2 of extent size */
  433. xfs_rtblock_t bbno, /* bitmap block number */
  434. int delta, /* change to make to summary info */
  435. struct xfs_buf **rbpp, /* in/out: summary block buffer */
  436. xfs_fsblock_t *rsb, /* in/out: summary block number */
  437. xfs_suminfo_t *sum) /* out: summary info for this block */
  438. {
  439. struct xfs_buf *bp; /* buffer for the summary block */
  440. int error; /* error value */
  441. xfs_fsblock_t sb; /* summary fsblock */
  442. int so; /* index into the summary file */
  443. xfs_suminfo_t *sp; /* pointer to returned data */
  444. /*
  445. * Compute entry number in the summary file.
  446. */
  447. so = XFS_SUMOFFS(mp, log, bbno);
  448. /*
  449. * Compute the block number in the summary file.
  450. */
  451. sb = XFS_SUMOFFSTOBLOCK(mp, so);
  452. /*
  453. * If we have an old buffer, and the block number matches, use that.
  454. */
  455. if (*rbpp && *rsb == sb)
  456. bp = *rbpp;
  457. /*
  458. * Otherwise we have to get the buffer.
  459. */
  460. else {
  461. /*
  462. * If there was an old one, get rid of it first.
  463. */
  464. if (*rbpp)
  465. xfs_trans_brelse(tp, *rbpp);
  466. error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
  467. if (error) {
  468. return error;
  469. }
  470. /*
  471. * Remember this buffer and block for the next call.
  472. */
  473. *rbpp = bp;
  474. *rsb = sb;
  475. }
  476. /*
  477. * Point to the summary information, modify/log it, and/or copy it out.
  478. */
  479. sp = XFS_SUMPTR(mp, bp, so);
  480. if (delta) {
  481. uint first = (uint)((char *)sp - (char *)bp->b_addr);
  482. *sp += delta;
  483. if (mp->m_rsum_cache) {
  484. if (*sp == 0 && log == mp->m_rsum_cache[bbno])
  485. mp->m_rsum_cache[bbno]++;
  486. if (*sp != 0 && log < mp->m_rsum_cache[bbno])
  487. mp->m_rsum_cache[bbno] = log;
  488. }
  489. xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
  490. }
  491. if (sum)
  492. *sum = *sp;
  493. return 0;
  494. }
  495. int
  496. xfs_rtmodify_summary(
  497. xfs_mount_t *mp, /* file system mount structure */
  498. xfs_trans_t *tp, /* transaction pointer */
  499. int log, /* log2 of extent size */
  500. xfs_rtblock_t bbno, /* bitmap block number */
  501. int delta, /* change to make to summary info */
  502. struct xfs_buf **rbpp, /* in/out: summary block buffer */
  503. xfs_fsblock_t *rsb) /* in/out: summary block number */
  504. {
  505. return xfs_rtmodify_summary_int(mp, tp, log, bbno,
  506. delta, rbpp, rsb, NULL);
  507. }
  508. /*
  509. * Set the given range of bitmap bits to the given value.
  510. * Do whatever I/O and logging is required.
  511. */
  512. int
  513. xfs_rtmodify_range(
  514. xfs_mount_t *mp, /* file system mount point */
  515. xfs_trans_t *tp, /* transaction pointer */
  516. xfs_rtblock_t start, /* starting block to modify */
  517. xfs_extlen_t len, /* length of extent to modify */
  518. int val) /* 1 for free, 0 for allocated */
  519. {
  520. xfs_rtword_t *b; /* current word in buffer */
  521. int bit; /* bit number in the word */
  522. xfs_rtblock_t block; /* bitmap block number */
  523. struct xfs_buf *bp; /* buf for the block */
  524. xfs_rtword_t *bufp; /* starting word in buffer */
  525. int error; /* error value */
  526. xfs_rtword_t *first; /* first used word in the buffer */
  527. int i; /* current bit number rel. to start */
  528. int lastbit; /* last useful bit in word */
  529. xfs_rtword_t mask; /* mask o frelevant bits for value */
  530. int word; /* word number in the buffer */
  531. /*
  532. * Compute starting bitmap block number.
  533. */
  534. block = XFS_BITTOBLOCK(mp, start);
  535. /*
  536. * Read the bitmap block, and point to its data.
  537. */
  538. error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
  539. if (error) {
  540. return error;
  541. }
  542. bufp = bp->b_addr;
  543. /*
  544. * Compute the starting word's address, and starting bit.
  545. */
  546. word = XFS_BITTOWORD(mp, start);
  547. first = b = &bufp[word];
  548. bit = (int)(start & (XFS_NBWORD - 1));
  549. /*
  550. * 0 (allocated) => all zeroes; 1 (free) => all ones.
  551. */
  552. val = -val;
  553. /*
  554. * If not starting on a word boundary, deal with the first
  555. * (partial) word.
  556. */
  557. if (bit) {
  558. /*
  559. * Compute first bit not changed and mask of relevant bits.
  560. */
  561. lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
  562. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  563. /*
  564. * Set/clear the active bits.
  565. */
  566. if (val)
  567. *b |= mask;
  568. else
  569. *b &= ~mask;
  570. i = lastbit - bit;
  571. /*
  572. * Go on to the next block if that's where the next word is
  573. * and we need the next word.
  574. */
  575. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  576. /*
  577. * Log the changed part of this block.
  578. * Get the next one.
  579. */
  580. xfs_trans_log_buf(tp, bp,
  581. (uint)((char *)first - (char *)bufp),
  582. (uint)((char *)b - (char *)bufp));
  583. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  584. if (error) {
  585. return error;
  586. }
  587. first = b = bufp = bp->b_addr;
  588. word = 0;
  589. } else {
  590. /*
  591. * Go on to the next word in the buffer
  592. */
  593. b++;
  594. }
  595. } else {
  596. /*
  597. * Starting on a word boundary, no partial word.
  598. */
  599. i = 0;
  600. }
  601. /*
  602. * Loop over whole words in buffers. When we use up one buffer
  603. * we move on to the next one.
  604. */
  605. while (len - i >= XFS_NBWORD) {
  606. /*
  607. * Set the word value correctly.
  608. */
  609. *b = val;
  610. i += XFS_NBWORD;
  611. /*
  612. * Go on to the next block if that's where the next word is
  613. * and we need the next word.
  614. */
  615. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  616. /*
  617. * Log the changed part of this block.
  618. * Get the next one.
  619. */
  620. xfs_trans_log_buf(tp, bp,
  621. (uint)((char *)first - (char *)bufp),
  622. (uint)((char *)b - (char *)bufp));
  623. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  624. if (error) {
  625. return error;
  626. }
  627. first = b = bufp = bp->b_addr;
  628. word = 0;
  629. } else {
  630. /*
  631. * Go on to the next word in the buffer
  632. */
  633. b++;
  634. }
  635. }
  636. /*
  637. * If not ending on a word boundary, deal with the last
  638. * (partial) word.
  639. */
  640. if ((lastbit = len - i)) {
  641. /*
  642. * Compute a mask of relevant bits.
  643. */
  644. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  645. /*
  646. * Set/clear the active bits.
  647. */
  648. if (val)
  649. *b |= mask;
  650. else
  651. *b &= ~mask;
  652. b++;
  653. }
  654. /*
  655. * Log any remaining changed bytes.
  656. */
  657. if (b > first)
  658. xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
  659. (uint)((char *)b - (char *)bufp - 1));
  660. return 0;
  661. }
  662. /*
  663. * Mark an extent specified by start and len freed.
  664. * Updates all the summary information as well as the bitmap.
  665. */
  666. int
  667. xfs_rtfree_range(
  668. xfs_mount_t *mp, /* file system mount point */
  669. xfs_trans_t *tp, /* transaction pointer */
  670. xfs_rtblock_t start, /* starting block to free */
  671. xfs_extlen_t len, /* length to free */
  672. struct xfs_buf **rbpp, /* in/out: summary block buffer */
  673. xfs_fsblock_t *rsb) /* in/out: summary block number */
  674. {
  675. xfs_rtblock_t end; /* end of the freed extent */
  676. int error; /* error value */
  677. xfs_rtblock_t postblock; /* first block freed > end */
  678. xfs_rtblock_t preblock; /* first block freed < start */
  679. end = start + len - 1;
  680. /*
  681. * Modify the bitmap to mark this extent freed.
  682. */
  683. error = xfs_rtmodify_range(mp, tp, start, len, 1);
  684. if (error) {
  685. return error;
  686. }
  687. /*
  688. * Assume we're freeing out of the middle of an allocated extent.
  689. * We need to find the beginning and end of the extent so we can
  690. * properly update the summary.
  691. */
  692. error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
  693. if (error) {
  694. return error;
  695. }
  696. /*
  697. * Find the next allocated block (end of allocated extent).
  698. */
  699. error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
  700. &postblock);
  701. if (error)
  702. return error;
  703. /*
  704. * If there are blocks not being freed at the front of the
  705. * old extent, add summary data for them to be allocated.
  706. */
  707. if (preblock < start) {
  708. error = xfs_rtmodify_summary(mp, tp,
  709. XFS_RTBLOCKLOG(start - preblock),
  710. XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
  711. if (error) {
  712. return error;
  713. }
  714. }
  715. /*
  716. * If there are blocks not being freed at the end of the
  717. * old extent, add summary data for them to be allocated.
  718. */
  719. if (postblock > end) {
  720. error = xfs_rtmodify_summary(mp, tp,
  721. XFS_RTBLOCKLOG(postblock - end),
  722. XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
  723. if (error) {
  724. return error;
  725. }
  726. }
  727. /*
  728. * Increment the summary information corresponding to the entire
  729. * (new) free extent.
  730. */
  731. error = xfs_rtmodify_summary(mp, tp,
  732. XFS_RTBLOCKLOG(postblock + 1 - preblock),
  733. XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
  734. return error;
  735. }
  736. /*
  737. * Check that the given range is either all allocated (val = 0) or
  738. * all free (val = 1).
  739. */
  740. int
  741. xfs_rtcheck_range(
  742. xfs_mount_t *mp, /* file system mount point */
  743. xfs_trans_t *tp, /* transaction pointer */
  744. xfs_rtblock_t start, /* starting block number of extent */
  745. xfs_extlen_t len, /* length of extent */
  746. int val, /* 1 for free, 0 for allocated */
  747. xfs_rtblock_t *new, /* out: first block not matching */
  748. int *stat) /* out: 1 for matches, 0 for not */
  749. {
  750. xfs_rtword_t *b; /* current word in buffer */
  751. int bit; /* bit number in the word */
  752. xfs_rtblock_t block; /* bitmap block number */
  753. struct xfs_buf *bp; /* buf for the block */
  754. xfs_rtword_t *bufp; /* starting word in buffer */
  755. int error; /* error value */
  756. xfs_rtblock_t i; /* current bit number rel. to start */
  757. xfs_rtblock_t lastbit; /* last useful bit in word */
  758. xfs_rtword_t mask; /* mask of relevant bits for value */
  759. xfs_rtword_t wdiff; /* difference from wanted value */
  760. int word; /* word number in the buffer */
  761. /*
  762. * Compute starting bitmap block number
  763. */
  764. block = XFS_BITTOBLOCK(mp, start);
  765. /*
  766. * Read the bitmap block.
  767. */
  768. error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
  769. if (error) {
  770. return error;
  771. }
  772. bufp = bp->b_addr;
  773. /*
  774. * Compute the starting word's address, and starting bit.
  775. */
  776. word = XFS_BITTOWORD(mp, start);
  777. b = &bufp[word];
  778. bit = (int)(start & (XFS_NBWORD - 1));
  779. /*
  780. * 0 (allocated) => all zero's; 1 (free) => all one's.
  781. */
  782. val = -val;
  783. /*
  784. * If not starting on a word boundary, deal with the first
  785. * (partial) word.
  786. */
  787. if (bit) {
  788. /*
  789. * Compute first bit not examined.
  790. */
  791. lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
  792. /*
  793. * Mask of relevant bits.
  794. */
  795. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  796. /*
  797. * Compute difference between actual and desired value.
  798. */
  799. if ((wdiff = (*b ^ val) & mask)) {
  800. /*
  801. * Different, compute first wrong bit and return.
  802. */
  803. xfs_trans_brelse(tp, bp);
  804. i = XFS_RTLOBIT(wdiff) - bit;
  805. *new = start + i;
  806. *stat = 0;
  807. return 0;
  808. }
  809. i = lastbit - bit;
  810. /*
  811. * Go on to next block if that's where the next word is
  812. * and we need the next word.
  813. */
  814. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  815. /*
  816. * If done with this block, get the next one.
  817. */
  818. xfs_trans_brelse(tp, bp);
  819. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  820. if (error) {
  821. return error;
  822. }
  823. b = bufp = bp->b_addr;
  824. word = 0;
  825. } else {
  826. /*
  827. * Go on to the next word in the buffer.
  828. */
  829. b++;
  830. }
  831. } else {
  832. /*
  833. * Starting on a word boundary, no partial word.
  834. */
  835. i = 0;
  836. }
  837. /*
  838. * Loop over whole words in buffers. When we use up one buffer
  839. * we move on to the next one.
  840. */
  841. while (len - i >= XFS_NBWORD) {
  842. /*
  843. * Compute difference between actual and desired value.
  844. */
  845. if ((wdiff = *b ^ val)) {
  846. /*
  847. * Different, compute first wrong bit and return.
  848. */
  849. xfs_trans_brelse(tp, bp);
  850. i += XFS_RTLOBIT(wdiff);
  851. *new = start + i;
  852. *stat = 0;
  853. return 0;
  854. }
  855. i += XFS_NBWORD;
  856. /*
  857. * Go on to next block if that's where the next word is
  858. * and we need the next word.
  859. */
  860. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  861. /*
  862. * If done with this block, get the next one.
  863. */
  864. xfs_trans_brelse(tp, bp);
  865. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  866. if (error) {
  867. return error;
  868. }
  869. b = bufp = bp->b_addr;
  870. word = 0;
  871. } else {
  872. /*
  873. * Go on to the next word in the buffer.
  874. */
  875. b++;
  876. }
  877. }
  878. /*
  879. * If not ending on a word boundary, deal with the last
  880. * (partial) word.
  881. */
  882. if ((lastbit = len - i)) {
  883. /*
  884. * Mask of relevant bits.
  885. */
  886. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  887. /*
  888. * Compute difference between actual and desired value.
  889. */
  890. if ((wdiff = (*b ^ val) & mask)) {
  891. /*
  892. * Different, compute first wrong bit and return.
  893. */
  894. xfs_trans_brelse(tp, bp);
  895. i += XFS_RTLOBIT(wdiff);
  896. *new = start + i;
  897. *stat = 0;
  898. return 0;
  899. } else
  900. i = len;
  901. }
  902. /*
  903. * Successful, return.
  904. */
  905. xfs_trans_brelse(tp, bp);
  906. *new = start + i;
  907. *stat = 1;
  908. return 0;
  909. }
  910. #ifdef DEBUG
  911. /*
  912. * Check that the given extent (block range) is allocated already.
  913. */
  914. STATIC int /* error */
  915. xfs_rtcheck_alloc_range(
  916. xfs_mount_t *mp, /* file system mount point */
  917. xfs_trans_t *tp, /* transaction pointer */
  918. xfs_rtblock_t bno, /* starting block number of extent */
  919. xfs_extlen_t len) /* length of extent */
  920. {
  921. xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */
  922. int stat;
  923. int error;
  924. error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat);
  925. if (error)
  926. return error;
  927. ASSERT(stat);
  928. return 0;
  929. }
  930. #else
  931. #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
  932. #endif
  933. /*
  934. * Free an extent in the realtime subvolume. Length is expressed in
  935. * realtime extents, as is the block number.
  936. */
  937. int /* error */
  938. xfs_rtfree_extent(
  939. xfs_trans_t *tp, /* transaction pointer */
  940. xfs_rtblock_t bno, /* starting block number to free */
  941. xfs_extlen_t len) /* length of extent freed */
  942. {
  943. int error; /* error value */
  944. xfs_mount_t *mp; /* file system mount structure */
  945. xfs_fsblock_t sb; /* summary file block number */
  946. struct xfs_buf *sumbp = NULL; /* summary file block buffer */
  947. mp = tp->t_mountp;
  948. ASSERT(mp->m_rbmip->i_itemp != NULL);
  949. ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
  950. error = xfs_rtcheck_alloc_range(mp, tp, bno, len);
  951. if (error)
  952. return error;
  953. /*
  954. * Free the range of realtime blocks.
  955. */
  956. error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
  957. if (error) {
  958. return error;
  959. }
  960. /*
  961. * Mark more blocks free in the superblock.
  962. */
  963. xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
  964. /*
  965. * If we've now freed all the blocks, reset the file sequence
  966. * number to 0.
  967. */
  968. if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
  969. mp->m_sb.sb_rextents) {
  970. if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
  971. mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
  972. *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
  973. xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
  974. }
  975. return 0;
  976. }
  977. /* Find all the free records within a given range. */
  978. int
  979. xfs_rtalloc_query_range(
  980. struct xfs_mount *mp,
  981. struct xfs_trans *tp,
  982. const struct xfs_rtalloc_rec *low_rec,
  983. const struct xfs_rtalloc_rec *high_rec,
  984. xfs_rtalloc_query_range_fn fn,
  985. void *priv)
  986. {
  987. struct xfs_rtalloc_rec rec;
  988. xfs_rtblock_t rtstart;
  989. xfs_rtblock_t rtend;
  990. xfs_rtblock_t high_key;
  991. int is_free;
  992. int error = 0;
  993. if (low_rec->ar_startext > high_rec->ar_startext)
  994. return -EINVAL;
  995. if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
  996. low_rec->ar_startext == high_rec->ar_startext)
  997. return 0;
  998. high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
  999. /* Iterate the bitmap, looking for discrepancies. */
  1000. rtstart = low_rec->ar_startext;
  1001. while (rtstart <= high_key) {
  1002. /* Is the first block free? */
  1003. error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
  1004. &is_free);
  1005. if (error)
  1006. break;
  1007. /* How long does the extent go for? */
  1008. error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
  1009. if (error)
  1010. break;
  1011. if (is_free) {
  1012. rec.ar_startext = rtstart;
  1013. rec.ar_extcount = rtend - rtstart + 1;
  1014. error = fn(mp, tp, &rec, priv);
  1015. if (error)
  1016. break;
  1017. }
  1018. rtstart = rtend + 1;
  1019. }
  1020. return error;
  1021. }
  1022. /* Find all the free records. */
  1023. int
  1024. xfs_rtalloc_query_all(
  1025. struct xfs_mount *mp,
  1026. struct xfs_trans *tp,
  1027. xfs_rtalloc_query_range_fn fn,
  1028. void *priv)
  1029. {
  1030. struct xfs_rtalloc_rec keys[2];
  1031. keys[0].ar_startext = 0;
  1032. keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
  1033. keys[0].ar_extcount = keys[1].ar_extcount = 0;
  1034. return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
  1035. }
  1036. /* Is the given extent all free? */
  1037. int
  1038. xfs_rtalloc_extent_is_free(
  1039. struct xfs_mount *mp,
  1040. struct xfs_trans *tp,
  1041. xfs_rtblock_t start,
  1042. xfs_extlen_t len,
  1043. bool *is_free)
  1044. {
  1045. xfs_rtblock_t end;
  1046. int matches;
  1047. int error;
  1048. error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
  1049. if (error)
  1050. return error;
  1051. *is_free = matches;
  1052. return 0;
  1053. }