From: Ignatich <ignatich@gmail.com>
To: reiserfs-list@namesys.com, linux-kernel@vger.kernel.org
Subject: REISER4: fix for reiser4_write_extent
Date: Fri, 06 Apr 2007 02:42:35 +0400 [thread overview]
Message-ID: <46157B5B.5000602@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 342 bytes --]
While trying to find the cause of problems with reiser4 in recent
kernels I came across this.
Incomplete write handling seem to be missing from reiser4_write_extent()
thanks to reiser4-temp-fix.patch. Strangely, there is a patch by Edward
Shishkin that should address that issue, but it is missing from -mm
tree. Please check.
Max
[-- Attachment #2: reiser4-fix-write_extent.patch --]
[-- Type: text/plain, Size: 6591 bytes --]
------------------------------------------------------
Subject: reiser4: fix write_extent
From: Edward Shishkin <[EMAIL PROTECTED]>
. Fix reiser4_write_extent():
1) handling incomplete writes missed in reiser4-temp-fix.patch
2) bugs in the case of returned errors
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---
fs/reiser4/plugin/item/extent_file_ops.c | 64 ++++++++++++---------
1 file changed, 37 insertions(+), 27 deletions(-)
diff -puN fs/reiser4/plugin/item/extent_file_ops.c~reiser4-fix-write_extent
fs/reiser4/plugin/item/extent_file_ops.c
--- a/fs/reiser4/plugin/item/extent_file_ops.c~reiser4-fix-write_extent
+++ a/fs/reiser4/plugin/item/extent_file_ops.c
@@ -941,15 +941,15 @@ static int write_extent_reserve_space(st
* reiser4_write_extent - write method of extent item plugin
* @file: file to write to
* @buf: address of user-space buffer
- * @write_amount: number of bytes to write
- * @off: position in file to write to
+ * @count: number of bytes to write
+ * @pos: position in file to write to
*
*/
ssize_t reiser4_write_extent(struct file *file, const char __user *buf,
size_t count, loff_t *pos)
{
int have_to_update_extent;
- int nr_pages;
+ int nr_pages, nr_dirty;
struct page *page;
jnode *jnodes[WRITE_GRANULARITY + 1];
struct inode *inode;
@@ -958,7 +958,7 @@ ssize_t reiser4_write_extent(struct file
int i;
int to_page, page_off;
size_t left, written;
- int result;
+ int result = 0;
inode = file->f_dentry->d_inode;
if (write_extent_reserve_space(inode))
@@ -972,10 +972,12 @@ ssize_t reiser4_write_extent(struct file
BUG_ON(get_current_context()->trans->atom != NULL);
+ left = count;
index = *pos >> PAGE_CACHE_SHIFT;
/* calculate number of pages which are to be written */
end = ((*pos + count - 1) >> PAGE_CACHE_SHIFT);
nr_pages = end - index + 1;
+ nr_dirty = 0;
assert("", nr_pages <= WRITE_GRANULARITY + 1);
/* get pages and jnodes */
@@ -983,22 +985,17 @@ ssize_t reiser4_write_extent(struct file
page = find_or_create_page(inode->i_mapping, index + i,
reiser4_ctx_gfp_mask_get());
if (page == NULL) {
- while(i --) {
- unlock_page(jnode_page(jnodes[i]));
- page_cache_release(jnode_page(jnodes[i]));
- }
- return RETERR(-ENOMEM);
+ nr_pages = i;
+ result = RETERR(-ENOMEM);
+ goto out;
}
-
jnodes[i] = jnode_of_page(page);
if (IS_ERR(jnodes[i])) {
unlock_page(page);
page_cache_release(page);
- while (i --) {
- jput(jnodes[i]);
- page_cache_release(jnode_page(jnodes[i]));
- }
- return RETERR(-ENOMEM);
+ nr_pages = i;
+ result = RETERR(-ENOMEM);
+ goto out;
}
/* prevent jnode and page from disconnecting */
JF_SET(jnodes[i], JNODE_WRITE_PREPARED);
@@ -1009,7 +1006,6 @@ ssize_t reiser4_write_extent(struct file
have_to_update_extent = 0;
- left = count;
page_off = (*pos & (PAGE_CACHE_SIZE - 1));
for (i = 0; i < nr_pages; i ++) {
to_page = PAGE_CACHE_SIZE - page_off;
@@ -1050,14 +1046,26 @@ ssize_t reiser4_write_extent(struct file
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
}
-
- written = filemap_copy_from_user(page, page_off, buf, to_page);
+ written = filemap_copy_from_user_atomic(page, page_off, buf,
+ to_page);
+ if (written != to_page)
+ /* Do it the slow way */
+ written = filemap_copy_from_user_nonatomic(page,
+ page_off,
+ buf,
+ to_page);
+ if (unlikely(written != to_page)) {
+ unlock_page(page);
+ result = RETERR(-EFAULT);
+ break;
+ }
flush_dcache_page(page);
reiser4_set_page_dirty_internal(page);
unlock_page(page);
+ nr_dirty ++;
+
mark_page_accessed(page);
SetPageUptodate(page);
- page_cache_release(page);
if (jnodes[i]->blocknr == 0)
have_to_update_extent ++;
@@ -1067,27 +1075,29 @@ ssize_t reiser4_write_extent(struct file
left -= to_page;
BUG_ON(get_current_context()->trans->atom != NULL);
}
-
if (have_to_update_extent) {
- update_extents(file, jnodes, nr_pages, *pos);
+ update_extents(file, jnodes, nr_dirty, *pos);
} else {
- for (i = 0; i < nr_pages; i ++) {
+ for (i = 0; i < nr_dirty; i ++) {
+ int ret;
spin_lock_jnode(jnodes[i]);
- result = reiser4_try_capture(jnodes[i],
+ ret = reiser4_try_capture(jnodes[i],
ZNODE_WRITE_LOCK, 0);
- BUG_ON(result != 0);
+ BUG_ON(ret != 0);
jnode_make_dirty_locked(jnodes[i]);
spin_unlock_jnode(jnodes[i]);
}
}
-
+ out:
for (i = 0; i < nr_pages; i ++) {
+ page_cache_release(jnode_page(jnodes[i]));
JF_CLR(jnodes[i], JNODE_WRITE_PREPARED);
jput(jnodes[i]);
}
+ /* the only errors handled so far is ENOMEM and
+ EFAULT on copy_from_user */
- /* the only error handled so far is EFAULT on copy_from_user */
- return (count - left) ? (count - left) : -EFAULT;
+ return (count - left) ? (count - left) : result;
}
static inline void zero_page(struct page *page)
next reply other threads:[~2007-04-05 22:42 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-05 22:42 Ignatich [this message]
2007-04-06 0:05 ` Reiser4. BEST FILESYSTEM EVER? I need help johnrobertbanks
2007-04-06 0:05 ` johnrobertbanks
2007-04-06 0:23 ` H. Peter Anvin
2007-04-06 0:34 ` johnrobertbanks
2007-04-06 0:39 ` H. Peter Anvin
2007-04-06 1:34 ` Reiser4. BEST FILESYSTEM EVER johnrobertbanks
2007-04-06 3:12 ` Valdis.Kletnieks
2007-04-06 4:07 ` H. Peter Anvin
2007-04-06 4:32 ` johnrobertbanks
[not found] ` <20070406152119.GC4228@delft.aura.cs.cmu.edu>
2007-04-07 2:47 ` johnrobertbanks
2007-04-07 3:30 ` Jan Harkes
2007-04-07 5:58 ` johnrobertbanks
2007-04-07 7:15 ` Willy Tarreau
2007-04-07 13:47 ` johnrobertbanks
2007-04-07 14:11 ` Krzysztof Halasa
2007-04-07 15:07 ` johnrobertbanks
2007-04-07 16:05 ` Pekka Enberg
2007-04-07 17:10 ` Valdis.Kletnieks
2007-04-08 16:31 ` Adrian Bunk
2007-04-07 17:21 ` Valdis.Kletnieks
2007-04-08 0:41 ` Krzysztof Halasa
2007-04-07 17:39 ` Valdis.Kletnieks
2007-04-08 4:32 ` David H. Lynch Jr
2007-04-07 19:17 ` Lennart Sorensen
2007-04-08 0:44 ` johnrobertbanks
2007-04-08 1:27 ` Lennart Sorensen
2007-04-08 2:56 ` Theodore Tso
2007-04-08 4:13 ` johnrobertbanks
2007-04-08 12:48 ` Jose Celestino
2007-04-08 13:21 ` johnrobertbanks
2007-04-08 14:14 ` Willy Tarreau
2007-04-08 17:03 ` Theodore Tso
2007-04-08 18:18 ` Jeff Mahoney
2007-04-08 4:32 ` Christer Weinigel
2007-04-08 21:50 ` Reiser4. BEST FILESYSTEM EVER - Christer Weinigel johnrobertbanks
2007-04-08 21:50 ` johnrobertbanks
2007-04-08 22:58 ` Richard Knutsson
2007-04-09 5:14 ` johnrobertbanks
2007-04-09 7:07 ` Willy Tarreau
2007-04-09 16:10 ` Richard Knutsson
2007-04-09 1:24 ` Christer Weinigel
2007-04-09 3:38 ` David H. Lynch Jr
2007-04-09 3:16 ` David H. Lynch Jr
2007-04-09 4:25 ` johnrobertbanks
2007-04-09 18:35 ` Reiser4. BEST FILESYSTEM EVER Nate Diller
2007-04-08 4:06 ` David H. Lynch Jr
2007-04-08 9:58 ` Jeff Garzik
2007-04-09 2:52 ` David H. Lynch Jr
2007-04-09 3:14 ` Jeff Garzik
2007-04-09 4:40 ` David H. Lynch Jr
2007-04-09 4:58 ` Jeff Garzik
2007-04-07 1:26 ` COMPILING AND CONFIGURING A NEW KERNEL johnrobertbanks
2007-04-07 1:26 ` johnrobertbanks
2007-04-07 7:45 ` johnrobertbanks
2007-04-07 16:57 ` Valdis.Kletnieks
2007-04-08 1:11 ` johnrobertbanks
2007-04-07 16:42 ` Valdis.Kletnieks
2007-04-08 1:02 ` johnrobertbanks
2007-04-08 1:42 ` Lennart Sorensen
2007-04-07 12:51 ` REISER4: fix for reiser4_write_extent Laurent Riffard
2007-04-07 12:51 ` Laurent Riffard
2007-04-07 19:29 ` Edward Shishkin
2007-04-07 19:29 ` 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=46157B5B.5000602@gmail.com \
--to=ignatich@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=reiserfs-list@namesys.com \
/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 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.