struct cl_page *page;
struct cl_object *obj;
- __u16 refcheck;
-
LASSERT(PageLocked(vmpage));
LASSERT(!PageWriteback(vmpage));
#else
if (offset == 0) {
#endif
- env = cl_env_get(&refcheck);
- if (!IS_ERR(env)) {
- inode = vmpage->mapping->host;
- obj = ll_i2info(inode)->lli_clob;
- if (obj != NULL) {
- page = cl_vmpage_page(vmpage, obj);
- if (page != NULL) {
- cl_page_delete(env, page);
- cl_page_put(env, page);
- }
- } else
- LASSERT(vmpage->private == 0);
- cl_env_put(env, &refcheck);
- }
+ /* See the comment in ll_releasepage() */
+ env = cl_env_percpu_get();
+ LASSERT(!IS_ERR(env));
+
+ inode = vmpage->mapping->host;
+ obj = ll_i2info(inode)->lli_clob;
+ if (obj != NULL) {
+ page = cl_vmpage_page(vmpage, obj);
+ if (page != NULL) {
+ cl_page_delete(env, page);
+ cl_page_put(env, page);
+ }
+ } else
+ LASSERT(vmpage->private == 0);
+
+ cl_env_percpu_put(env);
}
}
struct page **pagep, void **fsdata)
{
struct ll_cl_context *lcc;
- const struct lu_env *env;
+ const struct lu_env *env = NULL;
struct cl_io *io;
- struct cl_page *page;
+ struct cl_page *page = NULL;
struct cl_object *clob = ll_i2info(mapping->host)->lli_clob;
pgoff_t index = pos >> PAGE_SHIFT;
unlock_page(vmpage);
put_page(vmpage);
}
+ if (!IS_ERR_OR_NULL(page)) {
+ lu_ref_del(&page->cp_reference, "cl_io", io);
+ cl_page_put(env, page);
+ }
if (io)
io->ci_result = result;
} else {
}
run_test 407 "transaction fail should cause operation fail"
+test_408() {
+ dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 oflag=direct
+
+ #define OBD_FAIL_OSC_BRW_PREP_REQ2 0x40a
+ lctl set_param fail_loc=0x8000040a
+ # let ll_prepare_partial_page() fail
+ dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
+
+ rm -f $DIR/$tfile
+
+ # create at least 100 unused inodes so that
+ # shrink_icache_memory(0) should not return 0
+ touch $DIR/$tfile-{0..100}
+ rm -f $DIR/$tfile-{0..100}
+ sync
+
+ echo 2 > /proc/sys/vm/drop_caches
+}
+run_test 408 "drop_caches should not hang due to page leaks"
+
#
# tests that do cleanup/setup should be run at the end
#