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
6 * Carnegie Mellon encourages users to contribute improvements to
7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
10 #include <linux/version.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.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>
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 #include <linux/coda_cache.h>
28 /* initialize the debugging variables */
30 int coda_print_entry
= 0;
31 int coda_access_cache
= 1;
34 char * coda_f2s(ViceFid
*f
)
38 sprintf(s
, "(%-#lx,%-#lx,%-#lx)",
39 f
->Volume
, f
->Vnode
, f
->Unique
);
44 /* print another fid */
45 char * coda_f2s2(ViceFid
*f
)
49 sprintf(s
, "(%-#lx,%-#lx,%-#lx)",
50 f
->Volume
, f
->Vnode
, f
->Unique
);
55 /* recognize special .CONTROL name */
56 int coda_iscontrol(const char *name
, size_t length
)
58 if ((CODA_CONTROLLEN
== length
) &&
59 (strncmp(name
, CODA_CONTROL
, CODA_CONTROLLEN
) == 0))
64 /* recognize /coda inode */
65 int coda_isroot(struct inode
*i
)
67 if ( i
->i_sb
->s_root
->d_inode
== i
) {
74 /* is this a volume root FID */
75 int coda_fid_is_volroot(struct ViceFid
*fid
)
77 return ( (fid
->Vnode
== 1) && (fid
->Unique
== 1 ) );
80 int coda_fid_is_weird(struct ViceFid
*fid
)
83 if ( (fid
->Vnode
== 1) && (fid
->Unique
== 1 ) )
85 /* tmpfid unique (simulate.cc) */
86 if ( fid
->Unique
== 0xffffffff )
88 /* LocalFakeVnode (local.h) */
89 if ( fid
->Vnode
== 0xfffffffd )
91 /* LocalFileVnode (venus.private.h) */
92 if ( fid
->Vnode
== 0xfffffffe )
94 /* local fake vid (local.h) */
95 if ( fid
->Volume
== 0xffffffff )
97 /* local DirVnode (venus.private.h) */
98 if ( fid
->Vnode
== 0xffffffff )
100 /* FakeVnode (venus.private.h) */
101 if ( fid
->Vnode
== 0xfffffffc )
110 /* put the current process credentials in the cred */
111 void coda_load_creds(struct coda_cred
*cred
)
113 cred
->cr_uid
= (vuid_t
) current
->uid
;
114 cred
->cr_euid
= (vuid_t
) current
->euid
;
115 cred
->cr_suid
= (vuid_t
) current
->suid
;
116 cred
->cr_fsuid
= (vuid_t
) current
->fsuid
;
118 cred
->cr_groupid
= (vgid_t
) current
->gid
;
119 cred
->cr_egid
= (vgid_t
) current
->egid
;
120 cred
->cr_sgid
= (vgid_t
) current
->sgid
;
121 cred
->cr_fsgid
= (vgid_t
) current
->fsgid
;
124 int coda_cred_ok(struct coda_cred
*cred
)
126 return(current
->fsuid
== cred
->cr_fsuid
);
129 int coda_cred_eq(struct coda_cred
*cred1
, struct coda_cred
*cred2
)
131 return (cred1
->cr_fsuid
== cred2
->cr_fsuid
);
134 unsigned short coda_flags_to_cflags(unsigned short flags
)
136 unsigned short coda_flags
= 0;
138 if ( (flags
& O_ACCMODE
) == O_RDONLY
){
139 CDEBUG(D_FILE
, "--> C_O_READ added\n");
140 coda_flags
|= C_O_READ
;
143 if ( (flags
& O_ACCMODE
) == O_RDWR
) {
144 CDEBUG(D_FILE
, "--> C_O_READ | C_O_WRITE added\n");
145 coda_flags
|= C_O_READ
| C_O_WRITE
;
148 if ( (flags
& O_ACCMODE
) == O_WRONLY
){
149 CDEBUG(D_FILE
, "--> C_O_WRITE added\n");
150 coda_flags
|= C_O_WRITE
;
153 if ( flags
& O_TRUNC
) {
154 CDEBUG(D_FILE
, "--> C_O_TRUNC added\n");
155 coda_flags
|= C_O_TRUNC
;
158 if ( flags
& O_CREAT
) {
159 CDEBUG(D_FILE
, "--> C_O_CREAT added\n");
160 coda_flags
|= C_O_CREAT
;
163 if ( flags
& O_EXCL
) {
164 coda_flags
|= C_O_EXCL
;
165 CDEBUG(D_FILE
, "--> C_O_EXCL added\n");
172 /* utility functions below */
173 void coda_vattr_to_iattr(struct inode
*inode
, struct coda_vattr
*attr
)
176 /* inode's i_dev, i_flags, i_ino are set by iget
177 XXX: is this all we need ??
179 switch (attr
->va_type
) {
184 inode_type
= S_IFREG
;
187 inode_type
= S_IFDIR
;
190 inode_type
= S_IFLNK
;
195 inode
->i_mode
|= inode_type
;
197 if (attr
->va_mode
!= (u_short
) -1)
198 inode
->i_mode
= attr
->va_mode
| inode_type
;
199 if (attr
->va_uid
!= -1)
200 inode
->i_uid
= (uid_t
) attr
->va_uid
;
201 if (attr
->va_gid
!= -1)
202 inode
->i_gid
= (gid_t
) attr
->va_gid
;
203 if (attr
->va_nlink
!= -1)
204 inode
->i_nlink
= attr
->va_nlink
;
205 if (attr
->va_size
!= -1)
206 inode
->i_size
= attr
->va_size
;
207 if (attr
->va_blocksize
!= -1)
208 inode
->i_blksize
= attr
->va_blocksize
;
209 if (attr
->va_size
!= -1)
210 inode
->i_blocks
= (attr
->va_size
+ 511) >> 9;
211 if (attr
->va_atime
.tv_sec
!= -1)
212 inode
->i_atime
= attr
->va_atime
.tv_sec
;
213 if (attr
->va_mtime
.tv_sec
!= -1)
214 inode
->i_mtime
= attr
->va_mtime
.tv_sec
;
215 if (attr
->va_ctime
.tv_sec
!= -1)
216 inode
->i_ctime
= attr
->va_ctime
.tv_sec
;
221 * BSD sets attributes that need not be modified to -1.
222 * Linux uses the valid field to indicate what should be
223 * looked at. The BSD type field needs to be deduced from linux
225 * So we have to do some translations here.
228 void coda_iattr_to_vattr(struct iattr
*iattr
, struct coda_vattr
*vattr
)
233 vattr
->va_mode
= (umode_t
) -1;
234 vattr
->va_uid
= (vuid_t
) -1;
235 vattr
->va_gid
= (vgid_t
) -1;
236 vattr
->va_size
= (off_t
) -1;
237 vattr
->va_atime
.tv_sec
= (time_t) -1;
238 vattr
->va_mtime
.tv_sec
= (time_t) -1;
239 vattr
->va_ctime
.tv_sec
= (time_t) -1;
240 vattr
->va_atime
.tv_nsec
= (time_t) -1;
241 vattr
->va_mtime
.tv_nsec
= (time_t) -1;
242 vattr
->va_ctime
.tv_nsec
= (time_t) -1;
243 vattr
->va_type
= C_VNON
;
244 vattr
->va_fileid
= -1;
246 vattr
->va_bytes
= -1;
247 vattr
->va_nlink
= -1;
248 vattr
->va_blocksize
= -1;
252 /* determine the type */
254 mode
= iattr
->ia_mode
;
255 if ( S_ISDIR(mode
) ) {
256 vattr
->va_type
= C_VDIR
;
257 } else if ( S_ISREG(mode
) ) {
258 vattr
->va_type
= C_VREG
;
259 } else if ( S_ISLNK(mode
) ) {
260 vattr
->va_type
= C_VLNK
;
262 /* don't do others */
263 vattr
->va_type
= C_VNON
;
267 /* set those vattrs that need change */
268 valid
= iattr
->ia_valid
;
269 if ( valid
& ATTR_MODE
) {
270 vattr
->va_mode
= iattr
->ia_mode
;
272 if ( valid
& ATTR_UID
) {
273 vattr
->va_uid
= (vuid_t
) iattr
->ia_uid
;
275 if ( valid
& ATTR_GID
) {
276 vattr
->va_gid
= (vgid_t
) iattr
->ia_gid
;
278 if ( valid
& ATTR_SIZE
) {
279 vattr
->va_size
= iattr
->ia_size
;
281 if ( valid
& ATTR_ATIME
) {
282 vattr
->va_atime
.tv_sec
= iattr
->ia_atime
;
283 vattr
->va_atime
.tv_nsec
= 0;
285 if ( valid
& ATTR_MTIME
) {
286 vattr
->va_mtime
.tv_sec
= iattr
->ia_mtime
;
287 vattr
->va_mtime
.tv_nsec
= 0;
289 if ( valid
& ATTR_CTIME
) {
290 vattr
->va_ctime
.tv_sec
= iattr
->ia_ctime
;
291 vattr
->va_ctime
.tv_nsec
= 0;
296 void print_vattr(struct coda_vattr
*attr
)
300 switch (attr
->va_type
) {
334 printk("attr: type %s (%o) mode %o uid %d gid %d rdev %d\n",
335 typestr
, (int)attr
->va_type
, (int)attr
->va_mode
,
336 (int)attr
->va_uid
, (int)attr
->va_gid
, (int)attr
->va_rdev
);
338 printk(" fileid %d nlink %d size %d blocksize %d bytes %d\n",
339 (int)attr
->va_fileid
, (int)attr
->va_nlink
,
341 (int)attr
->va_blocksize
,(int)attr
->va_bytes
);
342 printk(" gen %ld flags %ld\n",
343 attr
->va_gen
, attr
->va_flags
);
344 printk(" atime sec %d nsec %d\n",
345 (int)attr
->va_atime
.tv_sec
, (int)attr
->va_atime
.tv_nsec
);
346 printk(" mtime sec %d nsec %d\n",
347 (int)attr
->va_mtime
.tv_sec
, (int)attr
->va_mtime
.tv_nsec
);
348 printk(" ctime sec %d nsec %d\n",
349 (int)attr
->va_ctime
.tv_sec
, (int)attr
->va_ctime
.tv_nsec
);