brintos

brintos / linux-shallow public Read only

0
0
Text · 5.2 KiB · 1d2dac9 Raw
209 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Inode operations for Coda filesystem4 * Original version: (C) 1996 P. Braam and M. Callahan5 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University6 * 7 * Carnegie Mellon encourages users to contribute improvements to8 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).9 */10 11#include <linux/types.h>12#include <linux/kernel.h>13#include <linux/time.h>14#include <linux/fs.h>15#include <linux/stat.h>16#include <linux/errno.h>17#include <linux/uaccess.h>18#include <linux/string.h>19 20#include <linux/coda.h>21#include "coda_psdev.h"22#include "coda_linux.h"23 24/* initialize the debugging variables */25int coda_fake_statfs;26 27/* print a fid */28char * coda_f2s(struct CodaFid *f)29{30	static char s[60];31 32 	sprintf(s, "(%08x.%08x.%08x.%08x)", f->opaque[0], f->opaque[1], f->opaque[2], f->opaque[3]);33 34	return s;35}36 37/* recognize special .CONTROL name */38int coda_iscontrol(const char *name, size_t length)39{40	return ((CODA_CONTROLLEN == length) && 41                (strncmp(name, CODA_CONTROL, CODA_CONTROLLEN) == 0));42}43 44unsigned short coda_flags_to_cflags(unsigned short flags)45{46	unsigned short coda_flags = 0;47	48	if ((flags & O_ACCMODE) == O_RDONLY)49		coda_flags |= C_O_READ;50 51	if ((flags & O_ACCMODE) == O_RDWR)52		coda_flags |= C_O_READ | C_O_WRITE;53 54	if ((flags & O_ACCMODE) == O_WRONLY)55		coda_flags |= C_O_WRITE;56 57	if (flags & O_TRUNC)58		coda_flags |= C_O_TRUNC;59 60	if (flags & O_CREAT)61		coda_flags |= C_O_CREAT;62 63	if (flags & O_EXCL)64		coda_flags |= C_O_EXCL;65 66	return coda_flags;67}68 69static struct timespec64 coda_to_timespec64(struct coda_timespec ts)70{71	struct timespec64 ts64 = {72		.tv_sec = ts.tv_sec,73		.tv_nsec = ts.tv_nsec,74	};75 76	return ts64;77}78 79static struct coda_timespec timespec64_to_coda(struct timespec64 ts64)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 89/* utility functions below */90umode_t coda_inode_type(struct coda_vattr *attr)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 105void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)106{107	/* inode's i_flags, i_ino are set by iget108	 * XXX: is this all we need ??109	 */110	umode_t inode_type = coda_inode_type(attr);111	inode->i_mode |= inode_type;112 113	if (attr->va_mode != (u_short) -1)114	        inode->i_mode = attr->va_mode | inode_type;115        if (attr->va_uid != -1) 116	        inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid);117        if (attr->va_gid != -1)118	        inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid);119	if (attr->va_nlink != -1)120		set_nlink(inode, attr->va_nlink);121	if (attr->va_size != -1)122	        inode->i_size = attr->va_size;123	if (attr->va_size != -1)124		inode->i_blocks = (attr->va_size + 511) >> 9;125	if (attr->va_atime.tv_sec != -1) 126		inode_set_atime_to_ts(inode,127				      coda_to_timespec64(attr->va_atime));128	if (attr->va_mtime.tv_sec != -1)129		inode_set_mtime_to_ts(inode,130				      coda_to_timespec64(attr->va_mtime));131        if (attr->va_ctime.tv_sec != -1)132		inode_set_ctime_to_ts(inode,133				      coda_to_timespec64(attr->va_ctime));134}135 136 137/* 138 * BSD sets attributes that need not be modified to -1. 139 * Linux uses the valid field to indicate what should be140 * looked at.  The BSD type field needs to be deduced from linux 141 * mode.142 * So we have to do some translations here.143 */144 145void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)146{147        unsigned int valid;148 149        /* clean out */        150	vattr->va_mode = -1;151        vattr->va_uid = (vuid_t) -1; 152        vattr->va_gid = (vgid_t) -1;153        vattr->va_size = (off_t) -1;154	vattr->va_atime.tv_sec = (int64_t) -1;155	vattr->va_atime.tv_nsec = (long) -1;156	vattr->va_mtime.tv_sec = (int64_t) -1;157	vattr->va_mtime.tv_nsec = (long) -1;158	vattr->va_ctime.tv_sec = (int64_t) -1;159	vattr->va_ctime.tv_nsec = (long) -1;160        vattr->va_type = C_VNON;161	vattr->va_fileid = -1;162	vattr->va_gen = -1;163	vattr->va_bytes = -1;164	vattr->va_nlink = -1;165	vattr->va_blocksize = -1;166	vattr->va_rdev = -1;167        vattr->va_flags = 0;168 169        /* determine the type */170#if 0171        mode = iattr->ia_mode;172                if ( S_ISDIR(mode) ) {173                vattr->va_type = C_VDIR; 174        } else if ( S_ISREG(mode) ) {175                vattr->va_type = C_VREG;176        } else if ( S_ISLNK(mode) ) {177                vattr->va_type = C_VLNK;178        } else {179                /* don't do others */180                vattr->va_type = C_VNON;181        }182#endif 183 184        /* set those vattrs that need change */185        valid = iattr->ia_valid;186        if ( valid & ATTR_MODE ) {187                vattr->va_mode = iattr->ia_mode;188	}189        if ( valid & ATTR_UID ) {190                vattr->va_uid = (vuid_t) from_kuid(&init_user_ns, iattr->ia_uid);191	}192        if ( valid & ATTR_GID ) {193                vattr->va_gid = (vgid_t) from_kgid(&init_user_ns, iattr->ia_gid);194	}195        if ( valid & ATTR_SIZE ) {196                vattr->va_size = iattr->ia_size;197	}198        if ( valid & ATTR_ATIME ) {199		vattr->va_atime = timespec64_to_coda(iattr->ia_atime);200	}201        if ( valid & ATTR_MTIME ) {202		vattr->va_mtime = timespec64_to_coda(iattr->ia_mtime);203	}204        if ( valid & ATTR_CTIME ) {205		vattr->va_ctime = timespec64_to_coda(iattr->ia_ctime);206	}207}208 209