On Thu, Feb 05, 2015 at 08:04:15AM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > Take the i_mmaplock over read page faults. These come through the > ->fault callout, so we need to wrap the generic implementation > with the i_mmaplock. While there, add tracepoints for the read > fault as it passes through XFS. > > This gives us a lock order of mmap_sem -> i_mmaplock -> page_lock > -> i_lock. > > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/xfs_file.c | 28 +++++++++++++++++++++++++++- > fs/xfs/xfs_trace.h | 2 ++ > 2 files changed, 29 insertions(+), 1 deletion(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 712d312..6cc1b7d 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1369,6 +1369,32 @@ xfs_file_llseek( > } > } > > +/* > + * Locking for serialisation of IO during page faults. This results in a lock > + * ordering of: > + * > + * mmap_sem (MM) > + * i_mmap_lock (XFS - truncate serialisation) > + * page_lock (MM) > + * i_lock (XFS - extent map serialisation) > + */ > +STATIC int > +xfs_filemap_fault( > + struct vm_area_struct *vma, > + struct vm_fault *vmf) > +{ > + struct xfs_inode *ip = XFS_I(vma->vm_file->f_mapping->host); > + int error; > + > + trace_xfs_filemap_fault(ip); > + > + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); > + error = filemap_fault(vma, vmf); > + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); > + > + return error; > +} > + > const struct file_operations xfs_file_operations = { > .llseek = xfs_file_llseek, > .read = new_sync_read, > @@ -1401,7 +1427,7 @@ const struct file_operations xfs_dir_file_operations = { > }; > > static const struct vm_operations_struct xfs_file_vm_ops = { > - .fault = filemap_fault, > + .fault = xfs_filemap_fault, > .map_pages = filemap_map_pages, > .page_mkwrite = xfs_vm_page_mkwrite, > .remap_pages = generic_file_remap_pages, > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 51372e3..c496153 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); > DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag); > DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); > > +DEFINE_INODE_EVENT(xfs_filemap_fault); > + > DECLARE_EVENT_CLASS(xfs_iref_class, > TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), > TP_ARGS(ip, caller_ip), > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@xxxxxxxxxxx > http://oss.sgi.com/mailman/listinfo/xfs _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs