1 /*
2 * Inode operations for Coda filesystem
3 * Original version: (C) 1996 P. Braam and M. Callahan
4 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
5 *
6 * Carnegie Mellon encourages users to contribute improvements to
7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
8 */
9
10 #include <linux/version.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h>
15 #include <linux/stat.h>
16 #include <linux/errno.h>
17 #include <linux/locks.h>
18 #include <asm/segment.h>
19 #include <asm/uaccess.h>
20 #include <linux/string.h>
21
22 #include <linux/coda.h>
23 #include <linux/coda_linux.h>
24 #include <linux/coda_psdev.h>
25 #include <linux/coda_fs_i.h>
26
27 /* initialize the debugging variables */
28 int coda_debug = 0;
29 int coda_print_entry = 0;
30 int coda_access_cache = 1;
31
32 /* print a fid */
33 char * coda_f2s(ViceFid *f)
34 {
35 static char s[60];
36 if ( f ) {
37 sprintf(s, "(%-#lx,%-#lx,%-#lx)",
38 f->Volume, f->Vnode, f->Unique);
39 }
40 return s;
41 }
42
43 /* print another fid */
44 char * coda_f2s2(ViceFid *f)
45 {
46 static char s[60];
47 if ( f ) {
48 sprintf(s, "(%-#lx,%-#lx,%-#lx)",
49 f->Volume, f->Vnode, f->Unique);
50 }
51 return s;
52 }
53
54 /* recognize special .CONTROL name */
55 int coda_iscontrol(const char *name, size_t length)
56 {
57 if ((CODA_CONTROLLEN == length) &&
58 (strncmp(name, CODA_CONTROL, CODA_CONTROLLEN) == 0))
59 return 1;
60 return 0;
61 }
62
63 /* recognize /coda inode */
64 int coda_isroot(struct inode *i)
65 {
66 if ( i->i_sb->s_root->d_inode == i ) {
67 return 1;
68 } else {
69 return 0;
70 }
71 }
72
73 int coda_fid_is_weird(struct ViceFid *fid)
74 {
75 /* volume roots */
76 if ( (fid->Vnode == 1) && (fid->Unique == 1 ) )
77 return 1;
78 /* tmpfid unique (simulate.cc) */
79 if ( fid->Unique == 0xffffffff )
80 return 1;
81 /* LocalFakeVnode (local.h) */
82 if ( fid->Vnode == 0xfffffffd )
83 return 1;
84 /* LocalFileVnode (venus.private.h) */
85 if ( fid->Vnode == 0xfffffffe )
86 return 1;
87 /* local fake vid (local.h) */
88 if ( fid->Volume == 0xffffffff )
89 return 1;
90 /* local DirVnode (venus.private.h) */
91 if ( fid->Vnode == 0xffffffff )
92 return 1;
93 /* FakeVnode (venus.private.h) */
94 if ( fid->Vnode == 0xfffffffc )
95 return 1;
96
97 return 0;
98 }
99
100
101
102 /* put the current process credentials in the cred */
103 void coda_load_creds(struct coda_cred *cred)
104 {
105 cred->cr_uid = (vuid_t) current->uid;
106 cred->cr_euid = (vuid_t) current->euid;
107 cred->cr_suid = (vuid_t) current->suid;
108 cred->cr_fsuid = (vuid_t) current->fsuid;
109
110 cred->cr_groupid = (vgid_t) current->gid;
111 cred->cr_egid = (vgid_t) current->egid;
112 cred->cr_sgid = (vgid_t) current->sgid;
113 cred->cr_fsgid = (vgid_t) current->fsgid;
114 }
115
116 int coda_cred_ok(struct coda_cred *cred)
117 {
118 return(current->fsuid == cred->cr_fsuid);
119 }
120
121 int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2)
122 {
123 return (cred1->cr_fsuid == cred2->cr_fsuid);
124 }
125
126 unsigned short coda_flags_to_cflags(unsigned short flags)
127 {
128 unsigned short coda_flags = 0;
129
130 if ( (flags & O_ACCMODE) == O_RDONLY ){
131 CDEBUG(D_FILE, "--> C_O_READ added\n");
132 coda_flags |= C_O_READ;
133 }
134
135 if ( (flags & O_ACCMODE) == O_RDWR ) {
136 CDEBUG(D_FILE, "--> C_O_READ | C_O_WRITE added\n");
137 coda_flags |= C_O_READ | C_O_WRITE;
138 }
139
140 if ( (flags & O_ACCMODE) == O_WRONLY ){
141 CDEBUG(D_FILE, "--> C_O_WRITE added\n");
142 coda_flags |= C_O_WRITE;
143 }
144
145 if ( flags & O_TRUNC ) {
146 CDEBUG(D_FILE, "--> C_O_TRUNC added\n");
147 coda_flags |= C_O_TRUNC;
148 }
149
150 if ( flags & O_CREAT ) {
151 CDEBUG(D_FILE, "--> C_O_CREAT added\n");
152 coda_flags |= C_O_CREAT;
153 }
154
155 if ( flags & O_EXCL ) {
156 coda_flags |= C_O_EXCL;
157 CDEBUG(D_FILE, "--> C_O_EXCL added\n");
158 }
159
160 return coda_flags;
161 }
162
163
164 /* utility functions below */
165 void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
166 {
167 int inode_type;
168 /* inode's i_dev, i_flags, i_ino are set by iget
169 XXX: is this all we need ??
170 */
171 switch (attr->va_type) {
172 case C_VNON:
173 inode_type = 0;
174 break;
175 case C_VREG:
176 inode_type = S_IFREG;
177 break;
178 case C_VDIR:
179 inode_type = S_IFDIR;
180 break;
181 case C_VLNK:
182 inode_type = S_IFLNK;
183 break;
184 default:
185 inode_type = 0;
186 }
187 inode->i_mode |= inode_type;
188
189 if (attr->va_mode != (u_short) -1)
190 inode->i_mode = attr->va_mode | inode_type;
191 if (attr->va_uid != -1)
192 inode->i_uid = (uid_t) attr->va_uid;
193 if (attr->va_gid != -1)
194 inode->i_gid = (gid_t) attr->va_gid;
195 if (attr->va_nlink != -1)
196 inode->i_nlink = attr->va_nlink;
197 if (attr->va_size != -1)
198 inode->i_size = attr->va_size;
199 if (attr->va_blocksize != -1)
200 inode->i_blksize = attr->va_blocksize;
201 if (attr->va_size != -1)
202 inode->i_blocks = (attr->va_size + 511) >> 9;
203 if (attr->va_atime.tv_sec != -1)
204 inode->i_atime = attr->va_atime.tv_sec;
205 if (attr->va_mtime.tv_sec != -1)
206 inode->i_mtime = attr->va_mtime.tv_sec;
207 if (attr->va_ctime.tv_sec != -1)
208 inode->i_ctime = attr->va_ctime.tv_sec;
209 }
210
211
212 /*
213 * BSD sets attributes that need not be modified to -1.
214 * Linux uses the valid field to indicate what should be
215 * looked at. The BSD type field needs to be deduced from linux
216 * mode.
217 * So we have to do some translations here.
218 */
219
220 void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)
221 {
222 unsigned int valid;
223
224 /* clean out */
225 vattr->va_mode = (umode_t) -1;
226 vattr->va_uid = (vuid_t) -1;
227 vattr->va_gid = (vgid_t) -1;
228 vattr->va_size = (off_t) -1;
229 vattr->va_atime.tv_sec = (time_t) -1;
230 vattr->va_mtime.tv_sec = (time_t) -1;
231 vattr->va_ctime.tv_sec = (time_t) -1;
232 vattr->va_atime.tv_nsec = (time_t) -1;
233 vattr->va_mtime.tv_nsec = (time_t) -1;
234 vattr->va_ctime.tv_nsec = (time_t) -1;
235 vattr->va_type = C_VNON;
236 vattr->va_fileid = -1;
237 vattr->va_gen = -1;
238 vattr->va_bytes = -1;
239 vattr->va_nlink = -1;
240 vattr->va_blocksize = -1;
241 vattr->va_rdev = -1;
242 vattr->va_flags = 0;
243
244 /* determine the type */
245 #if 0
246 mode = iattr->ia_mode;
247 if ( S_ISDIR(mode) ) {
248 vattr->va_type = C_VDIR;
249 } else if ( S_ISREG(mode) ) {
250 vattr->va_type = C_VREG;
251 } else if ( S_ISLNK(mode) ) {
252 vattr->va_type = C_VLNK;
253 } else {
254 /* don't do others */
255 vattr->va_type = C_VNON;
256 }
257 #endif
258
259 /* set those vattrs that need change */
260 valid = iattr->ia_valid;
261 if ( valid & ATTR_MODE ) {
262 vattr->va_mode = iattr->ia_mode;
263 }
264 if ( valid & ATTR_UID ) {
265 vattr->va_uid = (vuid_t) iattr->ia_uid;
266 }
267 if ( valid & ATTR_GID ) {
268 vattr->va_gid = (vgid_t) iattr->ia_gid;
269 }
270 if ( valid & ATTR_SIZE ) {
271 vattr->va_size = iattr->ia_size;
272 }
273 if ( valid & ATTR_ATIME ) {
274 vattr->va_atime.tv_sec = iattr->ia_atime;
275 vattr->va_atime.tv_nsec = 0;
276 }
277 if ( valid & ATTR_MTIME ) {
278 vattr->va_mtime.tv_sec = iattr->ia_mtime;
279 vattr->va_mtime.tv_nsec = 0;
280 }
281 if ( valid & ATTR_CTIME ) {
282 vattr->va_ctime.tv_sec = iattr->ia_ctime;
283 vattr->va_ctime.tv_nsec = 0;
284 }
285 }
286
287 void print_vattr(struct coda_vattr *attr)
288 {
289 char *typestr;
290
291 switch (attr->va_type) {
292 case C_VNON:
293 typestr = "C_VNON";
294 break;
295 case C_VREG:
296 typestr = "C_VREG";
297 break;
298 case C_VDIR:
299 typestr = "C_VDIR";
300 break;
301 case C_VBLK:
302 typestr = "C_VBLK";
303 break;
304 case C_VCHR:
305 typestr = "C_VCHR";
306 break;
307 case C_VLNK:
308 typestr = "C_VLNK";
309 break;
310 case C_VSOCK:
311 typestr = "C_VSCK";
312 break;
313 case C_VFIFO:
314 typestr = "C_VFFO";
315 break;
316 case C_VBAD:
317 typestr = "C_VBAD";
318 break;
319 default:
320 typestr = "????";
321 break;
322 }
323
324
325 printk("attr: type %s (%o) mode %o uid %d gid %d rdev %d\n",
326 typestr, (int)attr->va_type, (int)attr->va_mode,
327 (int)attr->va_uid, (int)attr->va_gid, (int)attr->va_rdev);
328
329 printk(" fileid %d nlink %d size %d blocksize %d bytes %d\n",
330 (int)attr->va_fileid, (int)attr->va_nlink,
331 (int)attr->va_size,
332 (int)attr->va_blocksize,(int)attr->va_bytes);
333 printk(" gen %ld flags %ld\n",
334 attr->va_gen, attr->va_flags);
335 printk(" atime sec %d nsec %d\n",
336 (int)attr->va_atime.tv_sec, (int)attr->va_atime.tv_nsec);
337 printk(" mtime sec %d nsec %d\n",
338 (int)attr->va_mtime.tv_sec, (int)attr->va_mtime.tv_nsec);
339 printk(" ctime sec %d nsec %d\n",
340 (int)attr->va_ctime.tv_sec, (int)attr->va_ctime.tv_nsec);
341 }
342
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.