The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/coda/inode.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Super block/filesystem wide operations
    3  *
    4  * Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and 
    5  * Michael Callahan <callahan@maths.ox.ac.uk> 
    6  * 
    7  * Rewritten for Linux 2.1.  Peter Braam <braam@cs.cmu.edu>
    8  * Copyright (C) Carnegie Mellon University
    9  */
   10 
   11 #define __NO_VERSION__
   12 #include <linux/module.h>
   13 #include <linux/kernel.h>
   14 #include <linux/mm.h>
   15 #include <linux/string.h>
   16 #include <linux/stat.h>
   17 #include <linux/errno.h>
   18 #include <linux/locks.h>
   19 #include <linux/unistd.h>
   20 #include <linux/smp_lock.h>
   21 #include <linux/file.h>
   22 
   23 #include <asm/system.h>
   24 #include <asm/uaccess.h>
   25 
   26 #include <linux/fs.h>
   27 #include <linux/vmalloc.h>
   28 
   29 #include <linux/coda.h>
   30 #include <linux/coda_linux.h>
   31 #include <linux/coda_psdev.h>
   32 #include <linux/coda_fs_i.h>
   33 #include <linux/coda_cache.h>
   34 
   35 /* VFS super_block ops */
   36 static struct super_block *coda_read_super(struct super_block *, void *, int);
   37 static void coda_read_inode(struct inode *);
   38 static void coda_clear_inode(struct inode *);
   39 static void coda_put_super(struct super_block *);
   40 static int coda_statfs(struct super_block *sb, struct statfs *buf);
   41 
   42 /* exported operations */
   43 struct super_operations coda_super_operations =
   44 {
   45         read_inode:     coda_read_inode,
   46         clear_inode:    coda_clear_inode,
   47         put_super:      coda_put_super,
   48         statfs:         coda_statfs,
   49 };
   50 
   51 static int get_device_index(struct coda_mount_data *data)
   52 {
   53         struct file *file;
   54         struct inode *inode;
   55         int idx;
   56 
   57         if(data == NULL) {
   58                 printk("coda_read_super: Bad mount data\n");
   59                 return -1;
   60         }
   61 
   62         if(data->version != CODA_MOUNT_VERSION) {
   63                 printk("coda_read_super: Bad mount version\n");
   64                 return -1;
   65         }
   66 
   67         file = fget(data->fd);
   68         inode = NULL;
   69         if(file)
   70                 inode = file->f_dentry->d_inode;
   71         
   72         if(!inode || !S_ISCHR(inode->i_mode) ||
   73            MAJOR(inode->i_rdev) != CODA_PSDEV_MAJOR) {
   74                 if(file)
   75                         fput(file);
   76 
   77                 printk("coda_read_super: Bad file\n");
   78                 return -1;
   79         }
   80 
   81         idx = MINOR(inode->i_rdev);
   82         fput(file);
   83 
   84         if(idx < 0 || idx >= MAX_CODADEVS) {
   85                 printk("coda_read_super: Bad minor number\n");
   86                 return -1;
   87         }
   88 
   89         return idx;
   90 }
   91 
   92 static struct super_block * coda_read_super(struct super_block *sb, 
   93                                             void *data, int silent)
   94 {
   95         struct inode *root = 0; 
   96         struct coda_sb_info *sbi = NULL;
   97         struct venus_comm *vc = NULL;
   98         ViceFid fid;
   99         int error;
  100         int idx;
  101 
  102         idx = get_device_index((struct coda_mount_data *) data);
  103 
  104         /* Ignore errors in data, for backward compatibility */
  105         if(idx == -1)
  106                 idx = 0;
  107         
  108         printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
  109 
  110         vc = &coda_comms[idx];
  111         if (!vc->vc_inuse) {
  112                 printk("coda_read_super: No pseudo device\n");
  113                 return NULL;
  114         }
  115 
  116         if ( vc->vc_sb ) {
  117                 printk("coda_read_super: Device already mounted\n");
  118                 return NULL;
  119         }
  120 
  121         sbi = kmalloc(sizeof(struct coda_sb_info), GFP_KERNEL);
  122         if(!sbi) {
  123                 return NULL;
  124         }
  125 
  126         vc->vc_sb = sb;
  127 
  128         sbi->sbi_sb = sb;
  129         sbi->sbi_vcomm = vc;
  130         INIT_LIST_HEAD(&sbi->sbi_cihead);
  131         init_MUTEX(&sbi->sbi_iget4_mutex);
  132 
  133         sb->u.generic_sbp = sbi;
  134         sb->s_blocksize = 1024; /* XXXXX  what do we put here?? */
  135         sb->s_blocksize_bits = 10;
  136         sb->s_magic = CODA_SUPER_MAGIC;
  137         sb->s_op = &coda_super_operations;
  138 
  139         /* get root fid from Venus: this needs the root inode */
  140         error = venus_rootfid(sb, &fid);
  141         if ( error ) {
  142                 printk("coda_read_super: coda_get_rootfid failed with %d\n",
  143                        error);
  144                 goto error;
  145         }         
  146         printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid));
  147         
  148         /* make root inode */
  149         error = coda_cnode_make(&root, &fid, sb);
  150         if ( error || !root ) {
  151             printk("Failure of coda_cnode_make for root: error %d\n", error);
  152             goto error;
  153         } 
  154 
  155         printk("coda_read_super: rootinode is %ld dev %d\n", 
  156                root->i_ino, root->i_dev);
  157         sb->s_root = d_alloc_root(root);
  158         return sb;
  159 
  160  error:
  161         if (sbi) {
  162                 kfree(sbi);
  163                 if(vc)
  164                         vc->vc_sb = NULL;               
  165         }
  166         if (root)
  167                 iput(root);
  168 
  169         return NULL;
  170 }
  171 
  172 static void coda_put_super(struct super_block *sb)
  173 {
  174         struct coda_sb_info *sbi;
  175 
  176         sbi = coda_sbp(sb);
  177         sbi->sbi_vcomm->vc_sb = NULL;
  178         list_del_init(&sbi->sbi_cihead);
  179 
  180         printk("Coda: Bye bye.\n");
  181         kfree(sbi);
  182 }
  183 
  184 /* all filling in of inodes postponed until lookup */
  185 static void coda_read_inode(struct inode *inode)
  186 {
  187         struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
  188         struct coda_inode_info *cii;
  189 
  190         if (!sbi) BUG();
  191 
  192         cii = ITOC(inode);
  193         if (!coda_isnullfid(&cii->c_fid)) {
  194             printk("coda_read_inode: initialized inode");
  195             return;
  196         }
  197 
  198         cii->c_mapcount = 0;
  199         list_add(&cii->c_cilist, &sbi->sbi_cihead);
  200 }
  201 
  202 static void coda_clear_inode(struct inode *inode)
  203 {
  204         struct coda_inode_info *cii = ITOC(inode);
  205 
  206         CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n", 
  207                inode->i_ino, atomic_read(&inode->i_count));        
  208         CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
  209 
  210         list_del_init(&cii->c_cilist);
  211         coda_cache_clear_inode(inode);
  212 }
  213 
  214 int coda_notify_change(struct dentry *de, struct iattr *iattr)
  215 {
  216         struct inode *inode = de->d_inode;
  217         struct coda_vattr vattr;
  218         int error;
  219 
  220         memset(&vattr, 0, sizeof(vattr)); 
  221 
  222         inode->i_ctime = CURRENT_TIME;
  223         coda_iattr_to_vattr(iattr, &vattr);
  224         vattr.va_type = C_VNON; /* cannot set type */
  225         CDEBUG(D_SUPER, "vattr.va_mode %o\n", vattr.va_mode);
  226 
  227         /* Venus is responsible for truncating the container-file!!! */
  228         error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
  229 
  230         if ( !error ) {
  231                 coda_vattr_to_iattr(inode, &vattr); 
  232                 coda_cache_clear_inode(inode);
  233         }
  234         CDEBUG(D_SUPER, "inode.i_mode %o, error %d\n", inode->i_mode, error);
  235 
  236         return error;
  237 }
  238 
  239 struct inode_operations coda_file_inode_operations = {
  240         permission:     coda_permission,
  241         revalidate:     coda_revalidate_inode,
  242         setattr:        coda_notify_change,
  243 };
  244 
  245 static int coda_statfs(struct super_block *sb, struct statfs *buf)
  246 {
  247         int error;
  248 
  249         error = venus_statfs(sb, buf);
  250 
  251         if (error) {
  252                 /* fake something like AFS does */
  253                 buf->f_blocks = 9000000;
  254                 buf->f_bfree  = 9000000;
  255                 buf->f_bavail = 9000000;
  256                 buf->f_files  = 9000000;
  257                 buf->f_ffree  = 9000000;
  258         }
  259 
  260         /* and fill in the rest */
  261         buf->f_type = CODA_SUPER_MAGIC;
  262         buf->f_bsize = 1024;
  263         buf->f_namelen = CODA_MAXNAMLEN;
  264 
  265         return 0; 
  266 }
  267 
  268 /* init_coda: used by filesystems.c to register coda */
  269 
  270 DECLARE_FSTYPE( coda_fs_type, "coda", coda_read_super, 0);
  271 

Cache object: 968ad4e61590508610d3f21c4b64ecbc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.