Commit 466341ba authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] remount: fs/sysv fixes

 - 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.
parent eccf6f14
...@@ -57,6 +57,16 @@ static void sysv_write_super(struct super_block *sb) ...@@ -57,6 +57,16 @@ static void sysv_write_super(struct super_block *sb)
unlock_kernel(); 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) static void sysv_put_super(struct super_block *sb)
{ {
struct sysv_sb_info *sbi = SYSV_SB(sb); struct sysv_sb_info *sbi = SYSV_SB(sb);
...@@ -321,6 +331,7 @@ struct super_operations sysv_sops = { ...@@ -321,6 +331,7 @@ struct super_operations sysv_sops = {
.delete_inode = sysv_delete_inode, .delete_inode = sysv_delete_inode,
.put_super = sysv_put_super, .put_super = sysv_put_super,
.write_super = sysv_write_super, .write_super = sysv_write_super,
.remount_fs = sysv_remount,
.statfs = sysv_statfs, .statfs = sysv_statfs,
}; };
......
...@@ -206,11 +206,11 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh) ...@@ -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) { if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) {
sbi->s_type = FSTYPE_AFS; sbi->s_type = FSTYPE_AFS;
sbi->s_forced_ro = 1;
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
printk("SysV FS: SCO EAFS on %s detected, " printk("SysV FS: SCO EAFS on %s detected, "
"forcing read-only mode.\n", "forcing read-only mode.\n",
sb->s_id); sb->s_id);
sb->s_flags |= MS_RDONLY;
} }
return sbd->s_type; return sbd->s_type;
} }
...@@ -234,7 +234,7 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh) ...@@ -234,7 +234,7 @@ static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh)
if (sbd->s_type >= 0x10) { if (sbd->s_type >= 0x10) {
printk("SysV FS: can't handle long file names on %s, " printk("SysV FS: can't handle long file names on %s, "
"forcing read-only mode.\n", sb->s_id); "forcing read-only mode.\n", sb->s_id);
sb->s_flags |= MS_RDONLY; sbi->s_forced_ro = 1;
} }
sbi->s_type = FSTYPE_SYSV4; sbi->s_type = FSTYPE_SYSV4;
...@@ -335,9 +335,10 @@ static int complete_read_super(struct super_block *sb, int silent, int size) ...@@ -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"); printk("SysV FS: get root dentry failed\n");
return 0; return 0;
} }
if (sbi->s_forced_ro)
sb->s_flags |= MS_RDONLY;
if (sbi->s_truncate) if (sbi->s_truncate)
sb->s_root->d_op = &sysv_dentry_operations; sb->s_root->d_op = &sysv_dentry_operations;
sb->s_flags |= MS_RDONLY;
sb->s_dirt = 1; sb->s_dirt = 1;
return 1; return 1;
} }
...@@ -481,6 +482,7 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) ...@@ -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) (fs32_to_cpu(sbi, v7i->i_size) & 017) != 0)
goto failed; goto failed;
brelse(bh2); brelse(bh2);
bh2 = NULL;
sbi->s_bh1 = bh; sbi->s_bh1 = bh;
sbi->s_bh2 = bh; sbi->s_bh2 = bh;
......
...@@ -54,6 +54,7 @@ struct sysv_sb_info { ...@@ -54,6 +54,7 @@ struct sysv_sb_info {
u32 s_ndatazones; /* total number of data zones */ u32 s_ndatazones; /* total number of data zones */
u32 s_nzones; /* same as s_sbd->s_fsize */ u32 s_nzones; /* same as s_sbd->s_fsize */
u16 s_namelen; /* max length of dir entry */ u16 s_namelen; /* max length of dir entry */
int s_forced_ro;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment