diff options
Diffstat (limited to 'fs/adfs/dir.c')
-rw-r--r-- | fs/adfs/dir.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index ac81954d7..738bb40b8 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c @@ -76,13 +76,34 @@ unsigned int adfs_val (unsigned char *p, int len) return val; } +static unsigned int adfs_filetype (unsigned int load) +{ + if ((load & 0xfff00000) != 0xfff00000) + return (unsigned int) -1; + return (load >> 8) & 0xfff; +} + static unsigned int adfs_time (unsigned int load, unsigned int exec) { unsigned int high, low; - high = ((load << 24) | (exec >> 8)) - 0x336e996a; + /* Check for unstamped files. */ + if ((load & 0xfff00000) != 0xfff00000) + return 0; + + high = ((load << 24) | (exec >> 8)); low = exec & 255; + /* Files dated pre 1970. */ + if (high < 0x336e996a) + return 0; + + high -= 0x336e996a; + + /* Files dated post 2038 ish. */ + if (high > 0x31ffffff) + return 0x7fffffff; + /* 65537 = h256,l1 * (h256 % 100) = 56 h256 / 100 = 2 * 56 << 8 = 14336 2 * 256 = 512 @@ -117,9 +138,6 @@ int adfs_dir_read_parent (struct inode *inode, struct buffer_head **bhp) struct super_block *sb; int i, size; - if (!inode) - return 0; - sb = inode->i_sb; size = 2048 >> sb->s_blocksize_bits; @@ -204,6 +222,18 @@ void adfs_dir_free (struct buffer_head **bhp, int buffers) brelse (bhp[i]); } +/* convert a disk-based directory entry to a Linux ADFS directory entry */ +static inline void +adfs_dirent_to_idirent(struct adfs_idir_entry *ide, struct adfs_direntry *de) +{ + ide->name_len = adfs_readname(ide->name, de->dirobname, ADFS_NAME_LEN); + ide->file_id = adfs_val(de->dirinddiscadd, 3); + ide->size = adfs_val(de->dirlen, 4); + ide->mode = de->newdiratts; + ide->mtime = adfs_time(adfs_val(de->dirload, 4), adfs_val(de->direxec, 4)); + ide->filetype = adfs_filetype(adfs_val(de->dirload, 4)); +} + int adfs_dir_get (struct super_block *sb, struct buffer_head **bhp, int buffers, int pos, unsigned long parent_object_id, struct adfs_idir_entry *ide) @@ -228,13 +258,8 @@ int adfs_dir_get (struct super_block *sb, struct buffer_head **bhp, if (!de.dirobname[0]) return 0; - ide->name_len = adfs_readname (ide->name, de.dirobname, ADFS_NAME_LEN); ide->inode_no = adfs_inode_generate (parent_object_id, pos); - ide->file_id = adfs_val (de.dirinddiscadd, 3); - ide->size = adfs_val (de.dirlen, 4); - ide->mode = de.newdiratts; - ide->mtime = adfs_time (adfs_val (de.dirload, 4), adfs_val (de.direxec, 4)); - ide->filetype = (adfs_val (de.dirload, 4) >> 8) & 0xfff; + adfs_dirent_to_idirent(ide, &de); return 1; } @@ -262,12 +287,7 @@ int adfs_dir_find_entry (struct super_block *sb, struct buffer_head **bhp, if (!de.dirobname[0]) return 0; - ide->name_len = adfs_readname (ide->name, de.dirobname, ADFS_NAME_LEN); - ide->size = adfs_val (de.dirlen, 4); - ide->mode = de.newdiratts; - ide->file_id = adfs_val (de.dirinddiscadd, 3); - ide->mtime = adfs_time (adfs_val (de.dirload, 4), adfs_val (de.direxec, 4)); - ide->filetype = (adfs_val (de.dirload, 4) >> 8) & 0xfff; + adfs_dirent_to_idirent(ide, &de); return 1; } |