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