jfs_extent.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /*
  2. * Copyright (C) International Business Machines Corp., 2000-2004
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  12. * the 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 to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. #include <linux/fs.h>
  19. #include <linux/quotaops.h>
  20. #include "jfs_incore.h"
  21. #include "jfs_superblock.h"
  22. #include "jfs_dmap.h"
  23. #include "jfs_extent.h"
  24. #include "jfs_debug.h"
  25. /*
  26. * forward references
  27. */
  28. static int extBalloc(struct inode *, s64, s64 *, s64 *);
  29. #ifdef _NOTYET
  30. static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
  31. #endif
  32. static s64 extRoundDown(s64 nb);
  33. /*
  34. * external references
  35. */
  36. extern int jfs_commit_inode(struct inode *, int);
  37. #define DPD(a) (printk("(a): %d\n",(a)))
  38. #define DPC(a) (printk("(a): %c\n",(a)))
  39. #define DPL1(a) \
  40. { \
  41. if ((a) >> 32) \
  42. printk("(a): %x%08x ",(a)); \
  43. else \
  44. printk("(a): %x ",(a) << 32); \
  45. }
  46. #define DPL(a) \
  47. { \
  48. if ((a) >> 32) \
  49. printk("(a): %x%08x\n",(a)); \
  50. else \
  51. printk("(a): %x\n",(a) << 32); \
  52. }
  53. #define DPD1(a) (printk("(a): %d ",(a)))
  54. #define DPX(a) (printk("(a): %08x\n",(a)))
  55. #define DPX1(a) (printk("(a): %08x ",(a)))
  56. #define DPS(a) (printk("%s\n",(a)))
  57. #define DPE(a) (printk("\nENTERING: %s\n",(a)))
  58. #define DPE1(a) (printk("\nENTERING: %s",(a)))
  59. #define DPS1(a) (printk(" %s ",(a)))
  60. /*
  61. * NAME: extAlloc()
  62. *
  63. * FUNCTION: allocate an extent for a specified page range within a
  64. * file.
  65. *
  66. * PARAMETERS:
  67. * ip - the inode of the file.
  68. * xlen - requested extent length.
  69. * pno - the starting page number with the file.
  70. * xp - pointer to an xad. on entry, xad describes an
  71. * extent that is used as an allocation hint if the
  72. * xaddr of the xad is non-zero. on successful exit,
  73. * the xad describes the newly allocated extent.
  74. * abnr - boolean_t indicating whether the newly allocated extent
  75. * should be marked as allocated but not recorded.
  76. *
  77. * RETURN VALUES:
  78. * 0 - success
  79. * -EIO - i/o error.
  80. * -ENOSPC - insufficient disk resources.
  81. */
  82. int
  83. extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
  84. {
  85. struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
  86. s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
  87. int rc;
  88. int xflag;
  89. /* This blocks if we are low on resources */
  90. txBeginAnon(ip->i_sb);
  91. /* Avoid race with jfs_commit_inode() */
  92. down(&JFS_IP(ip)->commit_sem);
  93. /* validate extent length */
  94. if (xlen > MAXXLEN)
  95. xlen = MAXXLEN;
  96. /* get the page's starting extent offset */
  97. xoff = pno << sbi->l2nbperpage;
  98. /* check if an allocation hint was provided */
  99. if ((hint = addressXAD(xp))) {
  100. /* get the size of the extent described by the hint */
  101. nxlen = lengthXAD(xp);
  102. /* check if the hint is for the portion of the file
  103. * immediately previous to the current allocation
  104. * request and if hint extent has the same abnr
  105. * value as the current request. if so, we can
  106. * extend the hint extent to include the current
  107. * extent if we can allocate the blocks immediately
  108. * following the hint extent.
  109. */
  110. if (offsetXAD(xp) + nxlen == xoff &&
  111. abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE))
  112. xaddr = hint + nxlen;
  113. /* adjust the hint to the last block of the extent */
  114. hint += (nxlen - 1);
  115. }
  116. /* allocate the disk blocks for the extent. initially, extBalloc()
  117. * will try to allocate disk blocks for the requested size (xlen).
  118. * if this fails (xlen contigious free blocks not avaliable), it'll
  119. * try to allocate a smaller number of blocks (producing a smaller
  120. * extent), with this smaller number of blocks consisting of the
  121. * requested number of blocks rounded down to the next smaller
  122. * power of 2 number (i.e. 16 -> 8). it'll continue to round down
  123. * and retry the allocation until the number of blocks to allocate
  124. * is smaller than the number of blocks per page.
  125. */
  126. nxlen = xlen;
  127. if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
  128. up(&JFS_IP(ip)->commit_sem);
  129. return (rc);
  130. }
  131. /* Allocate blocks to quota. */
  132. if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
  133. dbFree(ip, nxaddr, (s64) nxlen);
  134. up(&JFS_IP(ip)->commit_sem);
  135. return -EDQUOT;
  136. }
  137. /* determine the value of the extent flag */
  138. xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
  139. /* if we can extend the hint extent to cover the current request,
  140. * extend it. otherwise, insert a new extent to
  141. * cover the current request.
  142. */
  143. if (xaddr && xaddr == nxaddr)
  144. rc = xtExtend(0, ip, xoff, (int) nxlen, 0);
  145. else
  146. rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
  147. /* if the extend or insert failed,
  148. * free the newly allocated blocks and return the error.
  149. */
  150. if (rc) {
  151. dbFree(ip, nxaddr, nxlen);
  152. DQUOT_FREE_BLOCK(ip, nxlen);
  153. up(&JFS_IP(ip)->commit_sem);
  154. return (rc);
  155. }
  156. /* set the results of the extent allocation */
  157. XADaddress(xp, nxaddr);
  158. XADlength(xp, nxlen);
  159. XADoffset(xp, xoff);
  160. xp->flag = xflag;
  161. mark_inode_dirty(ip);
  162. up(&JFS_IP(ip)->commit_sem);
  163. /*
  164. * COMMIT_SyncList flags an anonymous tlock on page that is on
  165. * sync list.
  166. * We need to commit the inode to get the page written disk.
  167. */
  168. if (test_and_clear_cflag(COMMIT_Synclist,ip))
  169. jfs_commit_inode(ip, 0);
  170. return (0);
  171. }
  172. #ifdef _NOTYET
  173. /*
  174. * NAME: extRealloc()
  175. *
  176. * FUNCTION: extend the allocation of a file extent containing a
  177. * partial back last page.
  178. *
  179. * PARAMETERS:
  180. * ip - the inode of the file.
  181. * cp - cbuf for the partial backed last page.
  182. * xlen - request size of the resulting extent.
  183. * xp - pointer to an xad. on successful exit, the xad
  184. * describes the newly allocated extent.
  185. * abnr - boolean_t indicating whether the newly allocated extent
  186. * should be marked as allocated but not recorded.
  187. *
  188. * RETURN VALUES:
  189. * 0 - success
  190. * -EIO - i/o error.
  191. * -ENOSPC - insufficient disk resources.
  192. */
  193. int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
  194. {
  195. struct super_block *sb = ip->i_sb;
  196. s64 xaddr, xlen, nxaddr, delta, xoff;
  197. s64 ntail, nextend, ninsert;
  198. int rc, nbperpage = JFS_SBI(sb)->nbperpage;
  199. int xflag;
  200. /* This blocks if we are low on resources */
  201. txBeginAnon(ip->i_sb);
  202. down(&JFS_IP(ip)->commit_sem);
  203. /* validate extent length */
  204. if (nxlen > MAXXLEN)
  205. nxlen = MAXXLEN;
  206. /* get the extend (partial) page's disk block address and
  207. * number of blocks.
  208. */
  209. xaddr = addressXAD(xp);
  210. xlen = lengthXAD(xp);
  211. xoff = offsetXAD(xp);
  212. /* if the extend page is abnr and if the request is for
  213. * the extent to be allocated and recorded,
  214. * make the page allocated and recorded.
  215. */
  216. if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
  217. xp->flag = 0;
  218. if ((rc = xtUpdate(0, ip, xp)))
  219. goto exit;
  220. }
  221. /* try to allocated the request number of blocks for the
  222. * extent. dbRealloc() first tries to satisfy the request
  223. * by extending the allocation in place. otherwise, it will
  224. * try to allocate a new set of blocks large enough for the
  225. * request. in satisfying a request, dbReAlloc() may allocate
  226. * less than what was request but will always allocate enough
  227. * space as to satisfy the extend page.
  228. */
  229. if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
  230. goto exit;
  231. /* Allocat blocks to quota. */
  232. if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
  233. dbFree(ip, nxaddr, (s64) nxlen);
  234. up(&JFS_IP(ip)->commit_sem);
  235. return -EDQUOT;
  236. }
  237. delta = nxlen - xlen;
  238. /* check if the extend page is not abnr but the request is abnr
  239. * and the allocated disk space is for more than one page. if this
  240. * is the case, there is a miss match of abnr between the extend page
  241. * and the one or more pages following the extend page. as a result,
  242. * two extents will have to be manipulated. the first will be that
  243. * of the extent of the extend page and will be manipulated thru
  244. * an xtExtend() or an xtTailgate(), depending upon whether the
  245. * disk allocation occurred as an inplace extension. the second
  246. * extent will be manipulated (created) through an xtInsert() and
  247. * will be for the pages following the extend page.
  248. */
  249. if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) {
  250. ntail = nbperpage;
  251. nextend = ntail - xlen;
  252. ninsert = nxlen - nbperpage;
  253. xflag = XAD_NOTRECORDED;
  254. } else {
  255. ntail = nxlen;
  256. nextend = delta;
  257. ninsert = 0;
  258. xflag = xp->flag;
  259. }
  260. /* if we were able to extend the disk allocation in place,
  261. * extend the extent. otherwise, move the extent to a
  262. * new disk location.
  263. */
  264. if (xaddr == nxaddr) {
  265. /* extend the extent */
  266. if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
  267. dbFree(ip, xaddr + xlen, delta);
  268. DQUOT_FREE_BLOCK(ip, nxlen);
  269. goto exit;
  270. }
  271. } else {
  272. /*
  273. * move the extent to a new location:
  274. *
  275. * xtTailgate() accounts for relocated tail extent;
  276. */
  277. if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
  278. dbFree(ip, nxaddr, nxlen);
  279. DQUOT_FREE_BLOCK(ip, nxlen);
  280. goto exit;
  281. }
  282. }
  283. /* check if we need to also insert a new extent */
  284. if (ninsert) {
  285. /* perform the insert. if it fails, free the blocks
  286. * to be inserted and make it appear that we only did
  287. * the xtExtend() or xtTailgate() above.
  288. */
  289. xaddr = nxaddr + ntail;
  290. if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert,
  291. &xaddr, 0)) {
  292. dbFree(ip, xaddr, (s64) ninsert);
  293. delta = nextend;
  294. nxlen = ntail;
  295. xflag = 0;
  296. }
  297. }
  298. /* set the return results */
  299. XADaddress(xp, nxaddr);
  300. XADlength(xp, nxlen);
  301. XADoffset(xp, xoff);
  302. xp->flag = xflag;
  303. mark_inode_dirty(ip);
  304. exit:
  305. up(&JFS_IP(ip)->commit_sem);
  306. return (rc);
  307. }
  308. #endif /* _NOTYET */
  309. /*
  310. * NAME: extHint()
  311. *
  312. * FUNCTION: produce an extent allocation hint for a file offset.
  313. *
  314. * PARAMETERS:
  315. * ip - the inode of the file.
  316. * offset - file offset for which the hint is needed.
  317. * xp - pointer to the xad that is to be filled in with
  318. * the hint.
  319. *
  320. * RETURN VALUES:
  321. * 0 - success
  322. * -EIO - i/o error.
  323. */
  324. int extHint(struct inode *ip, s64 offset, xad_t * xp)
  325. {
  326. struct super_block *sb = ip->i_sb;
  327. struct xadlist xadl;
  328. struct lxdlist lxdl;
  329. lxd_t lxd;
  330. s64 prev;
  331. int rc, nbperpage = JFS_SBI(sb)->nbperpage;
  332. /* init the hint as "no hint provided" */
  333. XADaddress(xp, 0);
  334. /* determine the starting extent offset of the page previous
  335. * to the page containing the offset.
  336. */
  337. prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
  338. /* if the offsets in the first page of the file,
  339. * no hint provided.
  340. */
  341. if (prev < 0)
  342. return (0);
  343. /* prepare to lookup the previous page's extent info */
  344. lxdl.maxnlxd = 1;
  345. lxdl.nlxd = 1;
  346. lxdl.lxd = &lxd;
  347. LXDoffset(&lxd, prev)
  348. LXDlength(&lxd, nbperpage);
  349. xadl.maxnxad = 1;
  350. xadl.nxad = 0;
  351. xadl.xad = xp;
  352. /* perform the lookup */
  353. if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
  354. return (rc);
  355. /* check if not extent exists for the previous page.
  356. * this is possible for sparse files.
  357. */
  358. if (xadl.nxad == 0) {
  359. // assert(ISSPARSE(ip));
  360. return (0);
  361. }
  362. /* only preserve the abnr flag within the xad flags
  363. * of the returned hint.
  364. */
  365. xp->flag &= XAD_NOTRECORDED;
  366. if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
  367. jfs_error(ip->i_sb, "extHint: corrupt xtree");
  368. return -EIO;
  369. }
  370. return (0);
  371. }
  372. /*
  373. * NAME: extRecord()
  374. *
  375. * FUNCTION: change a page with a file from not recorded to recorded.
  376. *
  377. * PARAMETERS:
  378. * ip - inode of the file.
  379. * cp - cbuf of the file page.
  380. *
  381. * RETURN VALUES:
  382. * 0 - success
  383. * -EIO - i/o error.
  384. * -ENOSPC - insufficient disk resources.
  385. */
  386. int extRecord(struct inode *ip, xad_t * xp)
  387. {
  388. int rc;
  389. txBeginAnon(ip->i_sb);
  390. down(&JFS_IP(ip)->commit_sem);
  391. /* update the extent */
  392. rc = xtUpdate(0, ip, xp);
  393. up(&JFS_IP(ip)->commit_sem);
  394. return rc;
  395. }
  396. #ifdef _NOTYET
  397. /*
  398. * NAME: extFill()
  399. *
  400. * FUNCTION: allocate disk space for a file page that represents
  401. * a file hole.
  402. *
  403. * PARAMETERS:
  404. * ip - the inode of the file.
  405. * cp - cbuf of the file page represent the hole.
  406. *
  407. * RETURN VALUES:
  408. * 0 - success
  409. * -EIO - i/o error.
  410. * -ENOSPC - insufficient disk resources.
  411. */
  412. int extFill(struct inode *ip, xad_t * xp)
  413. {
  414. int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
  415. s64 blkno = offsetXAD(xp) >> ip->i_blksize;
  416. // assert(ISSPARSE(ip));
  417. /* initialize the extent allocation hint */
  418. XADaddress(xp, 0);
  419. /* allocate an extent to fill the hole */
  420. if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE)))
  421. return (rc);
  422. assert(lengthPXD(xp) == nbperpage);
  423. return (0);
  424. }
  425. #endif /* _NOTYET */
  426. /*
  427. * NAME: extBalloc()
  428. *
  429. * FUNCTION: allocate disk blocks to form an extent.
  430. *
  431. * initially, we will try to allocate disk blocks for the
  432. * requested size (nblocks). if this fails (nblocks
  433. * contigious free blocks not avaliable), we'll try to allocate
  434. * a smaller number of blocks (producing a smaller extent), with
  435. * this smaller number of blocks consisting of the requested
  436. * number of blocks rounded down to the next smaller power of 2
  437. * number (i.e. 16 -> 8). we'll continue to round down and
  438. * retry the allocation until the number of blocks to allocate
  439. * is smaller than the number of blocks per page.
  440. *
  441. * PARAMETERS:
  442. * ip - the inode of the file.
  443. * hint - disk block number to be used as an allocation hint.
  444. * *nblocks - pointer to an s64 value. on entry, this value specifies
  445. * the desired number of block to be allocated. on successful
  446. * exit, this value is set to the number of blocks actually
  447. * allocated.
  448. * blkno - pointer to a block address that is filled in on successful
  449. * return with the starting block number of the newly
  450. * allocated block range.
  451. *
  452. * RETURN VALUES:
  453. * 0 - success
  454. * -EIO - i/o error.
  455. * -ENOSPC - insufficient disk resources.
  456. */
  457. static int
  458. extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
  459. {
  460. struct jfs_inode_info *ji = JFS_IP(ip);
  461. struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
  462. s64 nb, nblks, daddr, max;
  463. int rc, nbperpage = sbi->nbperpage;
  464. struct bmap *bmp = sbi->bmap;
  465. int ag;
  466. /* get the number of blocks to initially attempt to allocate.
  467. * we'll first try the number of blocks requested unless this
  468. * number is greater than the maximum number of contigious free
  469. * blocks in the map. in that case, we'll start off with the
  470. * maximum free.
  471. */
  472. max = (s64) 1 << bmp->db_maxfreebud;
  473. if (*nblocks >= max && *nblocks > nbperpage)
  474. nb = nblks = (max > nbperpage) ? max : nbperpage;
  475. else
  476. nb = nblks = *nblocks;
  477. /* try to allocate blocks */
  478. while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) {
  479. /* if something other than an out of space error,
  480. * stop and return this error.
  481. */
  482. if (rc != -ENOSPC)
  483. return (rc);
  484. /* decrease the allocation request size */
  485. nb = min(nblks, extRoundDown(nb));
  486. /* give up if we cannot cover a page */
  487. if (nb < nbperpage)
  488. return (rc);
  489. }
  490. *nblocks = nb;
  491. *blkno = daddr;
  492. if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) {
  493. ag = BLKTOAG(daddr, sbi);
  494. spin_lock_irq(&ji->ag_lock);
  495. if (ji->active_ag == -1) {
  496. atomic_inc(&bmp->db_active[ag]);
  497. ji->active_ag = ag;
  498. } else if (ji->active_ag != ag) {
  499. atomic_dec(&bmp->db_active[ji->active_ag]);
  500. atomic_inc(&bmp->db_active[ag]);
  501. ji->active_ag = ag;
  502. }
  503. spin_unlock_irq(&ji->ag_lock);
  504. }
  505. return (0);
  506. }
  507. #ifdef _NOTYET
  508. /*
  509. * NAME: extBrealloc()
  510. *
  511. * FUNCTION: attempt to extend an extent's allocation.
  512. *
  513. * initially, we will try to extend the extent's allocation
  514. * in place. if this fails, we'll try to move the extent
  515. * to a new set of blocks. if moving the extent, we initially
  516. * will try to allocate disk blocks for the requested size
  517. * (nnew). if this fails (nnew contigious free blocks not
  518. * avaliable), we'll try to allocate a smaller number of
  519. * blocks (producing a smaller extent), with this smaller
  520. * number of blocks consisting of the requested number of
  521. * blocks rounded down to the next smaller power of 2
  522. * number (i.e. 16 -> 8). we'll continue to round down and
  523. * retry the allocation until the number of blocks to allocate
  524. * is smaller than the number of blocks per page.
  525. *
  526. * PARAMETERS:
  527. * ip - the inode of the file.
  528. * blkno - starting block number of the extents current allocation.
  529. * nblks - number of blocks within the extents current allocation.
  530. * newnblks - pointer to a s64 value. on entry, this value is the
  531. * the new desired extent size (number of blocks). on
  532. * successful exit, this value is set to the extent's actual
  533. * new size (new number of blocks).
  534. * newblkno - the starting block number of the extents new allocation.
  535. *
  536. * RETURN VALUES:
  537. * 0 - success
  538. * -EIO - i/o error.
  539. * -ENOSPC - insufficient disk resources.
  540. */
  541. static int
  542. extBrealloc(struct inode *ip,
  543. s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno)
  544. {
  545. int rc;
  546. /* try to extend in place */
  547. if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) {
  548. *newblkno = blkno;
  549. return (0);
  550. } else {
  551. if (rc != -ENOSPC)
  552. return (rc);
  553. }
  554. /* in place extension not possible.
  555. * try to move the extent to a new set of blocks.
  556. */
  557. return (extBalloc(ip, blkno, newnblks, newblkno));
  558. }
  559. #endif /* _NOTYET */
  560. /*
  561. * NAME: extRoundDown()
  562. *
  563. * FUNCTION: round down a specified number of blocks to the next
  564. * smallest power of 2 number.
  565. *
  566. * PARAMETERS:
  567. * nb - the inode of the file.
  568. *
  569. * RETURN VALUES:
  570. * next smallest power of 2 number.
  571. */
  572. static s64 extRoundDown(s64 nb)
  573. {
  574. int i;
  575. u64 m, k;
  576. for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) {
  577. if (m & nb)
  578. break;
  579. }
  580. i = 63 - i;
  581. k = (u64) 1 << i;
  582. k = ((k - 1) & nb) ? k : k >> 1;
  583. return (k);
  584. }