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/cnode.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 /* cnode related routines for the coda kernel code
    2    (C) 1996 Peter Braam
    3    */
    4 
    5 #include <linux/types.h>
    6 #include <linux/string.h>
    7 #include <linux/time.h>
    8 
    9 #include <linux/coda.h>
   10 #include <linux/coda_linux.h>
   11 #include <linux/coda_fs_i.h>
   12 #include <linux/coda_psdev.h>
   13 
   14 extern int coda_debug;
   15 
   16 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
   17 {
   18         if (fid1->Vnode != fid2->Vnode)   return 0;
   19         if (fid1->Volume != fid2->Volume) return 0;
   20         if (fid1->Unique != fid2->Unique) return 0;
   21         return 1;
   22 }
   23 
   24 inline int coda_isnullfid(ViceFid *fid)
   25 {
   26         if (fid->Vnode || fid->Volume || fid->Unique) return 0;
   27         return 1;
   28 }
   29 
   30 static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
   31 {
   32         return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
   33 }
   34 
   35 static struct inode_operations coda_symlink_inode_operations = {
   36         readlink:       page_readlink,
   37         follow_link:    page_follow_link,
   38         setattr:        coda_notify_change,
   39 };
   40 
   41 /* cnode.c */
   42 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
   43 {
   44         CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
   45 
   46         if (coda_debug & D_SUPER ) 
   47                 print_vattr(attr);
   48 
   49         coda_vattr_to_iattr(inode, attr);
   50 
   51         if (S_ISREG(inode->i_mode)) {
   52                 inode->i_op = &coda_file_inode_operations;
   53                 inode->i_fop = &coda_file_operations;
   54         } else if (S_ISDIR(inode->i_mode)) {
   55                 inode->i_op = &coda_dir_inode_operations;
   56                 inode->i_fop = &coda_dir_operations;
   57         } else if (S_ISLNK(inode->i_mode)) {
   58                 inode->i_op = &coda_symlink_inode_operations;
   59                 inode->i_data.a_ops = &coda_symlink_aops;
   60                 inode->i_mapping = &inode->i_data;
   61         } else
   62                 init_special_inode(inode, inode->i_mode, attr->va_rdev);
   63 }
   64 
   65 struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
   66                          struct coda_vattr * attr)
   67 {
   68         struct inode *inode;
   69         struct coda_inode_info *cii;
   70         ino_t ino = coda_f2i(fid);
   71         struct coda_sb_info *sbi = coda_sbp(sb);
   72 
   73         down(&sbi->sbi_iget4_mutex);
   74         inode = iget4(sb, ino, coda_inocmp, fid);
   75 
   76         if ( !inode ) { 
   77                 CDEBUG(D_CNODE, "coda_iget: no inode\n");
   78                 up(&sbi->sbi_iget4_mutex);
   79                 return ERR_PTR(-ENOMEM);
   80         }
   81 
   82         /* check if the inode is already initialized */
   83         cii = ITOC(inode);
   84         if (coda_isnullfid(&cii->c_fid))
   85                 /* new, empty inode found... initializing */
   86                 cii->c_fid = *fid;
   87         up(&sbi->sbi_iget4_mutex);
   88 
   89         /* always replace the attributes, type might have changed */
   90         coda_fill_inode(inode, attr);
   91         return inode;
   92 }
   93 
   94 /* this is effectively coda_iget:
   95    - get attributes (might be cached)
   96    - get the inode for the fid using vfs iget
   97    - link the two up if this is needed
   98    - fill in the attributes
   99 */
  100 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
  101 {
  102         struct coda_vattr attr;
  103         int error;
  104         
  105         /* We get inode numbers from Venus -- see venus source */
  106         error = venus_getattr(sb, fid, &attr);
  107         if ( error ) {
  108             CDEBUG(D_CNODE, 
  109                    "coda_cnode_make: coda_getvattr returned %d for %s.\n", 
  110                    error, coda_f2s(fid));
  111             *inode = NULL;
  112             return error;
  113         } 
  114 
  115         *inode = coda_iget(sb, fid, &attr);
  116         if ( IS_ERR(*inode) ) {
  117                 printk("coda_cnode_make: coda_iget failed\n");
  118                 return PTR_ERR(*inode);
  119         }
  120 
  121         CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
  122                 (*inode)->i_ino, atomic_read(&(*inode)->i_count), 
  123                 coda_f2s(&ITOC(*inode)->c_fid));
  124         return 0;
  125 }
  126 
  127 
  128 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, 
  129                       struct ViceFid *newfid)
  130 {
  131         struct coda_inode_info *cii;
  132         
  133         cii = ITOC(inode);
  134 
  135         if (!coda_fideq(&cii->c_fid, oldfid))
  136                 BUG();
  137 
  138         /* replace fid and rehash inode */
  139         /* XXX we probably need to hold some lock here! */
  140         remove_inode_hash(inode);
  141         cii->c_fid = *newfid;
  142         inode->i_ino = coda_f2i(newfid);
  143         insert_inode_hash(inode);
  144 }
  145 
  146 /* convert a fid to an inode. */
  147 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) 
  148 {
  149         ino_t nr;
  150         struct inode *inode;
  151         struct coda_inode_info *cii;
  152         struct coda_sb_info *sbi;
  153 
  154         if ( !sb ) {
  155                 printk("coda_fid_to_inode: no sb!\n");
  156                 return NULL;
  157         }
  158 
  159         CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
  160 
  161         sbi = coda_sbp(sb);
  162         nr = coda_f2i(fid);
  163         down(&sbi->sbi_iget4_mutex);
  164         inode = iget4(sb, nr, coda_inocmp, fid);
  165         if ( !inode ) {
  166                 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
  167                        sb, (long)nr);
  168                 goto out_unlock;
  169         }
  170 
  171         cii = ITOC(inode);
  172 
  173         /* The inode could already be purged due to memory pressure */
  174         if (coda_isnullfid(&cii->c_fid)) {
  175                 inode->i_nlink = 0;
  176                 iput(inode);
  177                 goto out_unlock;
  178         }
  179 
  180         CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
  181         up(&sbi->sbi_iget4_mutex);
  182         return inode;
  183 
  184 out_unlock:
  185         up(&sbi->sbi_iget4_mutex);
  186         return NULL;
  187 }
  188 
  189 /* the CONTROL inode is made without asking attributes from Venus */
  190 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
  191 {
  192         int error = 0;
  193 
  194         *inode = iget(sb, CTL_INO);
  195         if ( *inode ) {
  196                 (*inode)->i_op = &coda_ioctl_inode_operations;
  197                 (*inode)->i_fop = &coda_ioctl_operations;
  198                 (*inode)->i_mode = 0444;
  199                 error = 0;
  200         } else { 
  201                 error = -ENOMEM;
  202         }
  203     
  204         return error;
  205 }
  206 

Cache object: eaed4adb9236d8b827771f5d1372010b


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