aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/Kconfig67
-rw-r--r--fs/ext3/balloc.c3
-rw-r--r--fs/ext3/dir.c30
-rw-r--r--fs/ext3/inode.c7
-rw-r--r--fs/ext3/resize.c3
-rw-r--r--fs/ext3/super.c16
6 files changed, 116 insertions, 10 deletions
diff --git a/fs/ext3/Kconfig b/fs/ext3/Kconfig
new file mode 100644
index 000000000000..8e0cfe44b0fc
--- /dev/null
+++ b/fs/ext3/Kconfig
@@ -0,0 +1,67 @@
1config EXT3_FS
2 tristate "Ext3 journalling file system support"
3 select JBD
4 help
5 This is the journalling version of the Second extended file system
6 (often called ext3), the de facto standard Linux file system
7 (method to organize files on a storage device) for hard disks.
8
9 The journalling code included in this driver means you do not have
10 to run e2fsck (file system checker) on your file systems after a
11 crash. The journal keeps track of any changes that were being made
12 at the time the system crashed, and can ensure that your file system
13 is consistent without the need for a lengthy check.
14
15 Other than adding the journal to the file system, the on-disk format
16 of ext3 is identical to ext2. It is possible to freely switch
17 between using the ext3 driver and the ext2 driver, as long as the
18 file system has been cleanly unmounted, or e2fsck is run on the file
19 system.
20
21 To add a journal on an existing ext2 file system or change the
22 behavior of ext3 file systems, you can use the tune2fs utility ("man
23 tune2fs"). To modify attributes of files and directories on ext3
24 file systems, use chattr ("man chattr"). You need to be using
25 e2fsprogs version 1.20 or later in order to create ext3 journals
26 (available at <http://sourceforge.net/projects/e2fsprogs/>).
27
28 To compile this file system support as a module, choose M here: the
29 module will be called ext3.
30
31config EXT3_FS_XATTR
32 bool "Ext3 extended attributes"
33 depends on EXT3_FS
34 default y
35 help
36 Extended attributes are name:value pairs associated with inodes by
37 the kernel or by users (see the attr(5) manual page, or visit
38 <http://acl.bestbits.at/> for details).
39
40 If unsure, say N.
41
42 You need this for POSIX ACL support on ext3.
43
44config EXT3_FS_POSIX_ACL
45 bool "Ext3 POSIX Access Control Lists"
46 depends on EXT3_FS_XATTR
47 select FS_POSIX_ACL
48 help
49 Posix Access Control Lists (ACLs) support permissions for users and
50 groups beyond the owner/group/world scheme.
51
52 To learn more about Access Control Lists, visit the Posix ACLs for
53 Linux website <http://acl.bestbits.at/>.
54
55 If you don't know what Access Control Lists are, say N
56
57config EXT3_FS_SECURITY
58 bool "Ext3 Security Labels"
59 depends on EXT3_FS_XATTR
60 help
61 Security labels support alternative access control models
62 implemented by security modules like SELinux. This option
63 enables an extended attribute handler for file security
64 labels in the ext3 filesystem.
65
66 If you are not using a security module that requires using
67 extended attributes for file security labels, say N.
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 92fd0338a6eb..f5b57a2ca35a 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1547,6 +1547,7 @@ retry_alloc:
1547 * turn off reservation for this allocation 1547 * turn off reservation for this allocation
1548 */ 1548 */
1549 if (my_rsv && (free_blocks < windowsz) 1549 if (my_rsv && (free_blocks < windowsz)
1550 && (free_blocks > 0)
1550 && (rsv_is_empty(&my_rsv->rsv_window))) 1551 && (rsv_is_empty(&my_rsv->rsv_window)))
1551 my_rsv = NULL; 1552 my_rsv = NULL;
1552 1553
@@ -1585,7 +1586,7 @@ retry_alloc:
1585 * free blocks is less than half of the reservation 1586 * free blocks is less than half of the reservation
1586 * window size. 1587 * window size.
1587 */ 1588 */
1588 if (free_blocks <= (windowsz/2)) 1589 if (my_rsv && (free_blocks <= (windowsz/2)))
1589 continue; 1590 continue;
1590 1591
1591 brelse(bitmap_bh); 1592 brelse(bitmap_bh);
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 2eea96ec78ed..4c82531ea0a8 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
102 int err; 102 int err;
103 struct inode *inode = filp->f_path.dentry->d_inode; 103 struct inode *inode = filp->f_path.dentry->d_inode;
104 int ret = 0; 104 int ret = 0;
105 int dir_has_error = 0;
105 106
106 sb = inode->i_sb; 107 sb = inode->i_sb;
107 108
@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
148 * of recovering data when there's a bad sector 149 * of recovering data when there's a bad sector
149 */ 150 */
150 if (!bh) { 151 if (!bh) {
151 ext3_error (sb, "ext3_readdir", 152 if (!dir_has_error) {
152 "directory #%lu contains a hole at offset %lu", 153 ext3_error(sb, __func__, "directory #%lu "
153 inode->i_ino, (unsigned long)filp->f_pos); 154 "contains a hole at offset %lld",
155 inode->i_ino, filp->f_pos);
156 dir_has_error = 1;
157 }
154 /* corrupt size? Maybe no more blocks to read */ 158 /* corrupt size? Maybe no more blocks to read */
155 if (filp->f_pos > inode->i_blocks << 9) 159 if (filp->f_pos > inode->i_blocks << 9)
156 break; 160 break;
@@ -410,7 +414,7 @@ static int call_filldir(struct file * filp, void * dirent,
410 get_dtype(sb, fname->file_type)); 414 get_dtype(sb, fname->file_type));
411 if (error) { 415 if (error) {
412 filp->f_pos = curr_pos; 416 filp->f_pos = curr_pos;
413 info->extra_fname = fname->next; 417 info->extra_fname = fname;
414 return error; 418 return error;
415 } 419 }
416 fname = fname->next; 420 fname = fname->next;
@@ -449,11 +453,21 @@ static int ext3_dx_readdir(struct file * filp,
449 * If there are any leftover names on the hash collision 453 * If there are any leftover names on the hash collision
450 * chain, return them first. 454 * chain, return them first.
451 */ 455 */
452 if (info->extra_fname && 456 if (info->extra_fname) {
453 call_filldir(filp, dirent, filldir, info->extra_fname)) 457 if (call_filldir(filp, dirent, filldir, info->extra_fname))
454 goto finished; 458 goto finished;
455 459
456 if (!info->curr_node) 460 info->extra_fname = NULL;
461 info->curr_node = rb_next(info->curr_node);
462 if (!info->curr_node) {
463 if (info->next_hash == ~0) {
464 filp->f_pos = EXT3_HTREE_EOF;
465 goto finished;
466 }
467 info->curr_hash = info->next_hash;
468 info->curr_minor_hash = 0;
469 }
470 } else if (!info->curr_node)
457 info->curr_node = rb_first(&info->root); 471 info->curr_node = rb_first(&info->root);
458 472
459 while (1) { 473 while (1) {
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index ebfec4d0148e..f8424ad89971 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1186,6 +1186,13 @@ write_begin_failed:
1186 ext3_journal_stop(handle); 1186 ext3_journal_stop(handle);
1187 unlock_page(page); 1187 unlock_page(page);
1188 page_cache_release(page); 1188 page_cache_release(page);
1189 /*
1190 * block_write_begin may have instantiated a few blocks
1191 * outside i_size. Trim these off again. Don't need
1192 * i_size_read because we hold i_mutex.
1193 */
1194 if (pos + len > inode->i_size)
1195 vmtruncate(inode, inode->i_size);
1189 } 1196 }
1190 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) 1197 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
1191 goto retry; 1198 goto retry;
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 77278e947e94..78fdf3836370 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -790,7 +790,8 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
790 790
791 if (reserved_gdb || gdb_off == 0) { 791 if (reserved_gdb || gdb_off == 0) {
792 if (!EXT3_HAS_COMPAT_FEATURE(sb, 792 if (!EXT3_HAS_COMPAT_FEATURE(sb,
793 EXT3_FEATURE_COMPAT_RESIZE_INODE)){ 793 EXT3_FEATURE_COMPAT_RESIZE_INODE)
794 || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
794 ext3_warning(sb, __func__, 795 ext3_warning(sb, __func__,
795 "No reserved GDT blocks, can't resize"); 796 "No reserved GDT blocks, can't resize");
796 return -EPERM; 797 return -EPERM;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 399a96a6c556..3a260af5544d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -625,6 +625,9 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
625 else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) 625 else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
626 seq_puts(seq, ",data=writeback"); 626 seq_puts(seq, ",data=writeback");
627 627
628 if (test_opt(sb, DATA_ERR_ABORT))
629 seq_puts(seq, ",data_err=abort");
630
628 ext3_show_quota_options(seq, sb); 631 ext3_show_quota_options(seq, sb);
629 632
630 return 0; 633 return 0;
@@ -754,6 +757,7 @@ enum {
754 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, 757 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
755 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, 758 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
756 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 759 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
760 Opt_data_err_abort, Opt_data_err_ignore,
757 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 761 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
758 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 762 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
759 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, 763 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
@@ -796,6 +800,8 @@ static const match_table_t tokens = {
796 {Opt_data_journal, "data=journal"}, 800 {Opt_data_journal, "data=journal"},
797 {Opt_data_ordered, "data=ordered"}, 801 {Opt_data_ordered, "data=ordered"},
798 {Opt_data_writeback, "data=writeback"}, 802 {Opt_data_writeback, "data=writeback"},
803 {Opt_data_err_abort, "data_err=abort"},
804 {Opt_data_err_ignore, "data_err=ignore"},
799 {Opt_offusrjquota, "usrjquota="}, 805 {Opt_offusrjquota, "usrjquota="},
800 {Opt_usrjquota, "usrjquota=%s"}, 806 {Opt_usrjquota, "usrjquota=%s"},
801 {Opt_offgrpjquota, "grpjquota="}, 807 {Opt_offgrpjquota, "grpjquota="},
@@ -1011,6 +1017,12 @@ static int parse_options (char *options, struct super_block *sb,
1011 sbi->s_mount_opt |= data_opt; 1017 sbi->s_mount_opt |= data_opt;
1012 } 1018 }
1013 break; 1019 break;
1020 case Opt_data_err_abort:
1021 set_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1022 break;
1023 case Opt_data_err_ignore:
1024 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1025 break;
1014#ifdef CONFIG_QUOTA 1026#ifdef CONFIG_QUOTA
1015 case Opt_usrjquota: 1027 case Opt_usrjquota:
1016 qtype = USRQUOTA; 1028 qtype = USRQUOTA;
@@ -1986,6 +1998,10 @@ static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
1986 journal->j_flags |= JFS_BARRIER; 1998 journal->j_flags |= JFS_BARRIER;
1987 else 1999 else
1988 journal->j_flags &= ~JFS_BARRIER; 2000 journal->j_flags &= ~JFS_BARRIER;
2001 if (test_opt(sb, DATA_ERR_ABORT))
2002 journal->j_flags |= JFS_ABORT_ON_SYNCDATA_ERR;
2003 else
2004 journal->j_flags &= ~JFS_ABORT_ON_SYNCDATA_ERR;
1989 spin_unlock(&journal->j_state_lock); 2005 spin_unlock(&journal->j_state_lock);
1990} 2006}
1991 2007