1 // SPDX-License-Identifier: GPL-2.0
3 * Inode operations for Coda filesystem
4 * Original version: (C) 1996 P. Braam and M. Callahan
5 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
7 * Carnegie Mellon encourages users to contribute improvements to
8 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/time.h>
15 #include <linux/stat.h>
16 #include <linux/errno.h>
17 #include <linux/uaccess.h>
18 #include <linux/string.h>
20 #include <linux/coda.h>
21 #include "coda_psdev.h"
22 #include "coda_linux.h"
24 /* initialize the debugging variables */
28 char * coda_f2s(struct CodaFid
*f
)
32 sprintf(s
, "(%08x.%08x.%08x.%08x)", f
->opaque
[0], f
->opaque
[1], f
->opaque
[2], f
->opaque
[3]);
37 /* recognize special .CONTROL name */
38 int coda_iscontrol(const char *name
, size_t length
)
40 return ((CODA_CONTROLLEN
== length
) &&
41 (strncmp(name
, CODA_CONTROL
, CODA_CONTROLLEN
) == 0));
44 unsigned short coda_flags_to_cflags(unsigned short flags
)
46 unsigned short coda_flags
= 0;
48 if ((flags
& O_ACCMODE
) == O_RDONLY
)
49 coda_flags
|= C_O_READ
;
51 if ((flags
& O_ACCMODE
) == O_RDWR
)
52 coda_flags
|= C_O_READ
| C_O_WRITE
;
54 if ((flags
& O_ACCMODE
) == O_WRONLY
)
55 coda_flags
|= C_O_WRITE
;
58 coda_flags
|= C_O_TRUNC
;
61 coda_flags
|= C_O_CREAT
;
64 coda_flags
|= C_O_EXCL
;
69 static struct timespec64
coda_to_timespec64(struct coda_timespec ts
)
71 struct timespec64 ts64
= {
73 .tv_nsec
= ts
.tv_nsec
,
79 static struct coda_timespec
timespec64_to_coda(struct timespec64 ts64
)
81 struct coda_timespec ts
= {
82 .tv_sec
= ts64
.tv_sec
,
83 .tv_nsec
= ts64
.tv_nsec
,
89 /* utility functions below */
90 umode_t
coda_inode_type(struct coda_vattr
*attr
)
92 switch (attr
->va_type
) {
105 void coda_vattr_to_iattr(struct inode
*inode
, struct coda_vattr
*attr
)
107 /* inode's i_flags, i_ino are set by iget
108 * XXX: is this all we need ??
110 umode_t inode_type
= coda_inode_type(attr
);
111 inode
->i_mode
|= inode_type
;
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
));
138 * BSD sets attributes that need not be modified to -1.
139 * Linux uses the valid field to indicate what should be
140 * looked at. The BSD type field needs to be deduced from linux
142 * So we have to do some translations here.
145 void coda_iattr_to_vattr(struct iattr
*iattr
, struct coda_vattr
*vattr
)
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;
163 vattr
->va_bytes
= -1;
164 vattr
->va_nlink
= -1;
165 vattr
->va_blocksize
= -1;
169 /* determine the type */
171 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
;
179 /* don't do others */
180 vattr
->va_type
= C_VNON
;
184 /* set those vattrs that need change */
185 valid
= iattr
->ia_valid
;
186 if ( valid
& ATTR_MODE
) {
187 vattr
->va_mode
= iattr
->ia_mode
;
189 if ( valid
& ATTR_UID
) {
190 vattr
->va_uid
= (vuid_t
) from_kuid(&init_user_ns
, iattr
->ia_uid
);
192 if ( valid
& ATTR_GID
) {
193 vattr
->va_gid
= (vgid_t
) from_kgid(&init_user_ns
, iattr
->ia_gid
);
195 if ( valid
& ATTR_SIZE
) {
196 vattr
->va_size
= iattr
->ia_size
;
198 if ( valid
& ATTR_ATIME
) {
199 vattr
->va_atime
= timespec64_to_coda(iattr
->ia_atime
);
201 if ( valid
& ATTR_MTIME
) {
202 vattr
->va_mtime
= timespec64_to_coda(iattr
->ia_mtime
);
204 if ( valid
& ATTR_CTIME
) {
205 vattr
->va_ctime
= timespec64_to_coda(iattr
->ia_ctime
);