xref: /titanic_44/usr/src/uts/common/sys/fs/cachefs_dlog.h (revision ba3594ba9b5dd4c846c472a8d657edcb7c8109ac)
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 2014 Garrett D'Amore <garrett@damore.org>
24  *
25  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #ifndef	_SYS_FS_CACHEFS_DLOG_H
30 #define	_SYS_FS_CACHEFS_DLOG_H
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)
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 */
317