diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 3 | ||||
| -rw-r--r-- | fs/ext4/page-io.c | 18 | ||||
| -rw-r--r-- | fs/xfs/xfs_iops.c | 14 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 36 |
5 files changed, 40 insertions, 32 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e717dfd2f2b4..b7d7bd0f066e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -175,6 +175,7 @@ struct mpage_da_data { | |||
| 175 | */ | 175 | */ |
| 176 | #define EXT4_IO_END_UNWRITTEN 0x0001 | 176 | #define EXT4_IO_END_UNWRITTEN 0x0001 |
| 177 | #define EXT4_IO_END_ERROR 0x0002 | 177 | #define EXT4_IO_END_ERROR 0x0002 |
| 178 | #define EXT4_IO_END_QUEUED 0x0004 | ||
| 178 | 179 | ||
| 179 | struct ext4_io_page { | 180 | struct ext4_io_page { |
| 180 | struct page *p_page; | 181 | struct page *p_page; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c4da98a959ae..18d2558b7624 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -121,9 +121,6 @@ void ext4_evict_inode(struct inode *inode) | |||
| 121 | 121 | ||
| 122 | trace_ext4_evict_inode(inode); | 122 | trace_ext4_evict_inode(inode); |
| 123 | 123 | ||
| 124 | mutex_lock(&inode->i_mutex); | ||
| 125 | ext4_flush_completed_IO(inode); | ||
| 126 | mutex_unlock(&inode->i_mutex); | ||
| 127 | ext4_ioend_wait(inode); | 124 | ext4_ioend_wait(inode); |
| 128 | 125 | ||
| 129 | if (inode->i_nlink) { | 126 | if (inode->i_nlink) { |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 78839af7ce29..92f38ee13f8a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
| @@ -142,7 +142,23 @@ static void ext4_end_io_work(struct work_struct *work) | |||
| 142 | unsigned long flags; | 142 | unsigned long flags; |
| 143 | int ret; | 143 | int ret; |
| 144 | 144 | ||
| 145 | mutex_lock(&inode->i_mutex); | 145 | if (!mutex_trylock(&inode->i_mutex)) { |
| 146 | /* | ||
| 147 | * Requeue the work instead of waiting so that the work | ||
| 148 | * items queued after this can be processed. | ||
| 149 | */ | ||
| 150 | queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work); | ||
| 151 | /* | ||
| 152 | * To prevent the ext4-dio-unwritten thread from keeping | ||
| 153 | * requeueing end_io requests and occupying cpu for too long, | ||
| 154 | * yield the cpu if it sees an end_io request that has already | ||
| 155 | * been requeued. | ||
| 156 | */ | ||
| 157 | if (io->flag & EXT4_IO_END_QUEUED) | ||
| 158 | yield(); | ||
| 159 | io->flag |= EXT4_IO_END_QUEUED; | ||
| 160 | return; | ||
| 161 | } | ||
| 146 | ret = ext4_end_io_nolock(io); | 162 | ret = ext4_end_io_nolock(io); |
| 147 | if (ret < 0) { | 163 | if (ret < 0) { |
| 148 | mutex_unlock(&inode->i_mutex); | 164 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index b9c172b3fbbe..673704fab748 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
| @@ -70,9 +70,8 @@ xfs_synchronize_times( | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | /* | 72 | /* |
| 73 | * If the linux inode is valid, mark it dirty. | 73 | * If the linux inode is valid, mark it dirty, else mark the dirty state |
| 74 | * Used when committing a dirty inode into a transaction so that | 74 | * in the XFS inode to make sure we pick it up when reclaiming the inode. |
| 75 | * the inode will get written back by the linux code | ||
| 76 | */ | 75 | */ |
| 77 | void | 76 | void |
| 78 | xfs_mark_inode_dirty_sync( | 77 | xfs_mark_inode_dirty_sync( |
| @@ -82,6 +81,10 @@ xfs_mark_inode_dirty_sync( | |||
| 82 | 81 | ||
| 83 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) | 82 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) |
| 84 | mark_inode_dirty_sync(inode); | 83 | mark_inode_dirty_sync(inode); |
| 84 | else { | ||
| 85 | barrier(); | ||
| 86 | ip->i_update_core = 1; | ||
| 87 | } | ||
| 85 | } | 88 | } |
| 86 | 89 | ||
| 87 | void | 90 | void |
| @@ -92,6 +95,11 @@ xfs_mark_inode_dirty( | |||
| 92 | 95 | ||
| 93 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) | 96 | if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) |
| 94 | mark_inode_dirty(inode); | 97 | mark_inode_dirty(inode); |
| 98 | else { | ||
| 99 | barrier(); | ||
| 100 | ip->i_update_core = 1; | ||
| 101 | } | ||
| 102 | |||
| 95 | } | 103 | } |
| 96 | 104 | ||
| 97 | /* | 105 | /* |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 9a72dda58bd0..2366c54cc4fa 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
| @@ -356,6 +356,8 @@ xfs_parseargs( | |||
| 356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; | 356 | mp->m_flags |= XFS_MOUNT_DELAYLOG; |
| 357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 357 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
| 358 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; | 358 | mp->m_flags &= ~XFS_MOUNT_DELAYLOG; |
| 359 | xfs_warn(mp, | ||
| 360 | "nodelaylog is deprecated and will be removed in Linux 3.3"); | ||
| 359 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 361 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { |
| 360 | mp->m_flags |= XFS_MOUNT_DISCARD; | 362 | mp->m_flags |= XFS_MOUNT_DISCARD; |
| 361 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 363 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { |
| @@ -877,33 +879,17 @@ xfs_log_inode( | |||
| 877 | struct xfs_trans *tp; | 879 | struct xfs_trans *tp; |
| 878 | int error; | 880 | int error; |
| 879 | 881 | ||
| 880 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 881 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | 882 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); |
| 882 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | 883 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); |
| 883 | |||
| 884 | if (error) { | 884 | if (error) { |
| 885 | xfs_trans_cancel(tp, 0); | 885 | xfs_trans_cancel(tp, 0); |
| 886 | /* we need to return with the lock hold shared */ | ||
| 887 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
| 888 | return error; | 886 | return error; |
| 889 | } | 887 | } |
| 890 | 888 | ||
| 891 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 889 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 892 | 890 | xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL); | |
| 893 | /* | ||
| 894 | * Note - it's possible that we might have pushed ourselves out of the | ||
| 895 | * way during trans_reserve which would flush the inode. But there's | ||
| 896 | * no guarantee that the inode buffer has actually gone out yet (it's | ||
| 897 | * delwri). Plus the buffer could be pinned anyway if it's part of | ||
| 898 | * an inode in another recent transaction. So we play it safe and | ||
| 899 | * fire off the transaction anyway. | ||
| 900 | */ | ||
| 901 | xfs_trans_ijoin(tp, ip); | ||
| 902 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 891 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
| 903 | error = xfs_trans_commit(tp, 0); | 892 | return xfs_trans_commit(tp, 0); |
| 904 | xfs_ilock_demote(ip, XFS_ILOCK_EXCL); | ||
| 905 | |||
| 906 | return error; | ||
| 907 | } | 893 | } |
| 908 | 894 | ||
| 909 | STATIC int | 895 | STATIC int |
| @@ -918,7 +904,9 @@ xfs_fs_write_inode( | |||
| 918 | trace_xfs_write_inode(ip); | 904 | trace_xfs_write_inode(ip); |
| 919 | 905 | ||
| 920 | if (XFS_FORCED_SHUTDOWN(mp)) | 906 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 921 | return XFS_ERROR(EIO); | 907 | return -XFS_ERROR(EIO); |
| 908 | if (!ip->i_update_core) | ||
| 909 | return 0; | ||
| 922 | 910 | ||
| 923 | if (wbc->sync_mode == WB_SYNC_ALL) { | 911 | if (wbc->sync_mode == WB_SYNC_ALL) { |
| 924 | /* | 912 | /* |
| @@ -929,12 +917,10 @@ xfs_fs_write_inode( | |||
| 929 | * of synchronous log foces dramatically. | 917 | * of synchronous log foces dramatically. |
| 930 | */ | 918 | */ |
| 931 | xfs_ioend_wait(ip); | 919 | xfs_ioend_wait(ip); |
| 932 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 920 | error = xfs_log_inode(ip); |
| 933 | if (ip->i_update_core) { | 921 | if (error) |
| 934 | error = xfs_log_inode(ip); | 922 | goto out; |
| 935 | if (error) | 923 | return 0; |
| 936 | goto out_unlock; | ||
| 937 | } | ||
| 938 | } else { | 924 | } else { |
| 939 | /* | 925 | /* |
| 940 | * We make this non-blocking if the inode is contended, return | 926 | * We make this non-blocking if the inode is contended, return |
