aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/stat.c1
-rw-r--r--fs/ufs/balloc.c26
-rw-r--r--fs/ufs/inode.c28
-rw-r--r--fs/ufs/super.c18
-rw-r--r--fs/ufs/util.h10
5 files changed, 63 insertions, 20 deletions
diff --git a/fs/stat.c b/fs/stat.c
index f494b182c7c7..c35610845ab1 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -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}
675EXPORT_SYMBOL(__inode_add_bytes);
675 676
676void inode_add_bytes(struct inode *inode, loff_t bytes) 677void 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
499static 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
497static u64 ufs_add_fragments(struct inode *inode, u64 fragment, 513static 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;
718gotit: 740gotit:
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)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 7e41aee7b69a..da553ffec85b 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -235,7 +235,8 @@ ufs_extend_tail(struct inode *inode, u64 writes_to,
235 235
236 p = ufs_get_direct_data_ptr(uspi, ufsi, block); 236 p = ufs_get_direct_data_ptr(uspi, ufsi, block);
237 tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p), 237 tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p),
238 new_size, err, locked_page); 238 new_size - (lastfrag & uspi->s_fpbmask), err,
239 locked_page);
239 return tmp != 0; 240 return tmp != 0;
240} 241}
241 242
@@ -284,7 +285,7 @@ ufs_inode_getfrag(struct inode *inode, unsigned index,
284 goal += uspi->s_fpb; 285 goal += uspi->s_fpb;
285 } 286 }
286 tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), 287 tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment),
287 goal, uspi->s_fpb, err, locked_page); 288 goal, nfrags, err, locked_page);
288 289
289 if (!tmp) { 290 if (!tmp) {
290 *err = -ENOSPC; 291 *err = -ENOSPC;
@@ -402,7 +403,9 @@ static int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buff
402 403
403 if (!create) { 404 if (!create) {
404 phys64 = ufs_frag_map(inode, offsets, depth); 405 phys64 = ufs_frag_map(inode, offsets, depth);
405 goto out; 406 if (phys64)
407 map_bh(bh_result, sb, phys64 + frag);
408 return 0;
406 } 409 }
407 410
408 /* This code entered only while writing ....? */ 411 /* This code entered only while writing ....? */
@@ -841,8 +844,11 @@ void ufs_evict_inode(struct inode * inode)
841 truncate_inode_pages_final(&inode->i_data); 844 truncate_inode_pages_final(&inode->i_data);
842 if (want_delete) { 845 if (want_delete) {
843 inode->i_size = 0; 846 inode->i_size = 0;
844 if (inode->i_blocks) 847 if (inode->i_blocks &&
848 (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
849 S_ISLNK(inode->i_mode)))
845 ufs_truncate_blocks(inode); 850 ufs_truncate_blocks(inode);
851 ufs_update_inode(inode, inode_needs_sync(inode));
846 } 852 }
847 853
848 invalidate_inode_buffers(inode); 854 invalidate_inode_buffers(inode);
@@ -1100,7 +1106,7 @@ out:
1100 return err; 1106 return err;
1101} 1107}
1102 1108
1103static void __ufs_truncate_blocks(struct inode *inode) 1109static void ufs_truncate_blocks(struct inode *inode)
1104{ 1110{
1105 struct ufs_inode_info *ufsi = UFS_I(inode); 1111 struct ufs_inode_info *ufsi = UFS_I(inode);
1106 struct super_block *sb = inode->i_sb; 1112 struct super_block *sb = inode->i_sb;
@@ -1183,7 +1189,7 @@ static int ufs_truncate(struct inode *inode, loff_t size)
1183 1189
1184 truncate_setsize(inode, size); 1190 truncate_setsize(inode, size);
1185 1191
1186 __ufs_truncate_blocks(inode); 1192 ufs_truncate_blocks(inode);
1187 inode->i_mtime = inode->i_ctime = current_time(inode); 1193 inode->i_mtime = inode->i_ctime = current_time(inode);
1188 mark_inode_dirty(inode); 1194 mark_inode_dirty(inode);
1189out: 1195out:
@@ -1191,16 +1197,6 @@ out:
1191 return err; 1197 return err;
1192} 1198}
1193 1199
1194static void ufs_truncate_blocks(struct inode *inode)
1195{
1196 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1197 S_ISLNK(inode->i_mode)))
1198 return;
1199 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1200 return;
1201 __ufs_truncate_blocks(inode);
1202}
1203
1204int ufs_setattr(struct dentry *dentry, struct iattr *attr) 1200int ufs_setattr(struct dentry *dentry, struct iattr *attr)
1205{ 1201{
1206 struct inode *inode = d_inode(dentry); 1202 struct inode *inode = d_inode(dentry);
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 29ecaf739449..878cc6264f1a 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -746,6 +746,23 @@ static void ufs_put_super(struct super_block *sb)
746 return; 746 return;
747} 747}
748 748
749static u64 ufs_max_bytes(struct super_block *sb)
750{
751 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
752 int bits = uspi->s_apbshift;
753 u64 res;
754
755 if (bits > 21)
756 res = ~0ULL;
757 else
758 res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) +
759 (1LL << (3*bits));
760
761 if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift))
762 return MAX_LFS_FILESIZE;
763 return res << uspi->s_bshift;
764}
765
749static int ufs_fill_super(struct super_block *sb, void *data, int silent) 766static int ufs_fill_super(struct super_block *sb, void *data, int silent)
750{ 767{
751 struct ufs_sb_info * sbi; 768 struct ufs_sb_info * sbi;
@@ -1211,6 +1228,7 @@ magic_found:
1211 "fast symlink size (%u)\n", uspi->s_maxsymlinklen); 1228 "fast symlink size (%u)\n", uspi->s_maxsymlinklen);
1212 uspi->s_maxsymlinklen = maxsymlen; 1229 uspi->s_maxsymlinklen = maxsymlen;
1213 } 1230 }
1231 sb->s_maxbytes = ufs_max_bytes(sb);
1214 sb->s_max_links = UFS_LINK_MAX; 1232 sb->s_max_links = UFS_LINK_MAX;
1215 1233
1216 inode = ufs_iget(sb, UFS_ROOTINO); 1234 inode = ufs_iget(sb, UFS_ROOTINO);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index b7fbf53dbc81..398019fb1448 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -473,15 +473,19 @@ static inline unsigned _ubh_find_last_zero_bit_(
473static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi, 473static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
474 struct ufs_buffer_head * ubh, unsigned begin, unsigned block) 474 struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
475{ 475{
476 u8 mask;
476 switch (uspi->s_fpb) { 477 switch (uspi->s_fpb) {
477 case 8: 478 case 8:
478 return (*ubh_get_addr (ubh, begin + block) == 0xff); 479 return (*ubh_get_addr (ubh, begin + block) == 0xff);
479 case 4: 480 case 4:
480 return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2))); 481 mask = 0x0f << ((block & 0x01) << 2);
482 return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask;
481 case 2: 483 case 2:
482 return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1))); 484 mask = 0x03 << ((block & 0x03) << 1);
485 return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask;
483 case 1: 486 case 1:
484 return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07))); 487 mask = 0x01 << (block & 0x07);
488 return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask;
485 } 489 }
486 return 0; 490 return 0;
487} 491}