cachefs_dlog.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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 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
#pragma ident "%Z%%M% %I% %E% SMI"
#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) && defined(__STDC__)
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 */