2009-11-28 06:27:33

by Johannes Buchner

[permalink] [raw]
Subject: [PATCH 0/4] reiser4 fixes for -mm

These are the same patches as a previous email with the subject
'Re: Fw: reiser4 git repo', but without MIME.

The content of my previous mail:

> I had some issues with the reiser4 patch series from -mm.
> First of all, I'm not sure what release they are based on. I used
> a8a8a669e from Linus' git repository. I applied all reiser4 patches
> (except reiser4-disable of course) from
> http://userweb.kernel.org/~akpm/mmotm/, which worked fine.
>
> I think these patches are based on the reiser4-2.6.30 patch.
> I also compared them to the reiser4-2.6.31 patch, which adds some
> missing pieces ([1] reiser4-from-2.6.31-patch.patch).
>
> Additionally, some recent commits demand some changes, especially
> since current_is_pdflush and generic_sync_sb_inodes are not available
> any more (d8a8559cd7a9cc).
> [2] reiser4-pdflush-comments.patch only fixes some comments which
> still mention pdflush.
> In [3] reiser4-generic_sync_sb_inodes.patch I tried to
> replace generic_sync_sb_inodes. I am not 100% sure that this is
> correct, but that is what I understood from the commit diff+message of
> d8a8559cd7a9cc.
>
> The original patch
> 'reiser4-vfs-add-super_operationssync_inodes' introduced the call from
> sync_inodes_sb to the super operation sync_inodes(sb, NULL). This NULL
> pointer is dereferenced in reiser4_sync_inodes, which is fixed by
> [4] reiser4-sync_inodes-null-dereference.patch.
>
> All 4 additional patches are attached. I can only say that it works on
> my machine, before I had compilation issues and freezes on 'sync'.
>
> Cheers,
> Johannes
>
> PS: The git repo mentioned in
> http://userweb.kernel.org/~akpm/mmotm/mmotm-readme.txt is not
> available.


Johannes Buchner (4):
reiser4: some changes from reiser4-2.6.31 patch
reiser4: some comments were still mentioning pdflush
reiser4: generic_sync_sb_inodes doesn't exist anymore
reiser4: fixed null pointer dereference

fs/reiser4/carry.c | 2 +-
fs/reiser4/carry_ops.c | 2 +-
fs/reiser4/context.c | 2 +-
fs/reiser4/coord.c | 8 ++++----
fs/reiser4/entd.c | 4 +++-
fs/reiser4/super_ops.c | 6 ++++--
fs/reiser4/txnmgr.c | 4 ++--
fs/reiser4/znode.h | 1 -
include/linux/mm.h | 1 +
mm/filemap.c | 4 +++-
mm/page-writeback.c | 26 ++++++++++++++++++++++++++
11 files changed, 46 insertions(+), 14 deletions(-)


2009-11-28 06:27:51

by Johannes Buchner

[permalink] [raw]
Subject: [PATCH 1/4] reiser4: some changes from reiser4-2.6.31 patch

from
http://www.kernel.org/pub/linux/kernel/people/edward/reiser4/reiser4-for-2.6/
---
fs/reiser4/carry.c | 2 +-
fs/reiser4/carry_ops.c | 2 +-
fs/reiser4/coord.c | 8 ++++----
fs/reiser4/entd.c | 2 +-
fs/reiser4/super_ops.c | 2 +-
fs/reiser4/znode.h | 1 -
include/linux/mm.h | 1 +
mm/filemap.c | 4 +++-
mm/page-writeback.c | 26 ++++++++++++++++++++++++++
9 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/fs/reiser4/carry.c b/fs/reiser4/carry.c
index f2f1422..13a03f4 100644
--- a/fs/reiser4/carry.c
+++ b/fs/reiser4/carry.c
@@ -1095,7 +1095,7 @@ static void fatal_carry_error(carry_level * doing UNUSED_ARG /* carry level
*
* This function itself only manages changes in carry structures and delegates
* all hard work (allocation of znode for new root, changes of parent and
- * sibling pointers to the reiser4_add_tree_root().
+ * sibling pointers) to the reiser4_add_tree_root().
*
* Locking: old tree root is locked by carry at this point. Fake znode is also
* locked.
diff --git a/fs/reiser4/carry_ops.c b/fs/reiser4/carry_ops.c
index 0906dbd..4fe0e6e 100644
--- a/fs/reiser4/carry_ops.c
+++ b/fs/reiser4/carry_ops.c
@@ -2015,7 +2015,7 @@ static int carry_estimate_bitmaps(void)
int bytes;

bytes = capped_height() * (0 + /* bnode should be added, but
- * its is private to bitmap.c,
+ * it is private to bitmap.c,
* skip for now. */
2 * sizeof(jnode));
/* working and commit jnodes */
diff --git a/fs/reiser4/coord.c b/fs/reiser4/coord.c
index e37e2f9..5c34e0a 100644
--- a/fs/reiser4/coord.c
+++ b/fs/reiser4/coord.c
@@ -36,12 +36,12 @@ void coord_normalize(coord_t *coord)

coord_clear_iplug(coord);

- if (node_is_empty(node))
+ if (node_is_empty(node)) {
coord_init_first_unit(coord, node);
- else if ((coord->between == AFTER_ITEM)
- || (coord->between == AFTER_UNIT))
+ } else if ((coord->between == AFTER_ITEM)
+ || (coord->between == AFTER_UNIT)) {
return;
- else if (coord->item_pos == coord_num_items(coord)
+ } else if (coord->item_pos == coord_num_items(coord)
&& coord->between == BEFORE_ITEM) {
coord_dec_item_pos(coord);
coord->between = AFTER_ITEM;
diff --git a/fs/reiser4/entd.c b/fs/reiser4/entd.c
index 4ea64a8..f41f62d 100644
--- a/fs/reiser4/entd.c
+++ b/fs/reiser4/entd.c
@@ -241,7 +241,7 @@ static void entd_flush(struct super_block *super, struct wbq *rq)
if (rq->wbc->nr_to_write > 0) {
rq->wbc->range_start = 0;
rq->wbc->range_end = LLONG_MAX;
- generic_sync_sb_inodes(rq->wbc);
+ generic_sync_sb_inodes(super, rq->wbc);
}
rq->wbc->nr_to_write = ENTD_CAPTURE_APAGE_BURST;
reiser4_writeout(super, rq->wbc);
diff --git a/fs/reiser4/super_ops.c b/fs/reiser4/super_ops.c
index efc2d7b..85e6841 100644
--- a/fs/reiser4/super_ops.c
+++ b/fs/reiser4/super_ops.c
@@ -412,7 +412,7 @@ static void reiser4_sync_inodes(struct super_block *super,
* call reiser4_writepages for each of dirty inodes to turn dirty pages
* into transactions if they were not yet.
*/
- generic_sync_sb_inodes(wbc);
+ generic_sync_sb_inodes(super, wbc);

/* flush goes here */
wbc->nr_to_write = to_write;
diff --git a/fs/reiser4/znode.h b/fs/reiser4/znode.h
index 4894e92..7e84371 100644
--- a/fs/reiser4/znode.h
+++ b/fs/reiser4/znode.h
@@ -18,7 +18,6 @@

#include <linux/types.h>
#include <linux/spinlock.h>
-#include <linux/semaphore.h>
#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */
#include <asm/atomic.h>

diff --git a/include/linux/mm.h b/include/linux/mm.h
index e935946..f185d15 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -836,6 +836,7 @@ int redirty_page_for_writepage(struct writeback_control *wbc,
void account_page_dirtied(struct page *page, struct address_space *mapping);
int set_page_dirty(struct page *page);
int set_page_dirty_lock(struct page *page);
+int set_page_dirty_notag(struct page *page);
int clear_page_dirty_for_io(struct page *page);

extern unsigned long move_page_tables(struct vm_area_struct *vma,
diff --git a/mm/filemap.c b/mm/filemap.c
index 429489b..e7c57d5 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -139,6 +139,7 @@ void __remove_from_page_cache(struct page *page)
dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
}
}
+EXPORT_SYMBOL(__remove_from_page_cache);

void remove_from_page_cache(struct page *page)
{
@@ -151,6 +152,7 @@ void remove_from_page_cache(struct page *page)
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
}
+EXPORT_SYMBOL(remove_from_page_cache);

static int sync_page(void *word)
{
@@ -800,7 +802,6 @@ repeat:
rcu_read_unlock();
return ret;
}
-EXPORT_SYMBOL(find_get_pages);

/**
* find_get_pages_contig - gang contiguous pagecache lookup
@@ -970,6 +971,7 @@ static void shrink_readahead_size_eio(struct file *filp,
{
ra->ra_pages /= 4;
}
+EXPORT_SYMBOL(find_get_pages);

/**
* do_generic_file_read - generic file read routine
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 6d5d74f..8cfd5f0 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1143,6 +1143,32 @@ int __set_page_dirty_nobuffers(struct page *page)
EXPORT_SYMBOL(__set_page_dirty_nobuffers);

/*
+ * set_page_dirty_notag() -- similar to __set_page_dirty_nobuffers()
+ * except it doesn't tag the page dirty in the page-cache radix tree.
+ * This means that the address space using this cannot use the regular
+ * filemap ->writepages() helpers and must provide its own means of
+ * tracking and finding non-tagged dirty pages.
+ *
+ * NOTE: furthermore, this version also doesn't handle truncate races.
+ */
+int set_page_dirty_notag(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+
+ if (!TestSetPageDirty(page)) {
+ unsigned long flags;
+ WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page));
+ local_irq_save(flags);
+ account_page_dirtied(page, mapping);
+ local_irq_restore(flags);
+ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(set_page_dirty_notag);
+
+/*
* When a writepage implementation decides that it doesn't want to write this
* page for some reason, it should redirty the locked page via
* redirty_page_for_writepage() and it should then unlock the page and return 0
--
1.6.4.4

2009-11-28 06:27:54

by Johannes Buchner

[permalink] [raw]
Subject: [PATCH 2/4] reiser4: some comments were still mentioning pdflush

---
fs/reiser4/context.c | 2 +-
fs/reiser4/txnmgr.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/reiser4/context.c b/fs/reiser4/context.c
index eed3efa..248a21f 100644
--- a/fs/reiser4/context.c
+++ b/fs/reiser4/context.c
@@ -147,7 +147,7 @@ static void reiser4_throttle_write_at(reiser4_context *context)
* call balance_dirty_pages_ratelimited() to process formatted nodes
* dirtied during this system call. Do that only if we are not in mount
* and there were nodes dirtied in this context and we are not in
- * writepage (to avoid deadlock) and not in pdflush
+ * writepage (to avoid deadlock)
*/
if (sbinfo != NULL && sbinfo->fake != NULL &&
context->nr_marked_dirty != 0 &&
diff --git a/fs/reiser4/txnmgr.c b/fs/reiser4/txnmgr.c
index 74b49f2..844d19e 100644
--- a/fs/reiser4/txnmgr.c
+++ b/fs/reiser4/txnmgr.c
@@ -1360,7 +1360,7 @@ static int txn_try_to_fuse_small_atom(txn_mgr * tmgr, txn_atom * atom)
code tries to flush current atom.

flush_some_atom() is called as part of memory clearing process. It is
- invoked from balance_dirty_pages(), pdflushd, and entd.
+ invoked from balance_dirty_pages() and entd.

If we can flush no nodes, atom is committed, because this frees memory.

@@ -1469,7 +1469,7 @@ flush_some_atom(jnode * start, long *nr_submitted, const struct writeback_contro
* or atom is too old/large,
* we force current atom to commit */
/* wait for commit completion but only if this
- * wouldn't stall pdflushd and ent thread. */
+ * wouldn't stall ent thread. */
if (!wbc->nonblocking && !ctx->entd)
txnh->flags |= TXNH_WAIT_COMMIT;
atom->flags |= ATOM_FORCE_COMMIT;
--
1.6.4.4

2009-11-28 06:27:55

by Johannes Buchner

[permalink] [raw]
Subject: [PATCH 3/4] reiser4: generic_sync_sb_inodes doesn't exist anymore

generic_sync_sb_inodes was removed in d8a8559cd7a9cc, writeback_inodes_sb
and sync_inodes_sb should replace them.
---
fs/reiser4/entd.c | 4 +++-
fs/reiser4/super_ops.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/reiser4/entd.c b/fs/reiser4/entd.c
index f41f62d..3a26451 100644
--- a/fs/reiser4/entd.c
+++ b/fs/reiser4/entd.c
@@ -241,7 +241,9 @@ static void entd_flush(struct super_block *super, struct wbq *rq)
if (rq->wbc->nr_to_write > 0) {
rq->wbc->range_start = 0;
rq->wbc->range_end = LLONG_MAX;
- generic_sync_sb_inodes(super, rq->wbc);
+ writeback_inodes_sb(super);
+ if (rq->wbc->sync_mode == WB_SYNC_ALL)
+ sync_inodes_sb(super);
}
rq->wbc->nr_to_write = ENTD_CAPTURE_APAGE_BURST;
reiser4_writeout(super, rq->wbc);
diff --git a/fs/reiser4/super_ops.c b/fs/reiser4/super_ops.c
index 85e6841..0c09e3e 100644
--- a/fs/reiser4/super_ops.c
+++ b/fs/reiser4/super_ops.c
@@ -412,7 +412,9 @@ static void reiser4_sync_inodes(struct super_block *super,
* call reiser4_writepages for each of dirty inodes to turn dirty pages
* into transactions if they were not yet.
*/
- generic_sync_sb_inodes(super, wbc);
+ writeback_inodes_sb(super);
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ sync_inodes_sb(super);

/* flush goes here */
wbc->nr_to_write = to_write;
--
1.6.4.4

2009-11-28 06:28:12

by Johannes Buchner

[permalink] [raw]
Subject: [PATCH 4/4] reiser4: fixed null pointer dereference

The parameter wbc=NULL caused a NULL pointer dereference in
reiser4_sync_inodes.
This issue was introduced in patch reiser4-vfs-add-super_operationssync_inodes
---
fs/reiser4/super_ops.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/reiser4/super_ops.c b/fs/reiser4/super_ops.c
index 0c09e3e..f72d42a 100644
--- a/fs/reiser4/super_ops.c
+++ b/fs/reiser4/super_ops.c
@@ -395,7 +395,7 @@ static void reiser4_sync_inodes(struct super_block *super,
reiser4_context *ctx;
long to_write;

- if (wbc->for_kupdate)
+ if (wbc == NULL || wbc->for_kupdate)
/* reiser4 has its own means of periodical write-out */
return;

--
1.6.4.4

2009-11-29 11:28:29

by Johannes Buchner

[permalink] [raw]
Subject: Re: [PATCH 1/4] reiser4: some changes from reiser4-2.6.31 patch

> from
> http://www.kernel.org/pub/linux/kernel/people/edward/reiser4/reiser4-for-2.6/
I'm sorry, I did not see half of this is already covered by
vfs-take-2add-set_page_dirty_notag.patch. With that part removed,
this patch is only cosmetics now.

---
fs/reiser4/carry.c | 2 +-
fs/reiser4/carry_ops.c | 2 +-
fs/reiser4/znode.h | 1 -
mm/filemap.c | 2 +-
4 files changed, 3 insertions(+), 4 deletions(-)

Index: linux/fs/reiser4/carry.c
===================================================================
--- linux.orig/fs/reiser4/carry.c
+++ linux/fs/reiser4/carry.c
@@ -1095,7 +1095,7 @@ static void fatal_carry_error(carry_leve
*
* This function itself only manages changes in carry structures and delegates
* all hard work (allocation of znode for new root, changes of parent and
- * sibling pointers to the reiser4_add_tree_root().
+ * sibling pointers) to the reiser4_add_tree_root().
*
* Locking: old tree root is locked by carry at this point. Fake znode is also
* locked.
Index: linux/fs/reiser4/carry_ops.c
===================================================================
--- linux.orig/fs/reiser4/carry_ops.c
+++ linux/fs/reiser4/carry_ops.c
@@ -2015,7 +2015,7 @@ static int carry_estimate_bitmaps(void)
int bytes;

bytes = capped_height() * (0 + /* bnode should be added, but
- * its is private to bitmap.c,
+ * it is private to bitmap.c,
* skip for now. */
2 * sizeof(jnode));
/* working and commit jnodes */
Index: linux/fs/reiser4/znode.h
===================================================================
--- linux.orig/fs/reiser4/znode.h
+++ linux/fs/reiser4/znode.h
@@ -18,7 +18,6 @@

#include <linux/types.h>
#include <linux/spinlock.h>
-#include <linux/semaphore.h>
#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */
#include <asm/atomic.h>

Index: linux/mm/filemap.c
===================================================================
--- linux.orig/mm/filemap.c
+++ linux/mm/filemap.c
@@ -800,7 +802,6 @@ repeat:
rcu_read_unlock();
return ret;
}
-EXPORT_SYMBOL(find_get_pages);

/**
* find_get_pages_contig - gang contiguous pagecache lookup
@@ -970,6 +971,7 @@ static void shrink_readahead_size_eio(st
{
ra->ra_pages /= 4;
}
+EXPORT_SYMBOL(find_get_pages);

/**
* do_generic_file_read - generic file read routine

2009-11-29 11:28:38

by Johannes Buchner

[permalink] [raw]
Subject: Re: [PATCH 3/4] reiser4: generic_sync_sb_inodes doesn't exist anymore

> generic_sync_sb_inodes was removed in d8a8559cd7a9cc,
> writeback_inodes_sb and sync_inodes_sb should replace them.
Second version, now also fixes the last comments relating to
generic_sync_sb_inodes.

---
fs/reiser4/context.h | 2 +-
fs/reiser4/entd.c | 4 +++-
fs/reiser4/super_ops.c | 6 ++++--
3 files changed, 8 insertions(+), 4 deletions(-)

Index: linux/fs/reiser4/entd.c
===================================================================
--- linux.orig/fs/reiser4/entd.c
+++ linux/fs/reiser4/entd.c
@@ -241,7 +241,9 @@ static void entd_flush(struct super_bloc
if (rq->wbc->nr_to_write > 0) {
rq->wbc->range_start = 0;
rq->wbc->range_end = LLONG_MAX;
- generic_sync_sb_inodes(rq->wbc);
+ writeback_inodes_sb(super);
+ if (rq->wbc->sync_mode == WB_SYNC_ALL)
+ sync_inodes_sb(super);
}
rq->wbc->nr_to_write = ENTD_CAPTURE_APAGE_BURST;
reiser4_writeout(super, rq->wbc);
Index: linux/fs/reiser4/super_ops.c
===================================================================
--- linux.orig/fs/reiser4/super_ops.c
+++ linux/fs/reiser4/super_ops.c
@@ -384,7 +384,7 @@ static void reiser4_clear_inode(struct i
* @wbc:
*
* This method is called by background and non-backgound writeback. Reiser4's
- * implementation uses generic_sync_sb_inodes to call reiser4_writepages for
+ * implementation uses writeback/sync_inodes_sb to call reiser4_writepages for
* each of dirty inodes. Reiser4_writepages handles pages dirtied via shared
* mapping - dirty pages get into atoms. Writeout is called to flush some
* atoms.
@@ -412,7 +412,9 @@ static void reiser4_sync_inodes(struct s
* call reiser4_writepages for each of dirty inodes to turn dirty pages
* into transactions if they were not yet.
*/
- generic_sync_sb_inodes(wbc);
+ writeback_inodes_sb(super);
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ sync_inodes_sb(super);

/* flush goes here */
wbc->nr_to_write = to_write;
Index: linux/fs/reiser4/context.h
===================================================================
--- linux.orig/fs/reiser4/context.h
+++ linux/fs/reiser4/context.h
@@ -66,7 +66,7 @@ struct reiser4_context {
/* count non-trivial jnode_set_dirty() calls */
unsigned long nr_marked_dirty;

- /* reiser4_sync_inodes calls (via generic_sync_sb_inodes)
+ /* reiser4_sync_inodes calls (via writeback/sync_inodes_sb)
* reiser4_writepages for each of dirty inodes. Reiser4_writepages
* captures pages. When number of pages captured in one
* reiser4_sync_inodes reaches some threshold - some atoms get