A few V7 fs improvements
I'm resending these once again, since I suspect they may have gotten lost in a spam filter due to improper MTA configuration of mine.
They basically improve usability of PC v7 filesystems; such as those of PC/IX.
PATCH 1/3 Add v7 alias
So that the module gets autoloaded when a v7 filesystem is mounted.
--- fs/sysv/super.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
fs/sysv/super.c +1 -0
@@ -560,4 +560,5 @@ static void __exit exit_sysv_fs(void) module_init(init_sysv_fs) module_exit(exit_sysv_fs) +MODULE_ALIAS("v7");MODULE_LICENSE ("GPL" );
Signature · 1 line
1.6.5.2
PATCH 2/3 V7: Adjust sanity checks for some volumes
Newly mkfs-ed filesystems from Seventh Edition have last modification time set to zero, but are otherwise perfectly valid.
Also, tighten up other sanity checks to filter out most filesystems with different bytesex than we're using.
--- fs/sysv/super.c | 8 +++++--- include/linux/sysv_fs.h | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-)
fs/sysv/super.c +5 -3
@@ -470,8 +470,8 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) v7sb = (struct v7_super_block *) bh->b_data;if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE ||fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_time) ==0 ) - goto failed; +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ;/* plausibility check on root inode: it is a directory, with a nonzero size that is a multiple of 16 */
@@ -480,7 +480,9 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) v7i = (struct sysv_inode *)(bh2->b_data +64 );if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) !=0 ) + (fs32_to_cpu (sbi, v7i->i_size) &017 ) + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) { goto failed;brelse (bh2); bh2 =NULL ;
include/linux/sysv_fs.h +11 -0
@@ -148,6 +148,17 @@ struct v7_super_block {char s_fname[6 ];/* file system name */ char s_fpack[6 ];/* file system pack name */ }; +/* Constants to aid sanity checking */ +/* This is not a hard limit, nor enforced by v7 kernel. It's actually just +* the limit used by Seventh Edition's ls, though is high enough to assume +* that no reasonable file system would have that much entries in root +* directory. Thus, if we see anything higher, we just probably got the +* endiannes wrong. */ +#define V7_NFILES 1024 +/* Indirect blocks hold just three-byte addresses, therefore if see a file +* system whose length has the most significant byte non-zero something is +* most likely wrong (not a filesystem, bad bytesex). */ +#define V7_MAXSIZE 0x00ffffff/* Coherent super-block data on disk */ #define COH_NICINOD 100/* number of inode cache entries */
Signature · 1 line
1.6.5.2
PATCH 3/3 V7: Add support for non-PDP11 v7 filesystems
A mount-time option was added that makes it possible to override the endianness and an attempt is made to autodetect it (which seems easy, given the disk addresses are 3-byte.
No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
--- fs/sysv/super.c | 116 +++++++++++++++++++++++++++++++++++++---------- include/linux/sysv_fs.h | 6 +- 2 files changed, 95 insertions(+), 27 deletions(-)
fs/sysv/super.c +92 -24
@@ -24,6 +24,7 @@#include <linux/init.h> #include <linux/slab.h> #include <linux/buffer_head.h> +#include <linux/parser.h> #include "sysv.h" /*
@@ -435,12 +436,55 @@ Ebadsize: goto failed; } -static int v7_fill_super (struct super_block *sb,void *data,int silent) +static int v7_sanity_check (struct super_block *sb,struct buffer_head *bh) { -struct sysv_sb_info *sbi; -struct buffer_head *bh, *bh2 =NULL ;struct v7_super_block *v7sb;struct sysv_inode *v7i; +struct buffer_head *bh2; +struct sysv_sb_info *sbi; + + sbi = sb->s_fs_info; + +/* plausibility check on superblock */ + v7sb = (struct v7_super_block *) bh->b_data; +if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || +fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ; + +/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + } + + v7i = (struct sysv_inode *)(bh2->b_data +64 ); +if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || + (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || + (fs32_to_cpu (sbi, v7i->i_size) &017 ) || + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) { +brelse (bh2); +return 0 ; + } + +brelse (bh2); +return 1 ; +} + +enum { Opt_err, Opt_bytesex_pdp, Opt_bytesex_le, Opt_bytesex_be }; + +static const match_table_t v7_tokens = { + {Opt_bytesex_pdp,"bytesex=pdp" }, + {Opt_bytesex_le,"bytesex=le" }, + {Opt_bytesex_be,"bytesex=be" }, + {Opt_err,NULL } +}; + +static int v7_fill_super (struct super_block *sb,void *data,int silent) +{ +struct sysv_sb_info *sbi; +struct buffer_head *bh;if (440 !=sizeof (struct v7_super_block ))panic ("V7 FS: bad super-block size" );
@@ -454,7 +498,6 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) sbi->s_sb = sb; sbi->s_block_base =0 ; sbi->s_type =FSTYPE_V7 ; - sbi->s_bytesex =BYTESEX_PDP ; sb->s_fs_info = sbi;sb_set_blocksize (sb,512 );
@@ -466,26 +509,51 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) goto failed; } -/* plausibility check on superblock */ - v7sb = (struct v7_super_block *) bh->b_data; -if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || -fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) -return 0 ; +if (data) { +substring_t args[MAX_OPT_ARGS ]; +char *p; + +while ((p =strsep ((char **)&data,"," )) !=NULL ) { +int token; +if (!*p) +continue ; + token =match_token (p, v7_tokens, args); +switch (token) { +case Opt_bytesex_pdp: + sbi->s_bytesex =BYTESEX_PDP ; +break ; +case Opt_bytesex_le: + sbi->s_bytesex =BYTESEX_LE ; +break ; +case Opt_bytesex_be: + sbi->s_bytesex =BYTESEX_BE ; +break ; +default : +/* An unrecognized option */ + goto failed; + } + } + } -/* plausibility check on root inode: it is a directory, -with a nonzero size that is a multiple of 16 */ -if ((bh2 =sb_bread (sb,2 )) ==NULL ) - goto failed; - v7i = (struct sysv_inode *)(bh2->b_data +64 ); -if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || - (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) - (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * -sizeof (struct sysv_dir_entry ))) { - goto failed; -brelse (bh2); - bh2 =NULL ; +/* Endianness overridden by a mount option */ +if (sbi->s_bytesex) { +if (!v7_sanity_check (sb, bh)) + goto failed; + goto detected; + } + +/* Try PDP-11 UNIX */ + sbi->s_bytesex =BYTESEX_PDP ; +if (v7_sanity_check (sb, bh)) + goto detected; + +/* Try PC/IX, v7/x86 */ + sbi->s_bytesex =BYTESEX_LE ; +if (v7_sanity_check (sb, bh)) + goto detected; + + goto failed; +detected: sbi->s_bh1 = bh; sbi->s_bh2 = bh;
@@ -493,7 +561,7 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)return 0 ; failed: -brelse (bh2); +printk ("VFS: could not find a valid V7 on %s.\n" , sb->s_id);brelse (bh);kfree (sbi);return -EINVAL ;
include/linux/sysv_fs.h +3 -3
@@ -155,9 +155,9 @@ struct v7_super_block {* directory. Thus, if we see anything higher, we just probably got the * endiannes wrong. */ #define V7_NFILES 1024 -/* Indirect blocks hold just three-byte addresses, therefore if see a file -* system whose length has the most significant byte non-zero something is -* most likely wrong (not a filesystem, bad bytesex). */ +/* The disk addresses are three-byte (despite direct block addresses being +* aligned word-wise in inode). If the most significant byte is non-zero, +* something is most likely wrong (not a filesystem, bad bytesex). */ #define V7_MAXSIZE 0x00ffffff/* Coherent super-block data on disk */
Signature · 1 line
1.6.5.2
Re: [PATCH 3/3] [fs/sysv] V7: Add support for non-PDP11 v7 filesystems
Quoted 6 lines · Lubomir Rintel
A mount-time option was added that makes it possible to override the endianness and an attempt is made to autodetect it (which seems easy, given the disk addresses are 3-byte.
No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Do you actually need the mount option? We get away just fine with it for sysv filesystems. And if not I'd be consistent and accept the options for both sysv and v7 filesystems.
fs/sysv/super.c Ebadsize: · line 459
Quoted 5 lines
fs/sysv/super.c +5
-0+/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + }
A little style nitpick, this should be:
bh2 = sb_bread(sb, 2); if (!bh) return 0;
Re: [PATCH 3/3] [fs/sysv] V7: Add support for non-PDP11 v7 filesystems
Quoted 11 lines · Christoph Hellwig
Quoted 6 lines · Lubomir Rintel
A mount-time option was added that makes it possible to override the endianness and an attempt is made to autodetect it (which seems easy, given the disk addresses are 3-byte.
No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Do you actually need the mount option? We get away just fine with it for sysv filesystems. And if not I'd be consistent and accept the options for both sysv and v7 filesystems.
Well, there's no reliable way to detect endiannes of a v7 filesystem unless we do a deep check as fsck would do (there are cases where we can be sure that a filesystem is not of a certain bytesex, which is what the current sanity check does and what's abused for the lousy autodetection).
In super.c it looks like xenix and sysv use a magic number which the byte order can be determined from, thus the option would be useless there.
Coherent seems to always use PDP-11 bytesex. I can not check at the time, but I'm almost sure it never run on such machines (was PC and 68k only?), so I suspect the coherent kernel might have always done the translation to native byte order. I think I have some coherent (for PC) floppies at home, so I can check tomorrow.
Quoted 8 lines
fs/sysv/super.c Ebadsize: · line 459
Quoted 5 lines
fs/sysv/super.c +5
-0+/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + }A little style nitpick, this should be:
Quoted 4 lines
bh2 = sb_bread(sb, 2); if (!bh) return 0;
I actually did not write this myself, but merely moved from v7_fill_super(). It would probably a good idea to keep it as it is (not to obfuscate the changes) and fix it up in a separate commit if is worth.
Take care,
Lubo
Signature · 2 lines
Flash is the Web2.0 version of blink and animated gifs.
-- Stephen SmoogenRe: [PATCH 3/3] [fs/sysv] V7: Add support for non-PDP11 v7 filesystems
Quoted 1 line · Lubomir Rintel
On Mon, 2010-07-19 at 16:58 +0200, Christoph Hellwig wrote:
...
Quoted 3 lines
Quoted 3 lines
Do you actually need the mount option? We get away just fine with it for sysv filesystems. And if not I'd be consistent and accept the options for both sysv and v7 filesystems.
...
Quoted 5 lines
Coherent seems to always use PDP-11 bytesex. I can not check at the time, but I'm almost sure it never run on such machines (was PC and 68k only?), so I suspect the coherent kernel might have always done the translation to native byte order. I think I have some coherent (for PC) floppies at home, so I can check tomorrow.
This was just partly correct. Coherent indeed run on PDP-11 (and not on 68k), but the PC version uses the very same bytesex as PDP-11 one, translating the byte order on the fly (_canl() routine defined in i386/as.inc file of Coherent 4.2.10 for i386 kernel is used).
Thus the mount option is really only useful with v7 filesystem and none of those handled with sysv filesystem.
Signature · 2 lines
Flash is the Web2.0 version of blink and animated gifs.
-- Stephen SmoogenPATCH 1/1 V7: Add support for non-PDP11 v7 filesystems
A mount-time option was added that makes it possible to override the endianness and an attempt is made to autodetect it (which seems easy, given the disk addresses are 3-byte.
No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
--- fs/sysv/super.c | 116 +++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 92 insertions(+), 24 deletions(-)
fs/sysv/super.c +92 -24
@@ -24,6 +24,7 @@#include <linux/init.h> #include <linux/slab.h> #include <linux/buffer_head.h> +#include <linux/parser.h> #include "sysv.h" /*
@@ -435,12 +436,55 @@ Ebadsize: goto failed; } -static int v7_fill_super (struct super_block *sb,void *data,int silent) +static int v7_sanity_check (struct super_block *sb,struct buffer_head *bh) { -struct sysv_sb_info *sbi; -struct buffer_head *bh, *bh2 =NULL ;struct v7_super_block *v7sb;struct sysv_inode *v7i; +struct buffer_head *bh2; +struct sysv_sb_info *sbi; + + sbi = sb->s_fs_info; + +/* plausibility check on superblock */ + v7sb = (struct v7_super_block *) bh->b_data; +if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || +fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ; + +/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + } + + v7i = (struct sysv_inode *)(bh2->b_data +64 ); +if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || + (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || + (fs32_to_cpu (sbi, v7i->i_size) &017 ) || + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) { +brelse (bh2); +return 0 ; + } + +brelse (bh2); +return 1 ; +} + +enum { Opt_err, Opt_bytesex_pdp, Opt_bytesex_le, Opt_bytesex_be }; + +static const match_table_t v7_tokens = { + {Opt_bytesex_pdp,"bytesex=pdp" }, + {Opt_bytesex_le,"bytesex=le" }, + {Opt_bytesex_be,"bytesex=be" }, + {Opt_err,NULL } +}; + +static int v7_fill_super (struct super_block *sb,void *data,int silent) +{ +struct sysv_sb_info *sbi; +struct buffer_head *bh;if (440 !=sizeof (struct v7_super_block ))panic ("V7 FS: bad super-block size" );
@@ -454,7 +498,6 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) sbi->s_sb = sb; sbi->s_block_base =0 ; sbi->s_type =FSTYPE_V7 ; - sbi->s_bytesex =BYTESEX_PDP ; sb->s_fs_info = sbi;sb_set_blocksize (sb,512 );
@@ -466,34 +509,59 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) goto failed; } -/* plausibility check on superblock */ - v7sb = (struct v7_super_block *) bh->b_data; -if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || -fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) - goto failed; +if (data) { +substring_t args[MAX_OPT_ARGS ]; +char *p; + +while ((p =strsep ((char **)&data,"," )) !=NULL ) { +int token; +if (!*p) +continue ; + token =match_token (p, v7_tokens, args); +switch (token) { +case Opt_bytesex_pdp: + sbi->s_bytesex =BYTESEX_PDP ; +break ; +case Opt_bytesex_le: + sbi->s_bytesex =BYTESEX_LE ; +break ; +case Opt_bytesex_be: + sbi->s_bytesex =BYTESEX_BE ; +break ; +default : +/* An unrecognized option */ + goto failed; + } + } + } -/* plausibility check on root inode: it is a directory, -with a nonzero size that is a multiple of 16 */ -if ((bh2 =sb_bread (sb,2 )) ==NULL ) - goto failed; - v7i = (struct sysv_inode *)(bh2->b_data +64 ); -if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || - (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) || - (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * -sizeof (struct sysv_dir_entry ))) - goto failed; -brelse (bh2); - bh2 =NULL ; +/* Endianness overridden by a mount option */ +if (sbi->s_bytesex) { +if (!v7_sanity_check (sb, bh)) + goto failed; + goto detected; + } + +/* Try PDP-11 UNIX */ + sbi->s_bytesex =BYTESEX_PDP ; +if (v7_sanity_check (sb, bh)) + goto detected; + +/* Try PC/IX, v7/x86 */ + sbi->s_bytesex =BYTESEX_LE ; +if (v7_sanity_check (sb, bh)) + goto detected; + goto failed; + +detected: sbi->s_bh1 = bh; sbi->s_bh2 = bh;if (complete_read_super (sb, silent,1 ))return 0 ; failed: -brelse (bh2); +printk ("VFS: could not find a valid V7 on %s.\n" , sb->s_id);brelse (bh);kfree (sbi);return -EINVAL ;
Signature · 1 line
1.7.1
Re: [PATCH 3/3] [fs/sysv] V7: Add support for non-PDP11 v7 filesystems
In reply to Christoph HellwigQuoted 11 lines · Christoph Hellwig
Quoted 6 lines · Lubomir Rintel
A mount-time option was added that makes it possible to override the endianness and an attempt is made to autodetect it (which seems easy, given the disk addresses are 3-byte.
No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Do you actually need the mount option? We get away just fine with it for sysv filesystems. And if not I'd be consistent and accept the options for both sysv and v7 filesystems.
Actually, it shouldn't be too hard to detect the damn thing even without magic. Look - we always have the inode table starting at block 2, so on-disk root inode is guaranteed to be found correctly. Now, suppose we'd mistaken l-e for pdp or vice versa; the half-words of i_size would get swapped. What could pass both tests? Suppose the right size is a * 65536 + b; then we have: a and b are both multiples of 16 and at least one is non-zero. So all we need is to reject root directories bigger than 1Mb. And posted patches do reject that (and lower than that, actually).
So I'd rather see a variant without that option. Simply get both bh, then try the same sanity checks with LE and PDP used for s_bytesex. And use one that works - we _know_ that it's impossible to have both pass at the same time.
I'm fine with the rest of patch series as is; Lubomir, could you redo the last one that way and resend?
PATCH 1/1 V7: Add support for non-PDP11 v7 filesystems
This adds byte order autodetection (of PDP-11 and LE filesystems). No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
--- fs/sysv/super.c | 74 +++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 50 insertions(+), 24 deletions(-)
fs/sysv/super.c +50 -24
@@ -24,6 +24,7 @@#include <linux/init.h> #include <linux/slab.h> #include <linux/buffer_head.h> +#include <linux/parser.h> #include "sysv.h" /*
@@ -435,12 +436,46 @@ Ebadsize: goto failed; } -static int v7_fill_super (struct super_block *sb,void *data,int silent) +static int v7_sanity_check (struct super_block *sb,struct buffer_head *bh) { -struct sysv_sb_info *sbi; -struct buffer_head *bh, *bh2 =NULL ;struct v7_super_block *v7sb;struct sysv_inode *v7i; +struct buffer_head *bh2; +struct sysv_sb_info *sbi; + + sbi = sb->s_fs_info; + +/* plausibility check on superblock */ + v7sb = (struct v7_super_block *) bh->b_data; +if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || +fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ; + +/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + } + + v7i = (struct sysv_inode *)(bh2->b_data +64 ); +if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || + (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || + (fs32_to_cpu (sbi, v7i->i_size) &017 ) || + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) { +brelse (bh2); +return 0 ; + } + +brelse (bh2); +return 1 ; +} + +static int v7_fill_super (struct super_block *sb,void *data,int silent) +{ +struct sysv_sb_info *sbi; +struct buffer_head *bh;if (440 !=sizeof (struct v7_super_block ))panic ("V7 FS: bad super-block size" );
@@ -454,7 +489,6 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) sbi->s_sb = sb; sbi->s_block_base =0 ; sbi->s_type =FSTYPE_V7 ; - sbi->s_bytesex =BYTESEX_PDP ; sb->s_fs_info = sbi;sb_set_blocksize (sb,512 );
@@ -466,34 +500,26 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) goto failed; } -/* plausibility check on superblock */ - v7sb = (struct v7_super_block *) bh->b_data; -if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || -fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) - goto failed; +/* Try PDP-11 UNIX */ + sbi->s_bytesex =BYTESEX_PDP ; +if (v7_sanity_check (sb, bh)) + goto detected; -/* plausibility check on root inode: it is a directory, -with a nonzero size that is a multiple of 16 */ -if ((bh2 =sb_bread (sb,2 )) ==NULL ) - goto failed; - v7i = (struct sysv_inode *)(bh2->b_data +64 ); -if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || - (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) || - (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * -sizeof (struct sysv_dir_entry ))) - goto failed; -brelse (bh2); - bh2 =NULL ; +/* Try PC/IX, v7/x86 */ + sbi->s_bytesex =BYTESEX_LE ; +if (v7_sanity_check (sb, bh)) + goto detected; + goto failed; + +detected: sbi->s_bh1 = bh; sbi->s_bh2 = bh;if (complete_read_super (sb, silent,1 ))return 0 ; failed: -brelse (bh2); +printk ("VFS: could not find a valid V7 on %s.\n" , sb->s_id);brelse (bh);kfree (sbi);return -EINVAL ;
Signature · 1 line
1.7.2
Re: [PATCH] V7: Add support for non-PDP11 v7 filesystems
Quoted 33 lines · On Mon, 26 Jul 2010 00:59:16 +0200 Lubomir Rintel wrote:
This adds byte order autodetection (of PDP-11 and LE filesystems). No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Cc Christoph Hellwig <[email protected]>Cc Al Viro <[email protected]>Signed-off-by Lubomir Rintel <[email protected]>--- fs/sysv/super.c | 74 +++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 50 insertions(+), 24 deletions(-)fs/sysv/super.c +8
-3@@ -435,12 +436,46 @@ Ebadsize: goto failed; } -static int v7_fill_super (struct super_block *sb,void *data,int silent) +static int v7_sanity_check (struct super_block *sb,struct buffer_head *bh) { -struct sysv_sb_info *sbi; -struct buffer_head *bh, *bh2 =NULL ;struct v7_super_block *v7sb;struct sysv_inode *v7i; +struct buffer_head *bh2; +struct sysv_sb_info *sbi; + + sbi = sb->s_fs_info; + +/* plausibility check on superblock */ + v7sb = (struct v7_super_block *) bh->b_data;
fs/sysv/super.c Ebadsize: · line 459
Quoted 10 lines
fs/sysv/super.c +10
-0+if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || +fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ; + +/* plausibility check on root inode: it is a directory, +with a nonzero size that is a multiple of 16 */ +if ((bh2 =sb_bread (sb,2 )) ==NULL ) { +return 0 ; + }
Don't need the braces.
fs/sysv/super.c Ebadsize: · line 466
Quoted 7 lines
fs/sysv/super.c +7
-0+ + v7i = (struct sysv_inode *)(bh2->b_data +64 ); +if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || + (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || + (fs32_to_cpu (sbi, v7i->i_size) &017 ) || + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) {
sizeof(struct sysv_dir_entry))) {Quoted 57 lines
fs/sysv/super.c +21
-20+brelse (bh2); +return 0 ; + } + +brelse (bh2); +return 1 ; +} + +static int v7_fill_super (struct super_block *sb,void *data,int silent) +{ +struct sysv_sb_info *sbi; +struct buffer_head *bh;if (440 !=sizeof (struct v7_super_block ))panic ("V7 FS: bad super-block size" );@@ -454,7 +489,6 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) sbi->s_sb = sb; sbi->s_block_base =0 ; sbi->s_type =FSTYPE_V7 ; - sbi->s_bytesex =BYTESEX_PDP ; sb->s_fs_info = sbi;sb_set_blocksize (sb,512 );@@ -466,34 +500,26 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) goto failed; } -/* plausibility check on superblock */ - v7sb = (struct v7_super_block *) bh->b_data; -if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE || -fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) - goto failed; +/* Try PDP-11 UNIX */ + sbi->s_bytesex =BYTESEX_PDP ; +if (v7_sanity_check (sb, bh)) + goto detected; -/* plausibility check on root inode: it is a directory, -with a nonzero size that is a multiple of 16 */ -if ((bh2 =sb_bread (sb,2 )) ==NULL ) - goto failed; - v7i = (struct sysv_inode *)(bh2->b_data +64 ); -if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || - (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) || - (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * -sizeof (struct sysv_dir_entry ))) - goto failed; -brelse (bh2); - bh2 =NULL ; +/* Try PC/IX, v7/x86 */ + sbi->s_bytesex =BYTESEX_LE ; +if (v7_sanity_check (sb, bh)) + goto detected; + goto failed;
fs/sysv/super.c static int v7_fill_super(struct super_block *sb, void *data, int silent) · line 522
Quoted 10 lines
fs/sysv/super.c +3
-1+ +detected: sbi->s_bh1 = bh; sbi->s_bh2 = bh;if (complete_read_super (sb, silent,1 ))return 0 ; failed: -brelse (bh2); +printk ("VFS: could not find a valid V7 on %s.\n" , sb->s_id);
V7 fs (or V7 filesystem)
fs/sysv/super.c static int v7_fill_super(struct super_block *sb, void *data, int silent) · line 525
Quoted 4 lines
fs/sysv/super.c +0
-0brelse (bh);kfree (sbi);return -EINVAL ;
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [PATCH] V7: Add support for non-PDP11 v7 filesystems
In reply to Lubomir RintelQuoted 3 lines · On Mon, 26 Jul 2010 00:59:16 +0200 Lubomir Rintel <[email protected]> wrote:
This adds byte order autodetection (of PDP-11 and LE filesystems). No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Which kernel is this against? My v7_fill_super() is significantly different from yours.
Re: [PATCH] V7: Add support for non-PDP11 v7 filesystems
Quoted 9 lines · Andrew Morton
Quoted 3 lines · On Mon, 26 Jul 2010 00:59:16 +0200 Lubomir Rintel <[email protected]> wrote:
This adds byte order autodetection (of PDP-11 and LE filesystems). No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Which kernel is this against? My
v7_fill_super()is significantly different from yours.
This depends on [PATCH] V7: Adjust sanity checks for some volumes <[email protected]>.
It might be that I've messed up something in the communication so that the dependency was not immediately clear. To be honest, I'm not very familiar with the way reviews and adjustements to patches are tracked. What have I done wrong, here? How am I supposed to follow up with a change to a single patch of a multi-patch (be it just two in this case) set?
Signature · 2 lines
Flash is the Web2.0 version of blink and animated gifs.
-- Stephen SmoogenRe: [PATCH] V7: Add support for non-PDP11 v7 filesystems
Quoted 14 lines · On Tue, 27 Jul 2010 02:19:15 +0200 Lubomir Rintel <[email protected]> wrote:
Quoted 9 lines · Andrew Morton
Quoted 3 lines · On Mon, 26 Jul 2010 00:59:16 +0200 Lubomir Rintel <[email protected]> wrote:
This adds byte order autodetection (of PDP-11 and LE filesystems). No attempt is made to detect big-endian filesystems -- were there any? Tested with PDP-11 v7 filesystems and PC-IX maintenance floppy.
Which kernel is this against? My
v7_fill_super()is significantly different from yours.This depends on [PATCH] V7: Adjust sanity checks for some volumes <[email protected]>.
Quoted 6 lines
It might be that I've messed up something in the communication so that the dependency was not immediately clear. To be honest, I'm not very familiar with the way reviews and adjustements to patches are tracked. What have I done wrong, here? How am I supposed to follow up with a change to a single patch of a multi-patch (be it just two in this case) set?
ah, OK, I managed to confuse myself with fs-sysv-v7-adjust-sanity-checks-for-some-volumes-checkpatch-fixes.patch.
This new patch triggers many warnings also:
ERROR: do not use assignment in if condition
#52: FILE: fs/sysv/super.c:456:
+ if ((bh2 = sb_bread(sb, 2)) == NULL) {
WARNING: braces {} are not necessary for single statement blocks #52: FILE: fs/sysv/super.c:456:
+ if ((bh2 = sb_bread(sb, 2)) == NULL) {
+ return 0;
+ }
ERROR: code indent should use tabs where possible
#61: FILE: fs/sysv/super.c:465:
+ sizeof (struct sysv_dir_entry))) {$
WARNING: please, no space for starting a line,
excluding comments
#61: FILE: fs/sysv/super.c:465:
+ sizeof (struct sysv_dir_entry))) {$
WARNING: space prohibited between function name and open parenthesis '(' #61: FILE: fs/sysv/super.c:465:
+ sizeof (struct sysv_dir_entry))) {
WARNING: space prohibited between function name and open parenthesis '(' #97: FILE: fs/sysv/super.c:504:
+ if (v7_sanity_check (sb, bh))
WARNING: space prohibited between function name and open parenthesis '(' #115: FILE: fs/sysv/super.c:509:
+ if (v7_sanity_check (sb, bh))
WARNING: printk() should include KERN_ facility level #128: FILE: fs/sysv/super.c:521:
+ printk("VFS: could not find a valid V7 on %s.\n", sb->s_id);
total: 2 errors, 6 warnings, 109 lines checked
./patches/v7-add-support-for-non-pdp11-v7-filesystems.patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
fs/sysv/super.c renamed from fs/sysv/super.c~fs-sysv-superc-add-support-for-non-pdp11-v7-filesystems-checkpatch-fixes +7 -6
@@ -453,16 +453,16 @@ static int v7_sanity_check(struct super_/* plausibility check on root inode: it is a directory, with a nonzero size that is a multiple of 16 */ -if ((bh2 =sb_bread (sb,2 )) ==NULL ) { + bh2 =sb_bread (sb,2 ); +if (bh2 ==NULL )return 0 ; - } v7i = (struct sysv_inode *)(bh2->b_data +64 );if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || (fs32_to_cpu (sbi, v7i->i_size) &017 ) || (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * -sizeof (struct sysv_dir_entry ))) { +sizeof (struct sysv_dir_entry ))) {brelse (bh2);return 0 ; }
@@ -501,12 +501,12 @@ static int v7_fill_super(struct super_bl/* Try PDP-11 UNIX */ sbi->s_bytesex =BYTESEX_PDP ; -if (v7_sanity_check (sb, bh)) +if (v7_sanity_check (sb, bh)) goto detected;/* Try PC/IX, v7/x86 */ sbi->s_bytesex =BYTESEX_LE ; -if (v7_sanity_check (sb, bh)) +if (v7_sanity_check (sb, bh)) goto detected; goto failed;
@@ -518,7 +518,8 @@ detected:return 0 ; failed: -printk ("VFS: could not find a valid V7 on %s.\n" , sb->s_id); +printk (KERN_ERR "VFS: could not find a valid V7 on %s.\n" , + sb->s_id);brelse (bh);kfree (sbi);return -EINVAL ;
_
Re: [PATCH 2/3] [fs/sysv] V7: Adjust sanity checks for some volumes
In reply to Lubomir Rintelfs/sysv/super.c static int v7_fill_super(struct super_block *sb, void *data, int silent) · line 474
Quoted 6 lines
fs/sysv/super.c +2
-2if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE ||fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_time) ==0 ) - goto failed; +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) +return 0 ;
Ok.
fs/sysv/super.c static int v7_fill_super(struct super_block *sb, void *data, int silent) · line 485
Quoted 7 lines
fs/sysv/super.c +3
-1v7i = (struct sysv_inode *)(bh2->b_data +64 );if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) !=0 ) + (fs32_to_cpu (sbi, v7i->i_size) &017 ) + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) {
Maybe I'm missing something, but without and additional || on the first line you added this doesn't look like it will compile.
Re: [PATCH 2/3] [fs/sysv] V7: Adjust sanity checks for some volumes
Quoted 10 lines · Christoph Hellwig
fs/sysv/super.c static int v7_fill_super(struct super_block *sb, void *data, int silent) · line 485
Quoted 7 lines
fs/sysv/super.c +3
-1v7i = (struct sysv_inode *)(bh2->b_data +64 );if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) !=0 ) + (fs32_to_cpu (sbi, v7i->i_size) &017 ) + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) {Maybe I'm missing something, but without and additional || on the first line you added this doesn't look like it will compile.
You're right. In fact this hunk is fixed in a commit that followed it, I probably incorrectly merged the fixups in git (the latter commit also had an useless comment change and such).
I'll follow up with a fixed commit tomorrow, since I'm unable to test it now.
Thanks,
Lubo
Signature · 2 lines
Flash is the Web2.0 version of blink and animated gifs.
-- Stephen SmoogenPATCH 1/1 V7: Adjust sanity checks for some volumes
Newly mkfs-ed filesystems from Seventh Edition have last modification time set to zero, but are otherwise perfectly valid.
Also, tighten up other sanity checks to filter out most filesystems with different bytesex than we're using.
--- fs/sysv/super.c | 6 ++++-- include/linux/sysv_fs.h | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-)
fs/sysv/super.c +4 -2
@@ -470,7 +470,7 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) v7sb = (struct v7_super_block *) bh->b_data;if (fs16_to_cpu (sbi, v7sb->s_nfree) >V7_NICFREE ||fs16_to_cpu (sbi, v7sb->s_ninode) >V7_NICINOD || -fs32_to_cpu (sbi, v7sb->s_time) ==0 ) +fs32_to_cpu (sbi, v7sb->s_fsize) >V7_MAXSIZE ) goto failed;/* plausibility check on root inode: it is a directory,
@@ -480,7 +480,9 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) v7i = (struct sysv_inode *)(bh2->b_data +64 );if ((fs16_to_cpu (sbi, v7i->i_mode) & ~0777 ) !=S_IFDIR || (fs32_to_cpu (sbi, v7i->i_size) ==0 ) || - (fs32_to_cpu (sbi, v7i->i_size) &017 ) !=0 ) + (fs32_to_cpu (sbi, v7i->i_size) &017 ) || + (fs32_to_cpu (sbi, v7i->i_size) >V7_NFILES * +sizeof (struct sysv_dir_entry ))) goto failed;brelse (bh2); bh2 =NULL ;
include/linux/sysv_fs.h +11 -0
@@ -148,6 +148,17 @@ struct v7_super_block {char s_fname[6 ];/* file system name */ char s_fpack[6 ];/* file system pack name */ }; +/* Constants to aid sanity checking */ +/* This is not a hard limit, nor enforced by v7 kernel. It's actually just +* the limit used by Seventh Edition's ls, though is high enough to assume +* that no reasonable file system would have that much entries in root +* directory. Thus, if we see anything higher, we just probably got the +* endiannes wrong. */ +#define V7_NFILES 1024 +/* The disk addresses are three-byte (despite direct block addresses being +* aligned word-wise in inode). If the most significant byte is non-zero, +* something is most likely wrong (not a filesystem, bad bytesex). */ +#define V7_MAXSIZE 0x00ffffff/* Coherent super-block data on disk */ #define COH_NICINOD 100/* number of inode cache entries */
Signature · 1 line
1.7.1
Re: [PATCH 1/3] [fs/sysv] Add v7 alias
In reply to Lubomir RintelLooks good, thanks.
Quoted 2 lines · Lubomir Rintel
I'm resending these once again, since I suspect they may have gotten lost in a spam filter due to improper MTA configuration of mine.
Yes, I don't think I got them before.
Quoted 6 lines · Lubomir Rintel
I'm resending these once again, since I suspect they may have gotten lost in a spam filter due to improper MTA configuration of mine.
They basically improve usability of PC v7 filesystems; such as those of PC/IX.
I remember PC/IX fondly, I had people using it on an old XT for data entry. Wish I still had an install kit, I bet the AT version would install nicely in a VM. Would be a good teaching tool.
Signature · 3 lines
Bill Davidsen <[email protected]> "We have more to fear from the bungling of the incompetent than from the machinations of the wicked." - from Slashdot
Quoted 5 lines · Lubomir Rintel
I'm resending these once again, since I suspect they may have gotten lost in a spam filter due to improper MTA configuration of mine.
They basically improve usability of PC v7 filesystems; such as those of PC/IX.
Hi, do you by any chance know where I can find some docs about what we have in fs/sysv ? I saw issues there, but could not fix them because I could not find any docs. There are several flavors of FSes which fs/sysv supports, do you have anything which makes sense out of it and describes what exactly we support, what are the differences, what is the FS layout, etc.
Thanks.
Signature · 2 lines
Best Regards, Artem Bityutskiy (Артём Битюцкий)