diff mbox

[02/21] fs: ext4: Use current_fs_time() for inode timestamps

Message ID 1465448705-25055-3-git-send-email-deepa.kernel@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Deepa Dinamani June 9, 2016, 5:04 a.m. UTC
CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe.
current_fs_time() will be transitioned to be y2038 safe
along with vfs.

current_fs_time() returns timestamps according to the
granularities set in the super_block.
The granularity check to call current_fs_time() or
CURRENT_TIME_SEC is not required.
Use current_fs_time() to obtain timestamps
unconditionally.

Quota files are assumed to be on the same filesystem.
Hence, use current_fs_time() for these files as well.

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: linux-ext4@vger.kernel.org
---
 fs/ext4/acl.c     |  2 +-
 fs/ext4/ext4.h    |  6 ------
 fs/ext4/extents.c | 10 +++++-----
 fs/ext4/ialloc.c  |  2 +-
 fs/ext4/inline.c  |  4 ++--
 fs/ext4/inode.c   |  6 +++---
 fs/ext4/ioctl.c   |  8 ++++----
 fs/ext4/namei.c   | 24 +++++++++++++-----------
 fs/ext4/super.c   |  2 +-
 fs/ext4/xattr.c   |  2 +-
 10 files changed, 31 insertions(+), 35 deletions(-)

Comments

Linus Torvalds June 9, 2016, 6:45 p.m. UTC | #1
On Wed, Jun 8, 2016 at 10:04 PM, Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe.
> current_fs_time() will be transitioned to be y2038 safe
> along with vfs.
>
> current_fs_time() returns timestamps according to the
> granularities set in the super_block.

All existing users and all the ones in this patch (and the others too,
although I didn't go through them very carefully) really would prefer
just passing in the inode directly, rather than the superblock.

So I don't want to add more users of this broken interface.  It was a
mistake to use the superblock. The fact that the time granularity
exists there is pretty much irrelevant. If every single user wants to
use an inode pointer, then that is what the function should get.

                 Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Torvalds June 9, 2016, 6:55 p.m. UTC | #2
On Thu, Jun 9, 2016 at 11:45 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> All existing users and all the ones in this patch (and the others too,
> although I didn't go through them very carefully) really would prefer
> just passing in the inode directly, rather than the superblock.

Actually, there seems to be one exception to that "all existing
users", and that one exception (btrfs transacation time) really seems
to be broken. Exactly because it's *not* setting an inode time, it
shouldn't have used current_fs_time() to begin with, because it is
just setting an internal filesystem timestamp.

So not making the argument inode-related seems to actually encourage
people to misuse this function.

                Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann June 10, 2016, 10:19 p.m. UTC | #3
On Thursday, June 9, 2016 11:45:01 AM CEST Linus Torvalds wrote:
> On Wed, Jun 8, 2016 at 10:04 PM, Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> > CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe.
> > current_fs_time() will be transitioned to be y2038 safe
> > along with vfs.
> >
> > current_fs_time() returns timestamps according to the
> > granularities set in the super_block.
> 
> All existing users and all the ones in this patch (and the others too,
> although I didn't go through them very carefully) really would prefer
> just passing in the inode directly, rather than the superblock.
> 
> So I don't want to add more users of this broken interface.  It was a
> mistake to use the superblock. The fact that the time granularity
> exists there is pretty much irrelevant. If every single user wants to
> use an inode pointer, then that is what the function should get.

I guess it would help to give the function a new name in the process,
if only to avoid possible conflicts. That new name of course needs to
be at least as intuitive as the old one. How about

struct timespec fs_timestamp(struct inode *);

? 

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Deepa Dinamani June 14, 2016, 5:55 p.m. UTC | #4
On Fri, Jun 10, 2016 at 3:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday, June 9, 2016 11:45:01 AM CEST Linus Torvalds wrote:
>> On Wed, Jun 8, 2016 at 10:04 PM, Deepa Dinamani <deepa.kernel@gmail.com> wrote:
>> > CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe.
>> > current_fs_time() will be transitioned to be y2038 safe
>> > along with vfs.
>> >
>> > current_fs_time() returns timestamps according to the
>> > granularities set in the super_block.
>>
>> All existing users and all the ones in this patch (and the others too,
>> although I didn't go through them very carefully) really would prefer
>> just passing in the inode directly, rather than the superblock.
>>
>> So I don't want to add more users of this broken interface.  It was a
>> mistake to use the superblock. The fact that the time granularity
>> exists there is pretty much irrelevant. If every single user wants to
>> use an inode pointer, then that is what the function should get.
>
> I guess it would help to give the function a new name in the process,
> if only to avoid possible conflicts. That new name of course needs to
> be at least as intuitive as the old one. How about
>
> struct timespec fs_timestamp(struct inode *);

Would moving the function to fs/ directory (filesystems.c/ super.c /
inode.c) and calling it current_time() or fs_current_time() make
sense?
The declaration is already part of fs.h.

This is actually a vfs function.
And, the time functions it uses are already exported.
Leaving it in the time.c by renaming to current_time() would be
confusing in spite of
the struct inode* argument.

-Deepa
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arnd Bergmann June 14, 2016, 8:59 p.m. UTC | #5
On Tuesday, June 14, 2016 10:55:39 AM CEST Deepa Dinamani wrote:
> On Fri, Jun 10, 2016 at 3:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday, June 9, 2016 11:45:01 AM CEST Linus Torvalds wrote:
> >> On Wed, Jun 8, 2016 at 10:04 PM, Deepa Dinamani <deepa.kernel@gmail.com> wrote:
> >> > CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe.
> >> > current_fs_time() will be transitioned to be y2038 safe
> >> > along with vfs.
> >> >
> >> > current_fs_time() returns timestamps according to the
> >> > granularities set in the super_block.
> >>
> >> All existing users and all the ones in this patch (and the others too,
> >> although I didn't go through them very carefully) really would prefer
> >> just passing in the inode directly, rather than the superblock.
> >>
> >> So I don't want to add more users of this broken interface.  It was a
> >> mistake to use the superblock. The fact that the time granularity
> >> exists there is pretty much irrelevant. If every single user wants to
> >> use an inode pointer, then that is what the function should get.
> >
> > I guess it would help to give the function a new name in the process,
> > if only to avoid possible conflicts. That new name of course needs to
> > be at least as intuitive as the old one. How about
> >
> > struct timespec fs_timestamp(struct inode *);
> 
> Would moving the function to fs/ directory (filesystems.c/ super.c /
> inode.c) and calling it current_time() or fs_current_time() make
> sense?
> The declaration is already part of fs.h.
>
> This is actually a vfs function.
> And, the time functions it uses are already exported.
> Leaving it in the time.c by renaming to current_time() would be
> confusing in spite of
> the struct inode* argument.

I've looked up the original patch that introduced current_fs_time
at http://marc.info/?l=linux-kernel&m=110134111125012&w=3

From the patch, it's clear that current_fs_time was intentionally
added to the same file as current_kernel_time() so it could be
inlined there, but both functions have since been moved to different
files.

I agree moving both timespec_trunc and current_fs_time into
fs/inode.c or fs/attr.c seems appropriate then, or we could move
current_fs_time() into kernel/time/timekeeping.c and mark
current_kernel_time64() inline again.

When John Stultz moved this function in 2c6b47de17c7 ("Cleanup
non-arch xtime uses, use get_seconds() or current_kernel_time()."),
he evidently did not consider the "inline" behavior important
there, no idea if this is even measurable.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index c6601a4..f9469cc 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -197,7 +197,7 @@  __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
 			if (error < 0)
 				return error;
 			else {
-				inode->i_ctime = ext4_current_time(inode);
+				inode->i_ctime = current_fs_time(inode->i_sb);
 				ext4_mark_inode_dirty(handle, inode);
 				if (error == 0)
 					acl = NULL;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b84aa1c..14e5cf4 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1523,12 +1523,6 @@  static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
 	return container_of(inode, struct ext4_inode_info, vfs_inode);
 }
 
-static inline struct timespec ext4_current_time(struct inode *inode)
-{
-	return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ?
-		current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
-}
-
 static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
 {
 	return ino == EXT4_ROOT_INO ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 2a2eef9..ac303be 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4722,7 +4722,7 @@  retry:
 		map.m_lblk += ret;
 		map.m_len = len = len - ret;
 		epos = (loff_t)map.m_lblk << inode->i_blkbits;
-		inode->i_ctime = ext4_current_time(inode);
+		inode->i_ctime = current_fs_time(inode->i_sb);
 		if (new_size) {
 			if (epos > new_size)
 				epos = new_size;
@@ -4850,7 +4850,7 @@  static long ext4_zero_range(struct file *file, loff_t offset,
 		}
 		/* Now release the pages and zero block aligned part of pages */
 		truncate_pagecache_range(inode, start, end - 1);
-		inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+		inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 
 		ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
 					     flags, mode);
@@ -4875,7 +4875,7 @@  static long ext4_zero_range(struct file *file, loff_t offset,
 		goto out_dio;
 	}
 
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	if (new_size) {
 		ext4_update_inode_size(inode, new_size);
 	} else {
@@ -5574,7 +5574,7 @@  int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
 	up_write(&EXT4_I(inode)->i_data_sem);
 	if (IS_SYNC(inode))
 		ext4_handle_sync(handle);
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 
 out_stop:
@@ -5684,7 +5684,7 @@  int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
 	/* Expand file to avoid data loss if there is error while shifting */
 	inode->i_size += len;
 	EXT4_I(inode)->i_disksize += len;
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ret = ext4_mark_inode_dirty(handle, inode);
 	if (ret)
 		goto out_stop;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 3da4cf8..152ef38 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1039,7 +1039,7 @@  got:
 	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
-						       ext4_current_time(inode);
+						       current_fs_time(inode->i_sb);
 
 	memset(ei->i_data, 0, sizeof(ei->i_data));
 	ei->i_dir_start_lookup = 0;
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index ff7538c..67b3fe8 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1028,7 +1028,7 @@  static int ext4_add_dirent_to_inline(handle_t *handle,
 	 * happen is that the times are slightly out of date
 	 * and/or different from the directory change time.
 	 */
-	dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
+	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
 	ext4_update_dx_flag(dir);
 	dir->i_version++;
 	ext4_mark_inode_dirty(handle, dir);
@@ -1971,7 +1971,7 @@  out:
 	if (inode->i_nlink)
 		ext4_orphan_del(handle, inode);
 
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 	if (IS_SYNC(inode))
 		ext4_handle_sync(handle);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index f7140ca..1546c02 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3991,7 +3991,7 @@  int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
 	if (IS_SYNC(inode))
 		ext4_handle_sync(handle);
 
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 out_stop:
 	ext4_journal_stop(handle);
@@ -4145,7 +4145,7 @@  out_stop:
 	if (inode->i_nlink)
 		ext4_orphan_del(handle, inode);
 
-	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 	ext4_journal_stop(handle);
 
@@ -5120,7 +5120,7 @@  int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 			 * update c/mtime in shrink case below
 			 */
 			if (!shrink) {
-				inode->i_mtime = ext4_current_time(inode);
+				inode->i_mtime = current_fs_time(inode->i_sb);
 				inode->i_ctime = inode->i_mtime;
 			}
 			down_write(&EXT4_I(inode)->i_data_sem);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 28cc412..fb429ac 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -155,7 +155,7 @@  static long swap_inode_boot_loader(struct super_block *sb,
 
 	swap_inode_data(inode, inode_bl);
 
-	inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode);
+	inode->i_ctime = inode_bl->i_ctime = current_fs_time(inode->i_sb);
 
 	spin_lock(&sbi->s_next_gen_lock);
 	inode->i_generation = sbi->s_next_generation++;
@@ -274,7 +274,7 @@  static int ext4_ioctl_setflags(struct inode *inode,
 	}
 
 	ext4_set_inode_flags(inode);
-	inode->i_ctime = ext4_current_time(inode);
+	inode->i_ctime = current_fs_time(inode->i_sb);
 
 	err = ext4_mark_iloc_dirty(handle, inode, &iloc);
 flags_err:
@@ -373,7 +373,7 @@  static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
 		}
 	}
 	EXT4_I(inode)->i_projid = kprojid;
-	inode->i_ctime = ext4_current_time(inode);
+	inode->i_ctime = current_fs_time(inode->i_sb);
 out_dirty:
 	rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
 	if (!err)
@@ -505,7 +505,7 @@  long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		}
 		err = ext4_reserve_inode_write(handle, inode, &iloc);
 		if (err == 0) {
-			inode->i_ctime = ext4_current_time(inode);
+			inode->i_ctime = current_fs_time(inode->i_sb);
 			inode->i_generation = generation;
 			err = ext4_mark_iloc_dirty(handle, inode, &iloc);
 		}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index ec4c399..c4cc01d 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1939,7 +1939,7 @@  static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname,
 	 * happen is that the times are slightly out of date
 	 * and/or different from the directory change time.
 	 */
-	dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
+	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
 	ext4_update_dx_flag(dir);
 	dir->i_version++;
 	ext4_mark_inode_dirty(handle, dir);
@@ -2988,7 +2988,7 @@  static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
 	 * recovery. */
 	inode->i_size = 0;
 	ext4_orphan_add(handle, inode);
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 	ext4_dec_count(handle, dir);
 	ext4_update_dx_flag(dir);
@@ -3051,13 +3051,13 @@  static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 	retval = ext4_delete_entry(handle, dir, de, bh);
 	if (retval)
 		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
+	dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
 	ext4_update_dx_flag(dir);
 	ext4_mark_inode_dirty(handle, dir);
 	drop_nlink(inode);
 	if (!inode->i_nlink)
 		ext4_orphan_add(handle, inode);
-	inode->i_ctime = ext4_current_time(inode);
+	inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 
 end_unlink:
@@ -3256,7 +3256,7 @@  retry:
 	if (IS_DIRSYNC(dir))
 		ext4_handle_sync(handle);
 
-	inode->i_ctime = ext4_current_time(inode);
+	inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_inc_count(handle, inode);
 	ihold(inode);
 
@@ -3383,7 +3383,7 @@  static int ext4_setent(handle_t *handle, struct ext4_renament *ent,
 		ent->de->file_type = file_type;
 	ent->dir->i_version++;
 	ent->dir->i_ctime = ent->dir->i_mtime =
-		ext4_current_time(ent->dir);
+		current_fs_time(ent->dir->i_sb);
 	ext4_mark_inode_dirty(handle, ent->dir);
 	BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata");
 	if (!ent->inlined) {
@@ -3654,7 +3654,7 @@  static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old.inode->i_ctime = ext4_current_time(old.inode);
+	old.inode->i_ctime = current_fs_time(old.inode->i_sb);
 	ext4_mark_inode_dirty(handle, old.inode);
 
 	if (!whiteout) {
@@ -3666,9 +3666,9 @@  static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 	if (new.inode) {
 		ext4_dec_count(handle, new.inode);
-		new.inode->i_ctime = ext4_current_time(new.inode);
+		new.inode->i_ctime = current_fs_time(new.inode->i_sb);
 	}
-	old.dir->i_ctime = old.dir->i_mtime = ext4_current_time(old.dir);
+	old.dir->i_ctime = old.dir->i_mtime = current_fs_time(old.dir->i_sb);
 	ext4_update_dx_flag(old.dir);
 	if (old.dir_bh) {
 		retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino);
@@ -3726,6 +3726,7 @@  static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 	};
 	u8 new_file_type;
 	int retval;
+	struct timespec ctime;
 
 	if ((ext4_encrypted_inode(old_dir) ||
 	     ext4_encrypted_inode(new_dir)) &&
@@ -3828,8 +3829,9 @@  static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old.inode->i_ctime = ext4_current_time(old.inode);
-	new.inode->i_ctime = ext4_current_time(new.inode);
+	ctime = current_fs_time(old.inode->i_sb);
+	old.inode->i_ctime = ctime;
+	new.inode->i_ctime = ctime;
 	ext4_mark_inode_dirty(handle, old.inode);
 	ext4_mark_inode_dirty(handle, new.inode);
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3822a5a..c39cb7c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5165,7 +5165,7 @@  static int ext4_quota_off(struct super_block *sb, int type)
 	handle = ext4_journal_start(inode, EXT4_HT_QUOTA, 1);
 	if (IS_ERR(handle))
 		goto out;
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	ext4_mark_inode_dirty(handle, inode);
 	ext4_journal_stop(handle);
 
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index e79bd32..808609c 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1253,7 +1253,7 @@  ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
 	}
 	if (!error) {
 		ext4_xattr_update_super_block(handle, inode->i_sb);
-		inode->i_ctime = ext4_current_time(inode);
+		inode->i_ctime = current_fs_time(inode->i_sb);
 		if (!value)
 			ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
 		error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);