diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2017-08-01 11:53:49 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2017-08-15 11:54:47 -0400 |
commit | e824f99adaaf1ed0e03eac8574599af6d992163d (patch) | |
tree | c5d2716566d21f023bd278dae6a92a06cbe72816 /fs/nfs/write.c | |
parent | b30d2f04c35d539bf8003b3e014c389abefc249b (diff) |
NFSv4: Use a mutex to protect the per-inode commit lists
The commit lists can get very large, so using the inode->i_lock can
end up affecting general metadata performance.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 8d8fa6d4cfcc..5ab5ca24b48a 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -195,7 +195,7 @@ nfs_page_find_swap_request(struct page *page) | |||
195 | struct nfs_page *req = NULL; | 195 | struct nfs_page *req = NULL; |
196 | if (!PageSwapCache(page)) | 196 | if (!PageSwapCache(page)) |
197 | return NULL; | 197 | return NULL; |
198 | spin_lock(&inode->i_lock); | 198 | mutex_lock(&nfsi->commit_mutex); |
199 | if (PageSwapCache(page)) { | 199 | if (PageSwapCache(page)) { |
200 | req = nfs_page_search_commits_for_head_request_locked(nfsi, | 200 | req = nfs_page_search_commits_for_head_request_locked(nfsi, |
201 | page); | 201 | page); |
@@ -204,7 +204,7 @@ nfs_page_find_swap_request(struct page *page) | |||
204 | kref_get(&req->wb_kref); | 204 | kref_get(&req->wb_kref); |
205 | } | 205 | } |
206 | } | 206 | } |
207 | spin_unlock(&inode->i_lock); | 207 | mutex_unlock(&nfsi->commit_mutex); |
208 | return req; | 208 | return req; |
209 | } | 209 | } |
210 | 210 | ||
@@ -856,7 +856,8 @@ nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi, | |||
856 | * number of outstanding requests requiring a commit as well as | 856 | * number of outstanding requests requiring a commit as well as |
857 | * the MM page stats. | 857 | * the MM page stats. |
858 | * | 858 | * |
859 | * The caller must hold cinfo->inode->i_lock, and the nfs_page lock. | 859 | * The caller must hold NFS_I(cinfo->inode)->commit_mutex, and the |
860 | * nfs_page lock. | ||
860 | */ | 861 | */ |
861 | void | 862 | void |
862 | nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst, | 863 | nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst, |
@@ -884,9 +885,9 @@ EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked); | |||
884 | void | 885 | void |
885 | nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo) | 886 | nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo) |
886 | { | 887 | { |
887 | spin_lock(&cinfo->inode->i_lock); | 888 | mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); |
888 | nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); | 889 | nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); |
889 | spin_unlock(&cinfo->inode->i_lock); | 890 | mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); |
890 | if (req->wb_page) | 891 | if (req->wb_page) |
891 | nfs_mark_page_unstable(req->wb_page, cinfo); | 892 | nfs_mark_page_unstable(req->wb_page, cinfo); |
892 | } | 893 | } |
@@ -964,11 +965,11 @@ nfs_clear_request_commit(struct nfs_page *req) | |||
964 | struct nfs_commit_info cinfo; | 965 | struct nfs_commit_info cinfo; |
965 | 966 | ||
966 | nfs_init_cinfo_from_inode(&cinfo, inode); | 967 | nfs_init_cinfo_from_inode(&cinfo, inode); |
967 | spin_lock(&inode->i_lock); | 968 | mutex_lock(&NFS_I(inode)->commit_mutex); |
968 | if (!pnfs_clear_request_commit(req, &cinfo)) { | 969 | if (!pnfs_clear_request_commit(req, &cinfo)) { |
969 | nfs_request_remove_commit_list(req, &cinfo); | 970 | nfs_request_remove_commit_list(req, &cinfo); |
970 | } | 971 | } |
971 | spin_unlock(&inode->i_lock); | 972 | mutex_unlock(&NFS_I(inode)->commit_mutex); |
972 | nfs_clear_page_commit(req->wb_page); | 973 | nfs_clear_page_commit(req->wb_page); |
973 | } | 974 | } |
974 | } | 975 | } |
@@ -1027,7 +1028,7 @@ nfs_reqs_to_commit(struct nfs_commit_info *cinfo) | |||
1027 | return cinfo->mds->ncommit; | 1028 | return cinfo->mds->ncommit; |
1028 | } | 1029 | } |
1029 | 1030 | ||
1030 | /* cinfo->inode->i_lock held by caller */ | 1031 | /* NFS_I(cinfo->inode)->commit_mutex held by caller */ |
1031 | int | 1032 | int |
1032 | nfs_scan_commit_list(struct list_head *src, struct list_head *dst, | 1033 | nfs_scan_commit_list(struct list_head *src, struct list_head *dst, |
1033 | struct nfs_commit_info *cinfo, int max) | 1034 | struct nfs_commit_info *cinfo, int max) |
@@ -1039,13 +1040,12 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst, | |||
1039 | if (!nfs_lock_request(req)) | 1040 | if (!nfs_lock_request(req)) |
1040 | continue; | 1041 | continue; |
1041 | kref_get(&req->wb_kref); | 1042 | kref_get(&req->wb_kref); |
1042 | if (cond_resched_lock(&cinfo->inode->i_lock)) | ||
1043 | list_safe_reset_next(req, tmp, wb_list); | ||
1044 | nfs_request_remove_commit_list(req, cinfo); | 1043 | nfs_request_remove_commit_list(req, cinfo); |
1045 | nfs_list_add_request(req, dst); | 1044 | nfs_list_add_request(req, dst); |
1046 | ret++; | 1045 | ret++; |
1047 | if ((ret == max) && !cinfo->dreq) | 1046 | if ((ret == max) && !cinfo->dreq) |
1048 | break; | 1047 | break; |
1048 | cond_resched(); | ||
1049 | } | 1049 | } |
1050 | return ret; | 1050 | return ret; |
1051 | } | 1051 | } |
@@ -1065,7 +1065,7 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, | |||
1065 | { | 1065 | { |
1066 | int ret = 0; | 1066 | int ret = 0; |
1067 | 1067 | ||
1068 | spin_lock(&cinfo->inode->i_lock); | 1068 | mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); |
1069 | if (cinfo->mds->ncommit > 0) { | 1069 | if (cinfo->mds->ncommit > 0) { |
1070 | const int max = INT_MAX; | 1070 | const int max = INT_MAX; |
1071 | 1071 | ||
@@ -1073,7 +1073,7 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, | |||
1073 | cinfo, max); | 1073 | cinfo, max); |
1074 | ret += pnfs_scan_commit_lists(inode, cinfo, max - ret); | 1074 | ret += pnfs_scan_commit_lists(inode, cinfo, max - ret); |
1075 | } | 1075 | } |
1076 | spin_unlock(&cinfo->inode->i_lock); | 1076 | mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); |
1077 | return ret; | 1077 | return ret; |
1078 | } | 1078 | } |
1079 | 1079 | ||