diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /fs/minix | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'fs/minix')
-rw-r--r-- | fs/minix/Makefile | 6 | ||||
-rw-r--r-- | fs/minix/bitmap.c | 44 | ||||
-rw-r--r-- | fs/minix/file.c | 2 | ||||
-rw-r--r-- | fs/minix/inode.c | 44 | ||||
-rw-r--r-- | fs/minix/namei.c | 76 | ||||
-rw-r--r-- | fs/minix/truncate.c | 2 |
6 files changed, 99 insertions, 75 deletions
diff --git a/fs/minix/Makefile b/fs/minix/Makefile index 60bb07d97..537127b2d 100644 --- a/fs/minix/Makefile +++ b/fs/minix/Makefile @@ -1,11 +1,11 @@ # -# Makefile for the linux minix-filesystem routines. +# Makefile for the Linux minix filesystem routines. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). +# unless it's something special (not a .c file). # -# Note 2! The CFLAGS definitions are now in the main makefile... +# Note 2! The CFLAGS definitions are now in the main makefile. O_TARGET := minix.o O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 3d6f0a426..49dde4e44 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -36,16 +36,17 @@ static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, _ if (numblocks==0 || !(bh=map[numblocks-1])) return(0); - i = (numbits-(numblocks-1)*BLOCK_SIZE*8)/8; + i = ((numbits-(numblocks-1)*BLOCK_SIZE*8)/16)*2; for (j=0; j<i; j++) { sum += nibblemap[bh->b_data[j] & 0xf] + nibblemap[(bh->b_data[j]>>4) & 0xf]; } - i = numbits%8; + i = numbits%16; if (i!=0) { - i = bh->b_data[j] | ~((1<<i) - 1); + i = *(__u16 *)(&bh->b_data[j]) | ~((1<<i) - 1); sum += nibblemap[i & 0xf] + nibblemap[(i>>4) & 0xf]; + sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf]; } return(sum); } @@ -71,11 +72,11 @@ void minix_free_block(struct super_block * sb, int block) zone = block - sb->u.minix_sb.s_firstdatazone + 1; bit = zone & 8191; zone >>= 13; - bh = sb->u.minix_sb.s_zmap[zone]; - if (!bh) { + if (zone >= sb->u.minix_sb.s_zmap_blocks) { printk("minix_free_block: nonexistent bitmap buffer\n"); return; } + bh = sb->u.minix_sb.s_zmap[zone]; if (!minix_clear_bit(bit,bh->b_data)) printk("free_block (%s:%d): bit already cleared\n", kdevname(sb->s_dev), block); @@ -94,11 +95,13 @@ int minix_new_block(struct super_block * sb) } repeat: j = 8192; - for (i=0 ; i<64 ; i++) - if ((bh=sb->u.minix_sb.s_zmap[i]) != NULL) - if ((j=minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) - break; - if (i>=64 || !bh || j>=8192) + bh = NULL; + for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++) { + bh = sb->u.minix_sb.s_zmap[i]; + if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) + break; + } + if (!bh || j >= 8192) return 0; if (minix_set_bit(j,bh->b_data)) { printk("new_block: bit already set"); @@ -134,7 +137,7 @@ static struct buffer_head *V1_minix_clear_inode(struct inode *inode) int ino, block; ino = inode->i_ino; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s: %d is out of range\n", kdevname(inode->i_dev), ino); return 0; @@ -162,7 +165,7 @@ static struct buffer_head *V2_minix_clear_inode(struct inode *inode) int ino, block; ino = inode->i_ino; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s: %d is out of range\n", kdevname(inode->i_dev), ino); return 0; @@ -218,15 +221,16 @@ void minix_free_inode(struct inode * inode) printk("free_inode: inode on nonexistent device\n"); return; } - if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("free_inode: inode 0 or nonexistent inode\n"); return; } ino = inode->i_ino; - if (!(bh=inode->i_sb->u.minix_sb.s_imap[ino >> 13])) { + if ((ino >> 13) >= inode->i_sb->u.minix_sb.s_imap_blocks) { printk("free_inode: nonexistent imap in superblock\n"); return; } + bh = inode->i_sb->u.minix_sb.s_imap[ino >> 13]; minix_clear_inode(inode); clear_inode(inode); if (!minix_clear_bit(ino & 8191, bh->b_data)) @@ -247,10 +251,12 @@ struct inode * minix_new_inode(const struct inode * dir) inode->i_sb = sb; inode->i_flags = inode->i_sb->s_flags; j = 8192; - for (i=0 ; i<8 ; i++) - if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL) - if ((j=minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) - break; + bh = NULL; + for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) { + bh = inode->i_sb->u.minix_sb.s_imap[i]; + if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) + break; + } if (!bh || j >= 8192) { iput(inode); return NULL; @@ -262,7 +268,7 @@ struct inode * minix_new_inode(const struct inode * dir) } mark_buffer_dirty(bh, 1); j += i*8192; - if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) { iput(inode); return NULL; } diff --git a/fs/minix/file.c b/fs/minix/file.c index 5aaef83b2..a44a635b0 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -30,7 +30,7 @@ static ssize_t minix_file_write(struct file *, const char *, size_t, loff_t *); /* - * We have mostly NULL's here: the current defaults are ok for + * We have mostly NULLs here: the current defaults are OK for * the minix filesystem. */ static struct file_operations minix_file_operations = { diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 8934dc012..46ae5c11c 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -63,9 +63,9 @@ void minix_put_super(struct super_block *sb) sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state; mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1); } - for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++) + for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) brelse(sb->u.minix_sb.s_imap[i]); - for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++) + for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++) brelse(sb->u.minix_sb.s_zmap[i]); brelse (sb->u.minix_sb.s_sbh); kfree(sb->u.minix_sb.s_imap); @@ -122,7 +122,7 @@ int minix_remount (struct super_block * sb, int * flags, char * data) /* * Check the root directory of the filesystem to make sure - * it really _is_ a minix filesystem, and to check the size + * it really _is_ a Minix filesystem, and to check the size * of the directory entry. */ static const char * minix_checkroot(struct super_block *s, struct inode *dir) @@ -173,7 +173,8 @@ struct super_block *minix_read_super(struct super_block *s, void *data, const char * errmsg; struct inode *root_inode; - /* N.B. These should be compile-time tests */ + /* N.B. These should be compile-time tests. + Unfortunately that is impossible. */ if (32 != sizeof (struct minix_inode)) panic("bad V1 i-node size"); if (64 != sizeof(struct minix2_inode)) @@ -203,33 +204,37 @@ struct super_block *minix_read_super(struct super_block *s, void *data, s->u.minix_sb.s_version = MINIX_V1; s->u.minix_sb.s_dirsize = 16; s->u.minix_sb.s_namelen = 14; + s->u.minix_sb.s_link_max = MINIX_LINK_MAX; } else if (s->s_magic == MINIX_SUPER_MAGIC2) { s->u.minix_sb.s_version = MINIX_V1; s->u.minix_sb.s_dirsize = 32; s->u.minix_sb.s_namelen = 30; + s->u.minix_sb.s_link_max = MINIX_LINK_MAX; } else if (s->s_magic == MINIX2_SUPER_MAGIC) { s->u.minix_sb.s_version = MINIX_V2; + s->u.minix_sb.s_nzones = ms->s_zones; s->u.minix_sb.s_dirsize = 16; s->u.minix_sb.s_namelen = 14; + s->u.minix_sb.s_link_max = MINIX2_LINK_MAX; } else if (s->s_magic == MINIX2_SUPER_MAGIC2) { s->u.minix_sb.s_version = MINIX_V2; + s->u.minix_sb.s_nzones = ms->s_zones; s->u.minix_sb.s_dirsize = 32; s->u.minix_sb.s_namelen = 30; + s->u.minix_sb.s_link_max = MINIX2_LINK_MAX; } else goto out_no_fs; - if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS) - goto out_too_big; /* * Allocate the buffer map to keep the superblock small. */ - i = (MINIX_I_MAP_SLOTS + MINIX_Z_MAP_SLOTS) * sizeof(bh); + i = (s->u.minix_sb.s_imap_blocks + s->u.minix_sb.s_zmap_blocks) * sizeof(bh); map = kmalloc(i, GFP_KERNEL); if (!map) goto out_no_map; memset(map, 0, i); s->u.minix_sb.s_imap = &map[0]; - s->u.minix_sb.s_zmap = &map[MINIX_I_MAP_SLOTS]; + s->u.minix_sb.s_zmap = &map[s->u.minix_sb.s_imap_blocks]; block=2; for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++) { @@ -242,8 +247,6 @@ struct super_block *minix_read_super(struct super_block *s, void *data, goto out_no_bitmap; block++; } - if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) - goto out_no_bitmap; minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data); minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data); @@ -263,6 +266,8 @@ struct super_block *minix_read_super(struct super_block *s, void *data, if (!s->s_root) goto out_iput; + s->s_root->d_op = &minix_dentry_operations; + if (!(s->s_flags & MS_RDONLY)) { ms->s_state &= ~MINIX_VALID_FS; mark_buffer_dirty(bh, 1); @@ -292,9 +297,9 @@ out_no_root: out_no_bitmap: printk("MINIX-fs: bad superblock or unable to read bitmaps\n"); out_freemap: - for(i=0;i<MINIX_I_MAP_SLOTS;i++) + for (i = 0; i < s->u.minix_sb.s_imap_blocks; i++) brelse(s->u.minix_sb.s_imap[i]); - for(i=0;i<MINIX_Z_MAP_SLOTS;i++) + for (i = 0; i < s->u.minix_sb.s_zmap_blocks; i++) brelse(s->u.minix_sb.s_zmap[i]); kfree(s->u.minix_sb.s_imap); goto out_release; @@ -304,14 +309,9 @@ out_no_map: printk ("MINIX-fs: can't allocate map\n"); goto out_release; -out_too_big: - if (!silent) - printk ("MINIX-fs: filesystem too big\n"); - goto out_release; - out_no_fs: if (!silent) - printk("VFS: Can't find a minix or minix V2 filesystem on dev " + printk("VFS: Can't find a Minix or Minix V2 filesystem on device " "%s.\n", kdevname(dev)); out_release: brelse(bh); @@ -729,7 +729,7 @@ static void V1_minix_read_inode(struct inode * inode) ino = inode->i_ino; inode->i_op = NULL; inode->i_mode = 0; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s" ": %d is out of range\n", kdevname(inode->i_dev), ino); @@ -783,7 +783,7 @@ static void V2_minix_read_inode(struct inode * inode) ino = inode->i_ino; inode->i_op = NULL; inode->i_mode = 0; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s" ": %d is out of range\n", kdevname(inode->i_dev), ino); @@ -848,7 +848,7 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode) int ino, block; ino = inode->i_ino; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s" ": %d is out of range\n", kdevname(inode->i_dev), ino); @@ -886,7 +886,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode) int ino, block; ino = inode->i_ino; - if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) { + if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) { printk("Bad inode number on dev %s" ": %d is out of range\n", kdevname(inode->i_dev), ino); diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 3155e72e4..17ff53aed 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -23,34 +23,12 @@ static inline int namecompare(int len, int maxlen, const char * name, const char * buffer) { - if (len > maxlen) - return 0; if (len < maxlen && buffer[len]) return 0; return !memcmp(name, buffer, len); } /* - * ok, we cannot use strncmp, as the name is not in our data space. - * Thus we'll have to use minix_match. No big problem. Match also makes - * some sanity tests. - * - * NOTE! unlike strncmp, minix_match returns 1 for success, 0 for failure. - */ -static int minix_match(int len, const char * name, - struct buffer_head * bh, unsigned long * offset, - struct minix_sb_info * info) -{ - struct minix_dir_entry * de; - - de = (struct minix_dir_entry *) (bh->b_data + *offset); - *offset += info->s_dirsize; - if (!de->inode || len > info->s_namelen) - return 0; - return namecompare(len,info->s_namelen,name,de->name); -} - -/* * minix_find_entry() * * finds an entry in the specified directory with the wanted name. It @@ -64,6 +42,7 @@ static struct buffer_head * minix_find_entry(struct inode * dir, unsigned long block, offset; struct buffer_head * bh; struct minix_sb_info * info; + struct minix_dir_entry *de; *res_dir = NULL; if (!dir || !dir->i_sb) @@ -86,9 +65,12 @@ static struct buffer_head * minix_find_entry(struct inode * dir, continue; } } - *res_dir = (struct minix_dir_entry *) (bh->b_data + offset); - if (minix_match(namelen,name,bh,&offset,info)) + de = (struct minix_dir_entry *) (bh->b_data + offset); + offset += info->s_dirsize; + if (de->inode && namecompare(namelen,info->s_namelen,name,de->name)) { + *res_dir = de; return bh; + } if (offset < bh->b_size) continue; brelse(bh); @@ -97,16 +79,52 @@ static struct buffer_head * minix_find_entry(struct inode * dir, block++; } brelse(bh); - *res_dir = NULL; return NULL; } +#ifndef NO_TRUNCATE + +static int minix_hash(struct dentry *dentry, struct qstr *qstr) +{ + unsigned long hash; + int i; + const char *name; + + i = dentry->d_inode->i_sb->u.minix_sb.s_namelen; + if (i >= qstr->len) + return 0; + /* Truncate the name in place, avoids having to define a compare + function. */ + qstr->len = i; + name = qstr->name; + hash = init_name_hash(); + while (i--) + hash = partial_name_hash(*name++, hash); + qstr->hash = end_name_hash(hash); + return 0; +} + +#endif + +struct dentry_operations minix_dentry_operations = { + 0, /* revalidate */ +#ifndef NO_TRUNCATE + minix_hash, +#else + 0, +#endif + 0 /* compare */ +}; + int minix_lookup(struct inode * dir, struct dentry *dentry) { struct inode * inode = NULL; struct minix_dir_entry * de; struct buffer_head * bh; +#ifndef NO_TRUNCATE + dentry->d_op = &minix_dentry_operations; +#endif bh = minix_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (bh) { int ino = de->inode; @@ -296,7 +314,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) brelse(bh); return -EEXIST; } - if (dir->i_nlink >= MINIX_LINK_MAX) + if (dir->i_nlink >= info->s_link_max) return -EMLINK; inode = minix_new_inode(dir); if (!inode) @@ -434,7 +452,7 @@ int minix_rmdir(struct inode * dir, struct dentry *dentry) retval = -ENOENT; goto end_rmdir; } - if (inode->i_count > 1) { + if (dentry->d_count > 1) { retval = -EBUSY; goto end_rmdir; } @@ -573,7 +591,7 @@ int minix_link(struct dentry * old_dentry, struct inode * dir, if (S_ISDIR(inode->i_mode)) return -EPERM; - if (inode->i_nlink >= MINIX_LINK_MAX) + if (inode->i_nlink >= inode->i_sb->u.minix_sb.s_link_max) return -EMLINK; bh = minix_find_entry(dir, dentry->d_name.name, @@ -689,7 +707,7 @@ start_up: if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino) goto end_rename; retval = -EMLINK; - if (!new_inode && new_dir->i_nlink >= MINIX_LINK_MAX) + if (!new_inode && new_dir->i_nlink >= info->s_link_max) goto end_rename; } if (!new_bh) { diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c index 56b490841..0f0afa604 100644 --- a/fs/minix/truncate.c +++ b/fs/minix/truncate.c @@ -21,7 +21,7 @@ /* * Truncate has the most races in the whole filesystem: coding it is - * a pain in the a**. Especially as I don't do any locking... + * a pain in the a**, especially as I don't do any locking. * * The code may look a bit weird, but that's just because I've tried to * handle things like file-size changes in a somewhat graceful manner. |