1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #ifndef _SYS_FS_CACHEFS_DLOG_H
28 #define _SYS_FS_CACHEFS_DLOG_H
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #include <sys/vfs.h>
33 #include <sys/acl.h>
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 /*
40 * Version number of log file format.
41 * Put in an int at the start of the file.
42 * Large Files: Increment VER by 1.
43 */
44 #define CFS_DLOG_VERSION 1001
45
46 /* valid types of dlog records */
47 enum cfs_dlog_op {
48 CFS_DLOG_CREATE = 0x100,
49 CFS_DLOG_REMOVE,
50 CFS_DLOG_LINK,
51 CFS_DLOG_RENAME,
52 CFS_DLOG_MKDIR,
53 CFS_DLOG_RMDIR,
54 CFS_DLOG_SYMLINK,
55 CFS_DLOG_SETATTR,
56 CFS_DLOG_SETSECATTR,
57 CFS_DLOG_MODIFIED,
58 CFS_DLOG_MAPFID,
59 CFS_DLOG_TRAILER
60 };
61 typedef enum cfs_dlog_op cfs_dlog_op_t;
62
63 /* validity of records */
64 enum cfs_dlog_val {
65 CFS_DLOG_VAL_CRASH = 0x200, /* crash during record creation */
66 CFS_DLOG_VAL_COMMITTED, /* valid record */
67 CFS_DLOG_VAL_ERROR, /* error, operation not performed */
68 CFS_DLOG_VAL_PROCESSED /* record processed */
69 };
70 typedef enum cfs_dlog_val cfs_dlog_val_t;
71
72 /* number of bytes for groups appended to a cred structure */
73 #define CFS_DLOG_BUFSIZE (sizeof (gid_t) * (NGROUPS_MAX_DEFAULT - 1))
74
75 /* the old kernel credential; ossified on disk so we're stuck with this. */
76 typedef struct dl_cred {
77 uint_t __ign1; /* ignore (was ref count) */
78 uid_t cr_uid; /* effective user id */
79 gid_t cr_gid; /* effective group id */
80 uid_t cr_ruid; /* real user id */
81 gid_t cr_rgid; /* real group id */
82 uid_t cr_suid; /* "saved" user id (from exec) */
83 gid_t cr_sgid; /* "saved" group id (from exec) */
84 uint_t cr_ngroups; /* number of groups in cr_groups */
85 gid_t cr_groups[1]; /* supplementary group list */
86 } dl_cred_t;
87
88 /*
89 * cfs_dlog_mapping_space is stored on disk, so it needs to be the same
90 * 32-bit vs. 64-bit. The other structures below are also stored on disk,
91 * but they do not contain any 64-bit elements.
92 */
93
94 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
95 #pragma pack(4)
96 #endif
97
98 /* the basic elements in the mapping file */
99 struct cfs_dlog_mapping_space {
100 cfs_cid_t ms_cid; /* mapping key */
101 off_t ms_fid; /* offset to fid */
102 off_t ms_times; /* offset to timestamps */
103 };
104
105 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
106 #pragma pack()
107 #endif
108
109 /*
110 * XX64: For now we use the old time_t defs. In the next version the logs
111 * and on-disk structs may change to 64-bit. The structs here are used
112 * for the data log.
113 */
114 /* mtime and ctime stamps */
115 struct cfs_dlog_tm {
116 cfs_timestruc_t tm_mtime; /* cached mtime on file */
117 cfs_timestruc_t tm_ctime; /* cached ctime on file */
118 };
119 typedef struct cfs_dlog_tm cfs_dlog_tm_t;
120
121 /* structure populated for setattr */
122 struct cfs_dlog_setattr {
123 cfs_vattr_t dl_attrs; /* attrs to set file to */
124 int dl_flags; /* flags used with setattr */
125 cfs_cid_t dl_cid; /* cid of the file to setattr */
126 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
127 dl_cred_t dl_cred; /* creds used */
128 char dl_buffer[CFS_DLOG_BUFSIZE]; /* groups */
129 };
130
131 /* structure for setsecattr (aka setting an ACL) */
132 /* n.b. data for this can exceed sizeof this struct, due to 24k ACLs! */
133 struct cfs_dlog_setsecattr {
134 cfs_cid_t dl_cid; /* cid of file to setsecattr */
135 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
136 uint_t dl_mask; /* mask field in vsecattr_t */
137 int dl_aclcnt; /* count of ACLs */
138 int dl_dfaclcnt; /* count of default ACLs */
139 dl_cred_t dl_cred; /* creds used */
140 char dl_buffer[CFS_DLOG_BUFSIZE]; /* groups + ACLs */
141 };
142
143 /* structure populated for creates */
144 struct cfs_dlog_create {
145 cfs_cid_t dl_parent_cid; /* parent directory cid */
146 cfs_cid_t dl_new_cid; /* cid of the created file */
147 cfs_vattr_t dl_attrs; /* attrs to create with */
148 int dl_excl; /* exclusive mode flag */
149 int dl_mode; /* mode bits for created file */
150 int dl_exists; /* does file already exist? */
151 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
152 cfs_fid_t dl_fid; /* blank fid */
153 dl_cred_t dl_cred; /* user credentials */
154 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
155 };
156
157 /* struct used for remove */
158 struct cfs_dlog_remove {
159 cfs_cid_t dl_parent_cid; /* parent directory cid */
160 cfs_cid_t dl_child_cid; /* cid of entry that was removed */
161 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
162 dl_cred_t dl_cred; /* credentials to use */
163 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
164 };
165
166 /* struct used for rmdir */
167 struct cfs_dlog_rmdir {
168 cfs_cid_t dl_parent_cid; /* parent directory cid */
169 dl_cred_t dl_cred; /* credentials to use */
170 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
171 };
172
173 /* struct used for mkdir */
174 struct cfs_dlog_mkdir {
175 cfs_cid_t dl_parent_cid; /* parent directory cid */
176 cfs_cid_t dl_child_cid; /* cid of created entry */
177 cfs_vattr_t dl_attrs; /* attrs to insert with */
178 cfs_fid_t dl_fid; /* blank fid */
179 dl_cred_t dl_cred; /* credentials to use */
180 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
181 };
182
183 /* struct used for link */
184 struct cfs_dlog_link {
185 cfs_cid_t dl_parent_cid; /* parent directory cid */
186 cfs_cid_t dl_child_cid; /* cid of created entry */
187 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
188 dl_cred_t dl_cred; /* credentials to use */
189 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
190 };
191
192 /* struct used for symlink */
193 struct cfs_dlog_symlink {
194 cfs_cid_t dl_parent_cid; /* parent directory cid */
195 cfs_cid_t dl_child_cid; /* cid of created entry */
196 cfs_vattr_t dl_attrs; /* attrs to insert with */
197 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
198 cfs_fid_t dl_fid; /* blank fid */
199 dl_cred_t dl_cred; /* credentials to use */
200 char dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN + MAXPATHLEN];
201 };
202
203 struct cfs_dlog_rename {
204 cfs_cid_t dl_oparent_cid; /* cid of the original parent dir */
205 cfs_cid_t dl_nparent_cid; /* cid of the new parent dir */
206 cfs_cid_t dl_child_cid; /* cid of renamed file */
207 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
208 cfs_cid_t dl_del_cid; /* cid of deleted file */
209 cfs_dlog_tm_t dl_del_times; /* ctime and mtime on deleted file */
210 dl_cred_t dl_cred; /* credentials to use */
211 char dl_buffer[CFS_DLOG_BUFSIZE + (2 * MAXNAMELEN)];
212 };
213
214 struct cfs_dlog_modify {
215 cfs_cid_t dl_cid; /* cid of modified file */
216 cfs_dlog_tm_t dl_times; /* ctime and mtime on file */
217 off32_t dl_next; /* daemon links modifies together */
218 dl_cred_t dl_cred; /* credentials to use */
219 char dl_buffer[CFS_DLOG_BUFSIZE]; /* groups */
220 };
221
222 struct cfs_dlog_mapfid {
223 cfs_cid_t dl_cid; /* cid of file */
224 cfs_fid_t dl_fid; /* fid of file */
225 };
226
227 #define COMMON_RECORD_HDR() \
228 int dl_len; /* length of this record */ \
229 cfs_dlog_op_t dl_op; /* operation */ \
230 cfs_dlog_val_t dl_valid; /* validity of operation */ \
231 uint_t dl_seq; /* sequence number */
232
233 /*
234 * The trailer record must look just like the beginning of a record.
235 * This allows the cachefs daemon to throw it away(not process the record)
236 * with very little additional code.
237 */
238 struct cfs_dlog_trailer {
239 COMMON_RECORD_HDR()
240 };
241
242 struct cfs_dlog_entry {
243 COMMON_RECORD_HDR()
244
245 union cfs_dlog_entry_items {
246 struct cfs_dlog_setattr dl_setattr;
247 struct cfs_dlog_setsecattr dl_setsecattr;
248 struct cfs_dlog_create dl_create;
249 struct cfs_dlog_remove dl_remove;
250 struct cfs_dlog_rmdir dl_rmdir;
251 struct cfs_dlog_mkdir dl_mkdir;
252 struct cfs_dlog_link dl_link;
253 struct cfs_dlog_symlink dl_symlink;
254 struct cfs_dlog_rename dl_rename;
255 struct cfs_dlog_modify dl_modify;
256 struct cfs_dlog_mapfid dl_mapfid;
257 } dl_u;
258
259 struct cfs_dlog_trailer dl_trailer;
260 };
261 typedef struct cfs_dlog_entry cfs_dlog_entry_t;
262
263 /*
264 * XXXX the maxsize calculation below will give wrong answer if
265 * the total size of struct cfs_dlog_setsecattr + max aclsize is less than
266 * the size of the union above. This is currently true, but to be on the safe
267 * side, use struct size plus acl size (minus trailer because it's not
268 * not counted in the length field).
269 */
270 #define CFS_DLOG_SECATTR_MAXSIZE (sizeof (struct cfs_dlog_setsecattr) + \
271 (sizeof (aclent_t) * MAX_ACL_ENTRIES))
272
273 #ifndef MAX
274 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
275 #endif /* MAX */
276
277 #define CFS_DLOG_ENTRY_MAXSIZE \
278 MAX(offsetof(struct cfs_dlog_entry, dl_trailer), \
279 offsetof(struct cfs_dlog_entry, dl_u.dl_setsecattr) + \
280 CFS_DLOG_SECATTR_MAXSIZE)
281
282 #if defined(_KERNEL) && defined(__STDC__)
283 int cachefs_dlog_setup(fscache_t *fscp, int createfile);
284 void cachefs_dlog_teardown(fscache_t *fscp);
285 int cachefs_dlog_commit(fscache_t *fscp, off_t offset, int error);
286 int cachefs_dlog_cidmap(fscache_t *fscp);
287 off_t cachefs_dlog_setattr(fscache_t *fscp, struct vattr *vap, int flags,
288 cnode_t *cp, cred_t *cr);
289 off_t
290 cachefs_dlog_setsecattr(fscache_t *fscp, vsecattr_t *vsec, int flags,
291 cnode_t *cp, cred_t *cr);
292 off_t cachefs_dlog_create(fscache_t *fscp, cnode_t *pcp, char *nm,
293 vattr_t *vap, int excl, int mode, cnode_t *cp, int exists, cred_t *cr);
294 off_t cachefs_dlog_remove(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
295 cred_t *cr);
296 off_t cachefs_dlog_link(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
297 cred_t *cr);
298 off_t cachefs_dlog_rename(fscache_t *fscp, cnode_t *odcp, char *onm,
299 cnode_t *ndcp, char *nnm, cred_t *cr, cnode_t *cp, cnode_t *delcp);
300 off_t cachefs_dlog_mkdir(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *nm,
301 vattr_t *vap, cred_t *cr);
302 off_t cachefs_dlog_rmdir(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
303 cred_t *cr);
304 off_t cachefs_dlog_symlink(fscache_t *fscp, cnode_t *pcp, cnode_t *cp,
305 char *lnm, vattr_t *vap, char *tnm, cred_t *cr);
306 off_t cachefs_dlog_modify(fscache_t *fscp, cnode_t *cp, cred_t *cr,
307 uint_t *seqp);
308 int cachefs_dlog_mapfid(fscache_t *fscp, cnode_t *cp);
309 uint_t cachefs_dlog_seqnext(fscache_t *fscp);
310 #endif
311
312 #ifdef __cplusplus
313 }
314 #endif
315
316 #endif /* _SYS_FS_CACHEFS_DLOG_H */