1 // SPDX-License-Identifier: GPL-2.0 << 2 /* 1 /* 3 * Inode operations for Coda filesystem 2 * Inode operations for Coda filesystem 4 * Original version: (C) 1996 P. Braam and M. 3 * Original version: (C) 1996 P. Braam and M. Callahan 5 * Rewritten for Linux 2.1. (C) 1997 Carnegie 4 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University 6 * 5 * 7 * Carnegie Mellon encourages users to contrib 6 * Carnegie Mellon encourages users to contribute improvements to 8 * the Coda project. Contact Peter Braam (coda 7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu). 9 */ 8 */ 10 9 >> 10 #include <linux/version.h> 11 #include <linux/types.h> 11 #include <linux/types.h> 12 #include <linux/kernel.h> 12 #include <linux/kernel.h> 13 #include <linux/time.h> !! 13 #include <linux/sched.h> 14 #include <linux/fs.h> 14 #include <linux/fs.h> 15 #include <linux/stat.h> 15 #include <linux/stat.h> 16 #include <linux/errno.h> 16 #include <linux/errno.h> 17 #include <linux/uaccess.h> !! 17 #include <linux/locks.h> >> 18 #include <asm/uaccess.h> 18 #include <linux/string.h> 19 #include <linux/string.h> 19 20 20 #include <linux/coda.h> 21 #include <linux/coda.h> 21 #include "coda_psdev.h" !! 22 #include <linux/coda_linux.h> 22 #include "coda_linux.h" !! 23 #include <linux/coda_psdev.h> >> 24 #include <linux/coda_fs_i.h> 23 25 24 /* initialize the debugging variables */ 26 /* initialize the debugging variables */ >> 27 int coda_debug; >> 28 int coda_access_cache = 1; 25 int coda_fake_statfs; 29 int coda_fake_statfs; 26 30 27 /* print a fid */ 31 /* print a fid */ 28 char * coda_f2s(struct CodaFid *f) !! 32 char * coda_f2s(ViceFid *f) 29 { 33 { 30 static char s[60]; 34 static char s[60]; 31 !! 35 sprintf(s, "(%-#lx.%-#lx.%-#lx)", f->Volume, f->Vnode, f->Unique); 32 sprintf(s, "(%08x.%08x.%08x.%08x)", f- << 33 << 34 return s; 36 return s; 35 } 37 } 36 38 37 /* recognize special .CONTROL name */ 39 /* recognize special .CONTROL name */ 38 int coda_iscontrol(const char *name, size_t le 40 int coda_iscontrol(const char *name, size_t length) 39 { 41 { 40 return ((CODA_CONTROLLEN == length) && 42 return ((CODA_CONTROLLEN == length) && 41 (strncmp(name, CODA_CONTROL, C 43 (strncmp(name, CODA_CONTROL, CODA_CONTROLLEN) == 0)); 42 } 44 } 43 45 >> 46 /* recognize /coda inode */ >> 47 int 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 */ >> 53 void 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 >> 66 int coda_cred_ok(struct coda_cred *cred) >> 67 { >> 68 return(current->fsuid == cred->cr_fsuid); >> 69 } >> 70 >> 71 int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2) >> 72 { >> 73 return (cred1->cr_fsuid == cred2->cr_fsuid); >> 74 } >> 75 44 unsigned short coda_flags_to_cflags(unsigned s 76 unsigned short coda_flags_to_cflags(unsigned short flags) 45 { 77 { 46 unsigned short coda_flags = 0; 78 unsigned short coda_flags = 0; 47 79 48 if ((flags & O_ACCMODE) == O_RDONLY) !! 80 if ( (flags & O_ACCMODE) == O_RDONLY ){ >> 81 CDEBUG(D_FILE, "--> C_O_READ added\n"); 49 coda_flags |= C_O_READ; 82 coda_flags |= C_O_READ; >> 83 } 50 84 51 if ((flags & O_ACCMODE) == O_RDWR) !! 85 if ( (flags & O_ACCMODE) == O_RDWR ) { >> 86 CDEBUG(D_FILE, "--> C_O_READ | C_O_WRITE added\n"); 52 coda_flags |= C_O_READ | C_O_W 87 coda_flags |= C_O_READ | C_O_WRITE; >> 88 } 53 89 54 if ((flags & O_ACCMODE) == O_WRONLY) !! 90 if ( (flags & O_ACCMODE) == O_WRONLY ){ >> 91 CDEBUG(D_FILE, "--> C_O_WRITE added\n"); 55 coda_flags |= C_O_WRITE; 92 coda_flags |= C_O_WRITE; >> 93 } 56 94 57 if (flags & O_TRUNC) !! 95 if ( flags & O_TRUNC ) { >> 96 CDEBUG(D_FILE, "--> C_O_TRUNC added\n"); 58 coda_flags |= C_O_TRUNC; 97 coda_flags |= C_O_TRUNC; >> 98 } 59 99 60 if (flags & O_CREAT) !! 100 if ( flags & O_CREAT ) { >> 101 CDEBUG(D_FILE, "--> C_O_CREAT added\n"); 61 coda_flags |= C_O_CREAT; 102 coda_flags |= C_O_CREAT; >> 103 } 62 104 63 if (flags & O_EXCL) !! 105 if ( flags & O_EXCL ) { 64 coda_flags |= C_O_EXCL; 106 coda_flags |= C_O_EXCL; >> 107 CDEBUG(D_FILE, "--> C_O_EXCL added\n"); >> 108 } 65 109 66 return coda_flags; 110 return coda_flags; 67 } 111 } 68 112 69 static struct timespec64 coda_to_timespec64(st << 70 { << 71 struct timespec64 ts64 = { << 72 .tv_sec = ts.tv_sec, << 73 .tv_nsec = ts.tv_nsec, << 74 }; << 75 << 76 return ts64; << 77 } << 78 << 79 static struct coda_timespec timespec64_to_coda << 80 { << 81 struct coda_timespec ts = { << 82 .tv_sec = ts64.tv_sec, << 83 .tv_nsec = ts64.tv_nsec, << 84 }; << 85 << 86 return ts; << 87 } << 88 113 89 /* utility functions below */ 114 /* utility functions below */ 90 umode_t coda_inode_type(struct coda_vattr *att << 91 { << 92 switch (attr->va_type) { << 93 case C_VREG: << 94 return S_IFREG; << 95 case C_VDIR: << 96 return S_IFDIR; << 97 case C_VLNK: << 98 return S_IFLNK; << 99 case C_VNON: << 100 default: << 101 return 0; << 102 } << 103 } << 104 << 105 void coda_vattr_to_iattr(struct inode *inode, 115 void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr) 106 { 116 { 107 /* inode's i_flags, i_ino are set by i !! 117 int inode_type; 108 * XXX: is this all we need ?? !! 118 /* inode's i_dev, i_flags, i_ino are set by iget 109 */ !! 119 XXX: is this all we need ?? 110 umode_t inode_type = coda_inode_type(a !! 120 */ >> 121 switch (attr->va_type) { >> 122 case C_VNON: >> 123 inode_type = 0; >> 124 break; >> 125 case C_VREG: >> 126 inode_type = S_IFREG; >> 127 break; >> 128 case C_VDIR: >> 129 inode_type = S_IFDIR; >> 130 break; >> 131 case C_VLNK: >> 132 inode_type = S_IFLNK; >> 133 break; >> 134 default: >> 135 inode_type = 0; >> 136 } 111 inode->i_mode |= inode_type; 137 inode->i_mode |= inode_type; 112 138 113 if (attr->va_mode != (u_short) -1) 139 if (attr->va_mode != (u_short) -1) 114 inode->i_mode = attr->va_mode 140 inode->i_mode = attr->va_mode | inode_type; 115 if (attr->va_uid != -1) 141 if (attr->va_uid != -1) 116 inode->i_uid = make_kuid(&init !! 142 inode->i_uid = (uid_t) attr->va_uid; 117 if (attr->va_gid != -1) 143 if (attr->va_gid != -1) 118 inode->i_gid = make_kgid(&init !! 144 inode->i_gid = (gid_t) attr->va_gid; 119 if (attr->va_nlink != -1) 145 if (attr->va_nlink != -1) 120 set_nlink(inode, attr->va_nlin !! 146 inode->i_nlink = attr->va_nlink; 121 if (attr->va_size != -1) 147 if (attr->va_size != -1) 122 inode->i_size = attr->va_size; 148 inode->i_size = attr->va_size; >> 149 if (attr->va_blocksize != -1) >> 150 inode->i_blksize = attr->va_blocksize; 123 if (attr->va_size != -1) 151 if (attr->va_size != -1) 124 inode->i_blocks = (attr->va_si 152 inode->i_blocks = (attr->va_size + 511) >> 9; 125 if (attr->va_atime.tv_sec != -1) 153 if (attr->va_atime.tv_sec != -1) 126 inode_set_atime_to_ts(inode, !! 154 inode->i_atime = attr->va_atime.tv_sec; 127 coda_to_ << 128 if (attr->va_mtime.tv_sec != -1) 155 if (attr->va_mtime.tv_sec != -1) 129 inode_set_mtime_to_ts(inode, !! 156 inode->i_mtime = attr->va_mtime.tv_sec; 130 coda_to_ << 131 if (attr->va_ctime.tv_sec != -1) 157 if (attr->va_ctime.tv_sec != -1) 132 inode_set_ctime_to_ts(inode, !! 158 inode->i_ctime = attr->va_ctime.tv_sec; 133 coda_to_ << 134 } 159 } 135 160 136 161 137 /* 162 /* 138 * BSD sets attributes that need not be modifi 163 * BSD sets attributes that need not be modified to -1. 139 * Linux uses the valid field to indicate what 164 * Linux uses the valid field to indicate what should be 140 * looked at. The BSD type field needs to be 165 * looked at. The BSD type field needs to be deduced from linux 141 * mode. 166 * mode. 142 * So we have to do some translations here. 167 * So we have to do some translations here. 143 */ 168 */ 144 169 145 void coda_iattr_to_vattr(struct iattr *iattr, 170 void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr) 146 { 171 { 147 unsigned int valid; 172 unsigned int valid; 148 173 149 /* clean out */ 174 /* clean out */ 150 vattr->va_mode = -1; !! 175 vattr->va_mode = (umode_t) -1; 151 vattr->va_uid = (vuid_t) -1; 176 vattr->va_uid = (vuid_t) -1; 152 vattr->va_gid = (vgid_t) -1; 177 vattr->va_gid = (vgid_t) -1; 153 vattr->va_size = (off_t) -1; 178 vattr->va_size = (off_t) -1; 154 vattr->va_atime.tv_sec = (int64_t) -1; !! 179 vattr->va_atime.tv_sec = (time_t) -1; 155 vattr->va_atime.tv_nsec = (long) -1; !! 180 vattr->va_mtime.tv_sec = (time_t) -1; 156 vattr->va_mtime.tv_sec = (int64_t) -1; !! 181 vattr->va_ctime.tv_sec = (time_t) -1; 157 vattr->va_mtime.tv_nsec = (long) -1; !! 182 vattr->va_atime.tv_nsec = (time_t) -1; 158 vattr->va_ctime.tv_sec = (int64_t) -1; !! 183 vattr->va_mtime.tv_nsec = (time_t) -1; 159 vattr->va_ctime.tv_nsec = (long) -1; !! 184 vattr->va_ctime.tv_nsec = (time_t) -1; 160 vattr->va_type = C_VNON; 185 vattr->va_type = C_VNON; 161 vattr->va_fileid = -1; 186 vattr->va_fileid = -1; 162 vattr->va_gen = -1; 187 vattr->va_gen = -1; 163 vattr->va_bytes = -1; 188 vattr->va_bytes = -1; 164 vattr->va_nlink = -1; 189 vattr->va_nlink = -1; 165 vattr->va_blocksize = -1; 190 vattr->va_blocksize = -1; 166 vattr->va_rdev = -1; 191 vattr->va_rdev = -1; 167 vattr->va_flags = 0; 192 vattr->va_flags = 0; 168 193 169 /* determine the type */ 194 /* determine the type */ 170 #if 0 195 #if 0 171 mode = iattr->ia_mode; 196 mode = iattr->ia_mode; 172 if ( S_ISDIR(mode) ) { 197 if ( S_ISDIR(mode) ) { 173 vattr->va_type = C_VDIR; 198 vattr->va_type = C_VDIR; 174 } else if ( S_ISREG(mode) ) { 199 } else if ( S_ISREG(mode) ) { 175 vattr->va_type = C_VREG; 200 vattr->va_type = C_VREG; 176 } else if ( S_ISLNK(mode) ) { 201 } else if ( S_ISLNK(mode) ) { 177 vattr->va_type = C_VLNK; 202 vattr->va_type = C_VLNK; 178 } else { 203 } else { 179 /* don't do others */ 204 /* don't do others */ 180 vattr->va_type = C_VNON; 205 vattr->va_type = C_VNON; 181 } 206 } 182 #endif 207 #endif 183 208 184 /* set those vattrs that need change * 209 /* set those vattrs that need change */ 185 valid = iattr->ia_valid; 210 valid = iattr->ia_valid; 186 if ( valid & ATTR_MODE ) { 211 if ( valid & ATTR_MODE ) { 187 vattr->va_mode = iattr->ia_mod 212 vattr->va_mode = iattr->ia_mode; 188 } 213 } 189 if ( valid & ATTR_UID ) { 214 if ( valid & ATTR_UID ) { 190 vattr->va_uid = (vuid_t) from_ !! 215 vattr->va_uid = (vuid_t) iattr->ia_uid; 191 } 216 } 192 if ( valid & ATTR_GID ) { 217 if ( valid & ATTR_GID ) { 193 vattr->va_gid = (vgid_t) from_ !! 218 vattr->va_gid = (vgid_t) iattr->ia_gid; 194 } 219 } 195 if ( valid & ATTR_SIZE ) { 220 if ( valid & ATTR_SIZE ) { 196 vattr->va_size = iattr->ia_siz 221 vattr->va_size = iattr->ia_size; 197 } 222 } 198 if ( valid & ATTR_ATIME ) { 223 if ( valid & ATTR_ATIME ) { 199 vattr->va_atime = timespec64_t !! 224 vattr->va_atime.tv_sec = iattr->ia_atime; >> 225 vattr->va_atime.tv_nsec = 0; 200 } 226 } 201 if ( valid & ATTR_MTIME ) { 227 if ( valid & ATTR_MTIME ) { 202 vattr->va_mtime = timespec64_t !! 228 vattr->va_mtime.tv_sec = iattr->ia_mtime; >> 229 vattr->va_mtime.tv_nsec = 0; 203 } 230 } 204 if ( valid & ATTR_CTIME ) { 231 if ( valid & ATTR_CTIME ) { 205 vattr->va_ctime = timespec64_t !! 232 vattr->va_ctime.tv_sec = iattr->ia_ctime; >> 233 vattr->va_ctime.tv_nsec = 0; 206 } 234 } 207 } 235 } 208 236 >> 237 void print_vattr(struct coda_vattr *attr) >> 238 { >> 239 char *typestr; >> 240 >> 241 switch (attr->va_type) { >> 242 case C_VNON: >> 243 typestr = "C_VNON"; >> 244 break; >> 245 case C_VREG: >> 246 typestr = "C_VREG"; >> 247 break; >> 248 case C_VDIR: >> 249 typestr = "C_VDIR"; >> 250 break; >> 251 case C_VBLK: >> 252 typestr = "C_VBLK"; >> 253 break; >> 254 case C_VCHR: >> 255 typestr = "C_VCHR"; >> 256 break; >> 257 case C_VLNK: >> 258 typestr = "C_VLNK"; >> 259 break; >> 260 case C_VSOCK: >> 261 typestr = "C_VSCK"; >> 262 break; >> 263 case C_VFIFO: >> 264 typestr = "C_VFFO"; >> 265 break; >> 266 case C_VBAD: >> 267 typestr = "C_VBAD"; >> 268 break; >> 269 default: >> 270 typestr = "????"; >> 271 break; >> 272 } >> 273 >> 274 >> 275 printk("attr: type %s (%o) mode %o uid %d gid %d rdev %d\n", >> 276 typestr, (int)attr->va_type, (int)attr->va_mode, >> 277 (int)attr->va_uid, (int)attr->va_gid, (int)attr->va_rdev); >> 278 >> 279 printk(" fileid %d nlink %d size %d blocksize %d bytes %d\n", >> 280 (int)attr->va_fileid, (int)attr->va_nlink, >> 281 (int)attr->va_size, >> 282 (int)attr->va_blocksize,(int)attr->va_bytes); >> 283 printk(" gen %ld flags %ld\n", >> 284 attr->va_gen, attr->va_flags); >> 285 printk(" atime sec %d nsec %d\n", >> 286 (int)attr->va_atime.tv_sec, (int)attr->va_atime.tv_nsec); >> 287 printk(" mtime sec %d nsec %d\n", >> 288 (int)attr->va_mtime.tv_sec, (int)attr->va_mtime.tv_nsec); >> 289 printk(" ctime sec %d nsec %d\n", >> 290 (int)attr->va_ctime.tv_sec, (int)attr->va_ctime.tv_nsec); >> 291 } 209 292
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.