> 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>>>>

Attachment: cmsfs-1.1.7-readpage.diff
Description: Binary data

Reply via email to