aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-02-23 05:44:54 -0500
committerDave Chinner <david@fromorbit.com>2015-02-23 05:44:54 -0500
commit075a924d45cc69c75a35f20b4912b85aa98b180a (patch)
tree0c4112f87ca3d6b7669aa0d4b3913cd97f84a8ce /fs/xfs/xfs_file.c
parentde0e8c20ba3a65b0f15040aabbefdc1999876e6b (diff)
xfs: use i_mmaplock on write faults
Take the i_mmaplock over write page faults. These come through the ->page_mkwrite callout, so we need to wrap that calls with the i_mmaplock. This gives us a lock order of mmap_sem -> i_mmaplock -> page_lock -> i_lock. Also, move the page_mkwrite wrapper to the same region of xfs_file.c as the read fault wrappers and add a tracepoint. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index ac174226244a..d55f011401bf 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -991,20 +991,6 @@ xfs_file_mmap(
991} 991}
992 992
993/* 993/*
994 * mmap()d file has taken write protection fault and is being made
995 * writable. We can set the page state up correctly for a writable
996 * page, which means we can do correct delalloc accounting (ENOSPC
997 * checking!) and unwritten extent mapping.
998 */
999STATIC int
1000xfs_vm_page_mkwrite(
1001 struct vm_area_struct *vma,
1002 struct vm_fault *vmf)
1003{
1004 return block_page_mkwrite(vma, vmf, xfs_get_blocks);
1005}
1006
1007/*
1008 * This type is designed to indicate the type of offset we would like 994 * This type is designed to indicate the type of offset we would like
1009 * to search from page cache for xfs_seek_hole_data(). 995 * to search from page cache for xfs_seek_hole_data().
1010 */ 996 */
@@ -1405,6 +1391,29 @@ xfs_filemap_fault(
1405 return error; 1391 return error;
1406} 1392}
1407 1393
1394/*
1395 * mmap()d file has taken write protection fault and is being made writable. We
1396 * can set the page state up correctly for a writable page, which means we can
1397 * do correct delalloc accounting (ENOSPC checking!) and unwritten extent
1398 * mapping.
1399 */
1400STATIC int
1401xfs_filemap_page_mkwrite(
1402 struct vm_area_struct *vma,
1403 struct vm_fault *vmf)
1404{
1405 struct xfs_inode *ip = XFS_I(vma->vm_file->f_mapping->host);
1406 int error;
1407
1408 trace_xfs_filemap_page_mkwrite(ip);
1409
1410 xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
1411 error = block_page_mkwrite(vma, vmf, xfs_get_blocks);
1412 xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
1413
1414 return error;
1415}
1416
1408const struct file_operations xfs_file_operations = { 1417const struct file_operations xfs_file_operations = {
1409 .llseek = xfs_file_llseek, 1418 .llseek = xfs_file_llseek,
1410 .read = new_sync_read, 1419 .read = new_sync_read,
@@ -1439,5 +1448,5 @@ const struct file_operations xfs_dir_file_operations = {
1439static const struct vm_operations_struct xfs_file_vm_ops = { 1448static const struct vm_operations_struct xfs_file_vm_ops = {
1440 .fault = xfs_filemap_fault, 1449 .fault = xfs_filemap_fault,
1441 .map_pages = filemap_map_pages, 1450 .map_pages = filemap_map_pages,
1442 .page_mkwrite = xfs_vm_page_mkwrite, 1451 .page_mkwrite = xfs_filemap_page_mkwrite,
1443}; 1452};