goto done;
}
+/*
+ * Commence writeout of all the buffers against a page. The
+ * page must be locked. Returns zero on success or a negative
+ * errno.
+ */
+int writeout_one_page(struct page *page)
+{
+ struct buffer_head *bh, *head = page->buffers;
+
+ if (!PageLocked(page))
+ BUG();
+ bh = head;
+ do {
+ if (buffer_locked(bh) || !buffer_dirty(bh) || !buffer_uptodate(bh))
+ continue;
+
+ bh->b_flushtime = jiffies;
+ ll_rw_block(WRITE, 1, &bh);
+ } while ((bh = bh->b_this_page) != head);
+ return 0;
+}
+EXPORT_SYMBOL(writeout_one_page);
+
+/*
+ * Wait for completion of I/O of all buffers against a page. The page
+ * must be locked. Returns zero on success or a negative errno.
+ */
+int waitfor_one_page(struct page *page)
+{
+ int error = 0;
+ struct buffer_head *bh, *head = page->buffers;
+
+ bh = head;
+ do {
+ wait_on_buffer(bh);
+ if (buffer_req(bh) && !buffer_uptodate(bh))
+ error = -EIO;
+ } while ((bh = bh->b_this_page) != head);
+ return error;
+}
+EXPORT_SYMBOL(waitfor_one_page);
+
sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
get_block_t *get_block)
{
int err = 0;
dir->i_version = ++event;
page->mapping->a_ops->commit_write(NULL, page, from, to);
- if (IS_SYNC(dir))
- err = waitfor_one_page(page);
+ if (IS_SYNC(dir)) {
+ int err2;
+ err = writeout_one_page(page);
+ err2 = waitfor_one_page(page);
+ if (err == 0)
+ err = err2;
+ }
return err;
}
struct inode *dir = (struct inode *)page->mapping->host;
int err = 0;
page->mapping->a_ops->commit_write(NULL, page, from, to);
- if (IS_SYNC(dir))
- err = waitfor_one_page(page);
+ if (IS_SYNC(dir)) {
+ int err2;
+ err = writeout_one_page(page);
+ err2 = waitfor_one_page(page);
+ if (err == 0)
+ err = err2;
+ }
return err;
}
lock_page(page);
err = mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- de->inode = 0;
- err = dir_commit_chunk(page, from, to);
+ if (err == 0) {
+ de->inode = 0;
+ err = dir_commit_chunk(page, from, to);
+ }
UnlockPage(page);
dir_put_page(page);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
lock_page(page);
err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- de->inode = inode->i_ino;
- err = dir_commit_chunk(page, from, to);
+ if (err == 0) {
+ de->inode = inode->i_ino;
+ err = dir_commit_chunk(page, from, to);
+ }
UnlockPage(page);
dir_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+Thu Feb 14 2002 Andrew Morton <akpm@zip.com.au>
+
+ * dir_commit_chunk(): call writeout_one_page() as well as
+ waitfor_one_page() for IS_SYNC directories, so that we
+ actually do sync the directory. (forward-port from 2.4).
+
Thu Feb 7 2002 Alexander Viro <viro@math.psu.edu>
* super.c: switched to ->get_sb()
Remove symlink faking. Noone really wants to use these as
linux filesystems and native OSes don't support it anyway.
+
int err = 0;
page->mapping->a_ops->commit_write(NULL, page, from, to);
- if (IS_SYNC(dir))
- err = waitfor_one_page(page);
+ if (IS_SYNC(dir)) {
+ int err2;
+ err = writeout_one_page(page);
+ err2 = waitfor_one_page(page);
+ if (err == 0)
+ err = err2;
+ }
return err;
}
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
extern int generic_direct_IO(int, struct inode *, struct kiobuf *, unsigned long, int, get_block_t *);
+extern int waitfor_one_page(struct page *);
+extern int writeout_one_page(struct page *);
-extern int waitfor_one_page(struct page*);
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
EXPORT_SYMBOL(generic_commit_write);
EXPORT_SYMBOL(block_truncate_page);
EXPORT_SYMBOL(generic_block_bmap);
-EXPORT_SYMBOL(waitfor_one_page);
EXPORT_SYMBOL(generic_file_read);
EXPORT_SYMBOL(do_generic_file_read);
EXPORT_SYMBOL(generic_file_write);
return page;
}
-/*
- * By the time this is called, the page is locked and
- * we don't have to worry about any races any more.
- *
- * Start the IO..
- */
-static int writeout_one_page(struct page *page)
-{
- struct buffer_head *bh, *head = page->buffers;
-
- bh = head;
- do {
- if (buffer_locked(bh) || !buffer_dirty(bh) || !buffer_uptodate(bh))
- continue;
-
- bh->b_flushtime = jiffies;
- ll_rw_block(WRITE, 1, &bh);
- } while ((bh = bh->b_this_page) != head);
- return 0;
-}
-
-int waitfor_one_page(struct page *page)
-{
- int error = 0;
- struct buffer_head *bh, *head = page->buffers;
-
- bh = head;
- do {
- wait_on_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh))
- error = -EIO;
- } while ((bh = bh->b_this_page) != head);
- return error;
-}
-
static int do_buffer_fdatasync(struct list_head *head, unsigned long start, unsigned long end, int (*fn)(struct page *))
{
struct list_head *curr;