aboutsummaryrefslogtreecommitdiff
path: root/fs/udf
diff options
context:
space:
mode:
authorArnd Bergmann2018-06-14 14:51:13 +0200
committerArnd Bergmann2018-06-14 14:54:00 +0200
commit15eefe2a99b2b208f512047e7bc404c3efcf0a44 (patch)
treef5d977cb790bd9cedbfed851d3d5d16b442a41e0 /fs/udf
parent93b7f7ad2018d2037559b1d0892417864c78b371 (diff)
parent95582b00838837fc07e042979320caf917ce3fe6 (diff)
Merge branch 'vfs_timespec64' of https://github.com/deepa-hub/vfs into vfs-timespec64
Pull the timespec64 conversion from Deepa Dinamani: "The series aims to switch vfs timestamps to use struct timespec64. Currently vfs uses struct timespec, which is not y2038 safe. The flag patch applies cleanly. I've not seen the timestamps update logic change often. The series applies cleanly on 4.17-rc6 and linux-next tip (top commit: next-20180517). I'm not sure how to merge this kind of a series with a flag patch. We are targeting 4.18 for this. Let me know if you have other suggestions. The series involves the following: 1. Add vfs helper functions for supporting struct timepec64 timestamps. 2. Cast prints of vfs timestamps to avoid warnings after the switch. 3. Simplify code using vfs timestamps so that the actual replacement becomes easy. 4. Convert vfs timestamps to use struct timespec64 using a script. This is a flag day patch. I've tried to keep the conversions with the script simple, to aid in the reviews. I've kept all the internal filesystem data structures and function signatures the same. Next steps: 1. Convert APIs that can handle timespec64, instead of converting timestamps at the boundaries. 2. Update internal data structures to avoid timestamp conversions." I've pulled it into a branch based on top of the NFS changes that are now in mainline, so I could resolve the non-obvious conflict between the two while merging. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/ialloc.c4
-rw-r--r--fs/udf/inode.c59
-rw-r--r--fs/udf/super.c17
-rw-r--r--fs/udf/udfdecl.h4
-rw-r--r--fs/udf/udftime.c9
5 files changed, 45 insertions, 48 deletions
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index b7a0d4b4bda1..56569023783b 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -124,8 +124,8 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
else
iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
- inode->i_mtime = inode->i_atime = inode->i_ctime =
- iinfo->i_crtime = current_time(inode);
+ inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
+ iinfo->i_crtime = timespec64_to_timespec(inode->i_mtime);
if (unlikely(insert_inode_locked(inode) < 0)) {
make_bad_inode(inode);
iput(inode);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index c80765d62f7e..7f39d17352c9 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1271,6 +1271,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
struct udf_inode_info *iinfo = UDF_I(inode);
struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
struct kernel_lb_addr *iloc = &iinfo->i_location;
+ struct timespec ts;
unsigned int link_count;
unsigned int indirections = 0;
int bs = inode->i_sb->s_blocksize;
@@ -1443,15 +1444,12 @@ reread:
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9);
- 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;
+ udf_disk_stamp_to_time(&ts, fe->accessTime);
+ inode->i_atime = timespec_to_timespec64(ts);
+ udf_disk_stamp_to_time(&ts, fe->modificationTime);
+ inode->i_mtime = timespec_to_timespec64(ts);
+ udf_disk_stamp_to_time(&ts, fe->attrTime);
+ inode->i_ctime = timespec_to_timespec64(ts);
iinfo->i_unique = le64_to_cpu(fe->uniqueID);
iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
@@ -1461,18 +1459,13 @@ reread:
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9);
- 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;
+ udf_disk_stamp_to_time(&ts, efe->accessTime);
+ inode->i_atime = timespec_to_timespec64(ts);
+ udf_disk_stamp_to_time(&ts, efe->modificationTime);
+ inode->i_mtime = timespec_to_timespec64(ts);
+ udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime);
+ udf_disk_stamp_to_time(&ts, efe->attrTime);
+ inode->i_ctime = timespec_to_timespec64(ts);
iinfo->i_unique = le64_to_cpu(efe->uniqueID);
iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
@@ -1722,9 +1715,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
inode->i_sb->s_blocksize - sizeof(struct fileEntry));
fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
- 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);
+ udf_time_to_disk_stamp(&fe->accessTime,
+ timespec64_to_timespec(inode->i_atime));
+ udf_time_to_disk_stamp(&fe->modificationTime,
+ timespec64_to_timespec(inode->i_mtime));
+ udf_time_to_disk_stamp(&fe->attrTime,
+ timespec64_to_timespec(inode->i_ctime));
memset(&(fe->impIdent), 0, sizeof(struct regid));
strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1743,14 +1739,17 @@ static int udf_update_inode(struct inode *inode, int do_sync)
efe->objectSize = cpu_to_le64(inode->i_size);
efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
- udf_adjust_time(iinfo, inode->i_atime);
- udf_adjust_time(iinfo, inode->i_mtime);
- udf_adjust_time(iinfo, inode->i_ctime);
+ udf_adjust_time(iinfo, timespec64_to_timespec(inode->i_atime));
+ udf_adjust_time(iinfo, timespec64_to_timespec(inode->i_mtime));
+ udf_adjust_time(iinfo, timespec64_to_timespec(inode->i_ctime));
- 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->accessTime,
+ timespec64_to_timespec(inode->i_atime));
+ udf_time_to_disk_stamp(&efe->modificationTime,
+ timespec64_to_timespec(inode->i_mtime));
udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
- udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
+ udf_time_to_disk_stamp(&efe->attrTime,
+ timespec64_to_timespec(inode->i_ctime));
memset(&(efe->impIdent), 0, sizeof(efe->impIdent));
strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 7949c338efa5..8449e5190530 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -864,6 +864,9 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
struct buffer_head *bh;
uint16_t ident;
int ret = -ENOMEM;
+#ifdef UDFFS_DEBUG
+ struct timestamp *ts;
+#endif
outstr = kmalloc(128, GFP_NOFS);
if (!outstr)
@@ -882,15 +885,15 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
pvoldesc = (struct primaryVolDesc *)bh->b_data;
- if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
- pvoldesc->recordingDateAndTime)) {
+ udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
+ pvoldesc->recordingDateAndTime);
#ifdef UDFFS_DEBUG
- struct timestamp *ts = &pvoldesc->recordingDateAndTime;
- udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n",
- le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
- ts->minute, le16_to_cpu(ts->typeAndTimezone));
+ ts = &pvoldesc->recordingDateAndTime;
+ udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x)\n",
+ le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
+ ts->minute, le16_to_cpu(ts->typeAndTimezone));
#endif
- }
+
ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32);
if (ret < 0)
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 68e8a64d22e0..08e515c25a32 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -252,8 +252,8 @@ extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
/* udftime.c */
-extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest,
+extern void udf_disk_stamp_to_time(struct timespec *dest,
struct timestamp src);
-extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src);
+extern void udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src);
#endif /* __UDF_DECL_H */
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 0927a4b2ecaf..67b33ac5d41b 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -40,7 +40,7 @@
#include <linux/kernel.h>
#include <linux/time.h>
-struct timespec *
+void
udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
{
u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
@@ -67,10 +67,9 @@ udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
* recorded with bogus sub-second values.
*/
dest->tv_nsec %= NSEC_PER_SEC;
- return dest;
}
-struct timestamp *
+void
udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts)
{
long seconds;
@@ -79,9 +78,6 @@ udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts)
offset = -sys_tz.tz_minuteswest;
- if (!dest)
- return NULL;
-
dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF));
seconds = ts.tv_sec + offset * 60;
@@ -97,7 +93,6 @@ udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts)
dest->centiseconds * 10000) / 100;
dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
dest->hundredsOfMicroseconds * 100);
- return dest;
}
/* EOF */