Re: Generic API for asynchronous filesystems (w/ Patch)

From: Trond Myklebust (trond.myklebust@fys.uio.no)
Date: Thu Apr 27 2000 - 10:23:03 EST


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