summaryrefslogtreecommitdiffstats
path: root/fs/adfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/adfs/dir.c')
-rw-r--r--fs/adfs/dir.c52
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;
}