diff options
author | Christoph Hellwig <hch@lst.de> | 2015-04-12 21:38:29 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-04-12 21:38:29 -0400 |
commit | 21c3ea18819b5f650c75f59a0457415bc05d2b17 (patch) | |
tree | 4a6ffaa3bed47bc57441c3ffe9d2f1e55a8b197d /fs/xfs | |
parent | 66db8104968ad8c0bf5a45a100ae586ddfadc1e1 (diff) |
xfs: unlock i_mutex in xfs_break_layouts
We want to drop all I/O path locks when recalling layouts, and that includes
i_mutex for the write path. Without this we get stuck processe when recalls
take too long.
[dchinner: fix build with !CONFIG_PNFS]
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')
-rw-r--r-- | fs/xfs/xfs_file.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_pnfs.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_pnfs.h | 5 |
5 files changed, 13 insertions, 7 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index edeaccc7961a..f63aeddd31d5 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -555,7 +555,7 @@ restart: | |||
555 | if (error) | 555 | if (error) |
556 | return error; | 556 | return error; |
557 | 557 | ||
558 | error = xfs_break_layouts(inode, iolock); | 558 | error = xfs_break_layouts(inode, iolock, true); |
559 | if (error) | 559 | if (error) |
560 | return error; | 560 | return error; |
561 | 561 | ||
@@ -842,7 +842,7 @@ xfs_file_fallocate( | |||
842 | return -EOPNOTSUPP; | 842 | return -EOPNOTSUPP; |
843 | 843 | ||
844 | xfs_ilock(ip, iolock); | 844 | xfs_ilock(ip, iolock); |
845 | error = xfs_break_layouts(inode, &iolock); | 845 | error = xfs_break_layouts(inode, &iolock, false); |
846 | if (error) | 846 | if (error) |
847 | goto out_unlock; | 847 | goto out_unlock; |
848 | 848 | ||
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ac4feae45eb3..3a21cc71fda0 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -639,7 +639,7 @@ xfs_ioc_space( | |||
639 | return error; | 639 | return error; |
640 | 640 | ||
641 | xfs_ilock(ip, iolock); | 641 | xfs_ilock(ip, iolock); |
642 | error = xfs_break_layouts(inode, &iolock); | 642 | error = xfs_break_layouts(inode, &iolock, false); |
643 | if (error) | 643 | if (error) |
644 | goto out_unlock; | 644 | goto out_unlock; |
645 | 645 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index d7782ae1af3c..1d4efee4be17 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -988,7 +988,7 @@ xfs_vn_setattr( | |||
988 | uint iolock = XFS_IOLOCK_EXCL; | 988 | uint iolock = XFS_IOLOCK_EXCL; |
989 | 989 | ||
990 | xfs_ilock(ip, iolock); | 990 | xfs_ilock(ip, iolock); |
991 | error = xfs_break_layouts(dentry->d_inode, &iolock); | 991 | error = xfs_break_layouts(dentry->d_inode, &iolock, true); |
992 | if (!error) | 992 | if (!error) |
993 | error = xfs_setattr_size(ip, iattr); | 993 | error = xfs_setattr_size(ip, iattr); |
994 | xfs_iunlock(ip, iolock); | 994 | xfs_iunlock(ip, iolock); |
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index 4b33ef112400..cbb424f4d93a 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c | |||
@@ -31,7 +31,8 @@ | |||
31 | int | 31 | int |
32 | xfs_break_layouts( | 32 | xfs_break_layouts( |
33 | struct inode *inode, | 33 | struct inode *inode, |
34 | uint *iolock) | 34 | uint *iolock, |
35 | bool with_imutex) | ||
35 | { | 36 | { |
36 | struct xfs_inode *ip = XFS_I(inode); | 37 | struct xfs_inode *ip = XFS_I(inode); |
37 | int error; | 38 | int error; |
@@ -40,8 +41,12 @@ xfs_break_layouts( | |||
40 | 41 | ||
41 | while ((error = break_layout(inode, false) == -EWOULDBLOCK)) { | 42 | while ((error = break_layout(inode, false) == -EWOULDBLOCK)) { |
42 | xfs_iunlock(ip, *iolock); | 43 | xfs_iunlock(ip, *iolock); |
44 | if (with_imutex && (*iolock & XFS_IOLOCK_EXCL)) | ||
45 | mutex_unlock(&inode->i_mutex); | ||
43 | error = break_layout(inode, true); | 46 | error = break_layout(inode, true); |
44 | *iolock = XFS_IOLOCK_EXCL; | 47 | *iolock = XFS_IOLOCK_EXCL; |
48 | if (with_imutex) | ||
49 | mutex_lock(&inode->i_mutex); | ||
45 | xfs_ilock(ip, *iolock); | 50 | xfs_ilock(ip, *iolock); |
46 | } | 51 | } |
47 | 52 | ||
diff --git a/fs/xfs/xfs_pnfs.h b/fs/xfs/xfs_pnfs.h index b7fbfce660f6..8147ac108820 100644 --- a/fs/xfs/xfs_pnfs.h +++ b/fs/xfs/xfs_pnfs.h | |||
@@ -8,9 +8,10 @@ int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length, | |||
8 | int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps, | 8 | int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps, |
9 | struct iattr *iattr); | 9 | struct iattr *iattr); |
10 | 10 | ||
11 | int xfs_break_layouts(struct inode *inode, uint *iolock); | 11 | int xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex); |
12 | #else | 12 | #else |
13 | static inline int xfs_break_layouts(struct inode *inode, uint *iolock) | 13 | static inline int |
14 | xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex) | ||
14 | { | 15 | { |
15 | return 0; | 16 | return 0; |
16 | } | 17 | } |