ufs_filio.c revision bc69f433dafeba50eb91394b62dfd2d145407bc3
/*
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/resource.h>
#include <sys/pathname.h>
/*
* ufs_fioio is the ufs equivalent of NFS_CNVT and is tailored to
* metamucil's needs. It may change at any time.
*/
/* ARGSUSED */
int
int flag, /* flag from VOP_IOCTL() */
{
int error = 0;
/*
* must be privileged
*/
return (EPERM);
/*
* get user's copy of fioio struct
*/
return (EFAULT);
/*
* check the inode number against the fs's inode number bounds
*/
return (ESRCH);
return (ESRCH);
/*
* get the inode
*/
if (error)
return (error);
/*
* check the generation number
*/
goto errout;
}
/*
* check if the inode is free
*/
goto errout;
}
/*
* Adapted from copen: get a file struct
* Large Files: We open this file descriptor with FOFFMAX flag
* set so that it will be like a large file open.
*/
goto errout;
/*
* Adapted from vn_open: check access and then open the file
*/
goto errout;
goto errout;
/*
* Adapted from copen: initialize the file struct
*/
/*
* return the fd
*/
goto errout;
}
return (0);
/*
* free the file struct and fd
*/
if (fpio) {
}
/*
* release the hold on the inode
*/
if (ipio)
return (error);
}
/*
* ufs_fiosatime
* set access time w/o altering change time. This ioctl is tailored
* to metamucil's needs and may change at any time.
*/
int
int flag, /* flag from VOP_IOCTL() */
{
int now = 0;
/*
* must have sufficient privileges
*/
return (EPERM);
/*
* get user's copy of timeval struct and check values
* if input is NULL, will set time to now
*/
now = 1;
} else {
return (EFAULT);
} else {
return (EFAULT);
if (TIMEVAL_OVERFLOW(&tv64))
return (EOVERFLOW);
}
return (EINVAL);
}
/*
* update access time
*/
if (now) {
} else {
}
return (0);
}
/*
* ufs_fiogdio
* Get delayed-io state. This ioctl is tailored
* to metamucil's needs and may change at any time.
*/
/* ARGSUSED */
int
int flag, /* flag from ufs_ioctl */
{
/*
* forcibly unmounted
*/
return (EIO);
return (EFAULT);
return (0);
}
/*
* ufs_fiosdio
* Set delayed-io state. This ioctl is tailored
* to metamucil's needs and may change at any time.
*/
int
int flag, /* flag from ufs_ioctl */
{
int error = 0;
#ifdef lint
#endif
/* check input conditions */
return (EPERM);
return (EFAULT);
if (dio > 1)
return (EINVAL);
/* file system has been forcibly unmounted */
return (EIO);
/* logging file system; dio ignored */
if (TRANS_ISTRANS(ufsvfsp))
return (error);
/* hold the mutex to prevent race with a lockfs request */
if (ULOCKFS_IS_HLOCK(ulp)) {
goto out;
}
if (ULOCKFS_IS_ELOCK(ulp)) {
goto out;
}
/* wait for outstanding accesses to finish */
goto out;
/* flush w/invalidate */
goto out;
/*
* update dio
*/
/*
*/
if (dio)
else
} else
out:
/*
* we need this broadcast because of the ufs_quiesce call above
*/
return (error);
}
/*
* ufs_fioffs - ioctl handler for flushing file system
*/
/* ARGSUSED */
int
char *vap, /* must be NULL - reserved */
{
int error;
/* file system has been forcibly unmounted */
return (EIO);
/*
* suspend the delete thread
* this must be done outside the lockfs locking protocol
*/
/* hold the mutex to prevent race with a lockfs request */
if (ULOCKFS_IS_HLOCK(ulp)) {
goto out;
}
if (ULOCKFS_IS_ELOCK(ulp)) {
goto out;
}
/* wait for outstanding accesses to finish */
goto out;
/*
* If logging, and the logmap was marked as not rollable,
* make it rollable now, and start the trans_roll thread and
* the reclaim thread. The log at this point is safe to write to.
*/
int err;
(FS_RECLAIM|FS_RECLAIMING))) {
if (err =
"Filesystem Flush "
"Failed to update "
"Reclaim Status for "
" %s, Write failed to "
"update superblock, "
"error %d",
err);
}
}
}
}
}
/* synchronously flush dirty data and metadata */
out:
/*
* allow the delete thread to continue
*/
return (error);
}
/*
* ufs_fioisbusy
* Get number of references on this vnode.
* Contract-private interface for Legato's NetWorker product.
*/
/* ARGSUSED */
int
{
int is_it_busy;
/*
* The caller holds one reference, there may be one in the dnlc
* so we need to flush it.
*/
/*
* Since we've just flushed the dnlc and we hold a reference
* to this vnode, then anything but 1 means busy (this had
* BETTER not be zero!). Also, it's possible for someone to
* have this file mmap'ed with no additional reference count.
*/
is_it_busy = 0;
else
is_it_busy = 1;
return (EFAULT);
return (0);
}
/* ARGSUSED */
int
{
int error = 0;
/*
*/
if (cmd == DIRECTIO_ON)
else if (cmd == DIRECTIO_OFF)
else
return (error);
}
/*
* ufs_fiotune
* Allow some tunables to be set on a mounted fs
*/
int
{
/*
* must have sufficient privileges
*/
return (EPERM);
/*
* get user's copy
*/
return (EFAULT);
/*
* some minimal sanity checks
*/
return (EINVAL);
/*
* update superblock but don't write it! If it gets out, fine.
*/
/*
* Adjust cluster based on the new maxcontig. The cluster size
* can be any positive value. The check for this is done above.
*/
/*
* Adjust minfrags from minfree
*/
/*
* Write the superblock
*/
}
return (0);
}
/*
* Lseek support for finding holes (cmd == _FIO_SEEK_HOLE) and
*/
int
{
int error;
return (ENXIO);
}
/*
* Check for the usual case where a file has no holes.
* If so we can optimise to set the end of the file as the first
* (virtual) hole. This avoids bmap_find() searching through
* every block in the file for a (non-existent) hole.
*/
if (!bmap_has_holes(ip)) {
if (cmd == _FIO_SEEK_HOLE) {
return (0);
}
/* *off must already point to valid data (non hole) */
return (0);
}
/*
* Calling bmap_read() one block at a time on a 1TB file takes forever,
* so we use a special function to search for holes or blocks.
*/
if (cmd == _FIO_SEEK_HOLE)
else
/* end of file? */
/*
* Handle the virtual hole at the end of file.
*/
if (cmd == _FIO_SEEK_HOLE) {
return (0);
}
return (ENXIO);
}
return (error);
return (error);
}