/*
* 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/fssnap_if.h>
#include <sys/sysmacros.h>
#include <sys/inttypes.h>
static void release_backing_vnodes(vnode_t ***, int);
static int ufs_snap_find_candidates(void *, struct ufsvfs *, int);
/*
* Create a snapshot on a file system
*/
int
{
int error = 0;
/*
* Only privilege processes can create a snapshot for now. This
* would be better if it was based on the permissions of the device
* file.
*/
return (EPERM);
/*
* There is no reason to make a snapshot of a read-only file system
*/
return (EROFS);
}
/*
* Initialize the backing files to store old data. This assumes any
* preallocation and setup has been done already.
* ufs_snap_init_backfile() allocates and returns a pointer to
* a null-terminated array of vnodes in bfvpp.
*/
if (error) {
return (error);
}
/*
* File system must be write locked to prevent updates while
* the snapshot is being established.
*/
return (error);
}
if (!LOCKFS_IS_ULOCK(&lf)) {
return (EINVAL);
}
return (EINVAL);
}
/*
* File system must be fairly consistent to enable snapshots
*/
goto unlockout;
}
/*
* Only one snapshot is allowed per file system, so error if
* a snapshot is already enabled.
*/
if (ufsvfsp->vfs_snapshot) {
goto unlockout;
}
/* Tell bio.c how to call our strategy routine. XXX ugly hack */
if (bio_snapshot_strategy == NULL)
(void (*) (void *, buf_t *))fssnap_strategy;
/*
* use chunk size that is passed in, or the file system
* block size if it is zero. For most cases, the file system
* block size will be reasonably efficient. A larger
* chunksize uses less memory but may potentially induce more
* I/O copying the larger chunks aside.
*/
else
/*
* compute the number of chunks in this whole file system. Since
* the UFS allocation bitmaps are in units of fragments, we first
* compute the number of fragments per chunk. Things work out
* nicer if the chunk size is a power-of-two multiple of the
* fragment size.
*/
goto unlockout;
}
/*
* Create and initialize snapshot state and allocate/initialize
* translation table. This does the real work of taking the snapshot.
*/
goto unlockout;
}
if (error) {
"error = %d.", error);
goto unlockout;
}
/*
* Unlock the file system
*/
} else {
}
/* clean up the snapshot if an error occurred. */
(void) fssnap_delete(&snapid);
return (error);
}
static int
{
int i;
KM_SLEEP);
for (i = 0; i < count; i++) {
return (EBADF);
}
filedesc++;
/* make sure the backing file is on a different file system */
return (EINVAL);
}
vpp++;
}
return (0);
}
static void
{
while (*vpp) {
}
}
static int
{
int error = 0;
/*
* read through each ufs cylinder group and fetch the fragment
* allocation bitmap. UFS indicates a fragment is allocated by
* a zero bit (not a one bit) in the fragment offset.
*/
/* read the cylinder group in */
goto errout;
}
/* check the magic number */
"magic number (0x%x) does not match expected "
goto errout;
}
/*
* go through the allocation bitmap and set the
* corresponding bit in the candidate map.
*/
/*
* this assumes chunksize is a multiple of
* the fragment size
*/
/*
* no need to scan the rest of this chunk since
* it is already marked, so skip to the next
*/
}
}
} /* cylinder group loop */
return (error);
}
int
{
/*
* Initialize fields in the user's buffer
*/
/*
* No snapshot exists, we're done.
*/
return (ENOENT);
/*
* must have sufficient privileges.
*/
return (EPERM);
/*
* Readonly file system
*/
return (EROFS);
}
/* free the data structures and clear the vfs_snapshot field. */
return (EINVAL);
return (0);
}