cachefs_dlog.c 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
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/pathname.h>
#include <sys/sysmacros.h>
#include <sys/bootconf.h>
#ifdef _LP64
{ \
int ovferr = 0; \
if (ovferr) \
}
{ \
int ovferr = 0; \
if (ovferr) \
}
{ \
int ovferr = 0; \
if (ovferr) \
}
/*
* check attr error - if we get an overflow error copying vattr, make sure
* the field affected is actually wanted, or it might be junk
*/
static void
{
}
}
}
}
}
}
#else /* not _LP64 */
#endif /* _LP64 */
/*
*
* Cachefs used to know too much about how creds looked; since it's
* committed to persistent storage, we can't change the layout so
* it now has a "dl_cred_t" which (unsurprisingly) looks exactly like
* an old credential.
*
* The dst argument needs to point to:
* struct dl_cred_t;
* <buffer space> buffer for groups
*
* The source is a proper kernel cred_t.
*
*/
static size_t
{
int n;
/* copy the fixed fields */
dst->cr_ngroups = n;
}
/*
* Sets up for writing to the log files.
*/
int
{
int error = 0;
int createdone = 0;
int lookupdone = 0;
int version = CFS_DLOG_VERSION;
struct cfs_dlog_trailer trailer;
/* all done if the log files already exist */
if (fscp->fs_dlogfile) {
goto out;
}
/* see if the log file exists */
if (error && (createfile == 0))
goto out;
/* if the lookup failed then create file log files */
if (error) {
createdone++;
if (error) {
#ifdef CFSDEBUG
printf("cachefs: log file create fail %d\n",
error);
#endif
goto out;
}
/* write the version number into the log file */
if (error) {
#ifdef CFSDEBUG
printf("cachefs: log file init fail %d\n",
error);
#endif
goto out;
}
if (error) {
#ifdef CFSDEBUG
printf("cachefs: map file create fail %d\n",
error);
#endif
goto out;
}
fscp->fs_dlogseq = 0;
fscp->fs_dmapoff = 0;
fscp->fs_dmapsize = 0;
}
/*
* Else the lookup succeeded.
* Before mounting, fsck should have fixed any problems
* in the log file.
*/
else {
lookupdone++;
/* find the end of the log file */
if (error) {
#ifdef CFSDEBUG
printf("cachefs: log file getattr fail %d\n",
error);
#endif
goto out;
}
/*LINTED alignment okay*/
/*
* The last record in the dlog file is a trailer record
* that contains the last sequence number used. This is
* used to reset the sequence number when a logfile already
* exists.
*/
if (error == 0) {
/*
* Set the offset of the next record to be
* written, to over write the current
* trailer.
*/
} else {
#ifdef CFSDEBUG
"cachefs: can't find dlog trailer");
"cachefs: fsck required");
}
#endif /* CFSDEBUG */
/*LINTED alignment okay*/
}
} else {
#ifdef CFSDEBUG
"cachefs: error reading dlog trailer");
#endif /* CFSDEBUG */
/*LINTED alignment okay*/
}
if (error) {
#ifdef CFSDEBUG
printf("cachefs: map file lookup fail %d\n",
error);
#endif
goto out;
}
if (error) {
#ifdef CFSDEBUG
printf("cachefs: map file getattr fail %d\n",
error);
#endif
goto out;
}
}
out:
if (error) {
if (createdone) {
if (fscp->fs_dlogfile) {
}
if (fscp->fs_dmapfile) {
}
}
if (lookupdone) {
if (fscp->fs_dlogfile) {
}
if (fscp->fs_dmapfile) {
}
}
}
return (error);
}
/*
* Drops reference to the log file.
*/
void
{
/*LINTED: set but not used */
int error;
/* clean up the log file */
if (fscp->fs_dlogfile) {
}
/* clean up the map file */
if (fscp->fs_dmapfile) {
/* set the map file to the actual size needed */
#ifdef CFSDEBUG
if (error) {
error);
}
#endif
}
}
/*
* Outputs a dlog message to the log file.
*/
static off_t
{
int error;
int xx;
int len;
struct cfs_dlog_trailer *trail;
if (error) {
offset = 0;
goto out;
}
}
/* round up length to a 4 byte boundary */
if (xx) {
}
#if 0
/* XXX debugging hack, round up to 16 byte boundary */
#endif
/*
* All functions which allocate a dlog entry buffer must be sure
* to allocate space for the trailer record. The trailer record,
* is always located at the end of the log file. It contains the
* highest sequence number used. This allows cachefs_dlog_setup()
* to reset the sequence numbers properly when the log file
* already exists.
*/
/* get a sequence number for this log entry */
if (seq == 0) {
offset = 0;
#ifdef CFSDEBUG
#endif
goto out;
}
fscp->fs_dlogseq++;
/* add the sequence number to the record */
/* get offset into file to write record */
/* try to write the record to the log file */
/*
* NOTE This write will over write the previous trailer record and
* will add a new trailer record. This is done with a single
* write for performance reasons.
*/
if (error) {
offset = 0;
} else {
/* get offset of valid field */
}
/* return sequence number used if requested */
if (seqp)
out:
return (offset);
}
/*
* Commmits a previously written dlog message.
*/
int
{
if (error)
else
if (error)
return (error);
}
/*
* Reserves space in the map file.
*/
static int
{
int error = 0;
int len;
char *bufp;
if (error) {
return (error);
}
}
/* reserve 20% for optimal hashing */
/* grow file by a MAXBSIZE chunk */
if (error == 0) {
} else {
"failed (%d)", error);
}
} else {
}
return (error);
}
/*
* Reserves space for one cid mapping in the mapping file.
*/
int
{
int error;
sizeof (struct cfs_dlog_mapping_space));
return (error);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_setattr *up;
"cachefs_dlog_setattr: dl_attr");
/* store the cred info */
/* Calculate the length of this record */
/* write the record in the log */
return (offset);
}
/*ARGSUSED*/
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_setsecattr *up;
/* paranoia */
vsec->vsa_aclcnt = 0;
vsec->vsa_dfaclcnt = 0;
/* calculate length of ACL and cred data */
/*
* allocate entry. ACLs may be up to 24k currently, but they
* usually won't, so we don't want to make cfs_dlog_entry_t
* too big. so, we must compute the length here.
*/
#if 0
/* make up for weird behavior in cachefs_dlog_output */
KM_SLEEP);
#else
#endif
/* get the creds */
/* mask and counts */
/* get the acls themselves */
if (vsec->vsa_aclcnt > 0) {
}
if (vsec->vsa_dfaclcnt > 0) {
}
#if 0
#else
#endif
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_create *up;
"cachefs_dlog_create: dl_attr");
if (exists) {
"cachefs_dlog_create: ", "mtime");
"cachefs_dlog_create: ", "ctime");
} else {
}
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the created name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_remove *up;
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the removed name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_link *up;
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the link name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_rename *up;
if (delcp) {
"cachefs_dlog_rename: ", "del mtime");
"cachefs_dlog_rename: ", "del ctime");
} else {
}
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the old name */
/* store the new name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_mkdir *up;
"cachefs_dlog_mkdir: dl_attr");
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the new directory name */
/* calculate the length of this record */
/* write the record in the dlog */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_rmdir *up;
/* if not a local dir, log the cid to fid mapping */
return (0);
if (cachefs_dlog_cidmap(fscp))
return (0);
}
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the created name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_symlink *up;
"cachefs_dlog_symlink: dl_attr");
/* store the cred info */
/* find the address in buffer past where the creds are stored */
/* store the link name */
/* store new name */
/* calculate the length of this record */
/* write the record in the log */
return (offset);
}
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_modify *up;
"cachefs_dlog_modify: ", "mtime");
"cachefs_dlog_modify: ", "ctime");
/* store the cred info */
/* calculate the length of this record */
/* write the record in the log */
/* return sequence number */
return (offset);
}
int
{
struct cfs_dlog_entry *entp;
struct cfs_dlog_mapfid *up;
/* calculate the length of this record */
/* entp->dl_len = ((caddr_t)up - (caddr_t)entp + sizeof (*up)); */
sizeof (struct cfs_dlog_mapfid));
/* write the record in the log */
return (offset == 0);
}
/* Returns the next sequence number, 0 if an error */
{
int error;
if (error)
return (0);
}
/* get a sequence number for this log entry */
if (seq != 0) {
fscp->fs_dlogseq++;
}
#ifdef CFSDEBUG
else {
}
#endif
return (seq);
}