Home | History | Annotate | Download | only in fs
      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 */
    317