From: Andrew Morton <akpm@zip.com.au>
To: Andrea Arcangeli <andrea@suse.de>, Alexander Viro <viro@math.psu.edu>
Cc: lkml <linux-kernel@vger.kernel.org>
Subject: [patch] truncate fixes
Date: Sat, 05 Jan 2002 03:08:25 -0800 [thread overview]
Message-ID: <3C36DEA9.AEA2A402@zip.com.au> (raw)
This is the backport of the -ac truncate fixes we discussed
the other day. All code paths have been tested and work OK.
Please review.
--- linux-2.4.18-pre1/fs/buffer.c Fri Dec 21 11:19:14 2001
+++ linux-akpm/fs/buffer.c Sat Jan 5 01:26:38 2002
@@ -1512,6 +1512,7 @@ static int __block_write_full_page(struc
int err, i;
unsigned long block;
struct buffer_head *bh, *head;
+ int need_unlock;
if (!PageLocked(page))
BUG();
@@ -1567,8 +1568,34 @@ static int __block_write_full_page(struc
return 0;
out:
+ /*
+ * ENOSPC, or some other error. We may already have added some
+ * blocks to the file, so we need to write these out to avoid
+ * exposing stale data.
+ */
ClearPageUptodate(page);
- UnlockPage(page);
+ bh = head;
+ need_unlock = 1;
+ /* Recovery: lock and submit the mapped buffers */
+ do {
+ if (buffer_mapped(bh)) {
+ lock_buffer(bh);
+ set_buffer_async_io(bh);
+ need_unlock = 0;
+ }
+ bh = bh->b_this_page;
+ } while (bh != head);
+ do {
+ struct buffer_head *next = bh->b_this_page;
+ if (buffer_mapped(bh)) {
+ set_bit(BH_Uptodate, &bh->b_state);
+ clear_bit(BH_Dirty, &bh->b_state);
+ submit_bh(WRITE, bh);
+ }
+ bh = next;
+ } while (bh != head);
+ if (need_unlock)
+ UnlockPage(page);
return err;
}
@@ -1639,6 +1666,17 @@ static int __block_prepare_write(struct
}
return 0;
out:
+ bh = head;
+ block_start = 0;
+ do {
+ if (buffer_new(bh) && !buffer_uptodate(bh)) {
+ memset(kaddr+block_start, 0, bh->b_size);
+ set_bit(BH_Uptodate, &bh->b_state);
+ mark_buffer_dirty(bh);
+ }
+ block_start += bh->b_size;
+ bh = bh->b_this_page;
+ } while (bh != head);
return err;
}
--- linux-2.4.18-pre1/mm/filemap.c Wed Dec 26 11:47:41 2001
+++ linux-akpm/mm/filemap.c Sat Jan 5 01:26:50 2002
@@ -3004,7 +3004,7 @@ generic_file_write(struct file *file,con
kaddr = kmap(page);
status = mapping->a_ops->prepare_write(file, page, offset, offset+bytes);
if (status)
- goto unlock;
+ goto sync_failure;
page_fault = __copy_from_user(kaddr+offset, buf, bytes);
flush_dcache_page(page);
status = mapping->a_ops->commit_write(file, page, offset, offset+bytes);
@@ -3029,6 +3029,7 @@ unlock:
if (status < 0)
break;
} while (count);
+done:
*ppos = pos;
if (cached_page)
@@ -3050,6 +3051,18 @@ out:
fail_write:
status = -EFAULT;
goto unlock;
+
+sync_failure:
+ /*
+ * If blocksize < pagesize, prepare_write() may have instantiated a
+ * few blocks outside i_size. Trim these off again.
+ */
+ kunmap(page);
+ UnlockPage(page);
+ page_cache_release(page);
+ if (pos + bytes > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+ goto done;
o_direct:
written = generic_file_direct_IO(WRITE, file, (char *) buf, count, pos);
next reply other threads:[~2002-01-05 11:13 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-01-05 11:08 Andrew Morton [this message]
2002-01-07 2:46 ` [patch] truncate fixes Andrea Arcangeli
2002-01-07 2:53 ` Andrew Morton
2002-01-07 3:16 ` Andrea Arcangeli
2002-01-07 5:24 ` Alexander Viro
2002-01-07 3:11 ` Andrew Morton
2002-01-07 3:58 ` Andrea Arcangeli
2002-01-07 3:32 ` Andrea Arcangeli
2002-01-07 3:48 ` Andrew Morton
2002-01-07 4:12 ` Andrea Arcangeli
2002-01-07 4:28 ` Andrew Morton
2002-01-07 5:09 ` Andrea Arcangeli
2002-01-07 12:41 ` Daniel Phillips
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=3C36DEA9.AEA2A402@zip.com.au \
--to=akpm@zip.com.au \
--cc=andrea@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@math.psu.edu \
/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).