The following patch for 2.3.99-pre6 exhibits one way in which we could
split up the new task of syncing in readaheads and flushing out
writebacks.
Comments?
Cheers,
Trond
diff -u --recursive --new-file linux-2.3.99-pre6/fs/adfs/inode.c linux-2.3.99-pre6-devel/fs/adfs/inode.c
--- linux-2.3.99-pre6/fs/adfs/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/adfs/inode.c Thu Apr 27 15:26:28 2000
@@ -74,6 +74,7 @@
readpage: adfs_readpage,
writepage: adfs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: adfs_prepare_write,
commit_write: generic_commit_write,
bmap: _adfs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/affs/file.c linux-2.3.99-pre6-devel/fs/affs/file.c
--- linux-2.3.99-pre6/fs/affs/file.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/affs/file.c Thu Apr 27 15:27:04 2000
@@ -359,6 +359,7 @@
readpage: affs_readpage,
writepage: affs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: affs_prepare_write,
commit_write: generic_commit_write,
bmap: _affs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/bfs/file.c linux-2.3.99-pre6-devel/fs/bfs/file.c
--- linux-2.3.99-pre6/fs/bfs/file.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/bfs/file.c Thu Apr 27 15:27:44 2000
@@ -151,6 +151,7 @@
readpage: bfs_readpage,
writepage: bfs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: bfs_prepare_write,
commit_write: generic_commit_write,
bmap: bfs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/buffer.c linux-2.3.99-pre6-devel/fs/buffer.c
--- linux-2.3.99-pre6/fs/buffer.c Wed Apr 26 02:28:55 2000
+++ linux-2.3.99-pre6-devel/fs/buffer.c Thu Apr 27 15:24:41 2000
@@ -1288,7 +1288,7 @@
* we have truncated the file and are going to free the
* blocks on-disk..
*/
-int block_flushpage(struct page *page, unsigned long offset)
+int block_flushpage(struct page *page, unsigned int offset)
{
struct buffer_head *head, *bh, *next;
unsigned int curr_off = 0;
@@ -2417,7 +2417,8 @@
int block_sync_page(struct page *page)
{
- run_task_queue(&tq_disk);
+ if (!Page_Uptodate(page))
+ run_task_queue(&tq_disk);
return 0;
}
diff -u --recursive --new-file linux-2.3.99-pre6/fs/ext2/inode.c linux-2.3.99-pre6-devel/fs/ext2/inode.c
--- linux-2.3.99-pre6/fs/ext2/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/ext2/inode.c Thu Apr 27 15:28:26 2000
@@ -640,6 +640,7 @@
readpage: ext2_readpage,
writepage: ext2_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: ext2_prepare_write,
commit_write: generic_commit_write,
bmap: ext2_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/fat/inode.c linux-2.3.99-pre6-devel/fs/fat/inode.c
--- linux-2.3.99-pre6/fs/fat/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/fat/inode.c Thu Apr 27 15:28:43 2000
@@ -750,6 +750,7 @@
readpage: fat_readpage,
writepage: fat_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: fat_prepare_write,
commit_write: generic_commit_write,
bmap: _fat_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/hfs/inode.c linux-2.3.99-pre6-devel/fs/hfs/inode.c
--- linux-2.3.99-pre6/fs/hfs/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/hfs/inode.c Thu Apr 27 15:29:07 2000
@@ -238,6 +238,7 @@
readpage: hfs_readpage,
writepage: hfs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: hfs_prepare_write,
commit_write: generic_commit_write,
bmap: hfs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/hpfs/file.c linux-2.3.99-pre6-devel/fs/hpfs/file.c
--- linux-2.3.99-pre6/fs/hpfs/file.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/hpfs/file.c Thu Apr 27 15:29:35 2000
@@ -107,6 +107,7 @@
readpage: hpfs_readpage,
writepage: hpfs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: hpfs_prepare_write,
commit_write: generic_commit_write,
bmap: _hpfs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/minix/inode.c linux-2.3.99-pre6-devel/fs/minix/inode.c
--- linux-2.3.99-pre6/fs/minix/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/minix/inode.c Thu Apr 27 15:30:00 2000
@@ -1026,6 +1026,7 @@
readpage: minix_readpage,
writepage: minix_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: minix_prepare_write,
commit_write: generic_commit_write,
bmap: minix_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/nfs/file.c linux-2.3.99-pre6-devel/fs/nfs/file.c
--- linux-2.3.99-pre6/fs/nfs/file.c Wed Apr 26 02:28:55 2000
+++ linux-2.3.99-pre6-devel/fs/nfs/file.c Thu Apr 27 16:17:54 2000
@@ -179,28 +179,47 @@
{
struct inode *inode = (struct inode *)page->mapping->host;
unsigned long index = page_index(page);
- unsigned int rpages, wpages;
+ unsigned int rpages;
int result;
if (!inode)
- return 0;
+ return 1;
rpages = NFS_SERVER(inode)->rpages;
result = nfs_pagein_inode(inode, index, rpages);
if (result < 0)
goto out_bad;
- wpages = NFS_SERVER(inode)->wpages;
- result = nfs_sync_file(inode, NULL, index, wpages, FLUSH_STABLE);
- if (result < 0)
- goto out_bad;
- return 0;
+ return 1;
out_bad:
return result;
}
+/*
+ * The following tries to flush out any pending writes on a given page
+ * Note: in NFS we don't want it to wait on the flush request, since we
+ * often end up calling invalidate_inode_pages() from rpciod()
+ */
+static int nfs_flushpage(struct page *page, unsigned partial)
+{
+ struct inode *inode = (struct inode *)page->mapping->host;
+ unsigned long index = page_index(page);
+ unsigned int wpages;
+
+ if (!PageLocked(page))
+ BUG();
+ if (!inode)
+ goto out;
+
+ wpages = NFS_SERVER(inode)->wpages;
+ nfs_sync_file(inode, NULL, index, wpages, FLUSH_STABLE);
+ out:
+ return 1;
+}
+
struct address_space_operations nfs_file_aops = {
readpage: nfs_readpage,
sync_page: nfs_sync_page,
+ flush_page: nfs_flushpage,
writepage: nfs_writepage,
prepare_write: nfs_prepare_write,
commit_write: nfs_commit_write
diff -u --recursive --new-file linux-2.3.99-pre6/fs/ntfs/fs.c linux-2.3.99-pre6-devel/fs/ntfs/fs.c
--- linux-2.3.99-pre6/fs/ntfs/fs.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/ntfs/fs.c Thu Apr 27 16:18:28 2000
@@ -608,6 +608,7 @@
readpage: ntfs_readpage,
writepage: ntfs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: ntfs_prepare_write,
commit_write: generic_commit_write,
bmap: _ntfs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/qnx4/inode.c linux-2.3.99-pre6-devel/fs/qnx4/inode.c
--- linux-2.3.99-pre6/fs/qnx4/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/qnx4/inode.c Thu Apr 27 16:18:50 2000
@@ -431,6 +431,7 @@
readpage: qnx4_readpage,
writepage: qnx4_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: qnx4_prepare_write,
commit_write: generic_commit_write,
bmap: qnx4_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/sysv/inode.c linux-2.3.99-pre6-devel/fs/sysv/inode.c
--- linux-2.3.99-pre6/fs/sysv/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/sysv/inode.c Thu Apr 27 16:19:08 2000
@@ -959,6 +959,7 @@
readpage: sysv_readpage,
writepage: sysv_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: sysv_prepare_write,
commit_write: generic_commit_write,
bmap: sysv_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/fs/udf/file.c linux-2.3.99-pre6-devel/fs/udf/file.c
--- linux-2.3.99-pre6/fs/udf/file.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/udf/file.c Thu Apr 27 16:19:31 2000
@@ -119,6 +119,7 @@
readpage: udf_adinicb_readpage,
writepage: udf_adinicb_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: udf_adinicb_prepare_write,
commit_write: udf_adinicb_commit_write,
};
diff -u --recursive --new-file linux-2.3.99-pre6/fs/udf/inode.c linux-2.3.99-pre6-devel/fs/udf/inode.c
--- linux-2.3.99-pre6/fs/udf/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/udf/inode.c Thu Apr 27 16:19:53 2000
@@ -149,6 +149,7 @@
readpage: udf_readpage,
writepage: udf_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: udf_prepare_write,
commit_write: generic_commit_write,
bmap: udf_bmap,
diff -u --recursive --new-file linux-2.3.99-pre6/fs/ufs/inode.c linux-2.3.99-pre6-devel/fs/ufs/inode.c
--- linux-2.3.99-pre6/fs/ufs/inode.c Wed Apr 26 02:28:56 2000
+++ linux-2.3.99-pre6-devel/fs/ufs/inode.c Thu Apr 27 16:20:14 2000
@@ -560,6 +560,7 @@
readpage: ufs_readpage,
writepage: ufs_writepage,
sync_page: block_sync_page,
+ flush_page: block_flushpage,
prepare_write: ufs_prepare_write,
commit_write: generic_commit_write,
bmap: ufs_bmap
diff -u --recursive --new-file linux-2.3.99-pre6/include/linux/fs.h linux-2.3.99-pre6-devel/include/linux/fs.h
--- linux-2.3.99-pre6/include/linux/fs.h Thu Apr 27 13:44:35 2000
+++ linux-2.3.99-pre6-devel/include/linux/fs.h Thu Apr 27 16:26:50 2000
@@ -341,6 +341,7 @@
int (*writepage)(struct file *, struct dentry *, struct page *);
int (*readpage)(struct dentry *, struct page *);
int (*sync_page)(struct page *);
+ int (*flush_page)(struct page *, unsigned);
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
@@ -1087,7 +1088,7 @@
typedef int (get_block_t)(struct inode*,long,struct buffer_head*,int);
/* Generic buffer handling for block filesystems.. */
-extern int block_flushpage(struct page *, unsigned long);
+extern int block_flushpage(struct page *, unsigned);
extern int block_fsync(struct file *filp, struct dentry *dentry);
extern int block_symlink(struct inode *, const char *, int);
extern int block_write_full_page(struct page*, get_block_t*);
diff -u --recursive --new-file linux-2.3.99-pre6/mm/filemap.c linux-2.3.99-pre6-devel/mm/filemap.c
--- linux-2.3.99-pre6/mm/filemap.c Thu Apr 27 00:06:25 2000
+++ linux-2.3.99-pre6-devel/mm/filemap.c Thu Apr 27 15:23:36 2000
@@ -87,6 +87,15 @@
return 0;
}
+static inline int flush_page(struct page *page, unsigned int partial)
+{
+ struct address_space *mapping = page->mapping;
+
+ if (mapping && mapping->a_ops && mapping->a_ops->flush_page)
+ return mapping->a_ops->flush_page(page, partial);
+ return 1;
+}
+
/*
* Remove a page from the page cache and free it. Caller has to make
* sure the page is locked and that nobody else uses it - or that usage
@@ -97,8 +106,6 @@
if (!PageLocked(page))
PAGE_BUG(page);
- /* Initiate completion of any async operations */
- sync_page(page);
spin_lock(&pagecache_lock);
remove_page_from_inode_queue(page);
@@ -126,7 +133,9 @@
continue;
spin_unlock(&pagecache_lock);
- lru_cache_del(page);
+ /* Initiate completion of any async operations */
+ if (flush_page(page, 0))
+ lru_cache_del(page);
remove_inode_page(page);
UnlockPage(page);
page_cache_release(page);
@@ -172,9 +181,8 @@
get_page(page);
spin_unlock(&pagecache_lock);
- if (!page->buffers || block_flushpage(page, 0))
+ if (flush_page(page, 0))
lru_cache_del(page);
-
/*
* We remove the page from the page cache
* _after_ we have destroyed all buffer-cache
@@ -217,8 +225,7 @@
spin_unlock(&pagecache_lock);
memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
- if (page->buffers)
- block_flushpage(page, partial);
+ flush_page(page, partial);
partial = 0;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Apr 30 2000 - 21:00:13 EST