diff options
Diffstat (limited to 'fs/ntfs/inode.c')
-rw-r--r-- | fs/ntfs/inode.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index b24f4c4b2c5c..ea1bd3feea1b 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2125,13 +2125,13 @@ void ntfs_put_inode(struct inode *vi) ntfs_inode *ni = NTFS_I(vi); if (NInoIndexAllocPresent(ni)) { struct inode *bvi = NULL; - down(&vi->i_sem); + mutex_lock(&vi->i_mutex); if (atomic_read(&vi->i_count) == 2) { bvi = ni->itype.index.bmp_ino; if (bvi) ni->itype.index.bmp_ino = NULL; } - up(&vi->i_sem); + mutex_unlock(&vi->i_mutex); if (bvi) iput(bvi); } @@ -2311,7 +2311,7 @@ static const char *es = " Leaving inconsistent metadata. Unmount and run " * * Returns 0 on success or -errno on error. * - * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for + * Called with ->i_mutex held. In all but one case ->i_alloc_sem is held for * writing. The only case in the kernel where ->i_alloc_sem is not held is * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called * with the current i_size as the offset. The analogous place in NTFS is in @@ -2767,7 +2767,25 @@ unm_done: up_write(&ni->runlist.lock); done: /* Update the mtime and ctime on the base inode. */ - inode_update_time(VFS_I(base_ni), 1); + /* normally ->truncate shouldn't update ctime or mtime, + * but ntfs did before so it got a copy & paste version + * of file_update_time. one day someone should fix this + * for real. + */ + if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) { + struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb); + int sync_it = 0; + + if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) || + !timespec_equal(&VFS_I(base_ni)->i_ctime, &now)) + sync_it = 1; + VFS_I(base_ni)->i_mtime = now; + VFS_I(base_ni)->i_ctime = now; + + if (sync_it) + mark_inode_dirty_sync(VFS_I(base_ni)); + } + if (likely(!err)) { NInoClearTruncateFailed(ni); ntfs_debug("Done."); @@ -2831,7 +2849,7 @@ void ntfs_truncate_vfs(struct inode *vi) { * We also abort all changes of user, group, and mode as we do not implement * the NTFS ACLs yet. * - * Called with ->i_sem held. For the ATTR_SIZE (i.e. ->truncate) case, also + * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also * called with ->i_alloc_sem held for writing. * * Basically this is a copy of generic notify_change() and inode_setattr() |