cachefs_filegrp.c revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2007 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>
#if (defined(_SYSCALL32_IMPL) || defined(_LP64))
#define CACHEFS_ALLOC_CFS_METADATA(p, inp) \
#define CACHEFS_FREE_CFS_METADATA(p) \
cachefs_kmem_free(p, sizeof (struct cfs_cachefs_metadata))
/* CACHEFS_COPY_COMMON_METADATA_FIELDS - common code for the metadata copy */
&(outmdp)->md_timestamp); \
&(outmdp)->md_localmtime); \
&(outmdp)->md_localctime); \
#else /* not (_SYSCALL32_IMPL || _LP64) */
#define CACHEFS_ALLOC_CFS_METADATA(p, inp) \
p = (cfs_cachefs_metadata_t *)(inp)
#define CACHEFS_FREE_CFS_METADATA(p)
#endif /* _SYSCALL32_IMPL || _LP64 */
/* forward references */
int
/*ARGSUSED*/
{
return (0);
}
void
/*ARGSUSED*/
{
}
/*
* ------------------------------------------------------------------
*
* filegrp_create
*
* Description:
* Creates a filegrp object for the specified fscache.
* The CFS_FG_ALLOC_{ATTR, FILE} bits will be set in fg_flags
* if the cache is in NOCACHE and NOFILL mode or if
* the directory does not exist yet.
* The filegrp object maintains a reference to the specified
* fscache.
* Arguments:
* fscp fscache to create the file group in
* cidp start cid for the file group
* Returns:
* Returns the created filegrp object.
* Preconditions:
* precond(fscp)
* precond(cidp)
* precond(fscp->fs_info.fi_fgsize > 0)
*/
#define Bugid_1249206_notfixed
#ifdef Bugid_1249206_notfixed
int bugid_1249206 = 0;
#endif
{
int fgsize;
int flags;
#ifdef Bugid_1249206_notfixed
if (bugid_1249206)
#endif
#ifdef Bugid_1249206_notfixed
if (bugid_1249206) {
}
#endif
if (flags & CFS_FS_READ) {
if (flags & CFS_FS_WRITE) {
}
}
/* find the attrcache file and frontfile directory */
(void) filegrpattr_find(fgp);
/*
* XXX: we can tell from the file count in the attrcache
* whether we can expect to find a front file dir or
* not. If not, we can save the lookup here...
*/
(void) filegrpdir_find(fgp);
}
return (fgp);
}
/*
* ------------------------------------------------------------------
*
* filegrp_destroy
*
* Description:
* Destroys the filegrp object and releases any kernel
* resource associated with it.
* Additionally if the on disk file group directory does
* not contain any front files it is removed.
* Arguments:
* fgp filegrp object to destroy
* Returns:
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(fgp->fg_count == 0)
* precond(fgp->fg_next == NULL)
*/
void
{
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
int error;
if (error)
"cachefs: UFS error on cache, "
"run fsck %d", error);
}
}
/*
* If there are no attrcache entries in use and
* if we can modify the cache.
*/
/* remove attrcache file from the rl list */
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
/*
* XXX sam: since we're blowing away the
* attrcache file, i guess i don't need to set
* ach_rl_current to CACHEFS_RL_NONE and
* sync the attrcache file, right?
*
* fgp->fg_header->ach_rl_current = CACHEFS_RL_NONE;
* fgp->fg_flags |= CFS_FG_UPDATED;
*/
/* remove the attrcache file */
NULL, 0);
if (error) {
"cachefs: error in cache, run fsck");
} else {
0);
}
}
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_allocattr
*
* Description:
* Tries to find the attrcache file for the given filegroup.
* If the file does not yet exist it is created.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
int
{
int error = 0;
/* if we do not yet have the attrcache file */
/* fail if we tried to create it but failed previously */
goto out;
}
/* fail if we cannot read from the cache */
goto out;
}
/* try to find the attrcache file in the cache */
/* fail if we cannot create the attrcache file */
goto out;
}
/* try to create the attrcache file */
}
}
out:
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_hold
*
* Description:
* Increments the number of references to this filegrp object.
* Arguments:
* fgp filegrp object to reference
* Returns:
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
void
{
/* remove attrcache file from the rl list if necessary */
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_rele
*
* Description:
* Decrements the number of references to this filegrp object.
* Arguments:
* fgp filegrp object to dereference
* Returns:
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(number of references to filegrp is > 0)
*/
void
{
/* move attrcache file to the rl list if necessary */
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_ffhold
*
* Description:
* Increments the count of the number of front files for
* this filegrp by one.
* Arguments:
* fgp filegrp object to reference
* Returns:
* Returns 0 for success or a non-zero errno.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(number of references to filegrp is > 0)
* precond(filegrp is writable)
*/
int
{
int error = 0;
/* if the filegrp is no good, bail out with warning */
goto out;
}
/* if we do not have the directory vp yet */
/* create the directory if necessary */
if (error)
goto out;
}
/* else find the directory */
else {
if (error) {
#ifdef CFSDEBUG
printf("ffhold: no dir, errno %d, "
"fileno %llx\n",
#endif
goto out;
}
}
}
#ifdef CFSDEBUG
/*
* XXX sam: this used to remove from the active list,
* and put on `NONE'. now, we're on
* CACHEFS_RL_ATTRFILE if either count or nffs is
* nonzero; CACHEFS_RL_GC otherwise. since we just
* asserted that we're not on CACHEFS_RL_GC, there's
* nothing more to do. right?
*/
}
#endif /* CFSDEBUG */
out:
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_ffrele
*
* Description:
* Decrements the count of the number of front files for
* this filegrp by one.
* Arguments:
* fgp filegrp object to dereference
* Returns:
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(filegrp is writable)
* precond(number of references to filegrp is > 0)
* precond(number of front file references is > 0)
*/
void
{
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
int error = 0;
/* if the filegrp is corrupt, bail out with warning */
return;
}
if (error == 0) {
} else {
" frontfs cache error %d, run fsck", error);
}
/*
* XXX sam: this used to move from `NONE' to
* `CACHEFS_RL_ACTIVE'. now, we're on
* nonzero, and CACHEFS_RL_GC otherwise. since we
* just asserted that count > 0, there's nothing to
* do. right?
*/
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_sync
*
* Description:
* Writes the file group's attrcache header to the attrcache
* file if necessary and syncs it.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
int
{
int error = 0;
return (0);
}
if (error == 0)
if (error == 0)
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_read_metadata
*
* Description:
* Reads the metadata for the specified file from the attrcache
* file belonging to the filegrp object. Note that the md_rltype
* field may be incorrect if (cachep->c_flags & CACHE_CHECK_RLTYPE);
* in this case, if you care about md_rltype, you should double-check
* if rl_type is CACHEFS_RL_ACTIVE; cachefs_move_active_to_rl may have
* moved it without telling us.
* Arguments:
* fgp filegrp object
* cidp the file to search for
* mdp set to the metadata for the fileno
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(mdp)
* precond(slotp)
*/
int
struct cachefs_metadata *mdp)
{
int slot;
int error;
int index;
struct cfs_cachefs_metadata *tmpmdp;
return (ENOENT);
}
if (slot == 0) {
return (ENOENT);
}
/* see if metadata was ever written */
return (ENOENT);
}
if (error) {
"cachefs_read_metadata:"
" frontfs cache error %d, run fsck", error);
}
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_create_metadata
*
* Description:
* Allocates a slot for the specified fileno.
* Arguments:
* fgp filegrp object
* cidp the file to allocate a slot for
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
int
{
int slot;
int bitno;
int last;
int xx;
int index;
return (ENOENT);
}
if (slot) {
return (0);
}
goto found;
}
mask <<= 1;
}
}
}
return (ENOMEM);
}
return (0);
}
/*
* ------------------------------------------------------------------
*
* filegrp_write_metadata
*
* Description:
* Writes metadata to the slot held by file.
* Arguments:
* fgp filegrp object
* cidp the file to write the metadata for
* mdp the metadata to write
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(mdp)
*/
int
struct cachefs_metadata *mdp)
{
int error = 0;
int slot;
int index;
struct cfs_cachefs_metadata *tmpmdp;
goto out;
}
if (slot == 0) {
goto out;
}
/* allocate blocks for the data if necessary */
if (nblks > 0) {
if (error)
goto out;
if (error) {
goto out;
}
} else
nblks = 0;
/* write the metadata */
if (!error)
if (error) {
"cachefs: UFS write error %d, run fsck",
error);
}
goto out;
}
/* mark metadata as having been written */
/* update number of blocks used by the attrcache file */
/* force sync to be done eventually */
out:
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_destroy_metadata
*
* Description:
* Destroys the metadata associated with the specified file.
* Arguments:
* fgp filegrp object
* cidp the file to destroy the metadata for
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
int
{
int i;
int bitno;
int slot;
return (ENOENT);
}
if (slot == 0) {
return (ENOENT);
}
(int)sizeof (struct cfs_cachefs_metadata);
bitno = i & 7;
i = i >> 3;
else
"filegrp_destroy_metadata:"
return (0);
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_find
*
* Description:
* Looks for the filegrp that owns the specified file
* on the fscp filegrp lists.
* The fscp->fs_fslock must be held while this routine is called.
* By convention the filegrp object returned may be used as
* long as the fs_fslock is held. To use the filegrp after
* dropping fs_fslock, call filegrp_hold.
* Arguments:
* fscp fscache object
* cidp the file to search on
* Returns:
* Returns the filegrp object if found, NULL if not.
* Preconditions:
* precond(fscp is a valid fscache object)
*/
{
int findex;
/* get fileno of filegrp */
/* hash into array of file groups */
/* search set of file groups for this hash bucket */
break;
}
return (fgp);
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_add
*
* Description:
* Adds the filegrp to the list of filegrps in the fscp.
* The fscp->fs_fslock must be held while this routine is called.
* Arguments:
* fscp fscache object
* fgp filegrp object
* Returns:
* Preconditions:
* precond(fscp is a valid fscache object)
* precond(fgp is a valid filegrp object)
* precond(fgp is not already on a list of filegrps)
*/
void
{
int findex;
/* hash into array of file groups */
(CFS_FS_FGP_BUCKET_SIZE - 1));
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_remove
*
* Description:
* Removes the filegrp from the list of filegrps in the fscp.
* The fscp->fs_fslock must be held while this routine is called.
* Arguments:
* fscp fscache object
* fgp filegrp object
* Returns:
* Preconditions:
* precond(fscp is a valid fscache object)
* precond(fgp is a valid filegrp object)
* precond(fgp is on the list of filegrps in fscp)
*/
void
{
int found = 0;
int findex;
/* hash into array of file groups */
(CFS_FS_FGP_BUCKET_SIZE - 1));
found++;
break;
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_gc
*
* Description:
* Traverses the filegrp lists and throws away any filegrps that are
* not in use.
* The fscp->fs_fslock must be held while this routine is called.
* Arguments:
* fscp fscache object
* Returns:
* Preconditions:
* precond(fscp is a valid fscache object)
*/
void
{
int xx;
continue;
}
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_setup
*
* Description:
* Perform initialization actions on the given filegrp.
* The fgp->fg_mutex must be held while this routine is called.
* Arguments:
* fgp filegrp object
* flags flags to be OR'ed into the fgp flags field
* dorl indicates whether filegrp should be removed from rl or not
* Returns:
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
static void
{
/* turn on the specified flags */
if (flags)
/* if the attrcache file exists, find it */
(void) filegrpattr_find(fgp);
/* if the attrcache directory exists, find it */
(void) filegrpdir_find(fgp);
}
/* move from gc list to attrfile list if necessary */
if ((dorl != 0) &&
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_enable_caching_ro
*
* Description:
* Traverses the filegrp lists and enables the
* use of the cache read-only.
* The fscp->fs_fslock must be held while this routine is called.
* Arguments:
* fscp fscache object
* Returns:
* Preconditions:
* precond(fscp is a valid fscache object)
*/
void
{
int xx;
filegrp_setup(fgp, 0, 0);
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrp_list_enable_caching_rw
*
* Description:
* Traverses the filegrp lists and enables the
* use of the cache read-write.
* The fscp->fs_fslock must be held while this routine is called.
* Arguments:
* fscp fscache object
* Returns:
* Preconditions:
* precond(fscp is a valid fscache object)
* precond(all filegrps must be in the read-only state)
*/
void
{
int xx;
}
}
}
/*
* ------------------------------------------------------------------
*
* filegrpdir_find
*
* Description:
* Tries to find the filegrp frontfile directory in the cache.
* If found CFS_FG_ALLOC_FILE is turned off.
* This routine should not be called if CFS_FG_ALLOC_FILE is
* already off.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
*/
int
{
int error;
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
return (ENOENT);
if (error == 0) {
#ifdef CFSDEBUG
printf("filegrpdir_find: "
"%s found but no front files\n", fname);
}
#endif
}
#ifdef CFSDEBUG
printf("filegrpdir_find: "
"%s NOT found but %d front files\n",
}
#endif
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrparttr_find
*
* Description:
* Tries to find the attrcache file for the given filegrp.
* If found the header information is read in and
* CFS_FG_ALLOC_ATTR is turned off.
* This routine should not be called if CFS_FG_ALLOC_ATTR is
* already off.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(fgp is readable)
*/
int
{
int error = 0;
struct attrcache_header *ahp;
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
return (ENOENT);
if (error) {
return (error);
}
if (error) {
error);
} else {
sizeof (struct attrcache_index));
&rlp);
if (error) {
return (error);
}
}
}
/* if the attr file is on the rl */
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
/* remove from rl, put on active */
}
} else {
#ifdef CFSDEBUG
#endif /* CFSDEBUG */
}
}
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrpdir_create
*
* Description:
* Creates the filegrp directory in the cache.
* If created CFS_FG_ALLOC_FILE is turned off.
* This routine should not be called if CFS_FG_ALLOC_FILE is
* already off.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(filegrp is writeable)
*/
int
{
int error;
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
return (ENOENT);
/* allocate a 1 block file for the directory */
if (error) {
return (error);
}
if (error) {
return (error);
}
/*
* Construct a name for this file group directory and then do a mkdir
*/
KM_SLEEP);
0, NULL);
if (error) {
} else {
}
if (attrp)
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrpattr_create
*
* Description:
* Creates the attrcache file for the given filegrp.
* If created CFS_FG_ALLOC_ATTR is turned off.
* This routine should not be called if CFS_FG_ALLOC_ATTR is
* already off.
* Arguments:
* fgp filegrp object
* Returns:
* Returns 0 on success, an errno value on failure.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(filegrp is writable)
*/
int
{
int error;
int nblks = 0;
int gotrlent = 0;
char name[CFS_FRONTFILE_NAME_SIZE];
char *fname;
return (ENOENT);
/* allocate a file for the attrcache */
if (error) {
goto out;
}
if (error) {
goto out;
}
/* alloc blocks for the attrcache header */
if (error) {
nblks = 0;
goto out;
}
/* Construct an attrcache header */
/* write out the header to allocate space on ufs */
if (error)
goto out;
if (error)
goto out;
if (error)
goto out;
/* allocate an rl entry and mark it as an attrcache entry */
if (error)
goto out;
gotrlent = 1;
/* put on the gc */
} else {
/* put on attrfile list */
}
out:
if (error) {
if (attrvp) {
NULL, 0);
}
if (nblks)
if (gotrlent)
if (ahp)
} else {
sizeof (struct attrcache_index));
}
if (attrp)
return (error);
}
/*
* ------------------------------------------------------------------
*
* filegrp_cid_to_slot
*
* Description:
* Takes a file and returns the offset to the metadata
* slot for the specified filegrp.
* Arguments:
* fgp filegrp object
* cidp file to map to an offset
* Returns:
* Returns the offset or 0 if the slot is not allocated yet
* or it is invalid.
* Preconditions:
* precond(fgp is a valid filegrp object)
* precond(fgp is not ALLOC_PENDING or NOCACHE)
*/
int
{
int xx;
int slot;
int index;
return (0);
}
if (slot == 0)
return (0);
return (0);
}
return (slot);
}
/*
*
* filegrp_write_space
*
* Description:
* Writes garbage data to the specified file starting
* at the specified location for the specified number of bytes.
* slot for the specified filegrp.
* Arguments:
* vp vnode to write to
* offset offset to write at
* cnt number of bytes to write
* Returns:
* Returns 0 for success or on error the result of the
* last vn_rdwr call.
* Preconditions:
* precond(vp)
*/
int
{
char *bufp;
int xx;
int error = 0;
while (cnt > 0) {
else
if (error)
break;
}
return (error);
}