> Where can I find the operation of loopback mounts outlined? > It's not clear from kernel source nor from the Documentation > directory. > Here ya go Richard. This patch is probably not entirely correct and it requires that you're ext2 file be in fixed record length in multiples of 512, 1024, 2048, or 4096 (only tested 4096). It should handle the standard CMS block sizes.
This is just a cobbling of different pieces of code and this is the first
time I've played around with filesystems, so I'd do a lot of testing if'n I
were you. ;-D
Leland
<<<<snippity>>>>
--- cmsfs-1.1.7.orig/cmsfs24x.c 2003-03-04 11:56:17.000000000 -0600
+++ cmsfs-1.1.7/cmsfs24x.c 2003-07-17 03:06:14.000000000 -0500
@@ -463,6 +463,108 @@
open: cmsfs_file_open,
};
+static int
+cmsfs_readpage( struct file *fi, struct page *pg )
+{
+ struct CMSINODE *ci;
+ unsigned long offset;
+ unsigned long needlen;
+ unsigned long blksz;
+ unsigned long rdblk;
+ unsigned long len;
+ void *buf;
+ char *ptr;
+ int result = -EIO;
+
+ ci = fi->f_dentry->d_inode->u.generic_ip;
+ if( ci->vfsinode != fi->f_dentry->d_inode )
+ {
+ sprintf( cmsfs_ermsg,
+ "cmsfs_readpage(): CMS struct for inode %lu is corrupted",
+ fi->f_dentry->d_inode->i_ino );
+ cmsfs_error( cmsfs_ermsg );
+ return result;
+ }
+
+ if( ci->recfm[ 0 ] != 'F' )
+ {
+ sprintf( cmsfs_ermsg,
+ "cmsfs_readpage(): Record format not fixed" );
+ cmsfs_error( cmsfs_ermsg );
+ return result;
+ }
+
+ if( ci->rdbuf == NULL )
+ {
+ ci->rdbuf = cmsfs_malloc( ci->cmssuper->blksz );
+ if( ci->rdbuf == NULL )
+ {
+ cmsfs_error( "cmsfs_readpage(): unable to allocate a work
buffer");
+ return result;
+ }
+ }
+
+#if CMSFS_DEBUG
+ sprintf( cmsfs_ermsg,
+ "cmsfs_readpage(): inode %lu, file '%s'",
+ fi->f_dentry->d_inode->i_ino,ci->name );
+ cmsfs_error( cmsfs_ermsg );
+#endif
+
+ page_cache_get( pg );
+ buf = kmap( pg );
+ if( buf )
+ {
+ offset = pg->index << PAGE_CACHE_SHIFT;
+ if( offset < ci->bytes )
+ {
+ blksz = ci->cmssuper->blksz;
+ rdblk = offset / blksz;
+ ptr = buf;
+
+ needlen = PAGE_SIZE;
+ while( needlen > 0 )
+ {
+ if( cmsfsrd2( ci, ci->rdbuf, rdblk ) != blksz )
+ {
+ cmsfs_error( "cmsfs_read(): could not read block" );
+ break;
+ }
+ len = min_t( unsigned long, needlen, blksz );
+
+ memcpy( ptr, ci->rdbuf, len );
+ ptr += len;
+ needlen -= len;
+ rdblk++;
+ }
+
+ if( needlen == 0 )
+ {
+ SetPageUptodate( pg );
+ result = 0;
+ }
+ }
+
+ if( result )
+ {
+ memset( buf, 0, PAGE_SIZE );
+ SetPageError( pg );
+ }
+
+ flush_dcache_page( pg );
+ UnlockPage( pg );
+ kunmap( pg );
+ }
+
+ page_cache_release( pg );
+
+ return result;
+}
+
+static struct address_space_operations cmsfs_aops = {
+ readpage: cmsfs_readpage
+};
+
/* -------------------------------------------------- CMSFS_INODE_LOOKUP
* Search for the file in the CMS directory.
* Calls: cmsfs_lookup() to find the file,
@@ -720,6 +822,7 @@
cmsfs_error(cmsfs_ermsg);
#endif
cmssuper->inuse += ct;
+ in->i_data.a_ops = &cmsfs_aops;
#ifdef CMSFS_DEBUG
(void) sprintf(cmsfs_ermsg,
"cmsfs_read_inode(): CMS superblock usage now %d",
<<<<snippity>>>>
cmsfs-1.1.7-readpage.diff
Description: Binary data
