"Fossies" - the Fresh Open Source Software Archive

Member "linux-coda-6.9/linux2.2/file.c" (1 Dec 2009, 8761 Bytes) of package /linux/misc/old/linux-coda-6.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * File operations for Coda.
    3  * Original version: (C) 1996 Peter Braam 
    4  * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
    5  *
    6  * Carnegie Mellon encourages users of this code to contribute improvements
    7  * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
    8  */
    9 
   10 #include <linux/types.h>
   11 #include <linux/kernel.h>
   12 #include <linux/sched.h>
   13 #include <linux/fs.h>
   14 #include <linux/stat.h>
   15 #include <linux/errno.h>
   16 #include <linux/locks.h>
   17 #include <asm/segment.h>
   18 #include <linux/string.h>
   19 #include <asm/uaccess.h>
   20 
   21 #include <linux/coda.h>
   22 #include <linux/coda_linux.h>
   23 #include <linux/coda_fs_i.h>
   24 #include <linux/coda_psdev.h>
   25 #include <linux/coda_cache.h>
   26 #include <linux/coda_proc.h>
   27 
   28 /* file operations */
   29 static int coda_readpage(struct file *file, struct page * page);
   30 static ssize_t coda_file_read(struct file *f, char *buf, size_t count, loff_t *off);
   31 static ssize_t coda_file_write(struct file *f, const char *buf, size_t count, loff_t *off);
   32 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma);
   33 
   34 /* also exported from this file (used for dirs) */
   35 int coda_fsync(struct file *, struct dentry *dentry);
   36 
   37 struct inode_operations coda_file_inode_operations = {
   38     &coda_file_operations,  /* default file operations */
   39     NULL,           /* create */
   40     NULL,               /* lookup */
   41     NULL,           /* link */
   42     NULL,               /* unlink */
   43     NULL,           /* symlink */
   44     NULL,           /* mkdir */
   45     NULL,           /* rmdir */
   46     NULL,           /* mknod */
   47     NULL,               /* rename */
   48     NULL,           /* readlink */
   49     NULL,           /* follow_link */
   50     coda_readpage,      /* readpage */
   51     NULL,           /* writepage */
   52     NULL,           /* bmap */
   53     NULL,           /* truncate */
   54         coda_permission,        /* permission */
   55     NULL,                   /* smap */
   56     NULL,                   /* update page */
   57         coda_revalidate_inode   /* revalidate */
   58 };
   59 
   60 struct file_operations coda_file_operations = {
   61     NULL,               /* lseek - default should work for coda */
   62     coda_file_read,         /* read */
   63     coda_file_write,        /* write */
   64     NULL,               /* readdir */
   65     NULL,           /* select - default */
   66     NULL,               /* ioctl */
   67     coda_file_mmap,         /* mmap */
   68     coda_open,              /* open */
   69     NULL,
   70     coda_release,           /* release */
   71     coda_fsync,     /* fsync */
   72     NULL,                   /* fasync */
   73     NULL,                   /* check_media_change */
   74     NULL,                   /* revalidate */
   75     NULL                    /* lock */
   76 };
   77 
   78 /*  File file operations */
   79 static int coda_readpage(struct file * coda_file, struct page * page)
   80 {
   81     struct dentry *de = coda_file->f_dentry;
   82     struct inode *coda_inode = de->d_inode;
   83     struct dentry cont_dentry;
   84     struct file cont_file;
   85         struct coda_inode_info *cii;
   86 
   87         ENTRY;
   88     coda_vfs_stat.readpage++;
   89         
   90         cii = ITOC(coda_inode);
   91 
   92         if ( ! cii->c_ovp ) {
   93         printk("coda_readpage: no open inode for ino %ld, %s\n", 
   94                coda_inode->i_ino, de->d_name.name);
   95                 return -ENXIO;
   96         }
   97        
   98         coda_prepare_openfile(coda_inode, coda_file, cii->c_ovp,
   99                   &cont_file, &cont_dentry);
  100 
  101         CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", 
  102            coda_inode->i_ino, cii->c_ovp->i_ino, page->offset);
  103 
  104         generic_readpage(&cont_file, page);
  105         EXIT;
  106         return 0;
  107 }
  108 
  109 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma)
  110 {
  111         struct coda_inode_info *cii;
  112     int res;
  113 
  114     coda_vfs_stat.file_mmap++;
  115 
  116         ENTRY;
  117     cii = ITOC(file->f_dentry->d_inode);
  118     cii->c_mmcount++;
  119   
  120     res =generic_file_mmap(file, vma);
  121     EXIT;
  122     return res;
  123 }
  124 
  125 static ssize_t coda_file_read(struct file *coda_file, char *buff, 
  126                size_t count, loff_t *ppos)
  127 {
  128         struct coda_inode_info *cnp;
  129     struct inode *coda_inode = coda_file->f_dentry->d_inode;
  130         struct inode *cont_inode = NULL;
  131         struct file  cont_file;
  132     struct dentry cont_dentry;
  133         int result = 0;
  134 
  135     ENTRY;
  136     coda_vfs_stat.file_read++;
  137 
  138         cnp = ITOC(coda_inode);
  139         CHECK_CNODE(cnp);
  140     
  141         cont_inode = cnp->c_ovp;
  142         if ( cont_inode == NULL ) {
  143                 printk("coda_file_read: cached inode is 0!\n");
  144                 return -1;
  145         }
  146 
  147         coda_prepare_openfile(coda_inode, coda_file, cont_inode, 
  148                   &cont_file, &cont_dentry);
  149 
  150         if (!cont_file.f_op || ! cont_file.f_op->read) { 
  151                 printk( "container file has no read in file operations.\n");
  152                 return -1;
  153         }
  154 
  155         result = cont_file.f_op->read(&cont_file , buff, count, 
  156                       &(cont_file.f_pos));
  157 
  158         CDEBUG(D_FILE, "ops at %p result %d, count %ld, position: %d\n", 
  159            cont_file.f_op, result, (long)count, (int)cont_file.f_pos);
  160 
  161         coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file);
  162         return result;
  163 }
  164 
  165 
  166 static ssize_t coda_file_write(struct file *coda_file, const char *buff, 
  167                 size_t count, loff_t *ppos)
  168 {
  169         struct coda_inode_info *cnp;
  170     struct inode *coda_inode = coda_file->f_dentry->d_inode;
  171         struct inode *cont_inode = NULL;
  172         struct file  cont_file;
  173     struct dentry cont_dentry;
  174         int result = 0;
  175 
  176         ENTRY;
  177     coda_vfs_stat.file_write++;
  178 
  179         cnp = ITOC(coda_inode);
  180         CHECK_CNODE(cnp);
  181 
  182         cont_inode = cnp->c_ovp;
  183         if ( cont_inode == NULL ) {
  184                 printk("coda_file_write: cached inode is 0!\n");
  185                 return -1; 
  186         }
  187 
  188         coda_prepare_openfile(coda_inode, coda_file, cont_inode, 
  189                   &cont_file, &cont_dentry);
  190 
  191         if (!cont_file.f_op || !cont_file.f_op->write) {
  192                 printk("coda_file_write: container file has no file ops.\n");
  193                 return -1;
  194         }
  195 
  196     down(&cont_inode->i_sem);
  197         result = cont_file.f_op->write(&cont_file , buff, count, 
  198                        &(cont_file.f_pos));
  199     up(&cont_inode->i_sem);
  200         coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file);
  201     
  202     if (result)
  203         cnp->c_flags |= C_VATTR;
  204 
  205         return result;
  206 }
  207 
  208 int coda_fsync(struct file *coda_file, struct dentry *coda_dentry)
  209 {
  210         struct coda_inode_info *cnp;
  211     struct inode *coda_inode = coda_dentry->d_inode;
  212         struct inode *cont_inode = NULL;
  213         struct file  cont_file;
  214     struct dentry cont_dentry;
  215         int result = 0;
  216         ENTRY;
  217     coda_vfs_stat.fsync++;
  218 
  219     if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
  220           S_ISLNK(coda_inode->i_mode)))
  221         return -EINVAL;
  222 
  223         cnp = ITOC(coda_inode);
  224         CHECK_CNODE(cnp);
  225 
  226         cont_inode = cnp->c_ovp;
  227         if ( cont_inode == NULL ) {
  228                 printk("coda_file_write: cached inode is 0!\n");
  229                 return -1; 
  230         }
  231 
  232         coda_prepare_openfile(coda_inode, coda_file, cont_inode, 
  233                   &cont_file, &cont_dentry);
  234 
  235     down(&cont_inode->i_sem);
  236 
  237         result = file_fsync(&cont_file ,&cont_dentry);
  238     if ( result == 0 ) {
  239         result = venus_fsync(coda_inode->i_sb, &(cnp->c_fid));
  240     }
  241 
  242     up(&cont_inode->i_sem);
  243 
  244         coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file);
  245         return result;
  246 }
  247 /* 
  248  * support routines
  249  */
  250 
  251 /* instantiate the container file and dentry object to do io */                
  252 void coda_prepare_openfile(struct inode *i, struct file *coda_file, 
  253                struct inode *cont_inode, struct file *cont_file,
  254                struct dentry *cont_dentry)
  255 {
  256         cont_file->f_pos = coda_file->f_pos;
  257         cont_file->f_mode = coda_file->f_mode;
  258         cont_file->f_flags = coda_file->f_flags;
  259         cont_file->f_count  = coda_file->f_count;
  260         cont_file->f_owner  = coda_file->f_owner;
  261     cont_file->f_op = cont_inode->i_op->default_file_ops;
  262     cont_file->f_dentry = cont_dentry;
  263         cont_file->f_dentry->d_inode = cont_inode;
  264         return ;
  265 }
  266 
  267 /* update the Coda file & inode after I/O */
  268 void coda_restore_codafile(struct inode *coda_inode, struct file *coda_file, 
  269                struct inode *open_inode, struct file *open_file)
  270 {
  271         coda_file->f_pos = open_file->f_pos;
  272     /* XXX what about setting the mtime here too? */
  273     /* coda_inode->i_mtime = open_inode->i_mtime; */
  274     coda_inode->i_size = open_inode->i_size;
  275         return;
  276 }
  277 
  278 /* grab the ext2 inode of the container file */
  279 int coda_inode_grab(dev_t dev, ino_t ino, struct inode **ind)
  280 {
  281         struct super_block *sbptr;
  282 
  283         sbptr = get_super(dev);
  284 
  285         if ( !sbptr ) {
  286                 printk("coda_inode_grab: coda_find_super returns NULL.\n");
  287                 return -ENXIO;
  288         }
  289                 
  290         *ind = NULL;
  291         *ind = iget(sbptr, ino);
  292 
  293         if ( *ind == NULL ) {
  294                 printk("coda_inode_grab: iget(dev: %d, ino: %ld) 
  295                        returns NULL.\n", dev, (long)ino);
  296                 return -ENOENT;
  297         }
  298     CDEBUG(D_FILE, "ino: %ld, ops at %p\n", (long)ino, (*ind)->i_op);
  299         return 0;
  300 }
  301