aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-07-25 10:15:16 -0400
committerJan Kara <jack@suse.cz>2013-07-31 16:14:51 -0400
commite729eac6f65e11c5f03b09adcc84bd5bcb230467 (patch)
tree0165a2b95c0262c2df0510b50f8e445241672af1
parentd759bfa4e7919b89357de50a2e23817079889195 (diff)
udf: Refuse RW mount of the filesystem instead of making it RO
Refuse RW mount of udf filesystem. So far we just silently changed it to RO mount but when the media is writeable, block layer won't notice this change and thus will think device is used RW and will block eject button of the drive. That is unexpected by users because for non-writeable media eject button works just fine. Userspace mount(8) command handles this just fine and retries mounting with MS_RDONLY set so userspace shouldn't see any regression. Plus any tool mounting udf is likely confronted with the case of read-only media where block layer already refuses to mount the filesystem without MS_RDONLY set so our behavior shouldn't be anything new for it. Reported-by: Hui Wang <hui.wang@canonical.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/udf/super.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index c68da0dac2c5..839a2bad7f45 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -630,6 +630,12 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
630 struct udf_sb_info *sbi = UDF_SB(sb); 630 struct udf_sb_info *sbi = UDF_SB(sb);
631 int error = 0; 631 int error = 0;
632 632
633 if (sbi->s_lvid_bh) {
634 int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
635 if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY))
636 return -EACCES;
637 }
638
633 uopt.flags = sbi->s_flags; 639 uopt.flags = sbi->s_flags;
634 uopt.uid = sbi->s_uid; 640 uopt.uid = sbi->s_uid;
635 uopt.gid = sbi->s_gid; 641 uopt.gid = sbi->s_gid;
@@ -649,12 +655,6 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
649 sbi->s_dmode = uopt.dmode; 655 sbi->s_dmode = uopt.dmode;
650 write_unlock(&sbi->s_cred_lock); 656 write_unlock(&sbi->s_cred_lock);
651 657
652 if (sbi->s_lvid_bh) {
653 int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
654 if (write_rev > UDF_MAX_WRITE_VERSION)
655 *flags |= MS_RDONLY;
656 }
657
658 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 658 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
659 goto out_unlock; 659 goto out_unlock;
660 660
@@ -1284,16 +1284,18 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
1284 goto out_bh; 1284 goto out_bh;
1285 } 1285 }
1286 } else { 1286 } else {
1287 /*
1288 * If we have a partition with virtual map, we don't handle
1289 * writing to it (we overwrite blocks instead of relocating
1290 * them).
1291 */
1292 if (!(sb->s_flags & MS_RDONLY)) {
1293 ret = -EACCES;
1294 goto out_bh;
1295 }
1287 ret = udf_load_vat(sb, i, type1_idx); 1296 ret = udf_load_vat(sb, i, type1_idx);
1288 if (ret < 0) 1297 if (ret < 0)
1289 goto out_bh; 1298 goto out_bh;
1290 /*
1291 * Mark filesystem read-only if we have a partition with
1292 * virtual map since we don't handle writing to it (we
1293 * overwrite blocks instead of relocating them).
1294 */
1295 sb->s_flags |= MS_RDONLY;
1296 pr_notice("Filesystem marked read-only because writing to pseudooverwrite partition is not implemented\n");
1297 } 1299 }
1298 ret = 0; 1300 ret = 0;
1299out_bh: 1301out_bh:
@@ -2103,8 +2105,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
2103 UDF_MAX_READ_VERSION); 2105 UDF_MAX_READ_VERSION);
2104 ret = -EINVAL; 2106 ret = -EINVAL;
2105 goto error_out; 2107 goto error_out;
2106 } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) 2108 } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION &&
2107 sb->s_flags |= MS_RDONLY; 2109 !(sb->s_flags & MS_RDONLY)) {
2110 ret = -EACCES;
2111 goto error_out;
2112 }
2108 2113
2109 sbi->s_udfrev = minUDFWriteRev; 2114 sbi->s_udfrev = minUDFWriteRev;
2110 2115
@@ -2121,9 +2126,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
2121 } 2126 }
2122 2127
2123 if (sbi->s_partmaps[sbi->s_partition].s_partition_flags & 2128 if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
2124 UDF_PART_FLAG_READ_ONLY) { 2129 UDF_PART_FLAG_READ_ONLY &&
2125 pr_notice("Partition marked readonly; forcing readonly mount\n"); 2130 !(sb->s_flags & MS_RDONLY)) {
2126 sb->s_flags |= MS_RDONLY; 2131 ret = -EACCES;
2132 goto error_out;
2127 } 2133 }
2128 2134
2129 if (udf_find_fileset(sb, &fileset, &rootdir)) { 2135 if (udf_find_fileset(sb, &fileset, &rootdir)) {