xfs_rtbitmap.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  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. static 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. bit = 0;
  656. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  657. /*
  658. * Set/clear the active bits.
  659. */
  660. if (val)
  661. *b |= mask;
  662. else
  663. *b &= ~mask;
  664. b++;
  665. }
  666. /*
  667. * Log any remaining changed bytes.
  668. */
  669. if (b > first)
  670. xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
  671. (uint)((char *)b - (char *)bufp - 1));
  672. return 0;
  673. }
  674. /*
  675. * Mark an extent specified by start and len freed.
  676. * Updates all the summary information as well as the bitmap.
  677. */
  678. int
  679. xfs_rtfree_range(
  680. xfs_mount_t *mp, /* file system mount point */
  681. xfs_trans_t *tp, /* transaction pointer */
  682. xfs_rtblock_t start, /* starting block to free */
  683. xfs_extlen_t len, /* length to free */
  684. xfs_buf_t **rbpp, /* in/out: summary block buffer */
  685. xfs_fsblock_t *rsb) /* in/out: summary block number */
  686. {
  687. xfs_rtblock_t end; /* end of the freed extent */
  688. int error; /* error value */
  689. xfs_rtblock_t postblock; /* first block freed > end */
  690. xfs_rtblock_t preblock; /* first block freed < start */
  691. end = start + len - 1;
  692. /*
  693. * Modify the bitmap to mark this extent freed.
  694. */
  695. error = xfs_rtmodify_range(mp, tp, start, len, 1);
  696. if (error) {
  697. return error;
  698. }
  699. /*
  700. * Assume we're freeing out of the middle of an allocated extent.
  701. * We need to find the beginning and end of the extent so we can
  702. * properly update the summary.
  703. */
  704. error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
  705. if (error) {
  706. return error;
  707. }
  708. /*
  709. * Find the next allocated block (end of allocated extent).
  710. */
  711. error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
  712. &postblock);
  713. if (error)
  714. return error;
  715. /*
  716. * If there are blocks not being freed at the front of the
  717. * old extent, add summary data for them to be allocated.
  718. */
  719. if (preblock < start) {
  720. error = xfs_rtmodify_summary(mp, tp,
  721. XFS_RTBLOCKLOG(start - preblock),
  722. XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
  723. if (error) {
  724. return error;
  725. }
  726. }
  727. /*
  728. * If there are blocks not being freed at the end of the
  729. * old extent, add summary data for them to be allocated.
  730. */
  731. if (postblock > end) {
  732. error = xfs_rtmodify_summary(mp, tp,
  733. XFS_RTBLOCKLOG(postblock - end),
  734. XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
  735. if (error) {
  736. return error;
  737. }
  738. }
  739. /*
  740. * Increment the summary information corresponding to the entire
  741. * (new) free extent.
  742. */
  743. error = xfs_rtmodify_summary(mp, tp,
  744. XFS_RTBLOCKLOG(postblock + 1 - preblock),
  745. XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
  746. return error;
  747. }
  748. /*
  749. * Check that the given range is either all allocated (val = 0) or
  750. * all free (val = 1).
  751. */
  752. int
  753. xfs_rtcheck_range(
  754. xfs_mount_t *mp, /* file system mount point */
  755. xfs_trans_t *tp, /* transaction pointer */
  756. xfs_rtblock_t start, /* starting block number of extent */
  757. xfs_extlen_t len, /* length of extent */
  758. int val, /* 1 for free, 0 for allocated */
  759. xfs_rtblock_t *new, /* out: first block not matching */
  760. int *stat) /* out: 1 for matches, 0 for not */
  761. {
  762. xfs_rtword_t *b; /* current word in buffer */
  763. int bit; /* bit number in the word */
  764. xfs_rtblock_t block; /* bitmap block number */
  765. xfs_buf_t *bp; /* buf for the block */
  766. xfs_rtword_t *bufp; /* starting word in buffer */
  767. int error; /* error value */
  768. xfs_rtblock_t i; /* current bit number rel. to start */
  769. xfs_rtblock_t lastbit; /* last useful bit in word */
  770. xfs_rtword_t mask; /* mask of relevant bits for value */
  771. xfs_rtword_t wdiff; /* difference from wanted value */
  772. int word; /* word number in the buffer */
  773. /*
  774. * Compute starting bitmap block number
  775. */
  776. block = XFS_BITTOBLOCK(mp, start);
  777. /*
  778. * Read the bitmap block.
  779. */
  780. error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
  781. if (error) {
  782. return error;
  783. }
  784. bufp = bp->b_addr;
  785. /*
  786. * Compute the starting word's address, and starting bit.
  787. */
  788. word = XFS_BITTOWORD(mp, start);
  789. b = &bufp[word];
  790. bit = (int)(start & (XFS_NBWORD - 1));
  791. /*
  792. * 0 (allocated) => all zero's; 1 (free) => all one's.
  793. */
  794. val = -val;
  795. /*
  796. * If not starting on a word boundary, deal with the first
  797. * (partial) word.
  798. */
  799. if (bit) {
  800. /*
  801. * Compute first bit not examined.
  802. */
  803. lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
  804. /*
  805. * Mask of relevant bits.
  806. */
  807. mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
  808. /*
  809. * Compute difference between actual and desired value.
  810. */
  811. if ((wdiff = (*b ^ val) & mask)) {
  812. /*
  813. * Different, compute first wrong bit and return.
  814. */
  815. xfs_trans_brelse(tp, bp);
  816. i = XFS_RTLOBIT(wdiff) - bit;
  817. *new = start + i;
  818. *stat = 0;
  819. return 0;
  820. }
  821. i = lastbit - bit;
  822. /*
  823. * Go on to next block if that's where the next word is
  824. * and we need the next word.
  825. */
  826. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  827. /*
  828. * If done with this block, get the next one.
  829. */
  830. xfs_trans_brelse(tp, bp);
  831. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  832. if (error) {
  833. return error;
  834. }
  835. b = bufp = bp->b_addr;
  836. word = 0;
  837. } else {
  838. /*
  839. * Go on to the next word in the buffer.
  840. */
  841. b++;
  842. }
  843. } else {
  844. /*
  845. * Starting on a word boundary, no partial word.
  846. */
  847. i = 0;
  848. }
  849. /*
  850. * Loop over whole words in buffers. When we use up one buffer
  851. * we move on to the next one.
  852. */
  853. while (len - i >= XFS_NBWORD) {
  854. /*
  855. * Compute difference between actual and desired value.
  856. */
  857. if ((wdiff = *b ^ val)) {
  858. /*
  859. * Different, compute first wrong bit and return.
  860. */
  861. xfs_trans_brelse(tp, bp);
  862. i += XFS_RTLOBIT(wdiff);
  863. *new = start + i;
  864. *stat = 0;
  865. return 0;
  866. }
  867. i += XFS_NBWORD;
  868. /*
  869. * Go on to next block if that's where the next word is
  870. * and we need the next word.
  871. */
  872. if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
  873. /*
  874. * If done with this block, get the next one.
  875. */
  876. xfs_trans_brelse(tp, bp);
  877. error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
  878. if (error) {
  879. return error;
  880. }
  881. b = bufp = bp->b_addr;
  882. word = 0;
  883. } else {
  884. /*
  885. * Go on to the next word in the buffer.
  886. */
  887. b++;
  888. }
  889. }
  890. /*
  891. * If not ending on a word boundary, deal with the last
  892. * (partial) word.
  893. */
  894. if ((lastbit = len - i)) {
  895. /*
  896. * Mask of relevant bits.
  897. */
  898. mask = ((xfs_rtword_t)1 << lastbit) - 1;
  899. /*
  900. * Compute difference between actual and desired value.
  901. */
  902. if ((wdiff = (*b ^ val) & mask)) {
  903. /*
  904. * Different, compute first wrong bit and return.
  905. */
  906. xfs_trans_brelse(tp, bp);
  907. i += XFS_RTLOBIT(wdiff);
  908. *new = start + i;
  909. *stat = 0;
  910. return 0;
  911. } else
  912. i = len;
  913. }
  914. /*
  915. * Successful, return.
  916. */
  917. xfs_trans_brelse(tp, bp);
  918. *new = start + i;
  919. *stat = 1;
  920. return 0;
  921. }
  922. #ifdef DEBUG
  923. /*
  924. * Check that the given extent (block range) is allocated already.
  925. */
  926. STATIC int /* error */
  927. xfs_rtcheck_alloc_range(
  928. xfs_mount_t *mp, /* file system mount point */
  929. xfs_trans_t *tp, /* transaction pointer */
  930. xfs_rtblock_t bno, /* starting block number of extent */
  931. xfs_extlen_t len) /* length of extent */
  932. {
  933. xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */
  934. int stat;
  935. int error;
  936. error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat);
  937. if (error)
  938. return error;
  939. ASSERT(stat);
  940. return 0;
  941. }
  942. #else
  943. #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
  944. #endif
  945. /*
  946. * Free an extent in the realtime subvolume. Length is expressed in
  947. * realtime extents, as is the block number.
  948. */
  949. int /* error */
  950. xfs_rtfree_extent(
  951. xfs_trans_t *tp, /* transaction pointer */
  952. xfs_rtblock_t bno, /* starting block number to free */
  953. xfs_extlen_t len) /* length of extent freed */
  954. {
  955. int error; /* error value */
  956. xfs_mount_t *mp; /* file system mount structure */
  957. xfs_fsblock_t sb; /* summary file block number */
  958. xfs_buf_t *sumbp = NULL; /* summary file block buffer */
  959. mp = tp->t_mountp;
  960. ASSERT(mp->m_rbmip->i_itemp != NULL);
  961. ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
  962. error = xfs_rtcheck_alloc_range(mp, tp, bno, len);
  963. if (error)
  964. return error;
  965. /*
  966. * Free the range of realtime blocks.
  967. */
  968. error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
  969. if (error) {
  970. return error;
  971. }
  972. /*
  973. * Mark more blocks free in the superblock.
  974. */
  975. xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
  976. /*
  977. * If we've now freed all the blocks, reset the file sequence
  978. * number to 0.
  979. */
  980. if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
  981. mp->m_sb.sb_rextents) {
  982. if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM))
  983. mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
  984. *(__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
  985. xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
  986. }
  987. return 0;
  988. }