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/uaccess.h> 19#include <linux/string.h> 20 21#include <linux/coda.h> 22#include <linux/coda_linux.h> 23#include <linux/coda_psdev.h> 24#include <linux/coda_fs_i.h> 25 26/* initialize the debugging variables */ 27int coda_debug; 28int coda_access_cache = 1; 29int coda_fake_statfs; 30 31/* print a fid */ 32char * coda_f2s(ViceFid *f) 33{ 34 static char s[60]; 35 sprintf(s, "(%-#lx.%-#lx.%-#lx)", f->Volume, f->Vnode, f->Unique); 36 return s; 37} 38 39/* recognize special .CONTROL name */ 40int coda_iscontrol(const char *name, size_t length) 41{ 42 return ((CODA_CONTROLLEN == length) && 43 (strncmp(name, CODA_CONTROL, CODA_CONTROLLEN) == 0)); 44} 45 46/* recognize /coda inode */ 47int coda_isroot(struct inode *i) 48{ 49 return ( i->i_sb->s_root->d_inode == i ); 50} 51 52/* put the current process credentials in the cred */ 53void coda_load_creds(struct coda_cred *cred) 54{ 55 cred->cr_uid = (vuid_t) current->uid; 56 cred->cr_euid = (vuid_t) current->euid; 57 cred->cr_suid = (vuid_t) current->suid; 58 cred->cr_fsuid = (vuid_t) current->fsuid; 59 60 cred->cr_groupid = (vgid_t) current->gid; 61 cred->cr_egid = (vgid_t) current->egid; 62 cred->cr_sgid = (vgid_t) current->sgid; 63 cred->cr_fsgid = (vgid_t) current->fsgid; 64} 65 66int coda_cred_ok(struct coda_cred *cred) 67{ 68 return(current->fsuid == cred->cr_fsuid); 69} 70 71int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2) 72{ 73 return (cred1->cr_fsuid == cred2->cr_fsuid); 74} 75 76unsigned short coda_flags_to_cflags(unsigned short flags) 77{ 78 unsigned short coda_flags = 0; 79 80 if ( (flags & O_ACCMODE) == O_RDONLY ){ 81 CDEBUG(D_FILE, "--> C_O_READ added\n"); 82 coda_flags |= C_O_READ; 83 } 84 85 if ( (flags & O_ACCMODE) == O_RDWR ) { 86 CDEBUG(D_FILE, "--> C_O_READ | C_O_WRITE added\n"); 87 coda_flags |= C_O_READ | C_O_WRITE; 88 } 89 90 if ( (flags & O_ACCMODE) == O_WRONLY ){ 91 CDEBUG(D_FILE, "--> C_O_WRITE added\n"); 92 coda_flags |= C_O_WRITE; 93 } 94 95 if ( flags & O_TRUNC ) { 96 CDEBUG(D_FILE, "--> C_O_TRUNC added\n"); 97 coda_flags |= C_O_TRUNC; 98 } 99 100 if ( flags & O_CREAT ) { 101 CDEBUG(D_FILE, "--> C_O_CREAT added\n"); 102 coda_flags |= C_O_CREAT; 103 } 104 105 if ( flags & O_EXCL ) { 106 coda_flags |= C_O_EXCL; 107 CDEBUG(D_FILE, "--> C_O_EXCL added\n"); 108 } 109 110 return coda_flags; 111} 112 113 114/* utility functions below */ 115void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr) 116{ 117 int inode_type; 118 switch (attr->va_type) { 119 case C_VNON: 120 inode_type = 0; 121 break; 122 case C_VREG: 123 inode_type = S_IFREG; 124 break; 125 case C_VDIR: 126 inode_type = S_IFDIR; 127 break; 128 case C_VLNK: 129 inode_type = S_IFLNK; 130 break; 131 default: 132 inode_type = 0; 133 } 134 inode->i_mode |= inode_type; 135 136 if (attr->va_mode != (u_short) -1) 137 inode->i_mode = attr->va_mode | inode_type; 138 if (attr->va_uid != -1) 139 inode->i_uid = (uid_t) attr->va_uid; 140 if (attr->va_gid != -1) 141 inode->i_gid = (gid_t) attr->va_gid; 142 if (attr->va_nlink != -1) 143 inode->i_nlink = attr->va_nlink; 144 if (attr->va_size != -1) 145 inode->i_size = attr->va_size; 146 if (attr->va_blocksize != -1) 147 inode->i_blksize = attr->va_blocksize; 148 if (attr->va_size != -1) 149 inode->i_blocks = (attr->va_size + 511) >> 9; 150 if (attr->va_atime.tv_sec != -1) 151 inode->i_atime = attr->va_atime.tv_sec; 152 if (attr->va_mtime.tv_sec != -1) 153 inode->i_mtime = attr->va_mtime.tv_sec; 154 if (attr->va_ctime.tv_sec != -1) 155 inode->i_ctime = attr->va_ctime.tv_sec; 156} 157 158 159/* 160 * BSD sets attributes that need not be modified to -1. 161 * Linux uses the valid field to indicate what should be 162 * looked at. The BSD type field needs to be deduced from linux 163 * mode. 164 * So we have to do some translations here. 165 */ 166 167void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr) 168{ 169 unsigned int valid; 170 171 /* clean out */ 172 vattr->va_mode = (umode_t) -1; 173 vattr->va_uid = (vuid_t) -1; 174 vattr->va_gid = (vgid_t) -1; 175 vattr->va_size = (off_t) -1; 176 vattr->va_atime.tv_sec = (time_t) -1; 177 vattr->va_mtime.tv_sec = (time_t) -1; 178 vattr->va_ctime.tv_sec = (time_t) -1; 179 vattr->va_atime.tv_nsec = (time_t) -1; 180 vattr->va_mtime.tv_nsec = (time_t) -1; 181 vattr->va_ctime.tv_nsec = (time_t) -1; 182 vattr->va_type = C_VNON; 183 vattr->va_fileid = -1; 184 vattr->va_gen = -1; 185 vattr->va_bytes = -1; 186 vattr->va_nlink = -1; 187 vattr->va_blocksize = -1; 188 vattr->va_rdev = -1; 189 vattr->va_flags = 0; 190 191 /* determine the type */ 192 193 /* set those vattrs that need change */ 194 valid = iattr->ia_valid; 195 if ( valid & ATTR_MODE ) { 196 vattr->va_mode = iattr->ia_mode; 197 } 198 if ( valid & ATTR_UID ) { 199 vattr->va_uid = (vuid_t) iattr->ia_uid; 200 } 201 if ( valid & ATTR_GID ) { 202 vattr->va_gid = (vgid_t) iattr->ia_gid; 203 } 204 if ( valid & ATTR_SIZE ) { 205 vattr->va_size = iattr->ia_size; 206 } 207 if ( valid & ATTR_ATIME ) { 208 vattr->va_atime.tv_sec = iattr->ia_atime; 209 vattr->va_atime.tv_nsec = 0; 210 } 211 if ( valid & ATTR_MTIME ) { 212 vattr->va_mtime.tv_sec = iattr->ia_mtime; 213 vattr->va_mtime.tv_nsec = 0; 214 } 215 if ( valid & ATTR_CTIME ) { 216 vattr->va_ctime.tv_sec = iattr->ia_ctime; 217 vattr->va_ctime.tv_nsec = 0; 218 } 219} 220 221void print_vattr(struct coda_vattr *attr) 222{ 223 char *typestr; 224 225 switch (attr->va_type) { 226 case C_VNON: 227 typestr = "C_VNON"; 228 break; 229 case C_VREG: 230 typestr = "C_VREG"; 231 break; 232 case C_VDIR: 233 typestr = "C_VDIR"; 234 break; 235 case C_VBLK: 236 typestr = "C_VBLK"; 237 break; 238 case C_VCHR: 239 typestr = "C_VCHR"; 240 break; 241 case C_VLNK: 242 typestr = "C_VLNK"; 243 break; 244 case C_VSOCK: 245 typestr = "C_VSCK"; 246 break; 247 case C_VFIFO: 248 typestr = "C_VFFO"; 249 break; 250 case C_VBAD: 251 typestr = "C_VBAD"; 252 break; 253 default: 254 typestr = "????"; 255 break; 256 } 257 258 259 printk("attr: type %s (%o) mode %o uid %d gid %d rdev %d\n", 260 typestr, (int)attr->va_type, (int)attr->va_mode, 261 (int)attr->va_uid, (int)attr->va_gid, (int)attr->va_rdev); 262 263 printk(" fileid %d nlink %d size %d blocksize %d bytes %d\n", 264 (int)attr->va_fileid, (int)attr->va_nlink, 265 (int)attr->va_size, 266 (int)attr->va_blocksize,(int)attr->va_bytes); 267 printk(" gen %ld flags %ld\n", 268 attr->va_gen, attr->va_flags); 269 printk(" atime sec %d nsec %d\n", 270 (int)attr->va_atime.tv_sec, (int)attr->va_atime.tv_nsec); 271 printk(" mtime sec %d nsec %d\n", 272 (int)attr->va_mtime.tv_sec, (int)attr->va_mtime.tv_nsec); 273 printk(" ctime sec %d nsec %d\n", 274 (int)attr->va_ctime.tv_sec, (int)attr->va_ctime.tv_nsec); 275} 276