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) | |||
2125 | ntfs_inode *ni = NTFS_I(vi); | 2125 | ntfs_inode *ni = NTFS_I(vi); |
2126 | if (NInoIndexAllocPresent(ni)) { | 2126 | if (NInoIndexAllocPresent(ni)) { |
2127 | struct inode *bvi = NULL; | 2127 | struct inode *bvi = NULL; |
2128 | down(&vi->i_sem); | 2128 | mutex_lock(&vi->i_mutex); |
2129 | if (atomic_read(&vi->i_count) == 2) { | 2129 | if (atomic_read(&vi->i_count) == 2) { |
2130 | bvi = ni->itype.index.bmp_ino; | 2130 | bvi = ni->itype.index.bmp_ino; |
2131 | if (bvi) | 2131 | if (bvi) |
2132 | ni->itype.index.bmp_ino = NULL; | 2132 | ni->itype.index.bmp_ino = NULL; |
2133 | } | 2133 | } |
2134 | up(&vi->i_sem); | 2134 | mutex_unlock(&vi->i_mutex); |
2135 | if (bvi) | 2135 | if (bvi) |
2136 | iput(bvi); | 2136 | iput(bvi); |
2137 | } | 2137 | } |
@@ -2311,7 +2311,7 @@ static const char *es = " Leaving inconsistent metadata. Unmount and run " | |||
2311 | * | 2311 | * |
2312 | * Returns 0 on success or -errno on error. | 2312 | * Returns 0 on success or -errno on error. |
2313 | * | 2313 | * |
2314 | * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for | 2314 | * Called with ->i_mutex held. In all but one case ->i_alloc_sem is held for |
2315 | * writing. The only case in the kernel where ->i_alloc_sem is not held is | 2315 | * writing. The only case in the kernel where ->i_alloc_sem is not held is |
2316 | * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called | 2316 | * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called |
2317 | * with the current i_size as the offset. The analogous place in NTFS is in | 2317 | * with the current i_size as the offset. The analogous place in NTFS is in |
@@ -2767,7 +2767,25 @@ unm_done: | |||
2767 | up_write(&ni->runlist.lock); | 2767 | up_write(&ni->runlist.lock); |
2768 | done: | 2768 | done: |
2769 | /* Update the mtime and ctime on the base inode. */ | 2769 | /* Update the mtime and ctime on the base inode. */ |
2770 | inode_update_time(VFS_I(base_ni), 1); | 2770 | /* normally ->truncate shouldn't update ctime or mtime, |
2771 | * but ntfs did before so it got a copy & paste version | ||
2772 | * of file_update_time. one day someone should fix this | ||
2773 | * for real. | ||
2774 | */ | ||
2775 | if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) { | ||
2776 | struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb); | ||
2777 | int sync_it = 0; | ||
2778 | |||
2779 | if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) || | ||
2780 | !timespec_equal(&VFS_I(base_ni)->i_ctime, &now)) | ||
2781 | sync_it = 1; | ||
2782 | VFS_I(base_ni)->i_mtime = now; | ||
2783 | VFS_I(base_ni)->i_ctime = now; | ||
2784 | |||
2785 | if (sync_it) | ||
2786 | mark_inode_dirty_sync(VFS_I(base_ni)); | ||
2787 | } | ||
2788 | |||
2771 | if (likely(!err)) { | 2789 | if (likely(!err)) { |
2772 | NInoClearTruncateFailed(ni); | 2790 | NInoClearTruncateFailed(ni); |
2773 | ntfs_debug("Done."); | 2791 | ntfs_debug("Done."); |
@@ -2831,7 +2849,7 @@ void ntfs_truncate_vfs(struct inode *vi) { | |||
2831 | * We also abort all changes of user, group, and mode as we do not implement | 2849 | * We also abort all changes of user, group, and mode as we do not implement |
2832 | * the NTFS ACLs yet. | 2850 | * the NTFS ACLs yet. |
2833 | * | 2851 | * |
2834 | * Called with ->i_sem held. For the ATTR_SIZE (i.e. ->truncate) case, also | 2852 | * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also |
2835 | * called with ->i_alloc_sem held for writing. | 2853 | * called with ->i_alloc_sem held for writing. |
2836 | * | 2854 | * |
2837 | * Basically this is a copy of generic notify_change() and inode_setattr() | 2855 | * Basically this is a copy of generic notify_change() and inode_setattr() |