On Thu, Feb 05, 2015 at 08:04:16AM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/xfs_file.c | 39 ++++++++++++++++++++++++--------------- > fs/xfs/xfs_trace.h | 1 + > 2 files changed, 25 insertions(+), 15 deletions(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 6cc1b7d..2bb25fd 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -981,20 +981,6 @@ xfs_file_mmap( > } > > /* > - * mmap()d file has taken write protection fault and is being made > - * writable. We can set the page state up correctly for a writable > - * page, which means we can do correct delalloc accounting (ENOSPC > - * checking!) and unwritten extent mapping. > - */ > -STATIC int > -xfs_vm_page_mkwrite( > - struct vm_area_struct *vma, > - struct vm_fault *vmf) > -{ > - return block_page_mkwrite(vma, vmf, xfs_get_blocks); > -} > - > -/* > * This type is designed to indicate the type of offset we would like > * to search from page cache for xfs_seek_hole_data(). > */ > @@ -1395,6 +1381,29 @@ xfs_filemap_fault( > return error; > } > > +/* > + * mmap()d file has taken write protection fault and is being made writable. We > + * can set the page state up correctly for a writable page, which means we can > + * do correct delalloc accounting (ENOSPC checking!) and unwritten extent > + * mapping. > + */ > +STATIC int > +xfs_filemap_page_mkwrite( > + 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_page_mkwrite(ip); > + > + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); > + error = block_page_mkwrite(vma, vmf, xfs_get_blocks); > + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); > + > + return error; > +} > + > const struct file_operations xfs_file_operations = { > .llseek = xfs_file_llseek, > .read = new_sync_read, > @@ -1429,6 +1438,6 @@ const struct file_operations xfs_dir_file_operations = { > static const struct vm_operations_struct xfs_file_vm_ops = { > .fault = xfs_filemap_fault, > .map_pages = filemap_map_pages, > - .page_mkwrite = xfs_vm_page_mkwrite, > + .page_mkwrite = xfs_filemap_page_mkwrite, > .remap_pages = generic_file_remap_pages, > }; > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index c496153..b1e059b 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -686,6 +686,7 @@ DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag); > DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); > > DEFINE_INODE_EVENT(xfs_filemap_fault); > +DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); > > DECLARE_EVENT_CLASS(xfs_iref_class, > TP_PROTO(struct xfs_inode *ip, unsigned long 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