diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-08 21:15:03 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-09 16:28:01 -0400 |
| commit | eb315d2ae614493fd1ebb026c75a80573d84f7ad (patch) | |
| tree | 00fea56fd880b0678f63893a4206a8352650cc30 | |
| parent | 414cf7186dbec29bd946c138d6b5c09da5955a08 (diff) | |
ufs: restore maintaining ->i_blocks
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/stat.c | 1 | ||||
| -rw-r--r-- | fs/ufs/balloc.c | 26 |
2 files changed, 26 insertions, 1 deletions
| @@ -672,6 +672,7 @@ void __inode_add_bytes(struct inode *inode, loff_t bytes) | |||
| 672 | inode->i_bytes -= 512; | 672 | inode->i_bytes -= 512; |
| 673 | } | 673 | } |
| 674 | } | 674 | } |
| 675 | EXPORT_SYMBOL(__inode_add_bytes); | ||
| 675 | 676 | ||
| 676 | void inode_add_bytes(struct inode *inode, loff_t bytes) | 677 | void inode_add_bytes(struct inode *inode, loff_t bytes) |
| 677 | { | 678 | { |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index a0376a2c1c29..d642cc0a8271 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
| @@ -82,7 +82,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
| 82 | ufs_error (sb, "ufs_free_fragments", | 82 | ufs_error (sb, "ufs_free_fragments", |
| 83 | "bit already cleared for fragment %u", i); | 83 | "bit already cleared for fragment %u", i); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | inode_sub_bytes(inode, count << uspi->s_fshift); | ||
| 86 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); | 87 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); |
| 87 | uspi->cs_total.cs_nffree += count; | 88 | uspi->cs_total.cs_nffree += count; |
| 88 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 89 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
| @@ -184,6 +185,7 @@ do_more: | |||
| 184 | ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); | 185 | ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); |
| 185 | } | 186 | } |
| 186 | ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); | 187 | ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
| 188 | inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift); | ||
| 187 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 189 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
| 188 | ufs_clusteracct (sb, ucpi, blkno, 1); | 190 | ufs_clusteracct (sb, ucpi, blkno, 1); |
| 189 | 191 | ||
| @@ -494,6 +496,20 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
| 494 | return 0; | 496 | return 0; |
| 495 | } | 497 | } |
| 496 | 498 | ||
| 499 | static bool try_add_frags(struct inode *inode, unsigned frags) | ||
| 500 | { | ||
| 501 | unsigned size = frags * i_blocksize(inode); | ||
| 502 | spin_lock(&inode->i_lock); | ||
| 503 | __inode_add_bytes(inode, size); | ||
| 504 | if (unlikely((u32)inode->i_blocks != inode->i_blocks)) { | ||
| 505 | __inode_sub_bytes(inode, size); | ||
| 506 | spin_unlock(&inode->i_lock); | ||
| 507 | return false; | ||
| 508 | } | ||
| 509 | spin_unlock(&inode->i_lock); | ||
| 510 | return true; | ||
| 511 | } | ||
| 512 | |||
| 497 | static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | 513 | static u64 ufs_add_fragments(struct inode *inode, u64 fragment, |
| 498 | unsigned oldcount, unsigned newcount) | 514 | unsigned oldcount, unsigned newcount) |
| 499 | { | 515 | { |
| @@ -530,6 +546,9 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | |||
| 530 | for (i = oldcount; i < newcount; i++) | 546 | for (i = oldcount; i < newcount; i++) |
| 531 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) | 547 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) |
| 532 | return 0; | 548 | return 0; |
| 549 | |||
| 550 | if (!try_add_frags(inode, count)) | ||
| 551 | return 0; | ||
| 533 | /* | 552 | /* |
| 534 | * Block can be extended | 553 | * Block can be extended |
| 535 | */ | 554 | */ |
| @@ -647,6 +666,7 @@ cg_found: | |||
| 647 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); | 666 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
| 648 | i = uspi->s_fpb - count; | 667 | i = uspi->s_fpb - count; |
| 649 | 668 | ||
| 669 | inode_sub_bytes(inode, i << uspi->s_fshift); | ||
| 650 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); | 670 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); |
| 651 | uspi->cs_total.cs_nffree += i; | 671 | uspi->cs_total.cs_nffree += i; |
| 652 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); | 672 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); |
| @@ -657,6 +677,8 @@ cg_found: | |||
| 657 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); | 677 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); |
| 658 | if (result == INVBLOCK) | 678 | if (result == INVBLOCK) |
| 659 | return 0; | 679 | return 0; |
| 680 | if (!try_add_frags(inode, count)) | ||
| 681 | return 0; | ||
| 660 | for (i = 0; i < count; i++) | 682 | for (i = 0; i < count; i++) |
| 661 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); | 683 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); |
| 662 | 684 | ||
| @@ -716,6 +738,8 @@ norot: | |||
| 716 | return INVBLOCK; | 738 | return INVBLOCK; |
| 717 | ucpi->c_rotor = result; | 739 | ucpi->c_rotor = result; |
| 718 | gotit: | 740 | gotit: |
| 741 | if (!try_add_frags(inode, uspi->s_fpb)) | ||
| 742 | return 0; | ||
| 719 | blkno = ufs_fragstoblks(result); | 743 | blkno = ufs_fragstoblks(result); |
| 720 | ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); | 744 | ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
| 721 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 745 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
