From: Edward Shishkin <edward.shishkin@gmail.com>
To: Sandro Souza <escovadordebits@gmail.com>
Cc: ReiserFS Development List <reiserfs-devel@vger.kernel.org>
Subject: Re: Testing a custom kernel (2.6.39) with native reiser4 support
Date: Mon, 21 May 2012 02:12:31 +0200 [thread overview]
Message-ID: <4FB9886F.9000607@gmail.com> (raw)
In-Reply-To: <CANish_kwKO1EUys-QS44oJeD1T7daFMn1QA0LdPC1ZVG6_RtOg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2334 bytes --]
Hello.
Please, try the attached patch: it should help...
I have also fixed a deadlock because of reiser4
lock ordering violation:
do_lo_send_aops() keeps page locked and calls file_update_time()
which calls reiser4_update_sd, which tries to acquire a longterm
lock (bad).
Thanks,
Edward.
On 05/15/2012 12:55 AM, Sandro Souza wrote:
> Hello my friends.
>
> I made a new custom distro based on debian squeeze, but with 2.6.39
> kernel, patched with reiser4
[...]
> Trying to copy a folder from a reiser3 partition to a reiser4
> partition, I got error messages.
>
> Testing my custom kernel with "preemption model" in "Preemptible
> Kernel", I got these messages:
>
> [ 286.945598] ------------[ cut here ]------------
> [ 286.945609] kernel BUG at fs/reiser4/block_alloc.c:151!
> [ 286.945617] invalid opcode: 0000 [#1] PREEMPT SMP
> [ 286.945626] last sysfs file:
[...]
> ffffffff8118e00d
> [ 286.945808] Call Trace:
> [ 286.945817] [<ffffffff8117b484>] ? jnode_make_dirty_locked+0x112/0x18f
> [ 286.945824] [<ffffffff8117b529>] ? znode_make_dirty+0x28/0x87
> [ 286.945831] [<ffffffff8118e00d>] ? update_sd+0x344/0x3a4
> [ 286.945838] [<ffffffff81387a46>] ? sub_preempt_count+0x83/0x94
> [ 286.945845] [<ffffffff8118e096>] ? write_sd_by_inode_common+0x29/0x92
> [ 286.945852] [<ffffffff8103cb67>] ? get_parent_ip+0x9/0x1b
> [ 286.945858] [<ffffffff8118512b>] ? reiser4_dirty_inode+0x19/0x73
> [ 286.945865] [<ffffffff810edecb>] ? T.1132+0x12/0x2e
> [ 286.945872] [<ffffffff8104b288>] ? current_fs_time+0x1e/0x24
> [ 286.945878] [<ffffffff81112ddb>] ? __mark_inode_dirty+0x28/0x1c8
> [ 286.945885] [<ffffffff81108169>] ? file_update_time+0xf7/0x126
> [ 286.945891] [<ffffffff811924ee>] ? reiser4_write_end_careful+0x147/0x184
> [ 286.945897] [<ffffffff81115083>] ? pipe_to_file+0x152/0x161
> [ 286.945903] [<ffffffff81387af5>] ? add_preempt_count+0x9e/0xa0
> [ 286.945909] [<ffffffff81114f31>] ? generic_file_splice_write+0x133/0x133
> [ 286.945914] [<ffffffff811143cb>] ? splice_from_pipe_feed+0x6d/0xed
> [ 286.945920] [<ffffffff81114eb3>] ? generic_file_splice_write+0xb5/0x133
> [ 286.945933] [<ffffffff811162a6>] ? sys_splice+0x2f8/0x3d2
> [ 286.945939] [<ffffffff8138a7d2>] ? system_call_fastpath+0x16/0x1b
> [ 286.945944] Code: 25 80 cc 00 00 53 48 83 ec 08 48 8b 80 38 05 00
[-- Attachment #2: reiser4-fix-reservation-and-deadlock.patch --]
[-- Type: text/plain, Size: 7859 bytes --]
Reserve space in reiser4_write_begin() properly:
1) for update_sd() when changing file szie;
2) for update_sd() when updating mtime/ctime
Fix deadlock (reiser4 lock ordering violation):
release page lock in reiser4_dirty_inode()
before aquiring a longterm lock.
Signed-off-by: Edward Shishkin <edward.shishkin@gmail.com>
---
fs/reiser4/context.h | 4 +++
fs/reiser4/plugin/file/cryptcompress.c | 29 +++++++++++++++++++--
fs/reiser4/plugin/file/file.c | 41 +++++++++++++++++++++----------
fs/reiser4/plugin/file/file_conversion.c | 11 +++-----
fs/reiser4/super_ops.c | 17 +++++++++---
5 files changed, 76 insertions(+), 26 deletions(-)
Index: linux-2.6.39/fs/reiser4/plugin/file/cryptcompress.c
===================================================================
--- linux-2.6.39.orig/fs/reiser4/plugin/file/cryptcompress.c
+++ linux-2.6.39/fs/reiser4/plugin/file/cryptcompress.c
@@ -1521,7 +1521,9 @@ static int update_sd_cryptcompress(struc
BA_CAN_COMMIT);
if (result)
return result;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ if (!IS_NOCMTIME(inode))
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
result = reiser4_update_sd(inode);
if (unlikely(result != 0))
@@ -3755,7 +3757,9 @@ int write_begin_cryptcompress(struct fil
struct reiser4_slide *win;
struct cluster_handle *clust;
struct cryptcompress_info *info;
+ reiser4_context *ctx;
+ ctx = get_current_context();
inode = page->mapping->host;
info = cryptcompress_inode_data(inode);
@@ -3789,9 +3793,13 @@ int write_begin_cryptcompress(struct fil
ClearPageUptodate(page);
goto err0;
}
- /* Success. All resources (including checkin_mutex)
- will be released in ->write_end() */
+ /*
+ * Success. All resources (including checkin_mutex)
+ * will be released in ->write_end()
+ */
+ ctx->locked_page = page;
*fsdata = (void *)buf;
+
return 0;
err0:
put_cluster_handle(clust);
@@ -3812,15 +3820,18 @@ int write_end_cryptcompress(struct file
struct inode *inode;
struct cluster_handle *clust;
struct cryptcompress_info *info;
+ reiser4_context *ctx;
assert("edward-1566",
lock_stack_isclean(get_current_lock_stack()));
+ ctx = get_current_context();
inode = page->mapping->host;
info = cryptcompress_inode_data(inode);
clust = (struct cluster_handle *)fsdata;
hint = clust->hint;
unlock_page(page);
+ ctx->locked_page = NULL;
set_cluster_pages_dirty(clust, inode);
ret = checkin_logical_cluster(clust, inode);
if (ret) {
@@ -3831,6 +3842,18 @@ int write_end_cryptcompress(struct file
mutex_unlock(&info->checkin_mutex);
put_cluster_handle(clust);
+
+ if (pos + copied > inode->i_size) {
+ /*
+ * i_size has been updated in
+ * checkin_logical_cluster
+ */
+ ret = reiser4_update_sd(inode);
+ if (unlikely(ret != 0))
+ warning("edward-1603",
+ "Can not update stat-data: %i. FSCK?",
+ ret);
+ }
kfree(fsdata);
return ret;
}
Index: linux-2.6.39/fs/reiser4/plugin/file/file.c
===================================================================
--- linux-2.6.39.orig/fs/reiser4/plugin/file/file.c
+++ linux-2.6.39/fs/reiser4/plugin/file/file.c
@@ -2128,6 +2128,7 @@ ssize_t write_unix_file(struct file *fil
new_size = *pos + count;
while (left) {
+ int update_sd = 0;
if (left < to_write)
to_write = left;
@@ -2239,18 +2240,27 @@ ssize_t write_unix_file(struct file *fil
assert("edward-1555",
ergo(uf_info->container == UF_CONTAINER_TAILS,
write_op == reiser4_write_tail));
- if (*pos + written > inode->i_size)
+ if (*pos + written > inode->i_size) {
INODE_SET_FIELD(inode, i_size, *pos + written);
- file_update_time(file);
- /* space for update_sd was reserved in write_op */
- result = reiser4_update_sd(inode);
- if (result) {
- warning("edward-1574",
- "Can not update stat-data: %i. FSCK?",
- result);
- drop_access(uf_info);
- context_set_commit_async(ctx);
- break;
+ update_sd = 1;
+ }
+ if (!IS_NOCMTIME(inode)) {
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ update_sd = 1;
+ }
+ if (update_sd) {
+ /*
+ * space for update_sd was reserved in write_op
+ */
+ result = reiser4_update_sd(inode);
+ if (result) {
+ warning("edward-1574",
+ "Can not update stat-data: %i. FSCK?",
+ result);
+ drop_access(uf_info);
+ context_set_commit_async(ctx);
+ break;
+ }
}
drop_access(uf_info);
ea = NEITHER_OBTAINED;
@@ -2768,14 +2778,19 @@ int write_end_unix_file(struct file *fil
SetPageError(page);
goto exit;
}
- if (pos + copied > inode->i_size)
+ if (pos + copied > inode->i_size) {
INODE_SET_FIELD(inode, i_size, pos + copied);
+ ret = reiser4_update_sd(inode);
+ if (unlikely(ret != 0))
+ warning("edward-1604",
+ "Can not update stat-data: %i. FSCK?",
+ ret);
+ }
exit:
drop_exclusive_access(info);
return ret;
}
-
/*
* Local variables:
* c-indentation-style: "K&R"
Index: linux-2.6.39/fs/reiser4/plugin/file/file_conversion.c
===================================================================
--- linux-2.6.39.orig/fs/reiser4/plugin/file/file_conversion.c
+++ linux-2.6.39/fs/reiser4/plugin/file/file_conversion.c
@@ -671,9 +671,11 @@ int reiser4_write_begin_careful(struct f
ret = PTR_ERR(ctx);
goto err2;
}
- ret = reiser4_grab_space_force(/* one for stat data update */
- estimate_update_common(inode),
- BA_CAN_COMMIT);
+ ret = reiser4_grab_space_force(/* for update_sd:
+ * one when updating file size and
+ * one when updating mtime/ctime */
+ 2 * estimate_update_common(inode),
+ BA_CAN_COMMIT);
if (ret)
goto err1;
ret = PROT_PASSIVE(int, write_begin, (file, page, pos, len, fsdata));
@@ -713,9 +715,6 @@ int reiser4_write_end_careful(struct fil
ret = PROT_PASSIVE(int, write_end, (file, page, pos, copied, fsdata));
page_cache_release(page);
- file_update_time(file);
- /* space for update_sd was reserved in reiser4_write_begin */
- ret = reiser4_update_sd(inode);
/* don't commit transaction under inode semaphore */
context_set_commit_async(ctx);
reiser4_exit_context(ctx);
Index: linux-2.6.39/fs/reiser4/context.h
===================================================================
--- linux-2.6.39.orig/fs/reiser4/context.h
+++ linux-2.6.39/fs/reiser4/context.h
@@ -87,6 +87,10 @@ struct reiser4_context {
* flushed */
int nr_captured;
int nr_children; /* number of child contexts */
+ struct page *locked_page; /* page that should be unlocked in
+ * reiser4_dirty_inode() before taking
+ * a longterm lock (to not violate
+ * reiser4 lock ordering) */
#if REISER4_DEBUG
/* debugging information about reiser4 locks held by the current
* thread */
Index: linux-2.6.39/fs/reiser4/super_ops.c
===================================================================
--- linux-2.6.39.orig/fs/reiser4/super_ops.c
+++ linux-2.6.39/fs/reiser4/super_ops.c
@@ -166,16 +166,25 @@ static void reiser4_destroy_inode(struct
static void reiser4_dirty_inode(struct inode *inode)
{
int result;
+ reiser4_context *ctx;
if (!is_in_reiser4_context())
return;
- assert("", !IS_RDONLY(inode));
- assert("", (inode_file_plugin(inode)->estimate.update(inode) <=
- get_current_context()->grabbed_blocks));
+ assert("edward-1606", !IS_RDONLY(inode));
+ assert("edward-1607",
+ (inode_file_plugin(inode)->estimate.update(inode) <=
+ get_current_context()->grabbed_blocks));
+
+ ctx = get_current_context();
+ if (ctx->locked_page)
+ unlock_page(ctx->locked_page);
result = reiser4_update_sd(inode);
+
+ if (ctx->locked_page)
+ lock_page(ctx->locked_page);
if (result)
- warning("", "failed to dirty inode for %llu: %d",
+ warning("edward-1605", "failed to dirty inode for %llu: %d",
get_inode_oid(inode), result);
}
next prev parent reply other threads:[~2012-05-21 0:12 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-14 22:55 Testing a custom kernel (2.6.39) with native reiser4 support Sandro Souza
2012-05-15 10:12 ` Edward Shishkin
2012-05-15 11:14 ` Edward Shishkin
2012-05-15 11:49 ` Edward Shishkin
2012-05-21 0:12 ` Edward Shishkin [this message]
2012-05-24 17:53 ` Sandro Souza
2012-05-24 18:45 ` Edward Shishkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FB9886F.9000607@gmail.com \
--to=edward.shishkin@gmail.com \
--cc=escovadordebits@gmail.com \
--cc=reiserfs-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).