xfs_rtbitmap.c 27 KB

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