|
@@ -676,6 +676,7 @@ xfs_file_aio_write_checks(
|
|
|
xfs_fsize_t new_size;
|
|
|
int error = 0;
|
|
|
|
|
|
+ xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
|
|
|
*new_sizep = 0;
|
|
|
restart:
|
|
|
error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode));
|
|
@@ -798,14 +799,24 @@ xfs_file_dio_aio_write(
|
|
|
*iolock = XFS_IOLOCK_EXCL;
|
|
|
else
|
|
|
*iolock = XFS_IOLOCK_SHARED;
|
|
|
- xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
|
|
|
+ xfs_rw_ilock(ip, *iolock);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Recheck if there are cached pages that need invalidate after we got
|
|
|
+ * the iolock to protect against other threads adding new pages while
|
|
|
+ * we were waiting for the iolock.
|
|
|
+ */
|
|
|
+ if (mapping->nrpages && *iolock == XFS_IOLOCK_SHARED) {
|
|
|
+ xfs_rw_iunlock(ip, *iolock);
|
|
|
+ *iolock = XFS_IOLOCK_EXCL;
|
|
|
+ xfs_rw_ilock(ip, *iolock);
|
|
|
+ }
|
|
|
|
|
|
ret = xfs_file_aio_write_checks(file, &pos, &count, new_size, iolock);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
if (mapping->nrpages) {
|
|
|
- WARN_ON(*iolock != XFS_IOLOCK_EXCL);
|
|
|
ret = -xfs_flushinval_pages(ip, (pos & PAGE_CACHE_MASK), -1,
|
|
|
FI_REMAPF_LOCKED);
|
|
|
if (ret)
|
|
@@ -851,7 +862,7 @@ xfs_file_buffered_aio_write(
|
|
|
size_t count = ocount;
|
|
|
|
|
|
*iolock = XFS_IOLOCK_EXCL;
|
|
|
- xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
|
|
|
+ xfs_rw_ilock(ip, *iolock);
|
|
|
|
|
|
ret = xfs_file_aio_write_checks(file, &pos, &count, new_size, iolock);
|
|
|
if (ret)
|