diff options
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 1 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_raw.h | 12 | ||||
-rw-r--r-- | fs/hfsplus/options.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 20 |
4 files changed, 33 insertions, 6 deletions
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index c60e5635498d..df16fcbff3fb 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -151,6 +151,7 @@ struct hfsplus_sb_info { | |||
151 | 151 | ||
152 | #define HFSPLUS_SB_WRITEBACKUP 0x0001 | 152 | #define HFSPLUS_SB_WRITEBACKUP 0x0001 |
153 | #define HFSPLUS_SB_NODECOMPOSE 0x0002 | 153 | #define HFSPLUS_SB_NODECOMPOSE 0x0002 |
154 | #define HFSPLUS_SB_FORCE 0x0004 | ||
154 | 155 | ||
155 | 156 | ||
156 | struct hfsplus_inode_info { | 157 | struct hfsplus_inode_info { |
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h index 5bad37cfdb29..b4fbed633219 100644 --- a/fs/hfsplus/hfsplus_raw.h +++ b/fs/hfsplus/hfsplus_raw.h | |||
@@ -123,11 +123,13 @@ struct hfsplus_vh { | |||
123 | } __packed; | 123 | } __packed; |
124 | 124 | ||
125 | /* HFS+ volume attributes */ | 125 | /* HFS+ volume attributes */ |
126 | #define HFSPLUS_VOL_UNMNT (1 << 8) | 126 | #define HFSPLUS_VOL_UNMNT (1 << 8) |
127 | #define HFSPLUS_VOL_SPARE_BLK (1 << 9) | 127 | #define HFSPLUS_VOL_SPARE_BLK (1 << 9) |
128 | #define HFSPLUS_VOL_NOCACHE (1 << 10) | 128 | #define HFSPLUS_VOL_NOCACHE (1 << 10) |
129 | #define HFSPLUS_VOL_INCNSTNT (1 << 11) | 129 | #define HFSPLUS_VOL_INCNSTNT (1 << 11) |
130 | #define HFSPLUS_VOL_SOFTLOCK (1 << 15) | 130 | #define HFSPLUS_VOL_NODEID_REUSED (1 << 12) |
131 | #define HFSPLUS_VOL_JOURNALED (1 << 13) | ||
132 | #define HFSPLUS_VOL_SOFTLOCK (1 << 15) | ||
131 | 133 | ||
132 | /* HFS+ BTree node descriptor */ | 134 | /* HFS+ BTree node descriptor */ |
133 | struct hfs_bnode_desc { | 135 | struct hfs_bnode_desc { |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index cca0818aa4ca..935dafba0078 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
@@ -22,7 +22,7 @@ enum { | |||
22 | opt_umask, opt_uid, opt_gid, | 22 | opt_umask, opt_uid, opt_gid, |
23 | opt_part, opt_session, opt_nls, | 23 | opt_part, opt_session, opt_nls, |
24 | opt_nodecompose, opt_decompose, | 24 | opt_nodecompose, opt_decompose, |
25 | opt_err | 25 | opt_force, opt_err |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static match_table_t tokens = { | 28 | static match_table_t tokens = { |
@@ -36,6 +36,7 @@ static match_table_t tokens = { | |||
36 | { opt_nls, "nls=%s" }, | 36 | { opt_nls, "nls=%s" }, |
37 | { opt_decompose, "decompose" }, | 37 | { opt_decompose, "decompose" }, |
38 | { opt_nodecompose, "nodecompose" }, | 38 | { opt_nodecompose, "nodecompose" }, |
39 | { opt_force, "force" }, | ||
39 | { opt_err, NULL } | 40 | { opt_err, NULL } |
40 | }; | 41 | }; |
41 | 42 | ||
@@ -145,6 +146,9 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) | |||
145 | case opt_nodecompose: | 146 | case opt_nodecompose: |
146 | sbi->flags |= HFSPLUS_SB_NODECOMPOSE; | 147 | sbi->flags |= HFSPLUS_SB_NODECOMPOSE; |
147 | break; | 148 | break; |
149 | case opt_force: | ||
150 | sbi->flags |= HFSPLUS_SB_FORCE; | ||
151 | break; | ||
148 | default: | 152 | default: |
149 | return 0; | 153 | return 0; |
150 | } | 154 | } |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 0ce1c455ae55..8093351bd7c3 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -251,16 +251,28 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) | |||
251 | return 0; | 251 | return 0; |
252 | if (!(*flags & MS_RDONLY)) { | 252 | if (!(*flags & MS_RDONLY)) { |
253 | struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; | 253 | struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; |
254 | struct hfsplus_sb_info sbi; | ||
255 | |||
256 | memset(&sbi, 0, sizeof(struct hfsplus_sb_info)); | ||
257 | sbi.nls = HFSPLUS_SB(sb).nls; | ||
258 | if (!hfsplus_parse_options(data, &sbi)) | ||
259 | return -EINVAL; | ||
254 | 260 | ||
255 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { | 261 | if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { |
256 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " | 262 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " |
257 | "running fsck.hfsplus is recommended. leaving read-only.\n"); | 263 | "running fsck.hfsplus is recommended. leaving read-only.\n"); |
258 | sb->s_flags |= MS_RDONLY; | 264 | sb->s_flags |= MS_RDONLY; |
259 | *flags |= MS_RDONLY; | 265 | *flags |= MS_RDONLY; |
266 | } else if (sbi.flags & HFSPLUS_SB_FORCE) { | ||
267 | /* nothing */ | ||
260 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 268 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
261 | printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n"); | 269 | printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n"); |
262 | sb->s_flags |= MS_RDONLY; | 270 | sb->s_flags |= MS_RDONLY; |
263 | *flags |= MS_RDONLY; | 271 | *flags |= MS_RDONLY; |
272 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | ||
273 | printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n"); | ||
274 | sb->s_flags |= MS_RDONLY; | ||
275 | *flags |= MS_RDONLY; | ||
264 | } | 276 | } |
265 | } | 277 | } |
266 | return 0; | 278 | return 0; |
@@ -352,11 +364,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
352 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " | 364 | printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " |
353 | "running fsck.hfsplus is recommended. mounting read-only.\n"); | 365 | "running fsck.hfsplus is recommended. mounting read-only.\n"); |
354 | sb->s_flags |= MS_RDONLY; | 366 | sb->s_flags |= MS_RDONLY; |
367 | } else if (sbi->flags & HFSPLUS_SB_FORCE) { | ||
368 | /* nothing */ | ||
355 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { | 369 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { |
356 | if (!silent) | 370 | if (!silent) |
357 | printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n"); | 371 | printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n"); |
358 | sb->s_flags |= MS_RDONLY; | 372 | sb->s_flags |= MS_RDONLY; |
373 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | ||
374 | if (!silent) | ||
375 | printk("HFS+-fs: write access to a jounaled filesystem is not supported, " | ||
376 | "use the force option at your own risk, mounting read-only.\n"); | ||
377 | sb->s_flags |= MS_RDONLY; | ||
359 | } | 378 | } |
379 | sbi->flags &= ~HFSPLUS_SB_FORCE; | ||
360 | 380 | ||
361 | /* Load metadata objects (B*Trees) */ | 381 | /* Load metadata objects (B*Trees) */ |
362 | HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); | 382 | HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); |