diff options
Diffstat (limited to 'fs/jfs/jfs_imap.c')
-rw-r--r-- | fs/jfs/jfs_imap.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index b30e4cf2f579..ecb8e05b8b84 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -102,7 +102,7 @@ int diMount(struct inode *ipimap) * allocate/initialize the in-memory inode map control structure */ /* allocate the in-memory inode map control structure. */ - imap = kmalloc(sizeof(struct inomap), GFP_KERNEL); + imap = kzalloc(sizeof(struct inomap), GFP_KERNEL); if (imap == NULL) return -ENOMEM; @@ -456,7 +456,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) dp += inum % 8; /* 8 inodes per 4K page */ /* copy on-disk inode to in-memory inode */ - if ((copy_from_dinode(dp, ip)) != 0) { + if ((copy_from_dinode(dp, ip) != 0) || (ip->i_nlink == 0)) { /* handle bad return by returning NULL for ip */ set_nlink(ip, 1); /* Don't want iput() deleting it */ iput(ip); @@ -3029,14 +3029,23 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, * * RETURN VALUES: * 0 - success - * -ENOMEM - insufficient memory + * -EINVAL - unexpected inode type */ static int copy_from_dinode(struct dinode * dip, struct inode *ip) { struct jfs_inode_info *jfs_ip = JFS_IP(ip); struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); + int fileset = le32_to_cpu(dip->di_fileset); + + switch (fileset) { + case AGGR_RESERVED_I: case AGGREGATE_I: case BMAP_I: + case LOG_I: case BADBLOCK_I: case FILESYSTEM_I: + break; + default: + return -EINVAL; + } - jfs_ip->fileset = le32_to_cpu(dip->di_fileset); + jfs_ip->fileset = fileset; jfs_ip->mode2 = le32_to_cpu(dip->di_mode); jfs_set_inode_flags(ip); @@ -3070,10 +3079,10 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) } ip->i_size = le64_to_cpu(dip->di_size); - ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); - ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); - ip->i_mtime.tv_sec = le32_to_cpu(dip->di_mtime.tv_sec); - ip->i_mtime.tv_nsec = le32_to_cpu(dip->di_mtime.tv_nsec); + inode_set_atime(ip, le32_to_cpu(dip->di_atime.tv_sec), + le32_to_cpu(dip->di_atime.tv_nsec)); + inode_set_mtime(ip, le32_to_cpu(dip->di_mtime.tv_sec), + le32_to_cpu(dip->di_mtime.tv_nsec)); inode_set_ctime(ip, le32_to_cpu(dip->di_ctime.tv_sec), le32_to_cpu(dip->di_ctime.tv_nsec)); ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks)); @@ -3147,12 +3156,12 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) else /* Leave the original permissions alone */ dip->di_mode = cpu_to_le32(jfs_ip->mode2); - dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); - dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); - dip->di_ctime.tv_sec = cpu_to_le32(inode_get_ctime(ip).tv_sec); - dip->di_ctime.tv_nsec = cpu_to_le32(inode_get_ctime(ip).tv_nsec); - dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime.tv_sec); - dip->di_mtime.tv_nsec = cpu_to_le32(ip->i_mtime.tv_nsec); + dip->di_atime.tv_sec = cpu_to_le32(inode_get_atime_sec(ip)); + dip->di_atime.tv_nsec = cpu_to_le32(inode_get_atime_nsec(ip)); + dip->di_ctime.tv_sec = cpu_to_le32(inode_get_ctime_sec(ip)); + dip->di_ctime.tv_nsec = cpu_to_le32(inode_get_ctime_nsec(ip)); + dip->di_mtime.tv_sec = cpu_to_le32(inode_get_mtime_sec(ip)); + dip->di_mtime.tv_nsec = cpu_to_le32(inode_get_mtime_nsec(ip)); dip->di_ixpxd = jfs_ip->ixpxd; /* in-memory pxd's are little-endian */ dip->di_acl = jfs_ip->acl; /* as are dxd's */ dip->di_ea = jfs_ip->ea; |