diff options
| -rw-r--r-- | fs/xfs/xfs_file.c | 28 | ||||
| -rw-r--r-- | fs/xfs/xfs_trace.h | 2 |
2 files changed, 29 insertions, 1 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index ce615d12fb44..ac174226244a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
| @@ -1379,6 +1379,32 @@ xfs_file_llseek( | |||
| 1379 | } | 1379 | } |
| 1380 | } | 1380 | } |
| 1381 | 1381 | ||
| 1382 | /* | ||
| 1383 | * Locking for serialisation of IO during page faults. This results in a lock | ||
| 1384 | * ordering of: | ||
| 1385 | * | ||
| 1386 | * mmap_sem (MM) | ||
| 1387 | * i_mmap_lock (XFS - truncate serialisation) | ||
| 1388 | * page_lock (MM) | ||
| 1389 | * i_lock (XFS - extent map serialisation) | ||
| 1390 | */ | ||
| 1391 | STATIC int | ||
| 1392 | xfs_filemap_fault( | ||
| 1393 | struct vm_area_struct *vma, | ||
| 1394 | struct vm_fault *vmf) | ||
| 1395 | { | ||
| 1396 | struct xfs_inode *ip = XFS_I(vma->vm_file->f_mapping->host); | ||
| 1397 | int error; | ||
| 1398 | |||
| 1399 | trace_xfs_filemap_fault(ip); | ||
| 1400 | |||
| 1401 | xfs_ilock(ip, XFS_MMAPLOCK_SHARED); | ||
| 1402 | error = filemap_fault(vma, vmf); | ||
| 1403 | xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); | ||
| 1404 | |||
| 1405 | return error; | ||
| 1406 | } | ||
| 1407 | |||
| 1382 | const struct file_operations xfs_file_operations = { | 1408 | const struct file_operations xfs_file_operations = { |
| 1383 | .llseek = xfs_file_llseek, | 1409 | .llseek = xfs_file_llseek, |
| 1384 | .read = new_sync_read, | 1410 | .read = new_sync_read, |
| @@ -1411,7 +1437,7 @@ const struct file_operations xfs_dir_file_operations = { | |||
| 1411 | }; | 1437 | }; |
| 1412 | 1438 | ||
| 1413 | static const struct vm_operations_struct xfs_file_vm_ops = { | 1439 | static const struct vm_operations_struct xfs_file_vm_ops = { |
| 1414 | .fault = filemap_fault, | 1440 | .fault = xfs_filemap_fault, |
| 1415 | .map_pages = filemap_map_pages, | 1441 | .map_pages = filemap_map_pages, |
| 1416 | .page_mkwrite = xfs_vm_page_mkwrite, | 1442 | .page_mkwrite = xfs_vm_page_mkwrite, |
| 1417 | }; | 1443 | }; |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 51372e34d988..c496153b976b 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
| @@ -685,6 +685,8 @@ DEFINE_INODE_EVENT(xfs_inode_set_eofblocks_tag); | |||
| 685 | DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag); | 685 | DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag); |
| 686 | DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); | 686 | DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); |
| 687 | 687 | ||
| 688 | DEFINE_INODE_EVENT(xfs_filemap_fault); | ||
| 689 | |||
| 688 | DECLARE_EVENT_CLASS(xfs_iref_class, | 690 | DECLARE_EVENT_CLASS(xfs_iref_class, |
| 689 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), | 691 | TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), |
| 690 | TP_ARGS(ip, caller_ip), | 692 | TP_ARGS(ip, caller_ip), |
