udf: Fix regression in UDF anchor block detection
[safe/jmp/linux-2.6] / fs / udf / inode.c
index 3c0a60d..6e74b11 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
 #include <linux/slab.h>
+#include <linux/crc-itu-t.h>
 
 #include "udf_i.h"
 #include "udf_sb.h"
@@ -1136,20 +1137,6 @@ static void __udf_read_inode(struct inode *inode)
        brelse(bh);
 }
 
-static void udf_fill_inode_time(struct timespec *tspec,
-                               const timestamp *tstamp,
-                               struct udf_sb_info *sbi)
-{
-       time_t convtime;
-       long convtime_usec;
-       if (udf_stamp_to_time(&convtime, &convtime_usec,
-                               lets_to_cpu(*tstamp))) {
-               tspec->tv_sec = convtime;
-               tspec->tv_nsec = convtime_usec * 1000;
-       } else
-               *tspec = sbi->s_record_time;
-}
-
 static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
 {
        struct fileEntry *fe;
@@ -1241,10 +1228,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
                        (inode->i_sb->s_blocksize_bits - 9);
 
-               udf_fill_inode_time(&inode->i_atime, &fe->accessTime, sbi);
-               udf_fill_inode_time(&inode->i_mtime, &fe->modificationTime,
-                                   sbi);
-               udf_fill_inode_time(&inode->i_ctime, &fe->attrTime, sbi);
+               if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime))
+                       inode->i_atime = sbi->s_record_time;
+
+               if (!udf_disk_stamp_to_time(&inode->i_mtime,
+                                           fe->modificationTime))
+                       inode->i_mtime = sbi->s_record_time;
+
+               if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime))
+                       inode->i_ctime = sbi->s_record_time;
 
                iinfo->i_unique = le64_to_cpu(fe->uniqueID);
                iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
@@ -1254,11 +1246,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
                    (inode->i_sb->s_blocksize_bits - 9);
 
-               udf_fill_inode_time(&inode->i_atime, &efe->accessTime, sbi);
-               udf_fill_inode_time(&inode->i_mtime, &efe->modificationTime,
-                                   sbi);
-               udf_fill_inode_time(&iinfo->i_crtime, &efe->createTime, sbi);
-               udf_fill_inode_time(&inode->i_ctime, &efe->attrTime, sbi);
+               if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime))
+                       inode->i_atime = sbi->s_record_time;
+
+               if (!udf_disk_stamp_to_time(&inode->i_mtime,
+                                           efe->modificationTime))
+                       inode->i_mtime = sbi->s_record_time;
+
+               if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime))
+                       iinfo->i_crtime = sbi->s_record_time;
+
+               if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime))
+                       inode->i_ctime = sbi->s_record_time;
 
                iinfo->i_unique = le64_to_cpu(efe->uniqueID);
                iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
@@ -1277,6 +1276,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        case ICBTAG_FILE_TYPE_REALTIME:
        case ICBTAG_FILE_TYPE_REGULAR:
        case ICBTAG_FILE_TYPE_UNDEF:
+       case ICBTAG_FILE_TYPE_VAT20:
                if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
                        inode->i_data.a_ops = &udf_adinicb_aops;
                else
@@ -1302,6 +1302,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                inode->i_op = &page_symlink_inode_operations;
                inode->i_mode = S_IFLNK | S_IRWXUGO;
                break;
+       case ICBTAG_FILE_TYPE_MAIN:
+               udf_debug("METADATA FILE-----\n");
+               break;
+       case ICBTAG_FILE_TYPE_MIRROR:
+               udf_debug("METADATA MIRROR FILE-----\n");
+               break;
+       case ICBTAG_FILE_TYPE_BITMAP:
+               udf_debug("METADATA BITMAP FILE-----\n");
+               break;
        default:
                printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown "
                                "file type=%d\n", inode->i_ino,
@@ -1379,7 +1388,6 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        uint32_t udfperms;
        uint16_t icbflags;
        uint16_t crclen;
-       kernel_timestamp cpu_time;
        int err = 0;
        struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
@@ -1412,9 +1420,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                                                iinfo->i_location.
                                                        logicalBlockNum);
                use->descTag.descCRCLength = cpu_to_le16(crclen);
-               use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use +
-                                                          sizeof(tag), crclen,
-                                                          0));
+               use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
+                                                          sizeof(tag),
+                                                          crclen));
                use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
 
                mark_buffer_dirty(bh);
@@ -1482,12 +1490,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                        (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
                        (blocksize_bits - 9));
 
-               if (udf_time_to_stamp(&cpu_time, inode->i_atime))
-                       fe->accessTime = cpu_to_lets(cpu_time);
-               if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
-                       fe->modificationTime = cpu_to_lets(cpu_time);
-               if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
-                       fe->attrTime = cpu_to_lets(cpu_time);
+               udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
+               udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
+               udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
                memset(&(fe->impIdent), 0, sizeof(regid));
                strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
                fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1522,14 +1527,10 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                     iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
                        iinfo->i_crtime = inode->i_ctime;
 
-               if (udf_time_to_stamp(&cpu_time, inode->i_atime))
-                       efe->accessTime = cpu_to_lets(cpu_time);
-               if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
-                       efe->modificationTime = cpu_to_lets(cpu_time);
-               if (udf_time_to_stamp(&cpu_time, iinfo->i_crtime))
-                       efe->createTime = cpu_to_lets(cpu_time);
-               if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
-                       efe->attrTime = cpu_to_lets(cpu_time);
+               udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
+               udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
+               udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
+               udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
 
                memset(&(efe->impIdent), 0, sizeof(regid));
                strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
@@ -1584,8 +1585,8 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc -
                                                                sizeof(tag);
        fe->descTag.descCRCLength = cpu_to_le16(crclen);
-       fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag),
-                                                 crclen, 0));
+       fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag),
+                                                 crclen));
        fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
 
        /* write the data blocks */