diff options
author | Christoph Hellwig | 2015-02-16 11:59:50 +1100 |
---|---|---|
committer | Dave Chinner | 2015-02-16 11:59:50 +1100 |
commit | 781355c6e5ae87908de27dec3380a34918c33eee (patch) | |
tree | 9c747dd4207fae358368c3217d5e71f7d3a0af38 /fs/xfs/xfs_pnfs.c | |
parent | 527851124d10f9c50b1c578e0a56fcd49922422d (diff) |
xfs: recall pNFS layouts on conflicting access
Recall all outstanding pNFS layouts and truncates, writes and similar extent
list modifying operations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_pnfs.c')
-rw-r--r-- | fs/xfs/xfs_pnfs.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index 89912b34f184..4b33ef112400 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c @@ -19,6 +19,36 @@ #include "xfs_pnfs.h" /* + * Ensure that we do not have any outstanding pNFS layouts that can be used by + * clients to directly read from or write to this inode. This must be called + * before every operation that can remove blocks from the extent map. + * Additionally we call it during the write operation, where aren't concerned + * about exposing unallocated blocks but just want to provide basic + * synchronization between a local writer and pNFS clients. mmap writes would + * also benefit from this sort of synchronization, but due to the tricky locking + * rules in the page fault path we don't bother. + */ +int +xfs_break_layouts( + struct inode *inode, + uint *iolock) +{ + struct xfs_inode *ip = XFS_I(inode); + int error; + + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)); + + while ((error = break_layout(inode, false) == -EWOULDBLOCK)) { + xfs_iunlock(ip, *iolock); + error = break_layout(inode, true); + *iolock = XFS_IOLOCK_EXCL; + xfs_ilock(ip, *iolock); + } + + return error; +} + +/* * Get a unique ID including its location so that the client can identify * the exported device. */ |