diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-07-17 20:42:15 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-08-03 17:05:24 -0400 |
commit | e7029206ff43f6cf7d6fcb741adb126f47200516 (patch) | |
tree | 177e5c715690fdc397a2054c48ec61b9b5cbbea4 /fs/nfs/pagelist.c | |
parent | ec25422c669d38f4e8a83da7f77950094349de48 (diff) |
nfs: check wait_on_bit_lock err in page_group_lock
Return errors from wait_on_bit_lock from nfs_page_group_lock.
Add a bool argument @wait to nfs_page_group_lock. If true, loop over
wait_on_bit_lock until it returns cleanly. If false, return the error
from wait_on_bit_lock.
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r-- | fs/nfs/pagelist.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index e76a40e298f2..9425118e91d7 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -147,17 +147,25 @@ static int nfs_wait_bit_uninterruptible(void *word) | |||
147 | * @req - request in group that is to be locked | 147 | * @req - request in group that is to be locked |
148 | * | 148 | * |
149 | * this lock must be held if modifying the page group list | 149 | * this lock must be held if modifying the page group list |
150 | * | ||
151 | * returns result from wait_on_bit_lock: 0 on success, < 0 on error | ||
150 | */ | 152 | */ |
151 | void | 153 | int |
152 | nfs_page_group_lock(struct nfs_page *req) | 154 | nfs_page_group_lock(struct nfs_page *req, bool wait) |
153 | { | 155 | { |
154 | struct nfs_page *head = req->wb_head; | 156 | struct nfs_page *head = req->wb_head; |
157 | int ret; | ||
155 | 158 | ||
156 | WARN_ON_ONCE(head != head->wb_head); | 159 | WARN_ON_ONCE(head != head->wb_head); |
157 | 160 | ||
158 | wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, | 161 | do { |
162 | ret = wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, | ||
159 | nfs_wait_bit_uninterruptible, | 163 | nfs_wait_bit_uninterruptible, |
160 | TASK_UNINTERRUPTIBLE); | 164 | TASK_UNINTERRUPTIBLE); |
165 | } while (wait && ret != 0); | ||
166 | |||
167 | WARN_ON_ONCE(ret > 0); | ||
168 | return ret; | ||
161 | } | 169 | } |
162 | 170 | ||
163 | /* | 171 | /* |
@@ -218,7 +226,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit) | |||
218 | { | 226 | { |
219 | bool ret; | 227 | bool ret; |
220 | 228 | ||
221 | nfs_page_group_lock(req); | 229 | nfs_page_group_lock(req, true); |
222 | ret = nfs_page_group_sync_on_bit_locked(req, bit); | 230 | ret = nfs_page_group_sync_on_bit_locked(req, bit); |
223 | nfs_page_group_unlock(req); | 231 | nfs_page_group_unlock(req); |
224 | 232 | ||
@@ -858,8 +866,13 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
858 | struct nfs_page *subreq; | 866 | struct nfs_page *subreq; |
859 | unsigned int bytes_left = 0; | 867 | unsigned int bytes_left = 0; |
860 | unsigned int offset, pgbase; | 868 | unsigned int offset, pgbase; |
869 | int ret; | ||
861 | 870 | ||
862 | nfs_page_group_lock(req); | 871 | ret = nfs_page_group_lock(req, false); |
872 | if (ret < 0) { | ||
873 | desc->pg_error = ret; | ||
874 | return 0; | ||
875 | } | ||
863 | 876 | ||
864 | subreq = req; | 877 | subreq = req; |
865 | bytes_left = subreq->wb_bytes; | 878 | bytes_left = subreq->wb_bytes; |
@@ -881,7 +894,11 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
881 | if (desc->pg_recoalesce) | 894 | if (desc->pg_recoalesce) |
882 | return 0; | 895 | return 0; |
883 | /* retry add_request for this subreq */ | 896 | /* retry add_request for this subreq */ |
884 | nfs_page_group_lock(req); | 897 | ret = nfs_page_group_lock(req, false); |
898 | if (ret < 0) { | ||
899 | desc->pg_error = ret; | ||
900 | return 0; | ||
901 | } | ||
885 | continue; | 902 | continue; |
886 | } | 903 | } |
887 | 904 | ||