]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] remount: fs/sysv fixes
authorAlexander Viro <viro@www.linux.org.uk>
Fri, 16 Apr 2004 07:26:34 +0000 (00:26 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 16 Apr 2004 07:26:34 +0000 (00:26 -0700)
 - several variants of sysv fs are supported only r/o.  Driver does
   force r/o on mount, but doesn't do anything on remount.  As the
   result, one can remount them r/w and results are Not Pretty(tm).
   Missing checks added, code cleaned up.

 - we had double-brelse() in v7fs - if sanity checks on root inode will
   succeed, but allocation of root dentry fails, we brelse() the same
   buffer_head twice.  Fixed.

fs/sysv/inode.c
fs/sysv/super.c
fs/sysv/sysv.h

index 09c131fbb36f9368ff64612e877a53aa24925cd1..379d42408f53116854d8f16cb2183ab40a7d308a 100644 (file)
@@ -57,6 +57,16 @@ clean:
        unlock_kernel();
 }
 
+static int sysv_remount(struct super_block *sb, int *flags, char *data)
+{
+       struct sysv_sb_info *sbi = SYSV_SB(sb);
+       if (sbi->s_forced_ro)
+               *flags |= MS_RDONLY;
+       if (!(*flags & MS_RDONLY))
+               sb->s_dirt = 1;
+       return 0;
+}
+
 static void sysv_put_super(struct super_block *sb)
 {
        struct sysv_sb_info *sbi = SYSV_SB(sb);
@@ -321,6 +331,7 @@ struct super_operations sysv_sops = {
        .delete_inode   = sysv_delete_inode,
        .put_super      = sysv_put_super,
        .write_super    = sysv_write_super,
+       .remount_fs     = sysv_remount,
        .statfs         = sysv_statfs,
 };
 
index baf3157204b3f86d4e2f7fa54b8e0b94414553d9..f0e99fc617cc09ced7905399325d0121ff8dcc65 100644 (file)
@@ -206,11 +206,11 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh)
  
        if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) {
                sbi->s_type = FSTYPE_AFS;
+               sbi->s_forced_ro = 1;
                if (!(sb->s_flags & MS_RDONLY)) {
                        printk("SysV FS: SCO EAFS on %s detected, " 
                                "forcing read-only mode.\n", 
                                sb->s_id);
-                       sb->s_flags |= MS_RDONLY;
                }
                return sbd->s_type;
        }
@@ -234,7 +234,7 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh)
        if (sbd->s_type >= 0x10) {
                printk("SysV FS: can't handle long file names on %s, "
                       "forcing read-only mode.\n", sb->s_id);
-               sb->s_flags |= MS_RDONLY;
+               sbi->s_forced_ro = 1;
        }
 
        sbi->s_type = FSTYPE_SYSV4;
@@ -335,9 +335,10 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
                printk("SysV FS: get root dentry failed\n");
                return 0;
        }
+       if (sbi->s_forced_ro)
+               sb->s_flags |= MS_RDONLY;
        if (sbi->s_truncate)
                sb->s_root->d_op = &sysv_dentry_operations;
-       sb->s_flags |= MS_RDONLY;
        sb->s_dirt = 1;
        return 1;
 }
@@ -481,6 +482,7 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
            (fs32_to_cpu(sbi, v7i->i_size) & 017) != 0)
                goto failed;
        brelse(bh2);
+       bh2 = NULL;
 
        sbi->s_bh1 = bh;
        sbi->s_bh2 = bh;
index f759717bd01839b56cc29a56210b2ce33c63a673..493b0a6a4f0e3765370f91130bd66c72e89b0b94 100644 (file)
@@ -54,6 +54,7 @@ struct sysv_sb_info {
        u32            s_ndatazones;    /* total number of data zones */
        u32            s_nzones;        /* same as s_sbd->s_fsize */
        u16            s_namelen;       /* max length of dir entry */
+       int            s_forced_ro;
 };
 
 /*