patch-2.4.27 linux-2.4.27/fs/cramfs/inode.c

Next file: linux-2.4.27/fs/devfs/base.c
Previous file: linux-2.4.27/fs/buffer.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.26/fs/cramfs/inode.c linux-2.4.27/fs/cramfs/inode.c
@@ -111,8 +111,8 @@
  */
 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 @@
 		return 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 @@
 	/* 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 @@
 
 	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 @@
 	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;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)