From 5524f26f3c6f3ce54dd76bb8651fec4544199ae7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 18 Jan 2004 18:07:25 -0800 Subject: [PATCH] [PATCH] cramfs: use pagecache better From: viro@parcelfarce.linux.theplanet.co.uk Patch switches cramfs_read() to direct use of pagecache and eliminates all messing with buffer_heads. Fixes the interaction with ramdisk (there set_blocksize() simply killed the ramdisk contents) and gets code less brittle overall. --- fs/cramfs/inode.c | 50 ++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 2366983b20d57..c73eee7d7896c 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -112,8 +112,8 @@ static int next_buffer; */ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) { - struct buffer_head * bh_array[BLKS_PER_BUF]; - struct buffer_head * read_array[BLKS_PER_BUF]; + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; + struct page *pages[BLKS_PER_BUF]; unsigned i, blocknr, buffer, unread; unsigned long devsize; char *data; @@ -138,33 +138,36 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i return read_buffers[i] + blk_offset; } - devsize = sb->s_bdev->bd_inode->i_size >> 12; - if (!devsize) - devsize = ~0UL; + devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; /* Ok, read in BLKS_PER_BUF pages completely first. */ unread = 0; for (i = 0; i < BLKS_PER_BUF; i++) { - struct buffer_head *bh; + struct page *page = NULL; - bh = NULL; if (blocknr + i < devsize) { - bh = sb_getblk(sb, blocknr + i); - if (!buffer_uptodate(bh)) - read_array[unread++] = bh; + page = read_cache_page(mapping, blocknr + i, + (filler_t *)mapping->a_ops->readpage, + NULL); + /* synchronous error? */ + if (IS_ERR(page)) + page = NULL; } - bh_array[i] = bh; + pages[i] = page; } - if (unread) { - ll_rw_block(READ, unread, read_array); - do { - unread--; - wait_on_buffer(read_array[unread]); - } while (unread); + for (i = 0; i < BLKS_PER_BUF; i++) { + struct page *page = pages[i]; + if (page) { + wait_on_page_locked(page); + if (!PageUptodate(page)) { + /* asynchronous error */ + page_cache_release(page); + pages[i] = NULL; + } + } } - /* Ok, copy them to the staging area without sleeping. */ buffer = next_buffer; next_buffer = NEXT_BUFFER(buffer); buffer_blocknr[buffer] = blocknr; @@ -172,10 +175,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i data = read_buffers[buffer]; for (i = 0; i < BLKS_PER_BUF; i++) { - struct buffer_head * bh = bh_array[i]; - if (bh) { - memcpy(data, bh->b_data, PAGE_CACHE_SIZE); - brelse(bh); + struct page *page = pages[i]; + if (page) { + memcpy(data, kmap(page), PAGE_CACHE_SIZE); + kunmap(page); + page_cache_release(page); } else memset(data, 0, PAGE_CACHE_SIZE); data += PAGE_CACHE_SIZE; @@ -202,8 +206,6 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; memset(sbi, 0, sizeof(struct cramfs_sb_info)); - sb_set_blocksize(sb, PAGE_CACHE_SIZE); - /* Invalidate the read buffers on mount: think disk change.. */ down(&read_mutex); for (i = 0; i < READ_BUFFERS; i++) -- 2.53.0