diff options
Diffstat (limited to 'fs/ntfs')
-rw-r--r-- | fs/ntfs/dir.c | 10 | ||||
-rw-r--r-- | fs/ntfs/file.c | 13 | ||||
-rw-r--r-- | fs/ntfs/inode.c | 10 | ||||
-rw-r--r-- | fs/ntfs/inode.h | 2 |
4 files changed, 22 insertions, 13 deletions
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 0f48e7c5d9e..99e36107ff6 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
@@ -1527,13 +1527,20 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) | |||
1527 | * this problem for now. We do write the $BITMAP attribute if it is present | 1527 | * this problem for now. We do write the $BITMAP attribute if it is present |
1528 | * which is the important one for a directory so things are not too bad. | 1528 | * which is the important one for a directory so things are not too bad. |
1529 | */ | 1529 | */ |
1530 | static int ntfs_dir_fsync(struct file *filp, int datasync) | 1530 | static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end, |
1531 | int datasync) | ||
1531 | { | 1532 | { |
1532 | struct inode *bmp_vi, *vi = filp->f_mapping->host; | 1533 | struct inode *bmp_vi, *vi = filp->f_mapping->host; |
1533 | int err, ret; | 1534 | int err, ret; |
1534 | ntfs_attr na; | 1535 | ntfs_attr na; |
1535 | 1536 | ||
1536 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | 1537 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); |
1538 | |||
1539 | err = filemap_write_and_wait_range(vi->i_mapping, start, end); | ||
1540 | if (err) | ||
1541 | return err; | ||
1542 | mutex_lock(&vi->i_mutex); | ||
1543 | |||
1537 | BUG_ON(!S_ISDIR(vi->i_mode)); | 1544 | BUG_ON(!S_ISDIR(vi->i_mode)); |
1538 | /* If the bitmap attribute inode is in memory sync it, too. */ | 1545 | /* If the bitmap attribute inode is in memory sync it, too. */ |
1539 | na.mft_no = vi->i_ino; | 1546 | na.mft_no = vi->i_ino; |
@@ -1555,6 +1562,7 @@ static int ntfs_dir_fsync(struct file *filp, int datasync) | |||
1555 | else | 1562 | else |
1556 | ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " | 1563 | ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " |
1557 | "%u.", datasync ? "data" : "", vi->i_ino, -ret); | 1564 | "%u.", datasync ? "data" : "", vi->i_ino, -ret); |
1565 | mutex_unlock(&vi->i_mutex); | ||
1558 | return ret; | 1566 | return ret; |
1559 | } | 1567 | } |
1560 | 1568 | ||
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index f4b1057abdd..c587e2d2718 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -1832,9 +1832,8 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, | |||
1832 | * fails again. | 1832 | * fails again. |
1833 | */ | 1833 | */ |
1834 | if (unlikely(NInoTruncateFailed(ni))) { | 1834 | if (unlikely(NInoTruncateFailed(ni))) { |
1835 | down_write(&vi->i_alloc_sem); | 1835 | inode_dio_wait(vi); |
1836 | err = ntfs_truncate(vi); | 1836 | err = ntfs_truncate(vi); |
1837 | up_write(&vi->i_alloc_sem); | ||
1838 | if (err || NInoTruncateFailed(ni)) { | 1837 | if (err || NInoTruncateFailed(ni)) { |
1839 | if (!err) | 1838 | if (!err) |
1840 | err = -EIO; | 1839 | err = -EIO; |
@@ -2153,12 +2152,19 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2153 | * with this inode but since we have no simple way of getting to them we ignore | 2152 | * with this inode but since we have no simple way of getting to them we ignore |
2154 | * this problem for now. | 2153 | * this problem for now. |
2155 | */ | 2154 | */ |
2156 | static int ntfs_file_fsync(struct file *filp, int datasync) | 2155 | static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end, |
2156 | int datasync) | ||
2157 | { | 2157 | { |
2158 | struct inode *vi = filp->f_mapping->host; | 2158 | struct inode *vi = filp->f_mapping->host; |
2159 | int err, ret = 0; | 2159 | int err, ret = 0; |
2160 | 2160 | ||
2161 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | 2161 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); |
2162 | |||
2163 | err = filemap_write_and_wait_range(vi->i_mapping, start, end); | ||
2164 | if (err) | ||
2165 | return err; | ||
2166 | mutex_lock(&vi->i_mutex); | ||
2167 | |||
2162 | BUG_ON(S_ISDIR(vi->i_mode)); | 2168 | BUG_ON(S_ISDIR(vi->i_mode)); |
2163 | if (!datasync || !NInoNonResident(NTFS_I(vi))) | 2169 | if (!datasync || !NInoNonResident(NTFS_I(vi))) |
2164 | ret = __ntfs_write_inode(vi, 1); | 2170 | ret = __ntfs_write_inode(vi, 1); |
@@ -2176,6 +2182,7 @@ static int ntfs_file_fsync(struct file *filp, int datasync) | |||
2176 | else | 2182 | else |
2177 | ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " | 2183 | ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " |
2178 | "%u.", datasync ? "data" : "", vi->i_ino, -ret); | 2184 | "%u.", datasync ? "data" : "", vi->i_ino, -ret); |
2185 | mutex_unlock(&vi->i_mutex); | ||
2179 | return ret; | 2186 | return ret; |
2180 | } | 2187 | } |
2181 | 2188 | ||
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index c05d6dcf77a..1371487da95 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -2357,12 +2357,7 @@ static const char *es = " Leaving inconsistent metadata. Unmount and run " | |||
2357 | * | 2357 | * |
2358 | * Returns 0 on success or -errno on error. | 2358 | * Returns 0 on success or -errno on error. |
2359 | * | 2359 | * |
2360 | * Called with ->i_mutex held. In all but one case ->i_alloc_sem is held for | 2360 | * Called with ->i_mutex held. |
2361 | * writing. The only case in the kernel where ->i_alloc_sem is not held is | ||
2362 | * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called | ||
2363 | * with the current i_size as the offset. The analogous place in NTFS is in | ||
2364 | * fs/ntfs/file.c::ntfs_file_buffered_write() where we call vmtruncate() again | ||
2365 | * without holding ->i_alloc_sem. | ||
2366 | */ | 2361 | */ |
2367 | int ntfs_truncate(struct inode *vi) | 2362 | int ntfs_truncate(struct inode *vi) |
2368 | { | 2363 | { |
@@ -2887,8 +2882,7 @@ void ntfs_truncate_vfs(struct inode *vi) { | |||
2887 | * We also abort all changes of user, group, and mode as we do not implement | 2882 | * We also abort all changes of user, group, and mode as we do not implement |
2888 | * the NTFS ACLs yet. | 2883 | * the NTFS ACLs yet. |
2889 | * | 2884 | * |
2890 | * Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also | 2885 | * Called with ->i_mutex held. |
2891 | * called with ->i_alloc_sem held for writing. | ||
2892 | */ | 2886 | */ |
2893 | int ntfs_setattr(struct dentry *dentry, struct iattr *attr) | 2887 | int ntfs_setattr(struct dentry *dentry, struct iattr *attr) |
2894 | { | 2888 | { |
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index 2dabf813456..fe8e7e92888 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #ifndef _LINUX_NTFS_INODE_H | 24 | #ifndef _LINUX_NTFS_INODE_H |
25 | #define _LINUX_NTFS_INODE_H | 25 | #define _LINUX_NTFS_INODE_H |
26 | 26 | ||
27 | #include <asm/atomic.h> | 27 | #include <linux/atomic.h> |
28 | 28 | ||
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |