Skip to content
Snippets Groups Projects
Commit 36025d08 authored by Johann Lombardi's avatar Johann Lombardi
Browse files

Branch b1_6

Re-add the following patches as per Andreas' request (on rmg@):

ldiskfs/kernel_patches/patches/ext3-check-jbd-errors-2.6-sles10.patch
ldiskfs/kernel_patches/patches/ext3-external-journal-2.6.9.patch
ldiskfs/kernel_patches/patches/ext3-statfs-2.6.18.patch
lustre/kernel_patches/patches/link_notlast-susefix.patch
lustre/kernel_patches/patches/vfs_nointent-2.6-sles10.patch
parent e98a62bf
No related merge requests found
Index: linux-stage/include/linux/ext3_fs.h
===================================================================
--- linux-stage.orig/include/linux/ext3_fs.h
+++ linux-stage/include/linux/ext3_fs.h
@@ -921,6 +921,7 @@ extern unsigned ext3_list_backups(struct
unsigned *five, unsigned *seven);
/* super.c */
+extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
extern void ext3_error (struct super_block *, const char *, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
extern void __ext3_std_error (struct super_block *, const char *, int);
Index: linux-stage/fs/ext3/super.c
===================================================================
--- linux-stage.orig/fs/ext3/super.c
+++ linux-stage/fs/ext3/super.c
@@ -47,9 +47,6 @@ static int ext3_load_journal(struct supe
unsigned long journal_devnum);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
int);
-static void ext3_commit_super (struct super_block * sb,
- struct ext3_super_block * es,
- int sync);
static void ext3_mark_recovery_complete(struct super_block * sb,
struct ext3_super_block * es);
static void ext3_clear_journal_err(struct super_block * sb,
@@ -2175,7 +2172,7 @@ static int ext3_create_journal(struct su
return 0;
}
-static void ext3_commit_super (struct super_block * sb,
+void ext3_commit_super (struct super_block * sb,
struct ext3_super_block * es,
int sync)
{
Index: linux-stage/fs/ext3/namei.c
===================================================================
--- linux-stage.orig/fs/ext3/namei.c
+++ linux-stage/fs/ext3/namei.c
@@ -1591,7 +1591,7 @@ static int ext3_delete_entry (handle_t *
struct buffer_head * bh)
{
struct ext3_dir_entry_2 * de, * pde;
- int i;
+ int i, err;
i = 0;
pde = NULL;
@@ -1601,7 +1601,9 @@ static int ext3_delete_entry (handle_t *
return -EIO;
if (de == de_del) {
BUFFER_TRACE(bh, "get_write_access");
- ext3_journal_get_write_access(handle, bh);
+ err = ext3_journal_get_write_access(handle, bh);
+ if (err)
+ return err;
if (pde)
pde->rec_len =
cpu_to_le16(le16_to_cpu(pde->rec_len) +
Index: linux-stage/fs/ext3/inode.c
===================================================================
--- linux-stage.orig/fs/ext3/inode.c
+++ linux-stage/fs/ext3/inode.c
@@ -1838,8 +1838,18 @@ ext3_clear_blocks(handle_t *handle, stru
ext3_mark_inode_dirty(handle, inode);
ext3_journal_test_restart(handle, inode);
if (bh) {
+ int err;
BUFFER_TRACE(bh, "retaking write access");
- ext3_journal_get_write_access(handle, bh);
+ err = ext3_journal_get_write_access(handle, bh);
+ if (err) {
+ struct super_block *sb = inode->i_sb;
+ struct ext3_super_block *es = EXT3_SB(sb)->s_es;
+ printk (KERN_CRIT"EXT3-fs: can't continue truncate\n");
+ EXT3_SB(sb)->s_mount_state |= EXT3_ERROR_FS;
+ es->s_state |= cpu_to_le16(EXT3_ERROR_FS);
+ ext3_commit_super(sb, es, 1);
+ return;
+ }
}
}
Signed-off-by: Johann Lombardi <johann.lombardi@bull.net>
Index: linux-2.6.9-full/fs/ext3/super.c
===================================================================
--- linux-2.6.9-full.orig/fs/ext3/super.c 2006-05-20 01:14:14.000000000 +0400
+++ linux-2.6.9-full/fs/ext3/super.c 2006-05-20 01:17:10.000000000 +0400
@@ -39,7 +39,8 @@
#include "xattr.h"
#include "acl.h"
-static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
+ unsigned long journal_devnum);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
int);
static void ext3_commit_super (struct super_block * sb,
@@ -591,7 +592,7 @@ enum {
Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
Opt_reservation, Opt_noreservation, Opt_noload,
- Opt_commit, Opt_journal_update, Opt_journal_inum,
+ Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
@@ -630,6 +631,7 @@ static match_table_t tokens = {
{Opt_commit, "commit=%u"},
{Opt_journal_update, "journal=update"},
{Opt_journal_inum, "journal=%u"},
+ {Opt_journal_dev, "journal_dev=%u"},
{Opt_abort, "abort"},
{Opt_data_journal, "data=journal"},
{Opt_data_ordered, "data=ordered"},
@@ -675,8 +677,9 @@ static unsigned long get_sb_block(void *
return sb_block;
}
-static int parse_options (char * options, struct super_block *sb,
- unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
+static int parse_options (char *options, struct super_block *sb,
+ unsigned long *inum, unsigned long *journal_devnum,
+ unsigned long *n_blocks_count, int is_remount)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
char * p;
@@ -816,6 +819,16 @@ static int parse_options (char * options
return 0;
*inum = option;
break;
+ case Opt_journal_dev:
+ if (is_remount) {
+ printk(KERN_ERR "EXT3-fs: cannot specify "
+ "journal on remount\n");
+ return 0;
+ }
+ if (match_int(&args[0], &option))
+ return 0;
+ *journal_devnum = option;
+ break;
case Opt_noload:
set_opt (sbi->s_mount_opt, NOLOAD);
break;
@@ -1278,6 +1291,7 @@ static int ext3_fill_super (struct super
unsigned long logic_sb_block;
unsigned long offset = 0;
unsigned long journal_inum = 0;
+ unsigned long journal_devnum = 0;
unsigned long def_mount_opts;
struct inode *root;
int blocksize;
@@ -1361,7 +1375,8 @@ static int ext3_fill_super (struct super
set_opt(sbi->s_mount_opt, RESERVATION);
- if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
+ if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
+ NULL, 0))
goto failed_mount;
set_sb_time_gran(sb, 1000000000U);
@@ -1567,7 +1582,7 @@ static int ext3_fill_super (struct super
*/
if (!test_opt(sb, NOLOAD) &&
EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
- if (ext3_load_journal(sb, es))
+ if (ext3_load_journal(sb, es, journal_devnum))
goto failed_mount2;
} else if (journal_inum) {
if (ext3_create_journal(sb, es, journal_inum))
@@ -1831,15 +1846,24 @@ out_bdev:
return NULL;
}
-static int ext3_load_journal(struct super_block * sb,
- struct ext3_super_block * es)
+static int ext3_load_journal(struct super_block *sb,
+ struct ext3_super_block *es,
+ unsigned long journal_devnum)
{
journal_t *journal;
int journal_inum = le32_to_cpu(es->s_journal_inum);
- dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+ dev_t journal_dev;
int err = 0;
int really_read_only;
+ if (journal_devnum &&
+ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+ printk(KERN_INFO "EXT3-fs: external journal device major/minor "
+ "numbers have changed\n");
+ journal_dev = new_decode_dev(journal_devnum);
+ } else
+ journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+
really_read_only = bdev_read_only(sb->s_bdev);
/*
@@ -1898,6 +1922,16 @@ static int ext3_load_journal(struct supe
EXT3_SB(sb)->s_journal = journal;
ext3_clear_journal_err(sb, es);
+
+ if (journal_devnum &&
+ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+ es->s_journal_dev = cpu_to_le32(journal_devnum);
+ sb->s_dirt = 1;
+
+ /* Make sure we flush the recovery flag to disk. */
+ ext3_commit_super(sb, es, 1);
+ }
+
return 0;
}
@@ -2105,13 +2139,13 @@ int ext3_remount (struct super_block * s
{
struct ext3_super_block * es;
struct ext3_sb_info *sbi = EXT3_SB(sb);
- unsigned long tmp;
+ unsigned long tmp1, tmp2;
unsigned long n_blocks_count = 0;
/*
* Allow the "check" option to be passed as a remount option.
*/
- if (!parse_options(data, sb, &tmp, &n_blocks_count, 1))
+ if (!parse_options(data, sb, &tmp1, &tmp2, &n_blocks_count, 1))
return -EINVAL;
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
Index: linux-2.6.18.8/fs/ext3/super.c
===================================================================
--- linux-2.6.18.8.orig/fs/ext3/super.c 2007-07-20 16:51:14.000000000 +0200
+++ linux-2.6.18.8/fs/ext3/super.c 2007-07-20 16:54:17.000000000 +0200
@@ -2572,18 +2572,18 @@ static int ext3_statfs (struct dentry *
struct super_block *sb = dentry->d_sb;
struct ext3_sb_info *sbi = EXT3_SB(sb);
struct ext3_super_block *es = sbi->s_es;
- ext3_fsblk_t overhead;
- int i;
- if (test_opt (sb, MINIX_DF))
- overhead = 0;
- else {
- unsigned long ngroups;
- ngroups = EXT3_SB(sb)->s_groups_count;
+ if (test_opt(sb, MINIX_DF)) {
+ sbi->s_overhead_last = 0;
+ } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
+ unsigned long ngroups = sbi->s_groups_count, i;
+ ext3_fsblk_t overhead = 0;
smp_rmb();
/*
- * Compute the overhead (FS structures)
+ * Compute the overhead (FS structures). This is constant
+ * for a given filesystem unless the number of block groups
+ * changes so we cache the previous value until it does.
*/
/*
@@ -2605,18 +2605,23 @@ static int ext3_statfs (struct dentry *
* Every block group has an inode bitmap, a block
* bitmap, and an inode table.
*/
- overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group));
+ overhead += ngroups * (2 + sbi->s_itb_per_group);
+ sbi->s_overhead_last = overhead;
+ smp_wmb();
+ sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
}
buf->f_type = EXT3_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
- buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
+ buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
+ es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
buf->f_bavail = 0;
buf->f_files = le32_to_cpu(es->s_inodes_count);
buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
+ es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
buf->f_namelen = EXT3_NAME_LEN;
return 0;
}
Index: linux-2.6.18.8/include/linux/ext3_fs_sb.h
===================================================================
--- linux-2.6.18.8.orig/include/linux/ext3_fs_sb.h 2007-07-20 16:51:23.000000000 +0200
+++ linux-2.6.18.8/include/linux/ext3_fs_sb.h 2007-07-20 16:51:43.000000000 +0200
@@ -45,6 +45,8 @@ struct ext3_sb_info {
unsigned long s_gdb_count; /* Number of group descriptor blocks */
unsigned long s_desc_per_block; /* Number of group descriptors per block */
unsigned long s_groups_count; /* Number of groups in the fs */
+ unsigned long s_overhead_last; /* Last calculated overhead */
+ unsigned long s_blocks_last; /* Last seen block count */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment