Skip to content

Commit e2519c2

Browse files
committed
Merge tag 'fscache-fixes-20140917' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull fs-cache fixes from David Howells: - Put a timeout in releasepage() to deal with a recursive hang between the memory allocator, writeback, ext4 and fscache under memory pressure. - Fix a pair of refcount bugs in the fscache error handling. - Remove a couple of unused pagevecs. - The cachefiles requirement that the base directory support rename should permit rename2 as an alternative - otherwise certain filesystems cannot now be used as backing stores (such as ext4). * tag 'fscache-fixes-20140917' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: CacheFiles: Handle rename2 cachefiles: remove two unused pagevecs. FS-Cache: refcount becomes corrupt under vma pressure. FS-Cache: Reduce cookie ref count if submit fails. FS-Cache: Timeout for releasepage()
2 parents b0e2a55 + e2cf1f1 commit e2519c2

File tree

4 files changed

+24
-11
lines changed

4 files changed

+24
-11
lines changed

fs/cachefiles/namei.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,8 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
779779
!subdir->d_inode->i_op->lookup ||
780780
!subdir->d_inode->i_op->mkdir ||
781781
!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) ||
783784
!subdir->d_inode->i_op->rmdir ||
784785
!subdir->d_inode->i_op->unlink)
785786
goto check_error;

fs/cachefiles/rdwr.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
151151
struct cachefiles_one_read *monitor;
152152
struct cachefiles_object *object;
153153
struct fscache_retrieval *op;
154-
struct pagevec pagevec;
155154
int error, max;
156155

157156
op = container_of(_op, struct fscache_retrieval, op);
@@ -160,8 +159,6 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
160159

161160
_enter("{ino=%lu}", object->backer->d_inode->i_ino);
162161

163-
pagevec_init(&pagevec, 0);
164-
165162
max = 8;
166163
spin_lock_irq(&object->work_lock);
167164

@@ -396,7 +393,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
396393
{
397394
struct cachefiles_object *object;
398395
struct cachefiles_cache *cache;
399-
struct pagevec pagevec;
400396
struct inode *inode;
401397
sector_t block0, block;
402398
unsigned shift;
@@ -427,8 +423,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
427423
op->op.flags |= FSCACHE_OP_ASYNC;
428424
op->op.processor = cachefiles_read_copier;
429425

430-
pagevec_init(&pagevec, 0);
431-
432426
/* we assume the absence or presence of the first block is a good
433427
* enough indication for the page as a whole
434428
* - TODO: don't use bmap() for this as it is _not_ actually good

fs/fscache/object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,7 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj
982982
submit_op_failed:
983983
clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags);
984984
spin_unlock(&cookie->lock);
985+
fscache_unuse_cookie(object);
985986
kfree(op);
986987
_leave(" [EIO]");
987988
return transit_to(KILL_OBJECT);

fs/fscache/page.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
4343
}
4444
EXPORT_SYMBOL(__fscache_wait_on_page_write);
4545

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+
4659
/*
4760
* decide whether a page can be released, possibly by cancelling a store to it
4861
* - we're allowed to sleep if __GFP_WAIT is flagged
@@ -115,7 +128,10 @@ bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
115128
}
116129

117130
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+
119135
gfp &= ~__GFP_WAIT;
120136
goto try_again;
121137
}
@@ -182,7 +198,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
182198
{
183199
struct fscache_operation *op;
184200
struct fscache_object *object;
185-
bool wake_cookie;
201+
bool wake_cookie = false;
186202

187203
_enter("%p", cookie);
188204

@@ -212,15 +228,16 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
212228

213229
__fscache_use_cookie(cookie);
214230
if (fscache_submit_exclusive_op(object, op) < 0)
215-
goto nobufs;
231+
goto nobufs_dec;
216232
spin_unlock(&cookie->lock);
217233
fscache_stat(&fscache_n_attr_changed_ok);
218234
fscache_put_operation(op);
219235
_leave(" = 0");
220236
return 0;
221237

222-
nobufs:
238+
nobufs_dec:
223239
wake_cookie = __fscache_unuse_cookie(cookie);
240+
nobufs:
224241
spin_unlock(&cookie->lock);
225242
kfree(op);
226243
if (wake_cookie)

0 commit comments

Comments
 (0)