From e9d2c29f0ad03e31b6264deb9605f25989791630 Mon Sep 17 00:00:00 2001 From: Al Smith Date: Tue, 13 Apr 1999 15:52:53 +0000 Subject: bug fixes: block/char devices fixed (NB: IRIX uses 32-bit wide dev_t, linux only has 16-bit wide dev_t. this is apparently going to change in linux-2.3 but for now we can't handle devices with major or minor numbers > 255. handling of empty directory slots has been fixed. --- fs/efs/dir.c | 7 +++++-- fs/efs/inode.c | 34 +++++++++++++++++++++------------- fs/efs/namei.c | 5 ----- fs/efs/symlink.c | 6 ++---- include/linux/efs_fs.h | 2 +- include/linux/efs_fs_i.h | 13 +++++++++---- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/fs/efs/dir.c b/fs/efs/dir.c index 89dedbdb8..88e181690 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c @@ -46,8 +46,6 @@ struct inode_operations efs_dir_inode_operations = { NULL /* smap */ }; -/* read the next entry for a given directory */ - static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct inode *inode = filp->f_dentry->d_inode; struct efs_inode_info *ini = INODE_INFO(inode); @@ -94,6 +92,11 @@ static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { } while(slot < dirblock->slots) { + if (dirblock->space[slot] == 0) { + slot++; + continue; + } + dirslot = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot)); inodenum = be32_to_cpu(dirslot->inode); diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 33e3863f3..893af40ec 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -68,7 +68,6 @@ void efs_read_inode(struct inode *inode) { efs_inode = (struct efs_dinode *) (bh->b_data + offset); - /* fill in standard inode infos */ inode->i_mode = be16_to_cpu(efs_inode->di_mode); inode->i_nlink = be16_to_cpu(efs_inode->di_nlink); inode->i_uid = be16_to_cpu(efs_inode->di_uid); @@ -85,10 +84,20 @@ void efs_read_inode(struct inode *inode) { inode->i_blocks = ((inode->i_size - 1) >> EFS_BLOCKSIZE_BITS) + 1; } - device = be32_to_cpu(efs_inode->di_u.di_dev); - - /* The following values are stored in my private part of the Inode. - They are necessary for further operations with the file */ + /* + * BUG: irix devices are 32-bits. linux devices are only 16-bits. + * + * apparently linux will change to 32-bit devices sometime during + * linux 2.3. + * + * as is, this code maps devices that can't be represented in + * 16-bits (ie major > 255 or minor > 255) to major = minor = 255. + * + * during 2.3 when 32-bit devices become available, we should test + * to see whether odev contains 65535. if this is the case then we + * should do device = be32_to_cpu(efs_inode->di_u.di_dev.ndec). + */ + device = be16_to_cpu(efs_inode->di_u.di_dev.odev); /* get the number of extents for this object */ in->numextents = be16_to_cpu(efs_inode->di_numextents); @@ -111,7 +120,6 @@ void efs_read_inode(struct inode *inode) { inode->i_ino, in->numextents); #endif - /* Install the filetype Handler */ switch (inode->i_mode & S_IFMT) { case S_IFDIR: inode->i_op = &efs_dir_inode_operations; @@ -164,9 +172,9 @@ efs_extent_check(efs_extent *ptr, efs_block_t block, struct efs_sb_info *sb) { efs_block_t offset; /* - ** given an extent and a logical block within a file, - ** can this block be found within this extent ? - */ + * given an extent and a logical block within a file, + * can this block be found within this extent ? + */ start = ptr->cooked.ex_bn; length = ptr->cooked.ex_length; offset = ptr->cooked.ex_offset; @@ -178,8 +186,6 @@ efs_extent_check(efs_extent *ptr, efs_block_t block, struct efs_sb_info *sb) { } } -/* find the disk block number for a given logical file block number */ - efs_block_t efs_map_block(struct inode *inode, efs_block_t block) { struct efs_sb_info *sb = SUPER_INFO(inode->i_sb); struct efs_inode_info *in = INODE_INFO(inode); @@ -205,8 +211,10 @@ efs_block_t efs_map_block(struct inode *inode, efs_block_t block) { direxts = in->numextents; - /* check the stored extents in the inode */ - /* start with next extent and check forwards */ + /* + * check the stored extents in the inode + * start with next extent and check forwards + */ for(dirext = 1; dirext < direxts; dirext++) { cur = (last + dirext) % in->numextents; if ((result = efs_extent_check(&in->extents[cur], block, sb))) { diff --git a/fs/efs/namei.c b/fs/efs/namei.c index 088285f0c..0a70c181f 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c @@ -8,8 +8,6 @@ #include -/* search an efs directory inode for the given name */ - static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { struct efs_inode_info *in = INODE_INFO(inode); struct buffer_head *bh; @@ -60,9 +58,6 @@ static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) return(0); } - -/* get inode associated with directory entry */ - int efs_lookup(struct inode *dir, struct dentry *dentry) { efs_ino_t inodenum; struct inode * inode; diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index c1b84d12d..f17478bdb 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -9,10 +9,8 @@ #include #include -static int - efs_readlink(struct dentry *, char *, int); -static struct dentry * - efs_follow_link(struct dentry *, struct dentry *, unsigned int); +static int efs_readlink(struct dentry *, char *, int); +static struct dentry * efs_follow_link(struct dentry *, struct dentry *, unsigned int); struct inode_operations efs_symlink_inode_operations = { NULL, /* no symlink file-operations */ diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h index c9c30e290..b5e4d8804 100644 --- a/include/linux/efs_fs.h +++ b/include/linux/efs_fs.h @@ -9,7 +9,7 @@ #ifndef __EFS_FS_H__ #define __EFS_FS_H__ -#define EFS_VERSION "0.97e" +#define EFS_VERSION "0.98b" static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith "; diff --git a/include/linux/efs_fs_i.h b/include/linux/efs_fs_i.h index 60e21fc6f..de55021ad 100644 --- a/include/linux/efs_fs_i.h +++ b/include/linux/efs_fs_i.h @@ -15,18 +15,23 @@ typedef uint32_t efs_ino_t; #define EFS_DIRECTEXTENTS 12 /* - * layout of an extent, in memory and on disk. 8 bytes exactly + * layout of an extent, in memory and on disk. 8 bytes exactly. */ typedef union extent_u { + unsigned char raw[8]; struct extent_s { unsigned int ex_magic:8; /* magic # (zero) */ unsigned int ex_bn:24; /* basic block */ unsigned int ex_length:8; /* numblocks in this extent */ unsigned int ex_offset:24; /* logical offset into file */ } cooked; - unsigned char raw[8]; } efs_extent; +typedef struct edevs { + short odev; + unsigned int ndev; +} efs_devs; + /* * extent based filesystem inode as it appears on disk. The efs inode * is exactly 128 bytes long. @@ -45,8 +50,8 @@ struct efs_dinode { u_char di_version; /* version of inode */ u_char di_spare; /* spare - used by AFS */ union di_addr { - efs_extent di_extents[EFS_DIRECTEXTENTS]; - dev_t di_dev; /* device for IFCHR/IFBLK */ + efs_extent di_extents[EFS_DIRECTEXTENTS]; + efs_devs di_dev; /* device for IFCHR/IFBLK */ } di_u; }; -- cgit v1.2.3