~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/coda/cnode.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 extern int coda_print_entry;
 16 
 17 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
 18 {
 19         if (fid1->Vnode != fid2->Vnode)
 20                 return 0;
 21         if (fid1->Volume != fid2->Volume)
 22                 return 0;
 23         if (fid1->Unique != fid2->Unique)
 24                 return 0;
 25         return 1;
 26 }
 27 
 28 static struct inode_operations coda_symlink_inode_operations = {
 29         readlink:       page_readlink,
 30         follow_link:    page_follow_link,
 31         setattr:        coda_notify_change,
 32 };
 33 
 34 /* cnode.c */
 35 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
 36 {
 37         CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
 38 
 39         if (coda_debug & D_SUPER ) 
 40                 print_vattr(attr);
 41 
 42         coda_vattr_to_iattr(inode, attr);
 43 
 44         if (S_ISREG(inode->i_mode)) {
 45                 inode->i_op = &coda_file_inode_operations;
 46                 inode->i_fop = &coda_file_operations;
 47         } else if (S_ISDIR(inode->i_mode)) {
 48                 inode->i_op = &coda_dir_inode_operations;
 49                 inode->i_fop = &coda_dir_operations;
 50         } else if (S_ISLNK(inode->i_mode)) {
 51                 inode->i_op = &coda_symlink_inode_operations;
 52                 inode->i_data.a_ops = &coda_symlink_aops;
 53                 inode->i_mapping = &inode->i_data;
 54         } else
 55                 init_special_inode(inode, inode->i_mode, attr->va_rdev);
 56 }
 57 
 58 struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
 59                          struct coda_vattr * attr)
 60 {
 61         struct inode *inode;
 62         struct coda_inode_info *cii;
 63         ino_t ino = attr->va_fileid;
 64 
 65         inode = iget(sb, ino);
 66         if ( !inode ) { 
 67                 CDEBUG(D_CNODE, "coda_iget: no inode\n");
 68                 return ERR_PTR(-ENOMEM);
 69         }
 70 
 71         /* check if the inode is already initialized */
 72         cii = ITOC(inode);
 73         if (cii->c_fid.Volume != 0 || cii->c_fid.Vnode != 0 || cii->c_fid.Unique != 0) {
 74                 /* see if it is the right one (might have an inode collision) */
 75                 if ( !coda_fideq(fid, &cii->c_fid) ) {
 76                         printk("coda_iget: initialized inode old %s new %s!\n",
 77                                         coda_f2s(&cii->c_fid), coda_f2s2(fid));
 78                         iput(inode);
 79                         return ERR_PTR(-ENOENT);
 80                 }
 81                 /* we will still replace the attributes, type might have changed */
 82                 goto out;
 83         }
 84 
 85         /* new, empty inode found... initializing */
 86 
 87         /* Initialize the Coda inode info structure */
 88         cii->c_fid   = *fid;
 89         cii->c_vnode = inode;
 90 
 91 out:
 92         coda_fill_inode(inode, attr);
 93         return inode;
 94 }
 95 
 96 /* this is effectively coda_iget:
 97    - get attributes (might be cached)
 98    - get the inode for the fid using vfs iget
 99    - link the two up if this is needed
100    - fill in the attributes
101 */
102 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
103 {
104         struct coda_vattr attr;
105         int error;
106         
107         ENTRY;
108 
109         /* We get inode numbers from Venus -- see venus source */
110 
111         error = venus_getattr(sb, fid, &attr);
112         if ( error ) {
113             CDEBUG(D_CNODE, 
114                    "coda_cnode_make: coda_getvattr returned %d for %s.\n", 
115                    error, coda_f2s(fid));
116             *inode = NULL;
117             EXIT;
118             return error;
119         } 
120 
121         *inode = coda_iget(sb, fid, &attr);
122         if ( IS_ERR(*inode) ) {
123                 printk("coda_cnode_make: coda_iget failed\n");
124                 EXIT;
125                 return PTR_ERR(*inode);
126         }
127 
128         CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
129                 (*inode)->i_ino, atomic_read(&(*inode)->i_count), 
130                 coda_f2s(&(*inode)->u.coda_i.c_fid));
131         EXIT;
132         return 0;
133 }
134 
135 
136 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, 
137                       struct ViceFid *newfid)
138 {
139         struct coda_inode_info *cii;
140         
141         cii = ITOC(inode);
142 
143         if ( ! coda_fideq(&cii->c_fid, oldfid) )
144                 printk("What? oldfid != cii->c_fid. Call 911.\n");
145 
146         cii->c_fid = *newfid;
147 }
148 
149 
150  
151 
152 /* convert a fid to an inode. Mostly we can compute
153    the inode number from the FID, but not for volume
154    mount points: those are in a list */
155 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) 
156 {
157         ino_t nr;
158         struct inode *inode;
159         struct coda_inode_info *cii;
160         ENTRY;
161 
162         if ( !sb ) {
163                 printk("coda_fid_to_inode: no sb!\n");
164                 return NULL;
165         }
166 
167         CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
168 
169 
170         /* weird fids cannot be hashed, have to look for them the hard way */
171         if ( coda_fid_is_weird(fid) ) {
172                 struct coda_sb_info *sbi = coda_sbp(sb);
173                 struct list_head *le;
174 
175                 list_for_each(le, &sbi->sbi_cihead)
176                 {
177                         cii = list_entry(le, struct coda_inode_info, c_cilist);
178                         if ( cii->c_magic != CODA_CNODE_MAGIC ) BUG();
179 
180                         CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
181                                coda_f2s(&cii->c_fid), cii->c_vnode->i_ino);
182 
183                         if ( coda_fideq(&cii->c_fid, fid) ) {
184                                 inode = cii->c_vnode;
185                                 CDEBUG(D_INODE, "volume root, found %ld\n", inode->i_ino);
186                                 iget(sb, inode->i_ino);
187                                 return inode;
188                         }
189                 }
190                 return NULL;
191         }
192 
193         /* fid is not weird: ino should be computable */
194         nr = coda_f2i(fid);
195         inode = iget(sb, nr);
196         if ( !inode ) {
197                 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
198                        sb, (long)nr);
199                 return NULL;
200         }
201 
202         /* check if this inode is linked to a cnode */
203         cii = ITOC(inode);
204 
205         /* make sure this is the one we want */
206         if ( coda_fideq(fid, &cii->c_fid) ) {
207                 CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
208                 return inode;
209         }
210 
211 #if 0
212         printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr, coda_f2s(fid));
213 #endif
214         iput(inode);
215         return NULL;
216 
217 }
218 
219 /* the CONTROL inode is made without asking attributes from Venus */
220 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
221 {
222     int error = 0;
223 
224     *inode = iget(sb, CTL_INO);
225     if ( *inode ) {
226         (*inode)->i_op = &coda_ioctl_inode_operations;
227         (*inode)->i_fop = &coda_ioctl_operations;
228         (*inode)->i_mode = 0444;
229         error = 0;
230     } else { 
231         error = -ENOMEM;
232     }
233     
234     return error;
235 }
236 
237 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.