mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
xfs: introduce mmap/truncate lock
Right now we cannot serialise mmap against truncate or hole punch sanely. ->page_mkwrite is not able to take locks that the read IO path normally takes (i.e. the inode iolock) because that could result in lock inversions (read - iolock - page fault - page_mkwrite - iolock) and so we cannot use an IO path lock to serialise page write faults against truncate operations. Instead, introduce a new lock that is used *only* in the ->page_mkwrite path that is the equivalent of the iolock. The lock ordering in a page fault is i_mmaplock -> page lock -> i_ilock, and so in truncate we can i_iolock -> i_mmaplock and so lock out new write faults during the process of truncation. Because i_mmap_lock is outside the page lock, we can hold it across all the same operations we hold the i_iolock for. The only difference is that we never hold the i_mmaplock in the normal IO path and so do not ever have the possibility that we can page fault inside it. Hence there are no recursion issues on the i_mmap_lock and so we can use it to serialise page fault IO against inode modification operations that affect the IO path. This patch introduces the i_mmaplock infrastructure, lockdep annotations and initialisation/destruction code. Use of the new lock will be in subsequent patches. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
c517d838eb
commit
653c60b633
3 changed files with 120 additions and 37 deletions
|
@ -56,6 +56,7 @@ typedef struct xfs_inode {
|
|||
struct xfs_inode_log_item *i_itemp; /* logging information */
|
||||
mrlock_t i_lock; /* inode lock */
|
||||
mrlock_t i_iolock; /* inode IO lock */
|
||||
mrlock_t i_mmaplock; /* inode mmap IO lock */
|
||||
atomic_t i_pincount; /* inode pin count */
|
||||
spinlock_t i_flags_lock; /* inode i_flags lock */
|
||||
/* Miscellaneous state. */
|
||||
|
@ -263,15 +264,20 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
|
|||
#define XFS_IOLOCK_SHARED (1<<1)
|
||||
#define XFS_ILOCK_EXCL (1<<2)
|
||||
#define XFS_ILOCK_SHARED (1<<3)
|
||||
#define XFS_MMAPLOCK_EXCL (1<<4)
|
||||
#define XFS_MMAPLOCK_SHARED (1<<5)
|
||||
|
||||
#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
|
||||
| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)
|
||||
| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
|
||||
| XFS_MMAPLOCK_EXCL | XFS_MMAPLOCK_SHARED)
|
||||
|
||||
#define XFS_LOCK_FLAGS \
|
||||
{ XFS_IOLOCK_EXCL, "IOLOCK_EXCL" }, \
|
||||
{ XFS_IOLOCK_SHARED, "IOLOCK_SHARED" }, \
|
||||
{ XFS_ILOCK_EXCL, "ILOCK_EXCL" }, \
|
||||
{ XFS_ILOCK_SHARED, "ILOCK_SHARED" }
|
||||
{ XFS_ILOCK_SHARED, "ILOCK_SHARED" }, \
|
||||
{ XFS_MMAPLOCK_EXCL, "MMAPLOCK_EXCL" }, \
|
||||
{ XFS_MMAPLOCK_SHARED, "MMAPLOCK_SHARED" }
|
||||
|
||||
|
||||
/*
|
||||
|
@ -302,17 +308,26 @@ static inline int xfs_isiflocked(struct xfs_inode *ip)
|
|||
#define XFS_IOLOCK_SHIFT 16
|
||||
#define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT)
|
||||
|
||||
#define XFS_MMAPLOCK_SHIFT 20
|
||||
|
||||
#define XFS_ILOCK_SHIFT 24
|
||||
#define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT)
|
||||
#define XFS_ILOCK_RTBITMAP (XFS_LOCK_RTBITMAP << XFS_ILOCK_SHIFT)
|
||||
#define XFS_ILOCK_RTSUM (XFS_LOCK_RTSUM << XFS_ILOCK_SHIFT)
|
||||
|
||||
#define XFS_IOLOCK_DEP_MASK 0x00ff0000
|
||||
#define XFS_IOLOCK_DEP_MASK 0x000f0000
|
||||
#define XFS_MMAPLOCK_DEP_MASK 0x00f00000
|
||||
#define XFS_ILOCK_DEP_MASK 0xff000000
|
||||
#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
|
||||
#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | \
|
||||
XFS_MMAPLOCK_DEP_MASK | \
|
||||
XFS_ILOCK_DEP_MASK)
|
||||
|
||||
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
|
||||
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
|
||||
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) \
|
||||
>> XFS_IOLOCK_SHIFT)
|
||||
#define XFS_MMAPLOCK_DEP(flags) (((flags) & XFS_MMAPLOCK_DEP_MASK) \
|
||||
>> XFS_MMAPLOCK_SHIFT)
|
||||
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) \
|
||||
>> XFS_ILOCK_SHIFT)
|
||||
|
||||
/*
|
||||
* For multiple groups support: if S_ISGID bit is set in the parent
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue