Commit 5524f26f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent 8fbd544c
...@@ -112,8 +112,8 @@ static int next_buffer; ...@@ -112,8 +112,8 @@ static int next_buffer;
*/ */
static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
{ {
struct buffer_head * bh_array[BLKS_PER_BUF]; struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
struct buffer_head * read_array[BLKS_PER_BUF]; struct page *pages[BLKS_PER_BUF];
unsigned i, blocknr, buffer, unread; unsigned i, blocknr, buffer, unread;
unsigned long devsize; unsigned long devsize;
char *data; char *data;
...@@ -138,33 +138,36 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i ...@@ -138,33 +138,36 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
return read_buffers[i] + blk_offset; return read_buffers[i] + blk_offset;
} }
devsize = sb->s_bdev->bd_inode->i_size >> 12; devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT;
if (!devsize)
devsize = ~0UL;
/* Ok, read in BLKS_PER_BUF pages completely first. */ /* Ok, read in BLKS_PER_BUF pages completely first. */
unread = 0; unread = 0;
for (i = 0; i < BLKS_PER_BUF; i++) { for (i = 0; i < BLKS_PER_BUF; i++) {
struct buffer_head *bh; struct page *page = NULL;
bh = NULL;
if (blocknr + i < devsize) { if (blocknr + i < devsize) {
bh = sb_getblk(sb, blocknr + i); page = read_cache_page(mapping, blocknr + i,
if (!buffer_uptodate(bh)) (filler_t *)mapping->a_ops->readpage,
read_array[unread++] = bh; NULL);
/* synchronous error? */
if (IS_ERR(page))
page = NULL;
} }
bh_array[i] = bh; pages[i] = page;
} }
if (unread) { for (i = 0; i < BLKS_PER_BUF; i++) {
ll_rw_block(READ, unread, read_array); struct page *page = pages[i];
do { if (page) {
unread--; wait_on_page_locked(page);
wait_on_buffer(read_array[unread]); if (!PageUptodate(page)) {
} while (unread); /* asynchronous error */
page_cache_release(page);
pages[i] = NULL;
}
}
} }
/* Ok, copy them to the staging area without sleeping. */
buffer = next_buffer; buffer = next_buffer;
next_buffer = NEXT_BUFFER(buffer); next_buffer = NEXT_BUFFER(buffer);
buffer_blocknr[buffer] = blocknr; buffer_blocknr[buffer] = blocknr;
...@@ -172,10 +175,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i ...@@ -172,10 +175,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
data = read_buffers[buffer]; data = read_buffers[buffer];
for (i = 0; i < BLKS_PER_BUF; i++) { for (i = 0; i < BLKS_PER_BUF; i++) {
struct buffer_head * bh = bh_array[i]; struct page *page = pages[i];
if (bh) { if (page) {
memcpy(data, bh->b_data, PAGE_CACHE_SIZE); memcpy(data, kmap(page), PAGE_CACHE_SIZE);
brelse(bh); kunmap(page);
page_cache_release(page);
} else } else
memset(data, 0, PAGE_CACHE_SIZE); memset(data, 0, PAGE_CACHE_SIZE);
data += PAGE_CACHE_SIZE; data += PAGE_CACHE_SIZE;
...@@ -202,8 +206,6 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -202,8 +206,6 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
memset(sbi, 0, sizeof(struct cramfs_sb_info)); memset(sbi, 0, sizeof(struct cramfs_sb_info));
sb_set_blocksize(sb, PAGE_CACHE_SIZE);
/* Invalidate the read buffers on mount: think disk change.. */ /* Invalidate the read buffers on mount: think disk change.. */
down(&read_mutex); down(&read_mutex);
for (i = 0; i < READ_BUFFERS; i++) for (i = 0; i < READ_BUFFERS; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment