diff options
| -rw-r--r-- | fs/cachefiles/namei.c | 3 | ||||
| -rw-r--r-- | fs/cachefiles/rdwr.c | 6 | ||||
| -rw-r--r-- | fs/fscache/object.c | 1 | ||||
| -rw-r--r-- | fs/fscache/page.c | 25 |
4 files changed, 24 insertions, 11 deletions
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 5bf2b41e66d3..83e9c94ca2cf 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
| @@ -779,7 +779,8 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, | |||
| 779 | !subdir->d_inode->i_op->lookup || | 779 | !subdir->d_inode->i_op->lookup || |
| 780 | !subdir->d_inode->i_op->mkdir || | 780 | !subdir->d_inode->i_op->mkdir || |
| 781 | !subdir->d_inode->i_op->create || | 781 | !subdir->d_inode->i_op->create || |
| 782 | !subdir->d_inode->i_op->rename || | 782 | (!subdir->d_inode->i_op->rename && |
| 783 | !subdir->d_inode->i_op->rename2) || | ||
| 783 | !subdir->d_inode->i_op->rmdir || | 784 | !subdir->d_inode->i_op->rmdir || |
| 784 | !subdir->d_inode->i_op->unlink) | 785 | !subdir->d_inode->i_op->unlink) |
| 785 | goto check_error; | 786 | goto check_error; |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 4b1fb5ca65b8..25e745b8eb1b 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
| @@ -151,7 +151,6 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
| 151 | struct cachefiles_one_read *monitor; | 151 | struct cachefiles_one_read *monitor; |
| 152 | struct cachefiles_object *object; | 152 | struct cachefiles_object *object; |
| 153 | struct fscache_retrieval *op; | 153 | struct fscache_retrieval *op; |
| 154 | struct pagevec pagevec; | ||
| 155 | int error, max; | 154 | int error, max; |
| 156 | 155 | ||
| 157 | op = container_of(_op, struct fscache_retrieval, op); | 156 | op = container_of(_op, struct fscache_retrieval, op); |
| @@ -160,8 +159,6 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
| 160 | 159 | ||
| 161 | _enter("{ino=%lu}", object->backer->d_inode->i_ino); | 160 | _enter("{ino=%lu}", object->backer->d_inode->i_ino); |
| 162 | 161 | ||
| 163 | pagevec_init(&pagevec, 0); | ||
| 164 | |||
| 165 | max = 8; | 162 | max = 8; |
| 166 | spin_lock_irq(&object->work_lock); | 163 | spin_lock_irq(&object->work_lock); |
| 167 | 164 | ||
| @@ -396,7 +393,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
| 396 | { | 393 | { |
| 397 | struct cachefiles_object *object; | 394 | struct cachefiles_object *object; |
| 398 | struct cachefiles_cache *cache; | 395 | struct cachefiles_cache *cache; |
| 399 | struct pagevec pagevec; | ||
| 400 | struct inode *inode; | 396 | struct inode *inode; |
| 401 | sector_t block0, block; | 397 | sector_t block0, block; |
| 402 | unsigned shift; | 398 | unsigned shift; |
| @@ -427,8 +423,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
| 427 | op->op.flags |= FSCACHE_OP_ASYNC; | 423 | op->op.flags |= FSCACHE_OP_ASYNC; |
| 428 | op->op.processor = cachefiles_read_copier; | 424 | op->op.processor = cachefiles_read_copier; |
| 429 | 425 | ||
| 430 | pagevec_init(&pagevec, 0); | ||
| 431 | |||
| 432 | /* we assume the absence or presence of the first block is a good | 426 | /* we assume the absence or presence of the first block is a good |
| 433 | * enough indication for the page as a whole | 427 | * enough indication for the page as a whole |
| 434 | * - TODO: don't use bmap() for this as it is _not_ actually good | 428 | * - TODO: don't use bmap() for this as it is _not_ actually good |
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index d3b4539f1651..da032daf0e0d 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
| @@ -982,6 +982,7 @@ nomem: | |||
| 982 | submit_op_failed: | 982 | submit_op_failed: |
| 983 | clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); | 983 | clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); |
| 984 | spin_unlock(&cookie->lock); | 984 | spin_unlock(&cookie->lock); |
| 985 | fscache_unuse_cookie(object); | ||
| 985 | kfree(op); | 986 | kfree(op); |
| 986 | _leave(" [EIO]"); | 987 | _leave(" [EIO]"); |
| 987 | return transit_to(KILL_OBJECT); | 988 | return transit_to(KILL_OBJECT); |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 85332b9d19d1..de33b3fccca6 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
| @@ -44,6 +44,19 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa | |||
| 44 | EXPORT_SYMBOL(__fscache_wait_on_page_write); | 44 | EXPORT_SYMBOL(__fscache_wait_on_page_write); |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * wait for a page to finish being written to the cache. Put a timeout here | ||
| 48 | * since we might be called recursively via parent fs. | ||
| 49 | */ | ||
| 50 | static | ||
| 51 | bool release_page_wait_timeout(struct fscache_cookie *cookie, struct page *page) | ||
| 52 | { | ||
| 53 | wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0); | ||
| 54 | |||
| 55 | return wait_event_timeout(*wq, !__fscache_check_page_write(cookie, page), | ||
| 56 | HZ); | ||
| 57 | } | ||
| 58 | |||
| 59 | /* | ||
| 47 | * decide whether a page can be released, possibly by cancelling a store to it | 60 | * decide whether a page can be released, possibly by cancelling a store to it |
| 48 | * - we're allowed to sleep if __GFP_WAIT is flagged | 61 | * - we're allowed to sleep if __GFP_WAIT is flagged |
| 49 | */ | 62 | */ |
| @@ -115,7 +128,10 @@ page_busy: | |||
| 115 | } | 128 | } |
| 116 | 129 | ||
| 117 | fscache_stat(&fscache_n_store_vmscan_wait); | 130 | fscache_stat(&fscache_n_store_vmscan_wait); |
| 118 | __fscache_wait_on_page_write(cookie, page); | 131 | if (!release_page_wait_timeout(cookie, page)) |
| 132 | _debug("fscache writeout timeout page: %p{%lx}", | ||
| 133 | page, page->index); | ||
| 134 | |||
| 119 | gfp &= ~__GFP_WAIT; | 135 | gfp &= ~__GFP_WAIT; |
| 120 | goto try_again; | 136 | goto try_again; |
| 121 | } | 137 | } |
| @@ -182,7 +198,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
| 182 | { | 198 | { |
| 183 | struct fscache_operation *op; | 199 | struct fscache_operation *op; |
| 184 | struct fscache_object *object; | 200 | struct fscache_object *object; |
| 185 | bool wake_cookie; | 201 | bool wake_cookie = false; |
| 186 | 202 | ||
| 187 | _enter("%p", cookie); | 203 | _enter("%p", cookie); |
| 188 | 204 | ||
| @@ -212,15 +228,16 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
| 212 | 228 | ||
| 213 | __fscache_use_cookie(cookie); | 229 | __fscache_use_cookie(cookie); |
| 214 | if (fscache_submit_exclusive_op(object, op) < 0) | 230 | if (fscache_submit_exclusive_op(object, op) < 0) |
| 215 | goto nobufs; | 231 | goto nobufs_dec; |
| 216 | spin_unlock(&cookie->lock); | 232 | spin_unlock(&cookie->lock); |
| 217 | fscache_stat(&fscache_n_attr_changed_ok); | 233 | fscache_stat(&fscache_n_attr_changed_ok); |
| 218 | fscache_put_operation(op); | 234 | fscache_put_operation(op); |
| 219 | _leave(" = 0"); | 235 | _leave(" = 0"); |
| 220 | return 0; | 236 | return 0; |
| 221 | 237 | ||
| 222 | nobufs: | 238 | nobufs_dec: |
| 223 | wake_cookie = __fscache_unuse_cookie(cookie); | 239 | wake_cookie = __fscache_unuse_cookie(cookie); |
| 240 | nobufs: | ||
| 224 | spin_unlock(&cookie->lock); | 241 | spin_unlock(&cookie->lock); |
| 225 | kfree(op); | 242 | kfree(op); |
| 226 | if (wake_cookie) | 243 | if (wake_cookie) |
