0001
0002
0003
0004
0005
0006 #include "xfs.h"
0007 #include "xfs_fs.h"
0008 #include "xfs_shared.h"
0009 #include "xfs_format.h"
0010 #include "xfs_log_format.h"
0011 #include "xfs_trans_resv.h"
0012 #include "xfs_bit.h"
0013 #include "xfs_mount.h"
0014 #include "xfs_inode.h"
0015 #include "xfs_bmap.h"
0016 #include "xfs_bmap_btree.h"
0017 #include "xfs_trans.h"
0018 #include "xfs_trans_space.h"
0019 #include "xfs_icache.h"
0020 #include "xfs_rtalloc.h"
0021 #include "xfs_sb.h"
0022
0023
0024
0025
0026
0027
0028
0029 static int
0030 xfs_rtget_summary(
0031 xfs_mount_t *mp,
0032 xfs_trans_t *tp,
0033 int log,
0034 xfs_rtblock_t bbno,
0035 struct xfs_buf **rbpp,
0036 xfs_fsblock_t *rsb,
0037 xfs_suminfo_t *sum)
0038 {
0039 return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum);
0040 }
0041
0042
0043
0044
0045
0046 STATIC int
0047 xfs_rtany_summary(
0048 xfs_mount_t *mp,
0049 xfs_trans_t *tp,
0050 int low,
0051 int high,
0052 xfs_rtblock_t bbno,
0053 struct xfs_buf **rbpp,
0054 xfs_fsblock_t *rsb,
0055 int *stat)
0056 {
0057 int error;
0058 int log;
0059 xfs_suminfo_t sum;
0060
0061
0062 if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno])
0063 low = mp->m_rsum_cache[bbno];
0064
0065
0066
0067
0068 for (log = low; log <= high; log++) {
0069
0070
0071
0072 error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum);
0073 if (error) {
0074 return error;
0075 }
0076
0077
0078
0079 if (sum) {
0080 *stat = 1;
0081 goto out;
0082 }
0083 }
0084
0085
0086
0087 *stat = 0;
0088 out:
0089
0090 if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno])
0091 mp->m_rsum_cache[bbno] = log;
0092 return 0;
0093 }
0094
0095
0096
0097
0098
0099
0100 STATIC int
0101 xfs_rtcopy_summary(
0102 xfs_mount_t *omp,
0103 xfs_mount_t *nmp,
0104 xfs_trans_t *tp)
0105 {
0106 xfs_rtblock_t bbno;
0107 struct xfs_buf *bp;
0108 int error;
0109 int log;
0110 xfs_suminfo_t sum;
0111 xfs_fsblock_t sumbno;
0112
0113 bp = NULL;
0114 for (log = omp->m_rsumlevels - 1; log >= 0; log--) {
0115 for (bbno = omp->m_sb.sb_rbmblocks - 1;
0116 (xfs_srtblock_t)bbno >= 0;
0117 bbno--) {
0118 error = xfs_rtget_summary(omp, tp, log, bbno, &bp,
0119 &sumbno, &sum);
0120 if (error)
0121 return error;
0122 if (sum == 0)
0123 continue;
0124 error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum,
0125 &bp, &sumbno);
0126 if (error)
0127 return error;
0128 error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum,
0129 &bp, &sumbno);
0130 if (error)
0131 return error;
0132 ASSERT(sum > 0);
0133 }
0134 }
0135 return 0;
0136 }
0137
0138
0139
0140
0141 STATIC int
0142 xfs_rtallocate_range(
0143 xfs_mount_t *mp,
0144 xfs_trans_t *tp,
0145 xfs_rtblock_t start,
0146 xfs_extlen_t len,
0147 struct xfs_buf **rbpp,
0148 xfs_fsblock_t *rsb)
0149 {
0150 xfs_rtblock_t end;
0151 int error;
0152 xfs_rtblock_t postblock = 0;
0153 xfs_rtblock_t preblock = 0;
0154
0155 end = start + len - 1;
0156
0157
0158
0159
0160
0161 error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
0162 if (error) {
0163 return error;
0164 }
0165
0166
0167
0168 error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
0169 &postblock);
0170 if (error) {
0171 return error;
0172 }
0173
0174
0175
0176
0177 error = xfs_rtmodify_summary(mp, tp,
0178 XFS_RTBLOCKLOG(postblock + 1 - preblock),
0179 XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
0180 if (error) {
0181 return error;
0182 }
0183
0184
0185
0186
0187 if (preblock < start) {
0188 error = xfs_rtmodify_summary(mp, tp,
0189 XFS_RTBLOCKLOG(start - preblock),
0190 XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
0191 if (error) {
0192 return error;
0193 }
0194 }
0195
0196
0197
0198
0199 if (postblock > end) {
0200 error = xfs_rtmodify_summary(mp, tp,
0201 XFS_RTBLOCKLOG(postblock - end),
0202 XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb);
0203 if (error) {
0204 return error;
0205 }
0206 }
0207
0208
0209
0210 error = xfs_rtmodify_range(mp, tp, start, len, 0);
0211 return error;
0212 }
0213
0214
0215
0216
0217
0218
0219
0220 STATIC int
0221 xfs_rtallocate_extent_block(
0222 xfs_mount_t *mp,
0223 xfs_trans_t *tp,
0224 xfs_rtblock_t bbno,
0225 xfs_extlen_t minlen,
0226 xfs_extlen_t maxlen,
0227 xfs_extlen_t *len,
0228 xfs_rtblock_t *nextp,
0229 struct xfs_buf **rbpp,
0230 xfs_fsblock_t *rsb,
0231 xfs_extlen_t prod,
0232 xfs_rtblock_t *rtblock)
0233 {
0234 xfs_rtblock_t besti;
0235 xfs_rtblock_t bestlen;
0236 xfs_rtblock_t end;
0237 int error;
0238 xfs_rtblock_t i;
0239 xfs_rtblock_t next;
0240 int stat;
0241
0242
0243
0244
0245
0246 for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0,
0247 end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1;
0248 i <= end;
0249 i++) {
0250
0251 maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i;
0252
0253
0254
0255
0256
0257 error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat);
0258 if (error) {
0259 return error;
0260 }
0261 if (stat) {
0262
0263
0264
0265 error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp,
0266 rsb);
0267 if (error) {
0268 return error;
0269 }
0270 *len = maxlen;
0271 *rtblock = i;
0272 return 0;
0273 }
0274
0275
0276
0277
0278
0279
0280 if (minlen < maxlen) {
0281 xfs_rtblock_t thislen;
0282
0283 thislen = next - i;
0284 if (thislen >= minlen && thislen > bestlen) {
0285 besti = i;
0286 bestlen = thislen;
0287 }
0288 }
0289
0290
0291
0292 if (next < end) {
0293 error = xfs_rtfind_forw(mp, tp, next, end, &i);
0294 if (error) {
0295 return error;
0296 }
0297 } else
0298 break;
0299 }
0300
0301
0302
0303 if (minlen < maxlen && besti != -1) {
0304 xfs_extlen_t p;
0305
0306
0307
0308
0309 if (prod > 1) {
0310 div_u64_rem(bestlen, prod, &p);
0311 if (p)
0312 bestlen -= p;
0313 }
0314
0315
0316
0317
0318 error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb);
0319 if (error) {
0320 return error;
0321 }
0322 *len = bestlen;
0323 *rtblock = besti;
0324 return 0;
0325 }
0326
0327
0328
0329 *nextp = next;
0330 *rtblock = NULLRTBLOCK;
0331 return 0;
0332 }
0333
0334
0335
0336
0337
0338
0339
0340 STATIC int
0341 xfs_rtallocate_extent_exact(
0342 xfs_mount_t *mp,
0343 xfs_trans_t *tp,
0344 xfs_rtblock_t bno,
0345 xfs_extlen_t minlen,
0346 xfs_extlen_t maxlen,
0347 xfs_extlen_t *len,
0348 struct xfs_buf **rbpp,
0349 xfs_fsblock_t *rsb,
0350 xfs_extlen_t prod,
0351 xfs_rtblock_t *rtblock)
0352 {
0353 int error;
0354 xfs_extlen_t i;
0355 int isfree;
0356 xfs_rtblock_t next;
0357
0358 ASSERT(minlen % prod == 0 && maxlen % prod == 0);
0359
0360
0361
0362 error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree);
0363 if (error) {
0364 return error;
0365 }
0366 if (isfree) {
0367
0368
0369
0370 error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
0371 if (error) {
0372 return error;
0373 }
0374 *len = maxlen;
0375 *rtblock = bno;
0376 return 0;
0377 }
0378
0379
0380
0381 maxlen = next - bno;
0382 if (maxlen < minlen) {
0383
0384
0385
0386 *rtblock = NULLRTBLOCK;
0387 return 0;
0388 }
0389
0390
0391
0392 if (prod > 1 && (i = maxlen % prod)) {
0393 maxlen -= i;
0394 if (maxlen < minlen) {
0395
0396
0397
0398 *rtblock = NULLRTBLOCK;
0399 return 0;
0400 }
0401 }
0402
0403
0404
0405 error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
0406 if (error) {
0407 return error;
0408 }
0409 *len = maxlen;
0410 *rtblock = bno;
0411 return 0;
0412 }
0413
0414
0415
0416
0417
0418
0419 STATIC int
0420 xfs_rtallocate_extent_near(
0421 xfs_mount_t *mp,
0422 xfs_trans_t *tp,
0423 xfs_rtblock_t bno,
0424 xfs_extlen_t minlen,
0425 xfs_extlen_t maxlen,
0426 xfs_extlen_t *len,
0427 struct xfs_buf **rbpp,
0428 xfs_fsblock_t *rsb,
0429 xfs_extlen_t prod,
0430 xfs_rtblock_t *rtblock)
0431 {
0432 int any;
0433 xfs_rtblock_t bbno;
0434 int error;
0435 int i;
0436 int j;
0437 int log2len;
0438 xfs_rtblock_t n;
0439 xfs_rtblock_t r;
0440
0441 ASSERT(minlen % prod == 0 && maxlen % prod == 0);
0442
0443
0444
0445
0446 if (bno >= mp->m_sb.sb_rextents)
0447 bno = mp->m_sb.sb_rextents - 1;
0448
0449
0450 maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno;
0451 if (maxlen < minlen) {
0452 *rtblock = NULLRTBLOCK;
0453 return 0;
0454 }
0455
0456
0457
0458
0459 error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len,
0460 rbpp, rsb, prod, &r);
0461 if (error) {
0462 return error;
0463 }
0464
0465
0466
0467 if (r != NULLRTBLOCK) {
0468 *rtblock = r;
0469 return 0;
0470 }
0471 bbno = XFS_BITTOBLOCK(mp, bno);
0472 i = 0;
0473 ASSERT(minlen != 0);
0474 log2len = xfs_highbit32(minlen);
0475
0476
0477
0478 for (;;) {
0479
0480
0481
0482
0483 error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1,
0484 bbno + i, rbpp, rsb, &any);
0485 if (error) {
0486 return error;
0487 }
0488
0489
0490
0491
0492 if (any) {
0493
0494
0495
0496 if (i >= 0) {
0497
0498
0499
0500
0501 error = xfs_rtallocate_extent_block(mp, tp,
0502 bbno + i, minlen, maxlen, len, &n, rbpp,
0503 rsb, prod, &r);
0504 if (error) {
0505 return error;
0506 }
0507
0508
0509
0510 if (r != NULLRTBLOCK) {
0511 *rtblock = r;
0512 return 0;
0513 }
0514 }
0515
0516
0517
0518 else {
0519
0520
0521
0522
0523
0524
0525 for (j = -1; j > i; j--) {
0526
0527
0528
0529
0530 error = xfs_rtany_summary(mp, tp,
0531 log2len, mp->m_rsumlevels - 1,
0532 bbno + j, rbpp, rsb, &any);
0533 if (error) {
0534 return error;
0535 }
0536
0537
0538
0539
0540
0541
0542
0543
0544 if (any)
0545 continue;
0546 error = xfs_rtallocate_extent_block(mp,
0547 tp, bbno + j, minlen, maxlen,
0548 len, &n, rbpp, rsb, prod, &r);
0549 if (error) {
0550 return error;
0551 }
0552
0553
0554
0555 if (r != NULLRTBLOCK) {
0556 *rtblock = r;
0557 return 0;
0558 }
0559 }
0560
0561
0562
0563
0564
0565
0566
0567
0568 error = xfs_rtallocate_extent_block(mp, tp,
0569 bbno + i, minlen, maxlen, len, &n, rbpp,
0570 rsb, prod, &r);
0571 if (error) {
0572 return error;
0573 }
0574
0575
0576
0577 if (r != NULLRTBLOCK) {
0578 *rtblock = r;
0579 return 0;
0580 }
0581 }
0582 }
0583
0584
0585
0586
0587 if (i > 0 && (int)bbno - i >= 0)
0588 i = -i;
0589
0590
0591
0592
0593 else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)
0594 i++;
0595
0596
0597
0598
0599 else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)
0600 i = 1 - i;
0601
0602
0603
0604
0605 else if (i <= 0 && (int)bbno + i > 0)
0606 i--;
0607
0608
0609
0610 else
0611 break;
0612 }
0613 *rtblock = NULLRTBLOCK;
0614 return 0;
0615 }
0616
0617
0618
0619
0620
0621
0622 STATIC int
0623 xfs_rtallocate_extent_size(
0624 xfs_mount_t *mp,
0625 xfs_trans_t *tp,
0626 xfs_extlen_t minlen,
0627 xfs_extlen_t maxlen,
0628 xfs_extlen_t *len,
0629 struct xfs_buf **rbpp,
0630 xfs_fsblock_t *rsb,
0631 xfs_extlen_t prod,
0632 xfs_rtblock_t *rtblock)
0633 {
0634 int error;
0635 int i;
0636 int l;
0637 xfs_rtblock_t n;
0638 xfs_rtblock_t r;
0639 xfs_suminfo_t sum;
0640
0641 ASSERT(minlen % prod == 0 && maxlen % prod == 0);
0642 ASSERT(maxlen != 0);
0643
0644
0645
0646
0647
0648
0649
0650
0651 for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
0652
0653
0654
0655 for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
0656
0657
0658
0659 error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
0660 &sum);
0661 if (error) {
0662 return error;
0663 }
0664
0665
0666
0667 if (!sum)
0668 continue;
0669
0670
0671
0672 error = xfs_rtallocate_extent_block(mp, tp, i, maxlen,
0673 maxlen, len, &n, rbpp, rsb, prod, &r);
0674 if (error) {
0675 return error;
0676 }
0677
0678
0679
0680 if (r != NULLRTBLOCK) {
0681 *rtblock = r;
0682 return 0;
0683 }
0684
0685
0686
0687
0688
0689 if (XFS_BITTOBLOCK(mp, n) > i + 1)
0690 i = XFS_BITTOBLOCK(mp, n) - 1;
0691 }
0692 }
0693
0694
0695
0696
0697 if (minlen > --maxlen) {
0698 *rtblock = NULLRTBLOCK;
0699 return 0;
0700 }
0701 ASSERT(minlen != 0);
0702 ASSERT(maxlen != 0);
0703
0704
0705
0706
0707
0708
0709 for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
0710
0711
0712
0713
0714 for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
0715
0716
0717
0718 error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
0719 &sum);
0720 if (error) {
0721 return error;
0722 }
0723
0724
0725
0726 if (!sum)
0727 continue;
0728
0729
0730
0731
0732
0733 error = xfs_rtallocate_extent_block(mp, tp, i,
0734 XFS_RTMAX(minlen, 1 << l),
0735 XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),
0736 len, &n, rbpp, rsb, prod, &r);
0737 if (error) {
0738 return error;
0739 }
0740
0741
0742
0743 if (r != NULLRTBLOCK) {
0744 *rtblock = r;
0745 return 0;
0746 }
0747
0748
0749
0750
0751
0752 if (XFS_BITTOBLOCK(mp, n) > i + 1)
0753 i = XFS_BITTOBLOCK(mp, n) - 1;
0754 }
0755 }
0756
0757
0758
0759 *rtblock = NULLRTBLOCK;
0760 return 0;
0761 }
0762
0763
0764
0765
0766 STATIC int
0767 xfs_growfs_rt_alloc(
0768 struct xfs_mount *mp,
0769 xfs_extlen_t oblocks,
0770 xfs_extlen_t nblocks,
0771 struct xfs_inode *ip)
0772 {
0773 xfs_fileoff_t bno;
0774 struct xfs_buf *bp;
0775 xfs_daddr_t d;
0776 int error;
0777 xfs_fsblock_t fsbno;
0778 struct xfs_bmbt_irec map;
0779 int nmap;
0780 int resblks;
0781 enum xfs_blft buf_type;
0782 struct xfs_trans *tp;
0783
0784 if (ip == mp->m_rsumip)
0785 buf_type = XFS_BLFT_RTSUMMARY_BUF;
0786 else
0787 buf_type = XFS_BLFT_RTBITMAP_BUF;
0788
0789
0790
0791
0792 while (oblocks < nblocks) {
0793 resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
0794
0795
0796
0797 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks,
0798 0, 0, &tp);
0799 if (error)
0800 return error;
0801
0802
0803
0804 xfs_ilock(ip, XFS_ILOCK_EXCL);
0805 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
0806
0807 error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
0808 XFS_IEXT_ADD_NOSPLIT_CNT);
0809 if (error == -EFBIG)
0810 error = xfs_iext_count_upgrade(tp, ip,
0811 XFS_IEXT_ADD_NOSPLIT_CNT);
0812 if (error)
0813 goto out_trans_cancel;
0814
0815
0816
0817
0818 nmap = 1;
0819 error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks,
0820 XFS_BMAPI_METADATA, 0, &map, &nmap);
0821 if (!error && nmap < 1)
0822 error = -ENOSPC;
0823 if (error)
0824 goto out_trans_cancel;
0825
0826
0827
0828 error = xfs_trans_commit(tp);
0829 if (error)
0830 return error;
0831
0832
0833
0834
0835 for (bno = map.br_startoff, fsbno = map.br_startblock;
0836 bno < map.br_startoff + map.br_blockcount;
0837 bno++, fsbno++) {
0838
0839
0840
0841 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero,
0842 0, 0, 0, &tp);
0843 if (error)
0844 return error;
0845
0846
0847
0848 xfs_ilock(ip, XFS_ILOCK_EXCL);
0849 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
0850
0851
0852
0853 d = XFS_FSB_TO_DADDR(mp, fsbno);
0854 error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
0855 mp->m_bsize, 0, &bp);
0856 if (error)
0857 goto out_trans_cancel;
0858
0859 xfs_trans_buf_set_type(tp, bp, buf_type);
0860 bp->b_ops = &xfs_rtbuf_ops;
0861 memset(bp->b_addr, 0, mp->m_sb.sb_blocksize);
0862 xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
0863
0864
0865
0866 error = xfs_trans_commit(tp);
0867 if (error)
0868 return error;
0869 }
0870
0871
0872
0873 oblocks = map.br_startoff + map.br_blockcount;
0874 }
0875
0876 return 0;
0877
0878 out_trans_cancel:
0879 xfs_trans_cancel(tp);
0880 return error;
0881 }
0882
0883 static void
0884 xfs_alloc_rsum_cache(
0885 xfs_mount_t *mp,
0886 xfs_extlen_t rbmblocks)
0887 {
0888
0889
0890
0891
0892
0893 mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL);
0894 if (!mp->m_rsum_cache)
0895 xfs_warn(mp, "could not allocate realtime summary cache");
0896 }
0897
0898
0899
0900
0901
0902
0903
0904
0905 int
0906 xfs_growfs_rt(
0907 xfs_mount_t *mp,
0908 xfs_growfs_rt_t *in)
0909 {
0910 xfs_rtblock_t bmbno;
0911 struct xfs_buf *bp;
0912 int error;
0913 xfs_mount_t *nmp;
0914 xfs_rfsblock_t nrblocks;
0915 xfs_extlen_t nrbmblocks;
0916 xfs_rtblock_t nrextents;
0917 uint8_t nrextslog;
0918 xfs_extlen_t nrsumblocks;
0919 uint nrsumlevels;
0920 uint nrsumsize;
0921 xfs_sb_t *nsbp;
0922 xfs_extlen_t rbmblocks;
0923 xfs_extlen_t rsumblocks;
0924 xfs_sb_t *sbp;
0925 xfs_fsblock_t sumbno;
0926 uint8_t *rsum_cache;
0927
0928 sbp = &mp->m_sb;
0929
0930 if (!capable(CAP_SYS_ADMIN))
0931 return -EPERM;
0932
0933
0934 if (!XFS_IS_REALTIME_MOUNT(mp))
0935 return -EINVAL;
0936
0937
0938
0939
0940 if (!mp->m_rbmip || !mp->m_rsumip)
0941 return -EINVAL;
0942
0943
0944 if (in->newblocks <= sbp->sb_rblocks)
0945 return -EINVAL;
0946
0947
0948 if (sbp->sb_rblocks > 0 && in->extsize != sbp->sb_rextsize)
0949 return -EINVAL;
0950
0951
0952 if (XFS_FSB_TO_B(mp, in->extsize) > XFS_MAX_RTEXTSIZE ||
0953 XFS_FSB_TO_B(mp, in->extsize) < XFS_MIN_RTEXTSIZE)
0954 return -EINVAL;
0955
0956
0957 if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp))
0958 return -EOPNOTSUPP;
0959
0960 nrblocks = in->newblocks;
0961 error = xfs_sb_validate_fsb_count(sbp, nrblocks);
0962 if (error)
0963 return error;
0964
0965
0966
0967 error = xfs_buf_read_uncached(mp->m_rtdev_targp,
0968 XFS_FSB_TO_BB(mp, nrblocks - 1),
0969 XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
0970 if (error)
0971 return error;
0972 xfs_buf_relse(bp);
0973
0974
0975
0976
0977 nrextents = nrblocks;
0978 do_div(nrextents, in->extsize);
0979 nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
0980 nrextslog = xfs_highbit32(nrextents);
0981 nrsumlevels = nrextslog + 1;
0982 nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
0983 nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
0984 nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
0985
0986
0987
0988
0989
0990 if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1))
0991 return -EINVAL;
0992
0993
0994
0995
0996 rbmblocks = XFS_B_TO_FSB(mp, mp->m_rbmip->i_disk_size);
0997 rsumblocks = XFS_B_TO_FSB(mp, mp->m_rsumip->i_disk_size);
0998
0999
1000
1001 error = xfs_growfs_rt_alloc(mp, rbmblocks, nrbmblocks, mp->m_rbmip);
1002 if (error)
1003 return error;
1004 error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip);
1005 if (error)
1006 return error;
1007
1008 rsum_cache = mp->m_rsum_cache;
1009 if (nrbmblocks != sbp->sb_rbmblocks)
1010 xfs_alloc_rsum_cache(mp, nrbmblocks);
1011
1012
1013
1014
1015 nmp = kmem_alloc(sizeof(*nmp), 0);
1016
1017
1018
1019
1020
1021
1022 for (bmbno = sbp->sb_rbmblocks -
1023 ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
1024 bmbno < nrbmblocks;
1025 bmbno++) {
1026 struct xfs_trans *tp;
1027 xfs_rfsblock_t nrblocks_step;
1028
1029 *nmp = *mp;
1030 nsbp = &nmp->m_sb;
1031
1032
1033
1034 nsbp->sb_rextsize = in->extsize;
1035 nsbp->sb_rbmblocks = bmbno + 1;
1036 nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize *
1037 nsbp->sb_rextsize;
1038 nsbp->sb_rblocks = min(nrblocks, nrblocks_step);
1039 nsbp->sb_rextents = nsbp->sb_rblocks;
1040 do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
1041 ASSERT(nsbp->sb_rextents != 0);
1042 nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
1043 nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
1044 nrsumsize =
1045 (uint)sizeof(xfs_suminfo_t) * nrsumlevels *
1046 nsbp->sb_rbmblocks;
1047 nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
1048 nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
1049
1050
1051
1052 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0,
1053 &tp);
1054 if (error)
1055 break;
1056
1057
1058
1059 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
1060 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
1061
1062
1063
1064
1065
1066 mp->m_rbmip->i_disk_size =
1067 nsbp->sb_rbmblocks * nsbp->sb_blocksize;
1068 i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_disk_size);
1069 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1070
1071
1072
1073 xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
1074 xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
1075
1076
1077
1078
1079
1080 mp->m_rsumip->i_disk_size = nmp->m_rsumsize;
1081 i_size_write(VFS_I(mp->m_rsumip), mp->m_rsumip->i_disk_size);
1082 xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE);
1083
1084
1085
1086
1087 if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks ||
1088 mp->m_rsumlevels != nmp->m_rsumlevels) {
1089 error = xfs_rtcopy_summary(mp, nmp, tp);
1090 if (error)
1091 goto error_cancel;
1092 }
1093
1094
1095
1096 if (nsbp->sb_rextsize != sbp->sb_rextsize)
1097 xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE,
1098 nsbp->sb_rextsize - sbp->sb_rextsize);
1099 if (nsbp->sb_rbmblocks != sbp->sb_rbmblocks)
1100 xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS,
1101 nsbp->sb_rbmblocks - sbp->sb_rbmblocks);
1102 if (nsbp->sb_rblocks != sbp->sb_rblocks)
1103 xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS,
1104 nsbp->sb_rblocks - sbp->sb_rblocks);
1105 if (nsbp->sb_rextents != sbp->sb_rextents)
1106 xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS,
1107 nsbp->sb_rextents - sbp->sb_rextents);
1108 if (nsbp->sb_rextslog != sbp->sb_rextslog)
1109 xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG,
1110 nsbp->sb_rextslog - sbp->sb_rextslog);
1111
1112
1113
1114 bp = NULL;
1115 error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
1116 nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
1117 if (error) {
1118 error_cancel:
1119 xfs_trans_cancel(tp);
1120 break;
1121 }
1122
1123
1124
1125 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
1126 nsbp->sb_rextents - sbp->sb_rextents);
1127
1128
1129
1130 mp->m_rsumlevels = nrsumlevels;
1131 mp->m_rsumsize = nrsumsize;
1132
1133 error = xfs_trans_commit(tp);
1134 if (error)
1135 break;
1136
1137
1138 mp->m_features |= XFS_FEAT_REALTIME;
1139 }
1140 if (error)
1141 goto out_free;
1142
1143
1144 error = xfs_update_secondary_sbs(mp);
1145
1146 out_free:
1147
1148
1149
1150 kmem_free(nmp);
1151
1152
1153
1154
1155
1156
1157 if (rsum_cache != mp->m_rsum_cache) {
1158 if (error) {
1159 kmem_free(mp->m_rsum_cache);
1160 mp->m_rsum_cache = rsum_cache;
1161 } else {
1162 kmem_free(rsum_cache);
1163 }
1164 }
1165
1166 return error;
1167 }
1168
1169
1170
1171
1172
1173
1174 int
1175 xfs_rtallocate_extent(
1176 xfs_trans_t *tp,
1177 xfs_rtblock_t bno,
1178 xfs_extlen_t minlen,
1179 xfs_extlen_t maxlen,
1180 xfs_extlen_t *len,
1181 int wasdel,
1182 xfs_extlen_t prod,
1183 xfs_rtblock_t *rtblock)
1184 {
1185 xfs_mount_t *mp = tp->t_mountp;
1186 int error;
1187 xfs_rtblock_t r;
1188 xfs_fsblock_t sb;
1189 struct xfs_buf *sumbp;
1190
1191 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
1192 ASSERT(minlen > 0 && minlen <= maxlen);
1193
1194
1195
1196
1197 if (prod > 1) {
1198 xfs_extlen_t i;
1199
1200 if ((i = maxlen % prod))
1201 maxlen -= i;
1202 if ((i = minlen % prod))
1203 minlen += prod - i;
1204 if (maxlen < minlen) {
1205 *rtblock = NULLRTBLOCK;
1206 return 0;
1207 }
1208 }
1209
1210 retry:
1211 sumbp = NULL;
1212 if (bno == 0) {
1213 error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len,
1214 &sumbp, &sb, prod, &r);
1215 } else {
1216 error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen,
1217 len, &sumbp, &sb, prod, &r);
1218 }
1219
1220 if (error)
1221 return error;
1222
1223
1224
1225
1226 if (r != NULLRTBLOCK) {
1227 long slen = (long)*len;
1228
1229 ASSERT(*len >= minlen && *len <= maxlen);
1230 if (wasdel)
1231 xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FREXTENTS, -slen);
1232 else
1233 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, -slen);
1234 } else if (prod > 1) {
1235 prod = 1;
1236 goto retry;
1237 }
1238
1239 *rtblock = r;
1240 return 0;
1241 }
1242
1243
1244
1245
1246 int
1247 xfs_rtmount_init(
1248 struct xfs_mount *mp)
1249 {
1250 struct xfs_buf *bp;
1251 struct xfs_sb *sbp;
1252 xfs_daddr_t d;
1253 int error;
1254
1255 sbp = &mp->m_sb;
1256 if (sbp->sb_rblocks == 0)
1257 return 0;
1258 if (mp->m_rtdev_targp == NULL) {
1259 xfs_warn(mp,
1260 "Filesystem has a realtime volume, use rtdev=device option");
1261 return -ENODEV;
1262 }
1263 mp->m_rsumlevels = sbp->sb_rextslog + 1;
1264 mp->m_rsumsize =
1265 (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
1266 sbp->sb_rbmblocks;
1267 mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize);
1268 mp->m_rbmip = mp->m_rsumip = NULL;
1269
1270
1271
1272 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
1273 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) {
1274 xfs_warn(mp, "realtime mount -- %llu != %llu",
1275 (unsigned long long) XFS_BB_TO_FSB(mp, d),
1276 (unsigned long long) mp->m_sb.sb_rblocks);
1277 return -EFBIG;
1278 }
1279 error = xfs_buf_read_uncached(mp->m_rtdev_targp,
1280 d - XFS_FSB_TO_BB(mp, 1),
1281 XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
1282 if (error) {
1283 xfs_warn(mp, "realtime device size check failed");
1284 return error;
1285 }
1286 xfs_buf_relse(bp);
1287 return 0;
1288 }
1289
1290 static int
1291 xfs_rtalloc_count_frextent(
1292 struct xfs_mount *mp,
1293 struct xfs_trans *tp,
1294 const struct xfs_rtalloc_rec *rec,
1295 void *priv)
1296 {
1297 uint64_t *valp = priv;
1298
1299 *valp += rec->ar_extcount;
1300 return 0;
1301 }
1302
1303
1304
1305
1306
1307 int
1308 xfs_rtalloc_reinit_frextents(
1309 struct xfs_mount *mp)
1310 {
1311 uint64_t val = 0;
1312 int error;
1313
1314 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
1315 error = xfs_rtalloc_query_all(mp, NULL, xfs_rtalloc_count_frextent,
1316 &val);
1317 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL);
1318 if (error)
1319 return error;
1320
1321 spin_lock(&mp->m_sb_lock);
1322 mp->m_sb.sb_frextents = val;
1323 spin_unlock(&mp->m_sb_lock);
1324 percpu_counter_set(&mp->m_frextents, mp->m_sb.sb_frextents);
1325 return 0;
1326 }
1327
1328
1329
1330
1331
1332 int
1333 xfs_rtmount_inodes(
1334 xfs_mount_t *mp)
1335 {
1336 int error;
1337 xfs_sb_t *sbp;
1338
1339 sbp = &mp->m_sb;
1340 error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip);
1341 if (error)
1342 return error;
1343 ASSERT(mp->m_rbmip != NULL);
1344
1345 error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip);
1346 if (error) {
1347 xfs_irele(mp->m_rbmip);
1348 return error;
1349 }
1350 ASSERT(mp->m_rsumip != NULL);
1351 xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks);
1352 return 0;
1353 }
1354
1355 void
1356 xfs_rtunmount_inodes(
1357 struct xfs_mount *mp)
1358 {
1359 kmem_free(mp->m_rsum_cache);
1360 if (mp->m_rbmip)
1361 xfs_irele(mp->m_rbmip);
1362 if (mp->m_rsumip)
1363 xfs_irele(mp->m_rsumip);
1364 }
1365
1366
1367
1368
1369
1370
1371
1372
1373 int
1374 xfs_rtpick_extent(
1375 xfs_mount_t *mp,
1376 xfs_trans_t *tp,
1377 xfs_extlen_t len,
1378 xfs_rtblock_t *pick)
1379 {
1380 xfs_rtblock_t b;
1381 int log2;
1382 uint64_t resid;
1383 uint64_t seq;
1384 uint64_t *seqp;
1385
1386 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
1387
1388 seqp = (uint64_t *)&VFS_I(mp->m_rbmip)->i_atime;
1389 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) {
1390 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
1391 *seqp = 0;
1392 }
1393 seq = *seqp;
1394 if ((log2 = xfs_highbit64(seq)) == -1)
1395 b = 0;
1396 else {
1397 resid = seq - (1ULL << log2);
1398 b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
1399 (log2 + 1);
1400 if (b >= mp->m_sb.sb_rextents)
1401 div64_u64_rem(b, mp->m_sb.sb_rextents, &b);
1402 if (b + len > mp->m_sb.sb_rextents)
1403 b = mp->m_sb.sb_rextents - len;
1404 }
1405 *seqp = seq + 1;
1406 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1407 *pick = b;
1408 return 0;
1409 }