summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fs/cachefs_dlog.h
blob: 3914cad1148c7a225ad4937bff137e0942922289 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
 *
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_FS_CACHEFS_DLOG_H
#define	_SYS_FS_CACHEFS_DLOG_H

#include <sys/vfs.h>
#include <sys/acl.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Version number of log file format.
 * Put in an int at the start of the file.
 * Large Files: Increment VER by 1.
 */
#define	CFS_DLOG_VERSION 1001

/* valid types of dlog records */
enum cfs_dlog_op {
	CFS_DLOG_CREATE = 0x100,
	CFS_DLOG_REMOVE,
	CFS_DLOG_LINK,
	CFS_DLOG_RENAME,
	CFS_DLOG_MKDIR,
	CFS_DLOG_RMDIR,
	CFS_DLOG_SYMLINK,
	CFS_DLOG_SETATTR,
	CFS_DLOG_SETSECATTR,
	CFS_DLOG_MODIFIED,
	CFS_DLOG_MAPFID,
	CFS_DLOG_TRAILER
};
typedef enum cfs_dlog_op cfs_dlog_op_t;

/* validity of records */
enum cfs_dlog_val {
	CFS_DLOG_VAL_CRASH = 0x200,	/* crash during record creation */
	CFS_DLOG_VAL_COMMITTED,		/* valid record */
	CFS_DLOG_VAL_ERROR,		/* error, operation not performed */
	CFS_DLOG_VAL_PROCESSED		/* record processed */
};
typedef enum cfs_dlog_val cfs_dlog_val_t;

/* number of bytes for groups appended to a cred structure */
#define	CFS_DLOG_BUFSIZE (sizeof (gid_t) * (NGROUPS_MAX_DEFAULT - 1))

/* the old kernel credential; ossified on disk so we're stuck with this. */
typedef struct dl_cred {
	uint_t	__ign1;			/* ignore (was ref count) */
	uid_t	cr_uid;			/* effective user id */
	gid_t	cr_gid;			/* effective group id */
	uid_t	cr_ruid;		/* real user id */
	gid_t	cr_rgid;		/* real group id */
	uid_t	cr_suid;		/* "saved" user id (from exec) */
	gid_t	cr_sgid;		/* "saved" group id (from exec) */
	uint_t	cr_ngroups;		/* number of groups in cr_groups */
	gid_t	cr_groups[1];		/* supplementary group list */
} dl_cred_t;

/*
 * cfs_dlog_mapping_space is stored on disk, so it needs to be the same
 * 32-bit vs. 64-bit. The other structures below are also stored on disk,
 * but they do not contain any 64-bit elements.
 */

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

/* the basic elements in the mapping file */
struct cfs_dlog_mapping_space {
	cfs_cid_t	ms_cid;		/* mapping key */
	off_t		ms_fid;		/* offset to fid */
	off_t		ms_times;	/* offset to timestamps */
};

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

/*
 * XX64: For now we use the old time_t defs. In the next version the logs
 * and on-disk structs may change to 64-bit. The structs here are used
 * for the data log.
 */
/* mtime and ctime stamps */
struct cfs_dlog_tm {
	cfs_timestruc_t	tm_mtime;	/* cached mtime on file */
	cfs_timestruc_t	tm_ctime;	/* cached ctime on file */
};
typedef struct cfs_dlog_tm cfs_dlog_tm_t;

/* structure populated for setattr */
struct cfs_dlog_setattr {
	cfs_vattr_t	dl_attrs;	/* attrs to set file to */
	int		dl_flags;	/* flags used with setattr */
	cfs_cid_t	dl_cid;		/* cid of the file to setattr */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	dl_cred_t	dl_cred;	/* creds used */
	char		dl_buffer[CFS_DLOG_BUFSIZE];	/* groups */
};

/* structure for setsecattr (aka setting an ACL) */
/* n.b. data for this can exceed sizeof this struct, due to 24k ACLs! */
struct cfs_dlog_setsecattr {
	cfs_cid_t	dl_cid;		/* cid of file to setsecattr */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	uint_t		dl_mask;	/* mask field in vsecattr_t */
	int		dl_aclcnt;	/* count of ACLs */
	int		dl_dfaclcnt;	/* count of default ACLs */
	dl_cred_t	dl_cred;	/* creds used */
	char		dl_buffer[CFS_DLOG_BUFSIZE]; /* groups + ACLs */
};

/* structure populated for creates */
struct cfs_dlog_create {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	cfs_cid_t	dl_new_cid;	/* cid of the created file */
	cfs_vattr_t	dl_attrs;	/* attrs to create with */
	int		dl_excl;	/* exclusive mode flag */
	int		dl_mode;	/* mode bits for created file */
	int		dl_exists;	/* does file already exist? */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	cfs_fid_t	dl_fid;		/* blank fid */
	dl_cred_t	dl_cred;	/* user credentials */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
};

/* struct used for remove */
struct cfs_dlog_remove {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	cfs_cid_t	dl_child_cid;	/* cid of entry that was removed */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
};

/* struct used for rmdir */
struct cfs_dlog_rmdir {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
};

/* struct used for mkdir */
struct cfs_dlog_mkdir {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	cfs_cid_t	dl_child_cid;	/* cid of created entry */
	cfs_vattr_t	dl_attrs;	/* attrs to insert with */
	cfs_fid_t	dl_fid;		/* blank fid */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
};

/* struct used for link */
struct cfs_dlog_link {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	cfs_cid_t	dl_child_cid;	/* cid of created entry */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN];
};

/* struct used for symlink */
struct cfs_dlog_symlink {
	cfs_cid_t	dl_parent_cid;	/* parent directory cid */
	cfs_cid_t	dl_child_cid;	/* cid of created entry */
	cfs_vattr_t	dl_attrs;	/* attrs to insert with */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	cfs_fid_t	dl_fid;		/* blank fid */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + MAXNAMELEN + MAXPATHLEN];
};

struct cfs_dlog_rename {
	cfs_cid_t	dl_oparent_cid; /* cid of the original parent dir */
	cfs_cid_t	dl_nparent_cid;	/* cid of the new parent dir */
	cfs_cid_t	dl_child_cid;	/* cid of renamed file */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	cfs_cid_t	dl_del_cid;	/* cid of deleted file */
	cfs_dlog_tm_t	dl_del_times;	/* ctime and mtime on deleted file */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE + (2 * MAXNAMELEN)];
};

struct cfs_dlog_modify {
	cfs_cid_t	dl_cid;		/* cid of modified file */
	cfs_dlog_tm_t	dl_times;	/* ctime and mtime on file */
	off32_t		dl_next;	/* daemon links modifies together */
	dl_cred_t	dl_cred;	/* credentials to use */
	char		dl_buffer[CFS_DLOG_BUFSIZE];	/* groups */
};

struct cfs_dlog_mapfid {
	cfs_cid_t	dl_cid;		/* cid of file */
	cfs_fid_t	dl_fid;		/* fid of file */
};

#define	COMMON_RECORD_HDR()  						\
	int		dl_len;		/* length of this record */	\
	cfs_dlog_op_t 	dl_op;		/* operation */			\
	cfs_dlog_val_t 	dl_valid;	/* validity of operation */	\
	uint_t		dl_seq;		/* sequence number */

/*
 * The trailer record must look just like the beginning of a record.
 * This allows the cachefs daemon to throw it away(not process the record)
 * with very little additional code.
 */
struct cfs_dlog_trailer {
	COMMON_RECORD_HDR()
};

struct cfs_dlog_entry {
	COMMON_RECORD_HDR()

	union cfs_dlog_entry_items {
		struct cfs_dlog_setattr		dl_setattr;
		struct cfs_dlog_setsecattr	dl_setsecattr;
		struct cfs_dlog_create		dl_create;
		struct cfs_dlog_remove		dl_remove;
		struct cfs_dlog_rmdir		dl_rmdir;
		struct cfs_dlog_mkdir		dl_mkdir;
		struct cfs_dlog_link		dl_link;
		struct cfs_dlog_symlink		dl_symlink;
		struct cfs_dlog_rename		dl_rename;
		struct cfs_dlog_modify		dl_modify;
		struct cfs_dlog_mapfid		dl_mapfid;
	} dl_u;

	struct cfs_dlog_trailer dl_trailer;
};
typedef struct cfs_dlog_entry cfs_dlog_entry_t;

/*
 * XXXX the maxsize calculation below will give wrong answer if
 * the total size of struct cfs_dlog_setsecattr + max aclsize is less than
 * the size of the union above. This is currently true, but to be on the safe
 * side, use struct size plus acl size (minus trailer because it's not
 * not counted in the length field).
 */
#define	CFS_DLOG_SECATTR_MAXSIZE (sizeof (struct cfs_dlog_setsecattr) + \
	(sizeof (aclent_t) * MAX_ACL_ENTRIES))

#ifndef MAX
#define	MAX(a, b)	(((a) > (b)) ? (a) : (b))
#endif /* MAX */

#define	CFS_DLOG_ENTRY_MAXSIZE	\
	MAX(offsetof(struct cfs_dlog_entry, dl_trailer),		\
	    offsetof(struct cfs_dlog_entry, dl_u.dl_setsecattr) +	\
	    CFS_DLOG_SECATTR_MAXSIZE)

#if defined(_KERNEL)
int cachefs_dlog_setup(fscache_t *fscp, int createfile);
void cachefs_dlog_teardown(fscache_t *fscp);
int cachefs_dlog_commit(fscache_t *fscp, off_t offset, int error);
int cachefs_dlog_cidmap(fscache_t *fscp);
off_t cachefs_dlog_setattr(fscache_t *fscp, struct vattr *vap, int flags,
    cnode_t *cp, cred_t *cr);
off_t
cachefs_dlog_setsecattr(fscache_t *fscp, vsecattr_t *vsec, int flags,
    cnode_t *cp, cred_t *cr);
off_t cachefs_dlog_create(fscache_t *fscp, cnode_t *pcp, char *nm,
    vattr_t *vap, int excl, int mode, cnode_t *cp, int exists, cred_t *cr);
off_t cachefs_dlog_remove(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
    cred_t *cr);
off_t cachefs_dlog_link(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
    cred_t *cr);
off_t cachefs_dlog_rename(fscache_t *fscp, cnode_t *odcp, char *onm,
    cnode_t *ndcp, char *nnm, cred_t *cr, cnode_t *cp, cnode_t *delcp);
off_t cachefs_dlog_mkdir(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *nm,
    vattr_t *vap, cred_t *cr);
off_t cachefs_dlog_rmdir(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
    cred_t *cr);
off_t cachefs_dlog_symlink(fscache_t *fscp, cnode_t *pcp, cnode_t *cp,
    char *lnm, vattr_t *vap, char *tnm, cred_t *cr);
off_t cachefs_dlog_modify(fscache_t *fscp, cnode_t *cp, cred_t *cr,
    uint_t *seqp);
int cachefs_dlog_mapfid(fscache_t *fscp, cnode_t *cp);
uint_t cachefs_dlog_seqnext(fscache_t *fscp);
#endif

#ifdef __cplusplus
}
#endif

#endif	/* _SYS_FS_CACHEFS_DLOG_H */