cramfs use pagecache
PATCH 1/1 cramfs use pagecache
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
(sending again cause I messed up the lkml addr)
i
Hi Al,
We recently hit a problem when we wanted to have both cramfs and minix support built-in. If we tried to mount a minix filesystem from ramdisk, depending on link order, cramfs would be tried first, and it would invalidate the pagecache in an attempt to set_blocksize.
I saw you fixed this in 2.6, and I backported the fix to 2.4. If this looks good, could this get applied to the 2.4 tree?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD4DBQFAiUhydQs4kOxk3/MRAtATAJ0T98a+DpYiTDAPLsX2j4EmEOESCQCWP1Vr ElkL7Hz6vX2BYRxlCcOrrQ==
=yKtF
-----END PGP SIGNATURE-----
fs/cramfs/inode.c +27 -25
@@ -111,8 +111,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;int major, minor;
@@ -139,7 +139,7 @@ static void *cramfs_read(struct super_blreturn read_buffers[i] + blk_offset; } - devsize = ~0UL ; + devsize = mapping->host->i_size >>PAGE_CACHE_SHIFT ; major =MAJOR (sb->s_dev); minor =MINOR (sb->s_dev);
@@ -149,26 +149,31 @@ static void *cramfs_read(struct super_bl/* 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 (page); +if (!Page_Uptodate (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;
@@ -176,10 +181,11 @@ static void *cramfs_read(struct super_bl 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 ;
@@ -195,10 +201,6 @@ static struct super_block * cramfs_read_unsigned long root_offset;struct super_block * retval =NULL ; -set_blocksize (sb->s_dev,PAGE_CACHE_SIZE ); - sb->s_blocksize =PAGE_CACHE_SIZE ; - sb->s_blocksize_bits =PAGE_CACHE_SHIFT ; -/* Invalidate the read buffers on mount: think disk change.. */ for (i =0 ; i <READ_BUFFERS ; i++) buffer_blocknr[i] =-1 ;