* raid0 and rfs4
@ 2004-01-13 5:00 Bret Towe
2004-01-13 10:37 ` Nikita Danilov
2004-01-13 13:38 ` Nikita Danilov
0 siblings, 2 replies; 10+ messages in thread
From: Bret Towe @ 2004-01-13 5:00 UTC (permalink / raw
To: reiserfs-list
i recently tried reiser4 on a raid0 setup and well it didnt go so well
:\
what i got from dmesg was the following
dmesg was full up when i finally looked of the raid_make_request
all of those lines looked about the same cept the last 2 numbers
raid0_make_request bug: can't convert block across chunks or bigger than
512k 356200 124
raid0_make_request bug: can't convert block across chunks or bigger than 512k 357352 124
raid0_make_request bug: can't convert block across chunks or bigger than 512k 358344 60
Unable to handle kernel NULL pointer dereference at virtual address 00000004
printing eip:
c021706f
*pde = 00000000
Oops: 0000 [#1]
CPU: 0
EIP: 0060:[<c021706f>] Not tainted
EFLAGS: 00010246
EIP is at reiser4_status_write+0xef/0x250
eax: 00000000 ebx: d3f4e000 ecx: c0425640 edx: 13fc5000
esi: 00000000 edi: 00000000 ebp: d3f4fe04 esp: d3f4fdd8
ds: 007b es: 007b ss: 0068
Process ktxnmgrd:run (pid: 993, threadinfo=d3f4e000 task=d4761310)
Stack: d1aa7ed8 d1aa7ba4 d5dd9580 d3f5ce00 00000000 00000000 00000002 00000000
d3f5ce00 d3f5de80 00000000 d3f4e000 c0211034 00000002 00000000 00000000
00000000 c03dd57e d42e24c0 d42e24c0 c020a965 d42e24c0 d3f4fe50 d3f5de80
Call Trace:
[<c0211034>] reiser4_handle_error+0x44/0xe0
[<c020a965>] finish_all_fq+0xa5/0xb0
[<c020a993>] current_atom_finish_all_fq+0x23/0x70
[<c01fc74e>] current_atom_complete_writes+0xe/0x30
[<c01fc885>] commit_current_atom+0x115/0x250
[<c010b8ba>] apic_timer_interrupt+0x1a/0x20
[<c01fd33a>] try_commit_txnh+0x12a/0x1c0
[<c01fd408>] commit_txnh+0x38/0xd0
[<c01fbbdf>] txn_end+0x3f/0x50
[<c01fcdd4>] commit_some_atoms+0x184/0x210
[<c020b736>] scan_mgr+0x36/0x57
[<c020b388>] ktxnmgrd+0x1a8/0x290
[<c020b1e0>] ktxnmgrd+0x0/0x290
[<c0108c29>] kernel_thread_helper+0x5/0xc
Code: 8b 48 04 31 c0 89 82 3c 00 00 c0 89 8a 38 00 00 c0 8b 45 00
<6>note: ktxnmgrd:run[993] exited with preempt_count 1
the system is a dual pentium pro 200mhz (feel the speed! ;)
the devices md is using is 2 network block devices which are 2 hard drive partitions
on another computer
i have tested the same setup before its working on a solo system with reiserfs3
and the ppro also works fine with reiser3
im using kernel 2.6.1 only extra item it has is the 12-23 'all' patch
if you need more info or somethin do tell
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 5:00 raid0 and rfs4 Bret Towe
@ 2004-01-13 10:37 ` Nikita Danilov
2004-01-13 11:34 ` Christophe Saout
2004-01-13 13:38 ` Nikita Danilov
1 sibling, 1 reply; 10+ messages in thread
From: Nikita Danilov @ 2004-01-13 10:37 UTC (permalink / raw
To: Bret Towe; +Cc: reiserfs-list
Bret Towe writes:
> i recently tried reiser4 on a raid0 setup and well it didnt go so well
> :\
>
> what i got from dmesg was the following
> dmesg was full up when i finally looked of the raid_make_request
> all of those lines looked about the same cept the last 2 numbers
>
> raid0_make_request bug: can't convert block across chunks or bigger than
> 512k 356200 124
> raid0_make_request bug: can't convert block across chunks or bigger than 512k 357352 124
> raid0_make_request bug: can't convert block across chunks or bigger than 512k 358344 60
Hmm, probably raid is not happy that reiser4 sends so large bios to it.
> Unable to handle kernel NULL pointer dereference at virtual address 00000004
> printing eip:
> c021706f
> *pde = 00000000
> Oops: 0000 [#1]
> CPU: 0
> EIP: 0060:[<c021706f>] Not tainted
> EFLAGS: 00010246
> EIP is at reiser4_status_write+0xef/0x250
Can you please send us the output of
$ gdb vmlinux # kernel that produces oops
(gdb) disass reiser4_status_write
?
Nikita.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 10:37 ` Nikita Danilov
@ 2004-01-13 11:34 ` Christophe Saout
2004-01-13 11:38 ` Nikita Danilov
0 siblings, 1 reply; 10+ messages in thread
From: Christophe Saout @ 2004-01-13 11:34 UTC (permalink / raw
To: Nikita Danilov; +Cc: reiserfs-list
Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
> Hmm, probably raid is not happy that reiser4 sends so large bios to it.
You must call the queue->merge_bvec_fn to ask how big you can make your
bio.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 11:34 ` Christophe Saout
@ 2004-01-13 11:38 ` Nikita Danilov
2004-01-13 13:36 ` Christophe Saout
2004-01-13 13:46 ` Domenico Andreoli
0 siblings, 2 replies; 10+ messages in thread
From: Nikita Danilov @ 2004-01-13 11:38 UTC (permalink / raw
To: Christophe Saout; +Cc: reiserfs-list
Christophe Saout writes:
> Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
>
> > Hmm, probably raid is not happy that reiser4 sends so large bios to it.
>
> You must call the queue->merge_bvec_fn to ask how big you can make your
> bio.
Right. Or just use bio_add_page() to construct bios, which seems to be
canonical way now-days.
>
>
Nikita.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 11:38 ` Nikita Danilov
@ 2004-01-13 13:36 ` Christophe Saout
2004-01-13 13:46 ` Domenico Andreoli
1 sibling, 0 replies; 10+ messages in thread
From: Christophe Saout @ 2004-01-13 13:36 UTC (permalink / raw
To: Nikita Danilov; +Cc: reiserfs-list
Am Di, den 13.01.2004 schrieb Nikita Danilov um 12:38:
> Christophe Saout writes:
> > Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
> >
> > > Hmm, probably raid is not happy that reiser4 sends so large bios to it.
> >
> > You must call the queue->merge_bvec_fn to ask how big you can make your
> > bio.
>
> Right. Or just use bio_add_page() to construct bios, which seems to be
> canonical way now-days.
Right. bio_add_page also checks for other possible restrictions.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 5:00 raid0 and rfs4 Bret Towe
2004-01-13 10:37 ` Nikita Danilov
@ 2004-01-13 13:38 ` Nikita Danilov
2004-01-13 19:04 ` Bret Towe
1 sibling, 1 reply; 10+ messages in thread
From: Nikita Danilov @ 2004-01-13 13:38 UTC (permalink / raw
To: Bret Towe; +Cc: reiserfs-list
Bret Towe writes:
> i recently tried reiser4 on a raid0 setup and well it didnt go so well
> :\
>
> what i got from dmesg was the following
> dmesg was full up when i finally looked of the raid_make_request
> all of those lines looked about the same cept the last 2 numbers
>
> raid0_make_request bug: can't convert block across chunks or bigger than
> 512k 356200 124
> raid0_make_request bug: can't convert block across chunks or bigger than 512k 357352 124
> raid0_make_request bug: can't convert block across chunks or bigger than 512k 358344 60
Please try with the following patch applied:
----------------------------------------------------------------------
===== page_cache.c 1.265 vs edited =====
--- 1.265/page_cache.c Wed Dec 24 17:57:42 2003
+++ edited/page_cache.c Tue Jan 13 15:48:58 2004
@@ -499,17 +499,18 @@
assert("nikita-2275", blocknr != (reiser4_block_nr) 0);
assert("nikita-2276", !blocknr_is_fake(&blocknr));
- bio->bi_sector = blocknr * (blksz >> 9);
bio->bi_bdev = super->s_bdev;
- bio->bi_io_vec[0].bv_page = page;
- bio->bi_io_vec[0].bv_len = blksz;
- bio->bi_io_vec[0].bv_offset = 0;
- bio->bi_vcnt = 1;
- /* bio -> bi_idx is filled by bio_init() */
- bio->bi_size = blksz;
+ if (!bio_add_page(bio, page, blksz, 0)) {
+ warning("nikita-3452",
+ "Single page bio cannot be constructed");
+ return ERR_PTR(RETERR(-EINVAL));
+ }
- bio->bi_end_io = (rw == READ) ? end_bio_single_page_read : end_bio_single_page_write;
+ bio->bi_sector = blocknr * (blksz >> 9);
+ /* bio -> bi_idx is filled by bio_init() */
+ bio->bi_end_io = (rw == READ) ?
+ end_bio_single_page_read : end_bio_single_page_write;
return bio;
} else
===== wander.c 1.229 vs edited =====
--- 1.229/wander.c Tue Jan 13 14:02:11 2004
+++ edited/wander.c Tue Jan 13 16:18:31 2004
@@ -527,6 +527,26 @@
return ret;
}
+static void
+undo_bio(struct bio *bio)
+{
+ int i;
+
+ for (i = 0; i < bio->bi_vcnt; ++i) {
+ struct page *pg;
+ jnode *node;
+
+ pg = bio->bi_io_vec[i].bv_page;
+ ClearPageWriteback(pg);
+ node = jprivate(pg);
+ LOCK_JNODE(node);
+ JF_CLR(node, JNODE_WRITEBACK);
+ JF_SET(node, JNODE_DIRTY);
+ UNLOCK_JNODE(node);
+ }
+ bio_put(bio);
+}
+
#if REISER4_COPY_ON_CAPTURE
extern spinlock_t scan_lock;
@@ -715,11 +735,7 @@
ON_TRACE (TRACE_IO_W, "write of %d blocks starting from %llu\n",
nr, (unsigned long long)block);
-#if REISER4_USER_LEVEL_SIMULATION
- max_blocks = nr;
-#else
max_blocks = bdev_get_queue(super->s_bdev)->max_sectors >> (super->s_blocksize_bits - 9);
-#endif
while (nr > 0) {
struct bio *bio;
@@ -731,6 +747,7 @@
if (!bio)
return RETERR(-ENOMEM);
+ bio->bi_bdev = super->s_bdev;
for (nr_used = 0, i = 0; i < nr_blocks; i++) {
struct page *pg;
ON_DEBUG(int jnode_is_releasable(jnode *));
@@ -749,18 +766,27 @@
if (!JF_ISSET(cur, JNODE_WRITEBACK)) {
assert("zam-912", !JF_ISSET(cur, JNODE_WRITEBACK));
assert("nikita-3165", !jnode_is_releasable(cur));
+ UNLOCK_JNODE(cur);
+ if (!bio_add_page(bio,
+ pg, super->s_blocksize, 0))
+ /*
+ * underlying device is satiated. Stop
+ * adding pages to the bio.
+ */
+ break;
+
+ LOCK_JNODE(cur);
JF_SET(cur, JNODE_WRITEBACK);
JF_CLR(cur, JNODE_DIRTY);
UNLOCK_JNODE(cur);
SetPageWriteback(pg);
-
+
spin_lock(&pg->mapping->page_lock);
-#if REISER4_STATS
- if (!PageDirty(pg))
+ if (REISER4_STATS && !PageDirty(pg))
reiser4_stat_inc(pages_clean);
-#endif
+
/* don't check return value: submit page even if
it wasn't dirty. */
test_clear_page_dirty(pg);
@@ -771,10 +797,7 @@
spin_unlock(&pg->mapping->page_lock);
unlock_page(pg);
-
- bio->bi_io_vec[nr_used].bv_page = pg;
- bio->bi_io_vec[nr_used].bv_len = super->s_blocksize;
- bio->bi_io_vec[nr_used].bv_offset = 0;
+ nr_used ++;
} else {
/* jnode being WRITEBACK might be replaced on
ovrwr_nodes list with jnode CC. We just
@@ -790,31 +813,18 @@
cur = capture_list_next(cur);
if (!capture_list_end(head, cur))
JF_SET(cur, JNODE_SCANNED);
- else {
- /* end of overwrite list reached */
- assert("", i == nr_blocks - 1);
- assert("", nr_used + 1 == nr);
- }
spin_unlock(&scan_lock);
- nr_used ++;
}
if (nr_used > 0) {
bio->bi_sector = block * (super->s_blocksize >> 9);
- bio->bi_bdev = super->s_bdev;
- bio->bi_size = super->s_blocksize * nr_used;
- bio->bi_vcnt = nr_used;
+ assert("nikita-3455",
+ bio->bi_size = super->s_blocksize * nr_used);
+ assert("nikita-3456", bio->bi_vcnt == nr_used);
/* Check if we are allowed to write at all */
- if ( super->s_flags & MS_RDONLY ) {
- int i;
- for ( i = 0; i < nr_used ; i++) {
- struct page *pg = bio->bi_io_vec[i].bv_page;
- ClearPageWriteback(pg);
- JF_CLR((jnode *)pg->private, JNODE_WRITEBACK);
- JF_SET((jnode *)pg->private, JNODE_DIRTY);
- }
- bio_put(bio);
- } else {
+ if (super->s_flags & MS_RDONLY)
+ undo_bio(bio);
+ else {
add_fq_to_bio(fq, bio);
reiser4_submit_bio(WRITE, bio);
}
@@ -1142,11 +1152,7 @@
ON_TRACE (TRACE_IO_W, "write of %d blocks starting from %llu\n",
nr, (unsigned long long)block);
-#if REISER4_USER_LEVEL_SIMULATION
- max_blocks = nr;
-#else
max_blocks = bdev_get_queue(super->s_bdev)->max_sectors >> (super->s_blocksize_bits - 9);
-#endif
while (nr > 0) {
struct bio *bio;
@@ -1158,6 +1164,7 @@
if (!bio)
return RETERR(-ENOMEM);
+ bio->bi_bdev = super->s_bdev;
for (nr_used = 0, i = 0; i < nr_blocks; i++) {
struct page *pg;
ON_DEBUG(int jnode_is_releasable(jnode *));
@@ -1169,6 +1176,13 @@
lock_and_wait_page_writeback(pg);
+ if (!bio_add_page(bio, pg, super->s_blocksize, 0))
+ /*
+ * underlying device is satiated. Stop adding
+ * pages to the bio.
+ */
+ break;
+
LOCK_JNODE(cur);
ON_DEBUG_MODIFY(znode_set_checksum(cur, 1));
assert("nikita-3166",
@@ -1183,10 +1197,9 @@
spin_lock(&pg->mapping->page_lock);
-#if REISER4_STATS
- if (!PageDirty(pg))
+ if (REISER4_STATS && !PageDirty(pg))
reiser4_stat_inc(pages_clean);
-#endif
+
/* don't check return value: submit page even if it
wasn't dirty. */
test_clear_page_dirty(pg);
@@ -1198,34 +1211,19 @@
unlock_page(pg);
- bio->bi_io_vec[nr_used].bv_page = pg;
- bio->bi_io_vec[nr_used].bv_len = super->s_blocksize;
- bio->bi_io_vec[nr_used].bv_offset = 0;
-
cur = capture_list_next(cur);
nr_used ++;
}
if (nr_used > 0) {
bio->bi_sector = block * (super->s_blocksize >> 9);
- bio->bi_bdev = super->s_bdev;
- bio->bi_size = super->s_blocksize * nr_used;
- bio->bi_vcnt = nr_used;
+ assert("nikita-3453",
+ bio->bi_size == super->s_blocksize * nr_used);
+ assert("nikita-3454", bio->bi_vcnt == nr_used);
/* Check if we are allowed to write at all */
- if ( super->s_flags & MS_RDONLY ) {
- int i;
- for ( i = 0; i < nr_used ; i++) {
- struct page *pg = bio->bi_io_vec[i].bv_page;
- struct jnode *j;
-
- j = jprivate(pg);
- ClearPageWriteback(pg);
- JF_CLR(j, JNODE_WRITEBACK);
- ON_DEBUG_MODIFY(znode_set_checksum(j, 1));
- JF_SET(j, JNODE_DIRTY);
- }
- bio_put(bio);
- } else {
+ if (super->s_flags & MS_RDONLY)
+ undo_bio(bio);
+ else {
add_fq_to_bio(fq, bio);
reiser4_submit_bio(WRITE, bio);
}
----------------------------------------------------------------------
I gave it only light testing.
> Unable to handle kernel NULL pointer dereference at virtual address 00000004
Nikita.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 11:38 ` Nikita Danilov
2004-01-13 13:36 ` Christophe Saout
@ 2004-01-13 13:46 ` Domenico Andreoli
2004-01-13 13:57 ` Nikita Danilov
1 sibling, 1 reply; 10+ messages in thread
From: Domenico Andreoli @ 2004-01-13 13:46 UTC (permalink / raw
To: Nikita Danilov; +Cc: reiserfs-list
Nikita Danilov wrote:
> Christophe Saout writes:
> > Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
> >
> > > Hmm, probably raid is not happy that reiser4 sends so large bios to it.
> >
> > You must call the queue->merge_bvec_fn to ask how big you can make your
> > bio.
>
> Right. Or just use bio_add_page() to construct bios, which seems to be
> canonical way now-days.
>
so is reiser4 already doing the right thing?
i'm not a filesystem guru, even if i'd like to study them a little (any
good suggestion for a newbie?), and i have not any idea about what is a
"bio", but these day i was thinking about moving my raid0 from reiserfs
to reiser4 and this story interests me a lot.
cheers
domenico
-----[ Domenico Andreoli, aka cavok
--[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc
---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 13:46 ` Domenico Andreoli
@ 2004-01-13 13:57 ` Nikita Danilov
2004-01-13 14:06 ` Domenico Andreoli
0 siblings, 1 reply; 10+ messages in thread
From: Nikita Danilov @ 2004-01-13 13:57 UTC (permalink / raw
To: Domenico Andreoli; +Cc: reiserfs-list
Domenico Andreoli writes:
> Nikita Danilov wrote:
> > Christophe Saout writes:
> > > Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
> > >
> > > > Hmm, probably raid is not happy that reiser4 sends so large bios to it.
> > >
> > > You must call the queue->merge_bvec_fn to ask how big you can make your
> > > bio.
> >
> > Right. Or just use bio_add_page() to construct bios, which seems to be
> > canonical way now-days.
> >
> so is reiser4 already doing the right thing?
Yes, with a little help of the patch I sent few minutes ago.
>
> i'm not a filesystem guru, even if i'd like to study them a little (any
> good suggestion for a newbie?), and i have not any idea about what is a
> "bio", but these day i was thinking about moving my raid0 from reiserfs
> to reiser4 and this story interests me a lot.
"bio" (from Block Input-Output) is an entity used by the rest of the
linux kernel to communicate with block IO sub-system. Basically, it is a
mapping from a contiguous portion of block device to an array of regions
in the memory (think of readv(2), writev(2)). Block IO subsystem
provides calls to start read/write through this map. File system uses
bio's to write/read its data and meta-data.
>
> cheers
> domenico
>
Nikita.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 13:57 ` Nikita Danilov
@ 2004-01-13 14:06 ` Domenico Andreoli
0 siblings, 0 replies; 10+ messages in thread
From: Domenico Andreoli @ 2004-01-13 14:06 UTC (permalink / raw
To: reiserfs-list
Nikita Danilov wrote:
> Domenico Andreoli writes:
> > Nikita Danilov wrote:
> > > Christophe Saout writes:
> > > > Am Di, den 13.01.2004 schrieb Nikita Danilov um 11:37:
> > > >
> > > > > Hmm, probably raid is not happy that reiser4 sends so large bios to it.
> > > >
> > > > You must call the queue->merge_bvec_fn to ask how big you can make your
> > > > bio.
> > >
> > > Right. Or just use bio_add_page() to construct bios, which seems to be
> > > canonical way now-days.
> > >
> > so is reiser4 already doing the right thing?
>
> Yes, with a little help of the patch I sent few minutes ago.
>
i've just seen it...
> > i'm not a filesystem guru, even if i'd like to study them a little (any
> > good suggestion for a newbie?), and i have not any idea about what is a
> > "bio", but these day i was thinking about moving my raid0 from reiserfs
> > to reiser4 and this story interests me a lot.
>
> "bio" (from Block Input-Output) is an entity used by the rest of the
> linux kernel to communicate with block IO sub-system. Basically, it is a
> mapping from a contiguous portion of block device to an array of regions
> in the memory (think of readv(2), writev(2)). Block IO subsystem
> provides calls to start read/write through this map. File system uses
> bio's to write/read its data and meta-data.
>
yes i definitively need a good book and some knowledge of linux kernel
internals... thanks :)
domenico
-----[ Domenico Andreoli, aka cavok
--[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc
---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: raid0 and rfs4
2004-01-13 13:38 ` Nikita Danilov
@ 2004-01-13 19:04 ` Bret Towe
0 siblings, 0 replies; 10+ messages in thread
From: Bret Towe @ 2004-01-13 19:04 UTC (permalink / raw
To: Nikita Danilov; +Cc: reiserfs-list
ok i tried the below patch the kernel no longer blows up
but it still spews forth the raid0_make_request stuff
only 7 of em this time too (256k chunks btw) the file it
should be trying to write is 51mb
and if you want i can still do a gdb i think on the old kernel
i still have the old bzImage on cd
btw if you think this is going to take a while to debug let me know
i dont mind trying but i need to setup another comp to try on
this one i have to burn a cd for every try :\
On Tue, 2004-01-13 at 05:38, Nikita Danilov wrote:
> Bret Towe writes:
> > i recently tried reiser4 on a raid0 setup and well it didnt go so well
> > :\
> >
> > what i got from dmesg was the following
> > dmesg was full up when i finally looked of the raid_make_request
> > all of those lines looked about the same cept the last 2 numbers
> >
> > raid0_make_request bug: can't convert block across chunks or bigger than
> > 512k 356200 124
> > raid0_make_request bug: can't convert block across chunks or bigger than 512k 357352 124
> > raid0_make_request bug: can't convert block across chunks or bigger than 512k 358344 60
>
> Please try with the following patch applied:
> ----------------------------------------------------------------------
> ===== page_cache.c 1.265 vs edited =====
> --- 1.265/page_cache.c Wed Dec 24 17:57:42 2003
> +++ edited/page_cache.c Tue Jan 13 15:48:58 2004
> @@ -499,17 +499,18 @@
> assert("nikita-2275", blocknr != (reiser4_block_nr) 0);
> assert("nikita-2276", !blocknr_is_fake(&blocknr));
>
> - bio->bi_sector = blocknr * (blksz >> 9);
> bio->bi_bdev = super->s_bdev;
> - bio->bi_io_vec[0].bv_page = page;
> - bio->bi_io_vec[0].bv_len = blksz;
> - bio->bi_io_vec[0].bv_offset = 0;
>
> - bio->bi_vcnt = 1;
> - /* bio -> bi_idx is filled by bio_init() */
> - bio->bi_size = blksz;
> + if (!bio_add_page(bio, page, blksz, 0)) {
> + warning("nikita-3452",
> + "Single page bio cannot be constructed");
> + return ERR_PTR(RETERR(-EINVAL));
> + }
>
> - bio->bi_end_io = (rw == READ) ? end_bio_single_page_read : end_bio_single_page_write;
> + bio->bi_sector = blocknr * (blksz >> 9);
> + /* bio -> bi_idx is filled by bio_init() */
> + bio->bi_end_io = (rw == READ) ?
> + end_bio_single_page_read : end_bio_single_page_write;
>
> return bio;
> } else
> ===== wander.c 1.229 vs edited =====
> --- 1.229/wander.c Tue Jan 13 14:02:11 2004
> +++ edited/wander.c Tue Jan 13 16:18:31 2004
> @@ -527,6 +527,26 @@
> return ret;
> }
>
> +static void
> +undo_bio(struct bio *bio)
> +{
> + int i;
> +
> + for (i = 0; i < bio->bi_vcnt; ++i) {
> + struct page *pg;
> + jnode *node;
> +
> + pg = bio->bi_io_vec[i].bv_page;
> + ClearPageWriteback(pg);
> + node = jprivate(pg);
> + LOCK_JNODE(node);
> + JF_CLR(node, JNODE_WRITEBACK);
> + JF_SET(node, JNODE_DIRTY);
> + UNLOCK_JNODE(node);
> + }
> + bio_put(bio);
> +}
> +
> #if REISER4_COPY_ON_CAPTURE
>
> extern spinlock_t scan_lock;
> @@ -715,11 +735,7 @@
> ON_TRACE (TRACE_IO_W, "write of %d blocks starting from %llu\n",
> nr, (unsigned long long)block);
>
> -#if REISER4_USER_LEVEL_SIMULATION
> - max_blocks = nr;
> -#else
> max_blocks = bdev_get_queue(super->s_bdev)->max_sectors >> (super->s_blocksize_bits - 9);
> -#endif
>
> while (nr > 0) {
> struct bio *bio;
> @@ -731,6 +747,7 @@
> if (!bio)
> return RETERR(-ENOMEM);
>
> + bio->bi_bdev = super->s_bdev;
> for (nr_used = 0, i = 0; i < nr_blocks; i++) {
> struct page *pg;
> ON_DEBUG(int jnode_is_releasable(jnode *));
> @@ -749,18 +766,27 @@
> if (!JF_ISSET(cur, JNODE_WRITEBACK)) {
> assert("zam-912", !JF_ISSET(cur, JNODE_WRITEBACK));
> assert("nikita-3165", !jnode_is_releasable(cur));
> + UNLOCK_JNODE(cur);
> + if (!bio_add_page(bio,
> + pg, super->s_blocksize, 0))
> + /*
> + * underlying device is satiated. Stop
> + * adding pages to the bio.
> + */
> + break;
> +
> + LOCK_JNODE(cur);
> JF_SET(cur, JNODE_WRITEBACK);
> JF_CLR(cur, JNODE_DIRTY);
> UNLOCK_JNODE(cur);
>
> SetPageWriteback(pg);
> -
> +
> spin_lock(&pg->mapping->page_lock);
>
> -#if REISER4_STATS
> - if (!PageDirty(pg))
> + if (REISER4_STATS && !PageDirty(pg))
> reiser4_stat_inc(pages_clean);
> -#endif
> +
> /* don't check return value: submit page even if
> it wasn't dirty. */
> test_clear_page_dirty(pg);
> @@ -771,10 +797,7 @@
> spin_unlock(&pg->mapping->page_lock);
>
> unlock_page(pg);
> -
> - bio->bi_io_vec[nr_used].bv_page = pg;
> - bio->bi_io_vec[nr_used].bv_len = super->s_blocksize;
> - bio->bi_io_vec[nr_used].bv_offset = 0;
> + nr_used ++;
> } else {
> /* jnode being WRITEBACK might be replaced on
> ovrwr_nodes list with jnode CC. We just
> @@ -790,31 +813,18 @@
> cur = capture_list_next(cur);
> if (!capture_list_end(head, cur))
> JF_SET(cur, JNODE_SCANNED);
> - else {
> - /* end of overwrite list reached */
> - assert("", i == nr_blocks - 1);
> - assert("", nr_used + 1 == nr);
> - }
> spin_unlock(&scan_lock);
> - nr_used ++;
> }
> if (nr_used > 0) {
> bio->bi_sector = block * (super->s_blocksize >> 9);
> - bio->bi_bdev = super->s_bdev;
> - bio->bi_size = super->s_blocksize * nr_used;
> - bio->bi_vcnt = nr_used;
> + assert("nikita-3455",
> + bio->bi_size = super->s_blocksize * nr_used);
> + assert("nikita-3456", bio->bi_vcnt == nr_used);
>
> /* Check if we are allowed to write at all */
> - if ( super->s_flags & MS_RDONLY ) {
> - int i;
> - for ( i = 0; i < nr_used ; i++) {
> - struct page *pg = bio->bi_io_vec[i].bv_page;
> - ClearPageWriteback(pg);
> - JF_CLR((jnode *)pg->private, JNODE_WRITEBACK);
> - JF_SET((jnode *)pg->private, JNODE_DIRTY);
> - }
> - bio_put(bio);
> - } else {
> + if (super->s_flags & MS_RDONLY)
> + undo_bio(bio);
> + else {
> add_fq_to_bio(fq, bio);
> reiser4_submit_bio(WRITE, bio);
> }
> @@ -1142,11 +1152,7 @@
> ON_TRACE (TRACE_IO_W, "write of %d blocks starting from %llu\n",
> nr, (unsigned long long)block);
>
> -#if REISER4_USER_LEVEL_SIMULATION
> - max_blocks = nr;
> -#else
> max_blocks = bdev_get_queue(super->s_bdev)->max_sectors >> (super->s_blocksize_bits - 9);
> -#endif
>
> while (nr > 0) {
> struct bio *bio;
> @@ -1158,6 +1164,7 @@
> if (!bio)
> return RETERR(-ENOMEM);
>
> + bio->bi_bdev = super->s_bdev;
> for (nr_used = 0, i = 0; i < nr_blocks; i++) {
> struct page *pg;
> ON_DEBUG(int jnode_is_releasable(jnode *));
> @@ -1169,6 +1176,13 @@
>
> lock_and_wait_page_writeback(pg);
>
> + if (!bio_add_page(bio, pg, super->s_blocksize, 0))
> + /*
> + * underlying device is satiated. Stop adding
> + * pages to the bio.
> + */
> + break;
> +
> LOCK_JNODE(cur);
> ON_DEBUG_MODIFY(znode_set_checksum(cur, 1));
> assert("nikita-3166",
> @@ -1183,10 +1197,9 @@
>
> spin_lock(&pg->mapping->page_lock);
>
> -#if REISER4_STATS
> - if (!PageDirty(pg))
> + if (REISER4_STATS && !PageDirty(pg))
> reiser4_stat_inc(pages_clean);
> -#endif
> +
> /* don't check return value: submit page even if it
> wasn't dirty. */
> test_clear_page_dirty(pg);
> @@ -1198,34 +1211,19 @@
>
> unlock_page(pg);
>
> - bio->bi_io_vec[nr_used].bv_page = pg;
> - bio->bi_io_vec[nr_used].bv_len = super->s_blocksize;
> - bio->bi_io_vec[nr_used].bv_offset = 0;
> -
> cur = capture_list_next(cur);
> nr_used ++;
> }
> if (nr_used > 0) {
> bio->bi_sector = block * (super->s_blocksize >> 9);
> - bio->bi_bdev = super->s_bdev;
> - bio->bi_size = super->s_blocksize * nr_used;
> - bio->bi_vcnt = nr_used;
> + assert("nikita-3453",
> + bio->bi_size == super->s_blocksize * nr_used);
> + assert("nikita-3454", bio->bi_vcnt == nr_used);
>
> /* Check if we are allowed to write at all */
> - if ( super->s_flags & MS_RDONLY ) {
> - int i;
> - for ( i = 0; i < nr_used ; i++) {
> - struct page *pg = bio->bi_io_vec[i].bv_page;
> - struct jnode *j;
> -
> - j = jprivate(pg);
> - ClearPageWriteback(pg);
> - JF_CLR(j, JNODE_WRITEBACK);
> - ON_DEBUG_MODIFY(znode_set_checksum(j, 1));
> - JF_SET(j, JNODE_DIRTY);
> - }
> - bio_put(bio);
> - } else {
> + if (super->s_flags & MS_RDONLY)
> + undo_bio(bio);
> + else {
> add_fq_to_bio(fq, bio);
> reiser4_submit_bio(WRITE, bio);
> }
> ----------------------------------------------------------------------
> I gave it only light testing.
>
> > Unable to handle kernel NULL pointer dereference at virtual address 00000004
>
> Nikita.
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2004-01-13 19:04 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-13 5:00 raid0 and rfs4 Bret Towe
2004-01-13 10:37 ` Nikita Danilov
2004-01-13 11:34 ` Christophe Saout
2004-01-13 11:38 ` Nikita Danilov
2004-01-13 13:36 ` Christophe Saout
2004-01-13 13:46 ` Domenico Andreoli
2004-01-13 13:57 ` Nikita Danilov
2004-01-13 14:06 ` Domenico Andreoli
2004-01-13 13:38 ` Nikita Danilov
2004-01-13 19:04 ` Bret Towe
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.