}
+#endif
+
+/*
+ * Called by reiser4_sync_inodes(), during speculative write-back (through
+ * pdflush, or balance_dirty_pages()).
+ */
+static void
+writeout(struct super_block *sb, struct writeback_control *wbc)
+{
+ long written = 0;
+ int repeats = 0;
+
+ /*
+ * Performs early flushing, trying to free some memory. If there is
+ * nothing to flush, commits some atoms.
+ */
+
+ /* Commit all atoms if reiser4_writepages() is called from sys_sync() or
+ sys_fsync(). */
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ txnmgr_force_commit_all(sb, 1);
+ return;
+ }
+
+ do {
+ long nr_submitted = 0;
+ struct inode *fake;
+
+ fake = get_super_fake(sb);
+ if (fake != NULL) {
+ struct address_space *mapping;
+
+ mapping = fake->i_mapping;
+ /* do not put more requests to overload write queue */
+ if (wbc->nonblocking &&
+ bdi_write_congested(mapping->backing_dev_info)) {
+ blk_run_address_space(mapping);
+ wbc->encountered_congestion = 1;
+ break;
+ }
+ }
+ repeats ++;
+ flush_some_atom(&nr_submitted, wbc, JNODE_FLUSH_WRITE_BLOCKS);
+ if (!nr_submitted)
+ break;
+
+ wbc->nr_to_write -= nr_submitted;
+ written += nr_submitted;
+
+ } while (wbc->nr_to_write > 0);
+
+}
/* reiser4 writepages() address space operation this captures anonymous pages
and anonymous jnodes. Anonymous pages are pages which are dirtied via
@@ -578,10 +630,13 @@ reiser4_internal int
reiser4_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
+ reiser4_context ctx;
int ret = 0;
struct inode *inode;
file_plugin *fplug;
diff -puN fs/reiser4/plugin/item/tail.c~reiser4-no-inode_lock fs/reiser4/plugin/item/tail.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/item/tail.c~reiser4-no-inode_lock 2005-05-04 13:24:19.169042015 +0400
+++ linux-2.6.12-rc2-mm3-vs/fs/reiser4/plugin/item/tail.c 2005-05-04 13:24:19.240047525 +0400
@@ -481,8 +481,6 @@ tail_balance_dirty_pages(struct address_
/* FIXME-VS: this is temporary: the problem is that bdp takes
inodes from sb's dirty list and it looks like nobody puts
there inodes of files which are built of tails */
- move_inode_out_from_sync_inodes_loop(mapping);
-
uf_info = unix_file_inode_data(inode);
excl = unix_file_inode_data(inode)->exclusive_use;
if (excl)
diff -puN fs/reiser4/vfs_ops.c~reiser4-no-inode_lock fs/reiser4/vfs_ops.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/vfs_ops.c~reiser4-no-inode_lock 2005-05-04 13:24:19.183043102 +0400
+++ linux-2.6.12-rc2-mm3-vs/fs/reiser4/vfs_ops.c 2005-05-04 17:13:47.688704737 +0400
@@ -47,7 +47,6 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/quotaops.h>
#include <linux/security.h>
@@ -555,92 +554,35 @@ reiser4_put_inode(struct inode *inode)
reiser4_exit_context(&ctx);
}
-/*
- * Called by reiser4_sync_inodes(), during speculative write-back (through
- * pdflush, or balance_dirty_pages()).
- */
+/* ->sync_inodes() method. This is called by pdflush, and synchronous
+ * writeback (throttling by balance_dirty_pages()). */
static void
-writeout(struct super_block *sb, struct writeback_control *wbc)
+reiser4_sync_inodes(struct super_block *sb, struct writeback_control *wbc)
{
- long written = 0;
- int repeats = 0;
-
- /*
- * Performs early flushing, trying to free some memory. If there is
- * nothing to flush, commits some atoms.
- */
+ struct reiser4_wbc r4_wbc;
/* reiser4 has its own means of periodical write-out */
if (wbc->for_kupdate)
return;
- /* Commit all atoms if reiser4_writepages() is called from sys_sync() or
- sys_fsync(). */
- if (wbc->sync_mode != WB_SYNC_NONE) {
- txnmgr_force_commit_all(sb, 1);
- return;
- }
-
- do {
- long nr_submitted = 0;
- struct inode *fake;
-
- fake = get_super_fake(sb);
- if (fake != NULL) {
- struct address_space *mapping;
-
- mapping = fake->i_mapping;
- /* do not put more requests to overload write queue */
- if (wbc->nonblocking &&
- bdi_write_congested(mapping->backing_dev_info)) {
-
- blk_run_address_space(mapping);
- /*blk_run_queues();*/
- wbc->encountered_congestion = 1;
- break;
- }
- }
- repeats ++;
- flush_some_atom(&nr_submitted, wbc, JNODE_FLUSH_WRITE_BLOCKS);
- if (!nr_submitted)
- break;
-
- wbc->nr_to_write -= nr_submitted;
-
- written += nr_submitted;
-
- } while (wbc->nr_to_write > 0);
-
-}
-
-/* ->sync_inodes() method. This is called by pdflush, and synchronous
- * writeback (throttling by balance_dirty_pages()). */
-static void
-reiser4_sync_inodes(struct super_block * sb, struct writeback_control * wbc)
-{
- reiser4_context ctx;
-
- init_context(&ctx, sb);
- wbc->older_than_this = NULL;
+ assert("", wbc->older_than_this == NULL);
+ r4_wbc.wbc = *wbc;
+ r4_wbc.first = 1;
+ r4_wbc.magic = REISER4_WBC_MAGIC;
/*
- * What we are trying to do here is to capture all "anonymous" pages.
+ * call reiser4_writepages for sb's dirty inodes. First of them will do
+ * writeout
*/
- generic_sync_sb_inodes(sb, wbc);
- /*capture_reiser4_inodes(sb, wbc);*/
- spin_unlock(&inode_lock);
- writeout(sb, wbc);
-
- /* avoid recursive calls to ->sync_inodes */
- context_set_commit_async(&ctx);
- reiser4_exit_context(&ctx);
- spin_lock(&inode_lock);
+ generic_sync_sb_inodes(sb, &r4_wbc.wbc);
+ *wbc = r4_wbc.wbc;
}
- result = 0;
+ /* can not continue having transaction opened. It would deadlock with
+ reiser4_writepages/writeout which runs having inode locked */
+ txn_restart_current();
/* call iget(). Our ->read_inode() is dummy, so this will either
find inode in cache or return uninitialised inode */
@@ -439,6 +441,7 @@ reiser4_iget(struct super_block *super /
info->loading. The place in reiser4 which uses not initialized inode
is the reiser4 repacker, see repacker-related functions in
plugin/item/extent.c */
+ result = 0;
if (!is_inode_loaded(inode)) {
loading_down(info);
if (!is_inode_loaded(inode)) {
diff -puN fs/reiser4/txnmgr.c~reiser4-no-inode_lock fs/reiser4/txnmgr.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/txnmgr.c~reiser4-no-inode_lock 2005-05-04 17:07:08.392264602 +0400
+++ linux-2.6.12-rc2-mm3-vs/fs/reiser4/txnmgr.c 2005-05-04 17:13:00.072900260 +0400
@@ -526,6 +526,7 @@ txn_end(reiser4_context * context)
reiser4_internal void
txn_restart(reiser4_context * context)
{
+ assert("", context == get_current_context());
txn_end(context);
preempt_point();
txn_begin(context);
@@ -535,6 +536,7 @@ reiser4_internal void
txn_restart_current(void)
{
txn_restart(get_current_context());
+ grab_space_enable();
}