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 /fs/ufs | |
parent | 414cf7186dbec29bd946c138d6b5c09da5955a08 (diff) |
ufs: restore maintaining ->i_blocks
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/balloc.c | 26 |
1 files changed, 25 insertions, 1 deletions
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) |