xfs_rtbitmap.c 24 KB

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