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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* cnode related routines for the coda kernel code
  3    (C) 1996 Peter Braam
  4    */
  5 
  6 #include <linux/types.h>
  7 #include <linux/string.h>
  8 #include <linux/time.h>
  9 
 10 #include <linux/coda.h>
 11 #include <linux/pagemap.h>
 12 #include "coda_psdev.h"
 13 #include "coda_linux.h"
 14 
 15 static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
 16 {
 17         return memcmp(fid1, fid2, sizeof(*fid1)) == 0;
 18 }
 19 
 20 static const struct inode_operations coda_symlink_inode_operations = {
 21         .get_link       = page_get_link,
 22         .setattr        = coda_setattr,
 23 };
 24 
 25 /* cnode.c */
 26 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
 27 {
 28         coda_vattr_to_iattr(inode, attr);
 29 
 30         if (S_ISREG(inode->i_mode)) {
 31                 inode->i_op = &coda_file_inode_operations;
 32                 inode->i_fop = &coda_file_operations;
 33         } else if (S_ISDIR(inode->i_mode)) {
 34                 inode->i_op = &coda_dir_inode_operations;
 35                 inode->i_fop = &coda_dir_operations;
 36         } else if (S_ISLNK(inode->i_mode)) {
 37                 inode->i_op = &coda_symlink_inode_operations;
 38                 inode_nohighmem(inode);
 39                 inode->i_data.a_ops = &coda_symlink_aops;
 40                 inode->i_mapping = &inode->i_data;
 41         } else
 42                 init_special_inode(inode, inode->i_mode, huge_decode_dev(attr->va_rdev));
 43 }
 44 
 45 static int coda_test_inode(struct inode *inode, void *data)
 46 {
 47         struct CodaFid *fid = (struct CodaFid *)data;
 48         struct coda_inode_info *cii = ITOC(inode);
 49         return coda_fideq(&cii->c_fid, fid);
 50 }
 51 
 52 static int coda_set_inode(struct inode *inode, void *data)
 53 {
 54         struct CodaFid *fid = (struct CodaFid *)data;
 55         struct coda_inode_info *cii = ITOC(inode);
 56         cii->c_fid = *fid;
 57         return 0;
 58 }
 59 
 60 struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
 61                          struct coda_vattr * attr)
 62 {
 63         struct inode *inode;
 64         struct coda_inode_info *cii;
 65         unsigned long hash = coda_f2i(fid);
 66         umode_t inode_type = coda_inode_type(attr);
 67 
 68 retry:
 69         inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
 70         if (!inode)
 71                 return ERR_PTR(-ENOMEM);
 72 
 73         if (inode->i_state & I_NEW) {
 74                 cii = ITOC(inode);
 75                 /* we still need to set i_ino for things like stat(2) */
 76                 inode->i_ino = hash;
 77                 /* inode is locked and unique, no need to grab cii->c_lock */
 78                 cii->c_mapcount = 0;
 79                 coda_fill_inode(inode, attr);
 80                 unlock_new_inode(inode);
 81         } else if ((inode->i_mode & S_IFMT) != inode_type) {
 82                 /* Inode has changed type, mark bad and grab a new one */
 83                 remove_inode_hash(inode);
 84                 coda_flag_inode(inode, C_PURGE);
 85                 iput(inode);
 86                 goto retry;
 87         }
 88         return inode;
 89 }
 90 
 91 /* this is effectively coda_iget:
 92    - get attributes (might be cached)
 93    - get the inode for the fid using vfs iget
 94    - link the two up if this is needed
 95    - fill in the attributes
 96 */
 97 struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
 98 {
 99         struct coda_vattr attr;
100         struct inode *inode;
101         int error;
102         
103         /* We get inode numbers from Venus -- see venus source */
104         error = venus_getattr(sb, fid, &attr);
105         if (error)
106                 return ERR_PTR(error);
107 
108         inode = coda_iget(sb, fid, &attr);
109         if (IS_ERR(inode))
110                 pr_warn("%s: coda_iget failed\n", __func__);
111         return inode;
112 }
113 
114 
115 /* Although we treat Coda file identifiers as immutable, there is one
116  * special case for files created during a disconnection where they may
117  * not be globally unique. When an identifier collision is detected we
118  * first try to flush the cached inode from the kernel and finally
119  * resort to renaming/rehashing in-place. Userspace remembers both old
120  * and new values of the identifier to handle any in-flight upcalls.
121  * The real solution is to use globally unique UUIDs as identifiers, but
122  * retrofitting the existing userspace code for this is non-trivial. */
123 void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid, 
124                       struct CodaFid *newfid)
125 {
126         struct coda_inode_info *cii = ITOC(inode);
127         unsigned long hash = coda_f2i(newfid);
128         
129         BUG_ON(!coda_fideq(&cii->c_fid, oldfid));
130 
131         /* replace fid and rehash inode */
132         /* XXX we probably need to hold some lock here! */
133         remove_inode_hash(inode);
134         cii->c_fid = *newfid;
135         inode->i_ino = hash;
136         __insert_inode_hash(inode, hash);
137 }
138 
139 /* convert a fid to an inode. */
140 struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb) 
141 {
142         struct inode *inode;
143         unsigned long hash = coda_f2i(fid);
144 
145         inode = ilookup5(sb, hash, coda_test_inode, fid);
146         if ( !inode )
147                 return NULL;
148 
149         /* we should never see newly created inodes because we intentionally
150          * fail in the initialization callback */
151         BUG_ON(inode->i_state & I_NEW);
152 
153         return inode;
154 }
155 
156 struct coda_file_info *coda_ftoc(struct file *file)
157 {
158         struct coda_file_info *cfi = file->private_data;
159 
160         BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
161 
162         return cfi;
163 
164 }
165 
166 /* the CONTROL inode is made without asking attributes from Venus */
167 struct inode *coda_cnode_makectl(struct super_block *sb)
168 {
169         struct inode *inode = new_inode(sb);
170         if (inode) {
171                 inode->i_ino = CTL_INO;
172                 inode->i_op = &coda_ioctl_inode_operations;
173                 inode->i_fop = &coda_ioctl_operations;
174                 inode->i_mode = 0444;
175                 return inode;
176         }
177         return ERR_PTR(-ENOMEM);
178 }
179 
180 

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

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php