Commit 715feb63 authored by Ben Fennema's avatar Ben Fennema Committed by Linus Torvalds

[PATCH] fix nanosecond stat timefields in UDF

parent 65b5db50
......@@ -145,10 +145,7 @@ static ssize_t udf_file_write(struct file * file, const char * buf,
retval = generic_file_write(file, buf, count, ppos);
if (retval > 0)
{
UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME;
mark_inode_dirty(inode);
}
return retval;
}
......
......@@ -156,10 +156,8 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
else
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
UDF_I_CRTIME(inode) = get_seconds();
UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
UDF_I_UCRTIME(inode) = get_seconds();
inode->i_mtime = inode->i_atime = inode->i_ctime =
UDF_I_CRTIME(inode) = CURRENT_TIME;
insert_inode_hash(inode);
mark_inode_dirty(inode);
......
......@@ -573,7 +573,6 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
inode->i_ctime = CURRENT_TIME;
UDF_I_UCTIME(inode) = CURRENT_UTIME;
if (IS_SYNC(inode))
udf_sync_inode(inode);
......@@ -877,7 +876,6 @@ void udf_truncate(struct inode * inode)
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;
if (IS_SYNC(inode))
udf_sync_inode (inode);
else
......@@ -1023,10 +1021,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
UDF_I_STRAT4096(inode) = 1;
UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
UDF_I_UMTIME(inode) = 0;
UDF_I_UCTIME(inode) = 0;
UDF_I_CRTIME(inode) = 0;
UDF_I_UCRTIME(inode) = 0;
UDF_I_UNIQUE(inode) = 0;
UDF_I_LENEATTR(inode) = 0;
UDF_I_LENEXTENTS(inode) = 0;
......@@ -1084,40 +1078,33 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
lets_to_cpu(fe->accessTime)) )
{
inode->i_atime.tv_sec = convtime;
inode->i_atime.tv_nsec = 0;
inode->i_atime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_atime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_atime.tv_nsec = 0;
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
}
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->modificationTime)) )
{
inode->i_mtime.tv_sec = convtime;
inode->i_mtime.tv_nsec = 0;
UDF_I_UMTIME(inode) = convtime_usec;
inode->i_mtime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_mtime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_mtime.tv_nsec = 0;
UDF_I_UMTIME(inode) = 0;
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
}
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->attrTime)) )
{
inode->i_ctime.tv_sec = convtime;
inode->i_ctime.tv_nsec = 0;
UDF_I_UCTIME(inode) = convtime_usec;
inode->i_ctime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_ctime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_ctime.tv_nsec = 0;
UDF_I_UCTIME(inode) = 0;
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
}
UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
......@@ -1135,52 +1122,44 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
lets_to_cpu(efe->accessTime)) )
{
inode->i_atime.tv_sec = convtime;
inode->i_atime.tv_nsec = 0;
inode->i_atime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_atime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_atime.tv_nsec = 0;
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
}
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->modificationTime)) )
{
inode->i_mtime.tv_sec = convtime;
inode->i_mtime.tv_nsec = 0;
UDF_I_UMTIME(inode) = convtime_usec;
inode->i_mtime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_mtime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_mtime.tv_nsec = 0;
UDF_I_UMTIME(inode) = 0;
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
}
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->createTime)) )
{
UDF_I_CRTIME(inode) = convtime;
UDF_I_UCRTIME(inode) = convtime_usec;
UDF_I_CRTIME(inode).tv_sec = convtime;
UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
}
else
{
UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UCRTIME(inode) = 0;
}
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->attrTime)) )
{
inode->i_ctime.tv_sec = convtime;
inode->i_ctime.tv_nsec = 0;
UDF_I_UCTIME(inode) = convtime_usec;
inode->i_ctime.tv_nsec = convtime_usec * 1000;
}
else
{
inode->i_ctime.tv_sec = UDF_SB_RECORDTIME(inode->i_sb);
inode->i_ctime.tv_nsec = 0;
UDF_I_UCTIME(inode) = 0;
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
}
UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
......@@ -1423,11 +1402,11 @@ udf_update_inode(struct inode *inode, int do_sync)
(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
(inode->i_sb->s_blocksize_bits - 9));
if (udf_time_to_stamp(&cpu_time, inode->i_atime.tv_sec, 0))
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.tv_sec, UDF_I_UMTIME(inode)))
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.tv_sec, UDF_I_UCTIME(inode)))
if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
fe->attrTime = cpu_to_lets(cpu_time);
memset(&(fe->impIdent), 0, sizeof(regid));
strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
......@@ -1447,33 +1426,32 @@ udf_update_inode(struct inode *inode, int do_sync)
(inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
(inode->i_sb->s_blocksize_bits - 9));
if (UDF_I_CRTIME(inode) >= inode->i_atime.tv_sec)
if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))
{
UDF_I_CRTIME(inode) = inode->i_atime.tv_sec;
UDF_I_UCRTIME(inode) = 0;
UDF_I_CRTIME(inode) = inode->i_atime;
}
if (UDF_I_CRTIME(inode) > inode->i_mtime.tv_sec ||
(UDF_I_CRTIME(inode) == inode->i_mtime.tv_sec &&
UDF_I_UCRTIME(inode) > UDF_I_UMTIME(inode)))
if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))
{
UDF_I_CRTIME(inode) = inode->i_mtime.tv_sec;
UDF_I_UCRTIME(inode) = UDF_I_UMTIME(inode);
UDF_I_CRTIME(inode) = inode->i_mtime;
}
if (UDF_I_CRTIME(inode) > inode->i_ctime.tv_sec ||
(UDF_I_CRTIME(inode) == inode->i_ctime.tv_sec &&
UDF_I_UCRTIME(inode) > UDF_I_UCTIME(inode)))
if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
(UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))
{
UDF_I_CRTIME(inode) = inode->i_ctime.tv_sec;
UDF_I_UCRTIME(inode) = UDF_I_UCTIME(inode);
UDF_I_CRTIME(inode) = inode->i_ctime;
}
if (udf_time_to_stamp(&cpu_time, inode->i_atime.tv_sec, 0))
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.tv_sec, UDF_I_UMTIME(inode)))
if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
efe->modificationTime = cpu_to_lets(cpu_time);
if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode), UDF_I_UCRTIME(inode)))
if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
efe->createTime = cpu_to_lets(cpu_time);
if (udf_time_to_stamp(&cpu_time, inode->i_ctime.tv_sec, UDF_I_UCTIME(inode)))
if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
efe->attrTime = cpu_to_lets(cpu_time);
memset(&(efe->impIdent), 0, sizeof(regid));
......
......@@ -882,7 +882,6 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
mark_inode_dirty(inode);
dir->i_nlink --;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
UDF_I_UCTIME(inode) = UDF_I_UCTIME(dir) = UDF_I_UMTIME(dir) = CURRENT_UTIME;
mark_inode_dirty(dir);
end_rmdir:
......@@ -926,7 +925,6 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
if (retval)
goto end_unlink;
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
UDF_I_UCTIME(dir) = UDF_I_UMTIME(dir) = CURRENT_UTIME;
mark_inode_dirty(dir);
inode->i_nlink--;
mark_inode_dirty(inode);
......@@ -1157,7 +1155,6 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
udf_release_data(fibh.sbh);
inode->i_nlink ++;
inode->i_ctime = CURRENT_TIME;
UDF_I_UCTIME(inode) = CURRENT_UTIME;
mark_inode_dirty(inode);
atomic_inc(&inode->i_count);
d_instantiate(dentry, inode);
......@@ -1251,7 +1248,6 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
* rename.
*/
old_inode->i_ctime = CURRENT_TIME;
UDF_I_UCTIME(old_inode) = CURRENT_UTIME;
mark_inode_dirty(old_inode);
/*
......@@ -1270,11 +1266,9 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
{
new_inode->i_nlink--;
new_inode->i_ctime = CURRENT_TIME;
UDF_I_UCTIME(new_inode) = CURRENT_UTIME;
mark_inode_dirty(new_inode);
}
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
UDF_I_UCTIME(old_dir) = UDF_I_UMTIME(old_dir) = CURRENT_UTIME;
mark_inode_dirty(old_dir);
if (dir_fi)
......
......@@ -800,7 +800,8 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
recording, recording_usec,
ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
UDF_SB_RECORDTIME(sb) = recording;
UDF_SB_RECORDTIME(sb).tv_sec = recording;
UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;
}
if ( !udf_build_ustr(&instr, pvoldesc->volIdent, 32) )
......@@ -1339,7 +1340,7 @@ static void udf_open_lvid(struct super_block *sb)
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
if (udf_time_to_stamp(&cpu_time, get_seconds(), CURRENT_UTIME))
if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
......@@ -1367,7 +1368,7 @@ static void udf_close_lvid(struct super_block *sb)
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
if (udf_time_to_stamp(&cpu_time, get_seconds(), CURRENT_UTIME))
if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
......@@ -1536,7 +1537,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
if (!silent)
{
timestamp ts;
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
UDFFS_VERSION, UDFFS_DATE,
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
......
......@@ -18,10 +18,7 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode)
#define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat4096 )
#define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block )
#define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal )
#define UDF_I_UMTIME(X) ( UDF_I(X)->i_umtime )
#define UDF_I_UCTIME(X) ( UDF_I(X)->i_uctime )
#define UDF_I_CRTIME(X) ( UDF_I(X)->i_crtime )
#define UDF_I_UCRTIME(X) ( UDF_I(X)->i_ucrtime )
#define UDF_I_SAD(X) ( UDF_I(X)->i_ext.i_sad )
#define UDF_I_LAD(X) ( UDF_I(X)->i_ext.i_lad )
#define UDF_I_DATA(X) ( UDF_I(X)->i_ext.i_data )
......
......@@ -28,8 +28,6 @@
#define UDF_NAME_LEN 255
#define UDF_PATH_LEN 1023
#define CURRENT_UTIME (xtime.tv_nsec / 1000)
#define udf_file_entry_alloc_offset(inode)\
(UDF_I_USE(inode) ?\
sizeof(struct unallocSpaceEntry) :\
......@@ -185,6 +183,6 @@ extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
/* udftime.c */
extern time_t *udf_stamp_to_time(time_t *, long *, timestamp);
extern timestamp *udf_time_to_stamp(timestamp *, time_t, long);
extern timestamp *udf_time_to_stamp(timestamp *, struct timespec);
#endif /* __UDF_DECL_H */
......@@ -121,7 +121,7 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, timestamp src)
timestamp *
udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec)
udf_time_to_stamp(timestamp *dest, struct timespec ts)
{
long int days, rem, y;
const unsigned short int *ip;
......@@ -134,9 +134,9 @@ udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec)
dest->typeAndTimezone = 0x1000 | (offset & 0x0FFF);
tv_sec += offset * 60;
days = tv_sec / SECS_PER_DAY;
rem = tv_sec % SECS_PER_DAY;
ts.tv_sec += offset * 60;
days = ts.tv_sec / SECS_PER_DAY;
rem = ts.tv_sec % SECS_PER_DAY;
dest->hour = rem / SECS_PER_HOUR;
rem %= SECS_PER_HOUR;
dest->minute = rem / 60;
......@@ -164,9 +164,9 @@ udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec)
dest->month = y + 1;
dest->day = days + 1;
dest->centiseconds = tv_usec / 10000;
dest->hundredsOfMicroseconds = (tv_usec - dest->centiseconds * 10000) / 100;
dest->microseconds = (tv_usec - dest->centiseconds * 10000 -
dest->centiseconds = ts.tv_nsec / 10000000;
dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100;
dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
dest->hundredsOfMicroseconds * 100);
return dest;
}
......
......@@ -43,10 +43,7 @@ typedef struct
struct udf_inode_info
{
long i_umtime;
long i_uctime;
long i_crtime;
long i_ucrtime;
struct timespec i_crtime;
/* Physical address of inode */
lb_addr i_location;
__u64 i_unique;
......
......@@ -97,7 +97,7 @@ struct udf_sb_info
uid_t s_uid;
/* Root Info */
time_t s_recordtime;
struct timespec s_recordtime;
/* Fileset Info */
__u16 s_serialnum;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment