summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Eremin <a.eremin@nexenta.com>2015-09-22 00:48:58 +0000
committerDan McDonald <danmcd@omniti.com>2015-09-22 14:01:25 -0400
commitbd93c05dbd9b8f1e8d2edf48c777bc881f927608 (patch)
tree31b825856f43696cf1be7abe8fff0981db7cb1b4
parentb584d06cf5d63c0af8a641ca543c28986ec5cf81 (diff)
downloadillumos-joyent-bd93c05dbd9b8f1e8d2edf48c777bc881f927608.tar.gz
6198 Let's EOL cachefs
Reviewed by: Marcel Telka <marcel@telka.sk> Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Gordon Ross <gordon.w.ross@gmail.com>
-rw-r--r--usr/src/cmd/cmd-inet/sbin/netstrategy/netstrategy.c20
-rw-r--r--usr/src/cmd/fs.d/Makefile3
-rw-r--r--usr/src/cmd/fs.d/autofs/autod_nfs.c61
-rw-r--r--usr/src/cmd/fs.d/autofs/autod_parse.c67
-rw-r--r--usr/src/cmd/fs.d/autofs/automount.h4
-rw-r--r--usr/src/cmd/fs.d/cachefs/Makefile96
-rw-r--r--usr/src/cmd/fs.d/cachefs/Makefile.cachefs77
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefslog/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c275
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/Makefile52
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/docmds.c714
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.c600
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.h72
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/funcs.c255
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/main.c285
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/rules.c480
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/rules.h83
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefspack/subr.c174
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefsstat/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefsstat/cachefsstat.c234
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefswssize/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/cachefswssize/cachefswssize.c233
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsadmin/Makefile53
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsadmin/cfsadmin.c1306
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/Makefile77
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd.h35
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.c302
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.h66
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.c297
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.h62
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.c1550
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.h108
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.c1593
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.h112
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.c3422
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.h291
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.c565
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.h95
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_main.c509
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.c649
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.h79
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.c805
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.h44
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsd/cfsd_svc.c756
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsfstype/Makefile39
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfsfstype/cfsfstype.c196
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfstagchk/Makefile38
-rw-r--r--usr/src/cmd/fs.d/cachefs/cfstagchk/cfstagchk.c188
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/Makefile81
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/cachefsd.x152
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/stats.h244
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/stats_create.c379
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/stats_dbm.c355
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/stats_log.c1898
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/stats_stats.c253
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/subr.c1266
-rw-r--r--usr/src/cmd/fs.d/cachefs/common/subr.h97
-rw-r--r--usr/src/cmd/fs.d/cachefs/dfshares/Makefile39
-rw-r--r--usr/src/cmd/fs.d/cachefs/dfshares/dfshares.sh34
-rw-r--r--usr/src/cmd/fs.d/cachefs/fsck/Makefile44
-rw-r--r--usr/src/cmd/fs.d/cachefs/fsck/dlog_ck.c292
-rw-r--r--usr/src/cmd/fs.d/cachefs/fsck/fsck.c1879
-rw-r--r--usr/src/cmd/fs.d/cachefs/fsck/res.c719
-rw-r--r--usr/src/cmd/fs.d/cachefs/fsck/res.h52
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/Makefile50
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/dbug.c1494
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/flist.c191
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/flist.h65
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/mdbug.h108
-rw-r--r--usr/src/cmd/fs.d/cachefs/mdbug/priv.h120
-rw-r--r--usr/src/cmd/fs.d/cachefs/mount/Makefile51
-rw-r--r--usr/src/cmd/fs.d/cachefs/mount/mount.c1675
-rw-r--r--usr/src/cmd/fs.d/cachefs/share/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/share/share.c41
-rw-r--r--usr/src/cmd/fs.d/cachefs/umount/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/umount/umount.c372
-rw-r--r--usr/src/cmd/fs.d/cachefs/unshare/Makefile46
-rw-r--r--usr/src/cmd/fs.d/cachefs/unshare/unshare.c41
-rw-r--r--usr/src/cmd/fs.d/df.xcl1
-rw-r--r--usr/src/cmd/fs.d/mount.c25
-rw-r--r--usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c32
-rw-r--r--usr/src/cmd/fs.d/nfs/share/fstypes1
-rw-r--r--usr/src/cmd/fs.d/nfs/svc/nfs-client4
-rw-r--r--usr/src/cmd/fs.d/umount.c35
-rw-r--r--usr/src/cmd/initpkg/init.d/Makefile1
-rw-r--r--usr/src/cmd/initpkg/init.d/cachefs.daemon70
-rw-r--r--usr/src/cmd/initpkg/mountall.sh3
-rw-r--r--usr/src/cmd/initpkg/rc2.d/mk.rc2.d.sh4
-rw-r--r--usr/src/cmd/stmsboot/mpxio-upgrade75
-rw-r--r--usr/src/cmd/stmsboot/stmsboot.sh9
-rw-r--r--usr/src/cmd/svc/shell/smf_include.sh3
-rw-r--r--usr/src/cmd/svr4pkg/libinst/mntinfo.c13
-rw-r--r--usr/src/lib/libefi/common/rdwr_efi.c4
-rw-r--r--usr/src/lib/libpkg/common/isdir.c9
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c4
-rw-r--r--usr/src/lib/lvm/libmeta/common/meta_check.c2
-rw-r--r--usr/src/lib/lvm/libmeta/common/meta_mount.c3
-rw-r--r--usr/src/man/man1/filesync.131
-rw-r--r--usr/src/man/man1m/Intro.1m20
-rw-r--r--usr/src/man/man1m/Makefile10
-rw-r--r--usr/src/man/man1m/automount.1m88
-rw-r--r--usr/src/man/man1m/cachefsd.1m88
-rw-r--r--usr/src/man/man1m/cachefslog.1m160
-rw-r--r--usr/src/man/man1m/cachefspack.1m237
-rw-r--r--usr/src/man/man1m/cachefsstat.1m139
-rw-r--r--usr/src/man/man1m/cachefswssize.1m107
-rw-r--r--usr/src/man/man1m/cfsadmin.1m414
-rw-r--r--usr/src/man/man1m/fsck.1m15
-rw-r--r--usr/src/man/man1m/fsck_cachefs.1m66
-rw-r--r--usr/src/man/man1m/mount.1m28
-rw-r--r--usr/src/man/man1m/mount_cachefs.1m260
-rw-r--r--usr/src/man/man1m/mount_nfs.1m7
-rw-r--r--usr/src/man/man1m/zoneadm.1m6
-rw-r--r--usr/src/man/man4/mnttab.421
-rw-r--r--usr/src/man/man4/packingrules.419
-rw-r--r--usr/src/man/man4/vfstab.439
-rw-r--r--usr/src/man/man5/largefile.555
-rw-r--r--usr/src/pkg/manifests/SUNWcs.man1m.inc10
-rw-r--r--usr/src/pkg/manifests/SUNWcs.mf23
-rw-r--r--usr/src/pkg/manifests/system-header.mf9
-rw-r--r--usr/src/pkg/manifests/system-kernel.mf3
-rw-r--r--usr/src/tools/env/illumos.sh6
-rw-r--r--usr/src/uts/common/Makefile.files9
-rw-r--r--usr/src/uts/common/Makefile.rules7
-rw-r--r--usr/src/uts/common/cpr/cpr_misc.c3
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_cnode.c1965
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_cod.c345
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_dir.c1365
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_dlog.c1177
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_filegrp.c1819
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_fscache.c1323
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_ioctl.c2589
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_log.c1739
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_module.c311
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_noopc.c225
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_resource.c1433
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_strict.c420
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_subr.c2916
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_vfsops.c1342
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_vnops.c10249
-rw-r--r--usr/src/uts/common/fs/vfs.c5
-rw-r--r--usr/src/uts/common/os/swapgeneric.c5
-rw-r--r--usr/src/uts/common/sys/Makefile8
-rw-r--r--usr/src/uts/common/sys/filio.h6
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_dir.h95
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_dlog.h316
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_filegrp.h107
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_fs.h1331
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_fscache.h233
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_ioctl.h316
-rw-r--r--usr/src/uts/common/sys/fs/cachefs_log.h400
-rw-r--r--usr/src/uts/common/sys/mntent.h2
-rw-r--r--usr/src/uts/common/sys/vfs.h10
-rw-r--r--usr/src/uts/common/sys/vtoc.h3
-rw-r--r--usr/src/uts/intel/Makefile.intel2
-rw-r--r--usr/src/uts/intel/cachefs/Makefile103
-rw-r--r--usr/src/uts/sparc/Makefile.sparc3
-rw-r--r--usr/src/uts/sparc/cachefs/Makefile107
158 files changed, 149 insertions, 63589 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/netstrategy/netstrategy.c b/usr/src/cmd/cmd-inet/sbin/netstrategy/netstrategy.c
index 043bfeb0c8..60c5ebef6e 100644
--- a/usr/src/cmd/cmd-inet/sbin/netstrategy/netstrategy.c
+++ b/usr/src/cmd/cmd-inet/sbin/netstrategy/netstrategy.c
@@ -22,9 +22,9 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This program does the following:
@@ -36,7 +36,7 @@
* b) If the program is successful, it prints three tokens to
* stdout: <root fs type> <interface name> <net config strategy>.
* where:
- * <root fs type> - "nfs" or "ufs"
+ * <root fs type> - "nfs", "ufs" or "zfs"
* <interface name> - "hme0" or "none"
* <net config strategy> - "dhcp", "rarp", "bootprops"
* or "none"
@@ -308,14 +308,14 @@ main(int argc, char *argv[])
* "ufs rarp" (consumers are coded to deal with this reality), so
* there are three possible situations:
*
- * 1. We're "ufs dhcp" if there are any interfaces which have
- * obtained their addresses through DHCP. That is, if there
- * are any IFF_UP and non-IFF_VIRTUAL interfaces also have
- * IFF_DHCPRUNNING set.
+ * 1. We're either "ufs dhcp" or "zfs dhcp" if there are any
+ * interfaces which have obtained their addresses through DHCP.
+ * That is, if there are any IFF_UP and non-IFF_VIRTUAL
+ * interfaces also have IFF_DHCPRUNNING set.
*
- * 2. We're "ufs none" if our filesystem is local and there
- * are no interfaces which have obtained their addresses
- * through DHCP.
+ * 2. We're either "ufs none" or "zfs none" if our filesystem
+ * is local and there are no interfaces which have obtained
+ * their addresses through DHCP.
*
* 3. We're "nfs rarp" if our filesystem is remote and there's
* at least IFF_UP non-IFF_VIRTUAL interface (which there
@@ -329,7 +329,7 @@ main(int argc, char *argv[])
if (dhcp_running)
strategy = "dhcp";
- if (strcmp(root, "nfs") == 0 || strcmp(root, "cachefs") == 0) {
+ if (strcmp(root, "nfs") == 0) {
if (interface == NULL) {
(void) fprintf(stderr,
"%s: cannot identify root interface.\n", program);
diff --git a/usr/src/cmd/fs.d/Makefile b/usr/src/cmd/fs.d/Makefile
index 8e8faaa643..c21fe81543 100644
--- a/usr/src/cmd/fs.d/Makefile
+++ b/usr/src/cmd/fs.d/Makefile
@@ -19,6 +19,7 @@
# CDDL HEADER END
#
# Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
# The filesystem independent utilities clri, fsdb, dcopy, labelit, and mkfs
@@ -39,7 +40,7 @@ DEFAULTFILES= fs.dfl
include ../Makefile.cmd
SUBDIR1= lofs zfs
-SUBDIR2= dev fd pcfs nfs hsfs proc ctfs udfs ufs tmpfs cachefs \
+SUBDIR2= dev fd pcfs nfs hsfs proc ctfs udfs ufs tmpfs \
autofs mntfs objfs sharefs smbclnt reparsed
SUBDIRS= $(SUBDIR1) $(SUBDIR2)
I18NDIRS= $(SUBDIR2)
diff --git a/usr/src/cmd/fs.d/autofs/autod_nfs.c b/usr/src/cmd/fs.d/autofs/autod_nfs.c
index ebc6b7d6d8..0e7ce475ba 100644
--- a/usr/src/cmd/fs.d/autofs/autod_nfs.c
+++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c
@@ -97,8 +97,6 @@ extern enum snego_stat nfs_sec_nego();
#define MAXHOSTS 512
-#define MNTTYPE_CACHEFS "cachefs"
-
/*
* host cache states
*/
@@ -131,7 +129,7 @@ typedef struct mfs_snego_t mfs_snego_t;
static struct cache_entry *cache_head = NULL;
rwlock_t cache_lock; /* protect the cache chain */
-static enum nfsstat nfsmount(struct mapfs *, char *, char *, int, int, uid_t,
+static enum nfsstat nfsmount(struct mapfs *, char *, char *, int, uid_t,
action_list *);
static int is_nfs_port(char *);
@@ -236,7 +234,6 @@ mount_nfs(
{
struct mapfs *mfs, *mp;
int err = -1;
- int cached;
action_list *alp;
char *dir;
@@ -278,10 +275,9 @@ mount_nfs(
}
}
if (err) {
- cached = strcmp(me->map_mounter, MNTTYPE_CACHEFS) == 0;
dir = strdup(mfs->mfs_dir);
err = nfsmount(mfs, mntpnt, me->map_mntopts,
- cached, overlay, uid, alp);
+ overlay, uid, alp);
if (err && trace > 1) {
trace_prt(1, " Couldn't mount %s:%s, err=%d\n",
mfs->mfs_host ? mfs->mfs_host : "",
@@ -639,7 +635,7 @@ static enum nfsstat
nfsmount(
struct mapfs *mfs_in,
char *mntpnt, char *opts,
- int cached, int overlay,
+ int overlay,
uid_t uid,
action_list *alp)
{
@@ -715,13 +711,6 @@ nfsmount(
mntpnt);
replicated = 0;
}
- if (replicated && cached) {
- if (verbose)
- syslog(LOG_WARNING,
- "mount on %s is cached and will not be replicated.",
- mntpnt);
- replicated = 0;
- }
if (replicated)
loglevel = LOG_WARNING;
else
@@ -1180,50 +1169,6 @@ retry:
if (trace > 4 && replicated)
trace_prt(1, " nfsmount: examining %s\n", remname);
- /*
- * If it's cached we need to get cachefs to mount it.
- */
- if (cached) {
- char *copts = opts;
-
- /*
- * If we started with a URL we need to turn on
- * -o public if not on already
- */
- if (use_pubfh == FALSE &&
- (mfs->mfs_flags & MFS_FH_VIA_WEBNFS)) {
-
- copts = malloc(strlen(opts) +
- strlen(",public")+1);
-
- if (copts == NULL) {
- syslog(LOG_ERR, "nfsmount: no memory");
- last_error = NFSERR_IO;
- goto out;
- }
-
- strcpy(copts, opts);
-
- if (strlen(copts) != 0)
- strcat(copts, ",");
-
- strcat(copts, "public");
- }
-
- last_error = mount_generic(remname, MNTTYPE_CACHEFS,
- copts, mntpnt, overlay);
-
- if (copts != opts)
- free(copts);
-
- if (last_error) {
- skipentry = 1;
- mfs->mfs_ignore = 1;
- continue;
- }
- goto out;
- }
-
if (mfs->mfs_args == NULL) {
/*
diff --git a/usr/src/cmd/fs.d/autofs/autod_parse.c b/usr/src/cmd/fs.d/autofs/autod_parse.c
index c0e558a052..fa3f9ca08a 100644
--- a/usr/src/cmd/fs.d/autofs/autod_parse.c
+++ b/usr/src/cmd/fs.d/autofs/autod_parse.c
@@ -23,6 +23,7 @@
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdio.h>
@@ -561,8 +562,6 @@ push_options(hiernode *node, char *defaultopts, char *mapopts, int err)
return (rc);
}
-#define BACKFSTYPE "backfstype" /* used in cachefs options */
-#define BACKFSTYPE_EQ "backfstype="
#define FSTYPE "fstype"
#define FSTYPE_EQ "fstype="
#define NO_OPTS ""
@@ -608,33 +607,6 @@ set_mapent_opts(struct mapent *me, char *opts, char *defaultopts,
strcpy(mounter, fstype);
/*
- * The following ugly chunk of code crept in as a result of
- * cachefs. If it's a cachefs mount of an nfs filesystem, then
- * it's important to parse the nfs special field. Otherwise,
- * just hand the special field to the fs-specific mount
- */
- if (strcmp(fstype, MNTTYPE_CACHEFS) == 0) {
- struct mnttab m;
- char *p;
-
- m.mnt_mntopts = entryopts;
- if ((p = hasmntopt(&m, BACKFSTYPE)) != NULL) {
- int len = strlen(MNTTYPE_NFS);
-
- p += strlen(BACKFSTYPE_EQ);
-
- if (strncmp(p, MNTTYPE_NFS, len) == 0 &&
- (p[len] == '\0' || p[len] == ',')) {
- /*
- * Cached nfs mount
- */
- (void) strcpy(fstype, MNTTYPE_NFS);
- (void) strcpy(mounter, MNTTYPE_CACHEFS);
- }
- }
- }
-
- /*
* child options are exactly fstype = somefs, we need to do some
* more option pushing work.
*/
@@ -664,9 +636,9 @@ done:
* and the option string with the fstype
* option removed, e.g.
*
- * input: "fstype=cachefs,ro,nosuid"
+ * input: "fstype=nfs,ro,nosuid"
* opts: "ro,nosuid"
- * fstype: "cachefs"
+ * fstype: "nfs"
*
* Also indicates if the fstype option was present
* by setting a flag, if the pointer to the flag
@@ -710,7 +682,6 @@ static int
fstype_opts(struct mapent *me, char *opts, char *defaultopts,
char *mapopts)
{
- char pushopts[AUTOFS_MAXOPTSLEN];
char pushentryopts[AUTOFS_MAXOPTSLEN];
char pushfstype[MAX_FSLEN];
@@ -726,16 +697,11 @@ fstype_opts(struct mapent *me, char *opts, char *defaultopts,
if (*mapopts == '-')
mapopts++;
get_opts(mapopts, pushentryopts, pushfstype, NULL);
- strcpy(pushopts, mapopts);
} else {
get_opts(defaultopts, pushentryopts, pushfstype, NULL);
- strcpy(pushopts, defaultopts);
}
- if (strcmp(pushfstype, MNTTYPE_CACHEFS) == 0)
- me->map_mntopts = strdup(pushopts);
- else
- me->map_mntopts = strdup(pushentryopts);
+ me->map_mntopts = strdup(pushentryopts);
if (!me->map_mntopts) {
syslog(LOG_ERR, "fstype_opts: No memory");
@@ -1989,34 +1955,9 @@ retry:
}
exlist = texlist;
- /*
- * The following ugly chunk of code crept in as
- * a result of cachefs. If it's a cachefs mount
- * of an nfs filesystem, then have it handled as
- * an nfs mount but have cachefs do the mount.
- */
(void) strcpy(fstype, MNTTYPE_NFS);
get_opts(mapopts, entryopts, fstype, NULL);
(void) strcpy(mounter, fstype);
- if (strcmp(fstype, MNTTYPE_CACHEFS) == 0) {
- struct mnttab m;
- char *p;
-
- m.mnt_mntopts = entryopts;
- if ((p = hasmntopt(&m, "backfstype")) != NULL) {
- int len = strlen(MNTTYPE_NFS);
-
- p += 11;
- if (strncmp(p, MNTTYPE_NFS, len) == 0 &&
- (p[len] == '\0' || p[len] == ',')) {
- /*
- * Cached nfs mount
- */
- (void) strcpy(fstype, MNTTYPE_NFS);
- (void) strcpy(mounter, MNTTYPE_CACHEFS);
- }
- }
- }
/* Now create a mapent from the export list */
ms = NULL;
diff --git a/usr/src/cmd/fs.d/autofs/automount.h b/usr/src/cmd/fs.d/autofs/automount.h
index 11de5e49bd..3c981f3642 100644
--- a/usr/src/cmd/fs.d/autofs/automount.h
+++ b/usr/src/cmd/fs.d/autofs/automount.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -140,7 +140,7 @@ struct mapfs {
*/
struct mapent {
char *map_fstype; /* file system type e.g. "nfs" */
- char *map_mounter; /* base fs e.g. "cachefs" */
+ char *map_mounter; /* base fs */
char *map_root; /* path to mount root */
char *map_mntpnt; /* path from mount root */
char *map_mntopts; /* mount options */
diff --git a/usr/src/cmd/fs.d/cachefs/Makefile b/usr/src/cmd/fs.d/cachefs/Makefile
deleted file mode 100644
index 8620430b06..0000000000
--- a/usr/src/cmd/fs.d/cachefs/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# 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.
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/fs.d/cachefs/Makefile
-#
-
-SUBDIRS= common \
- cfsadmin \
- cfsfstype \
- cfstagchk \
- fsck \
- mount \
- umount \
- cachefslog \
- cachefswssize \
- cachefsstat \
- cachefspack \
- mdbug \
- cfsd \
- dfshares \
- share \
- unshare
-
-# MANIFESTS
-# METHODS
-
-# Zip Stuff
-#SUBDIRS += cfscowchk \
-# cfscowchk \
-# cfscvtmnt \
-# cfslu \
-# cfspin \
-# cfsunpin
-
-all := TARGET= all
-install := TARGET= install
-clean := TARGET= clean
-clobber := TARGET= clobber
-lint := TARGET= lint
-
-# include Makefile.cmd and Makefile.targ for _msg target
-include ../../Makefile.cmd
-
-POFILE= cachefs.po
-GREP= grep
-SED= sed
-
-.KEEP_STATE:
-
-all clean clobber lint: $(SUBDIRS)
-
-install: $(SUBDIRS) $(ROOTMANIFEST) $(ROOTSVCMETHOD)
-
-$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-check: $(CHKMANIFEST)
-
-catalog: $(POFILE)
-
-$(POFILE):
- $(RM) messages.po
- $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext */*.[ch]`
- $(SED) "/^domain/d" < messages.po > $@
- $(RM) messages.po
-
-local_clobber:
- $(RM) $(CLOBBERFILES)
-
-FRC:
-
-include ../../Makefile.targ
diff --git a/usr/src/cmd/fs.d/cachefs/Makefile.cachefs b/usr/src/cmd/fs.d/cachefs/Makefile.cachefs
deleted file mode 100644
index 4b7bc57fb3..0000000000
--- a/usr/src/cmd/fs.d/cachefs/Makefile.cachefs
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# 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 (c) 1989,2001 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-
-CACHEFSDIR= $(SRC)/cmd/fs.d/$(FSTYPE)/common
-
-#
-# This next line is only enabled if you are NOT doing a RELEASE_BUILD. It
-# causes changes to header files in $(SRC)/uts/common to cause a rebuild.
-#
-#$(NOT_RELEASE_BUILD)CPPFLAGS = $(CPPFLAGS.master)
-
-#
-# The next line can be uncommented to turn on debugging when not doing a
-# RELEASE_BUILD.
-#
-#$(NOT_RELEASE_BUILD)CFLAGS += -g
-
-#
-# Uncomment the next line if you want ZIP extensions.
-#
-#$(NOT_RELEASE_BUILD)CPPFLAGS += -DZIP
-
-OBJS= $(PROGOBJS)
-SRCS= $(OBJS:%.o=%.c)
-LIBRARY= libcachefs.a
-LIBRARYMT= libcachefsmt.a
-CFSLIB= $(CACHEFSDIR)/$(LIBRARY)
-CFSLIBMT= $(CACHEFSDIR)/$(LIBRARYMT)
-LDLIBS += $(CFSLIB)
-
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-implicit-function-declaration
-CERRWARN += -_gcc=-Wno-uninitialized
-CERRWARN += -_gcc=-Wno-unused-function
-
-$(LIBPROG): $(OBJS)
- $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
- $(POST_PROCESS)
-
-$(CFSLIB):
- cd $(@D); pwd; $(MAKE) $(TARGET);
- @pwd
-
-$(CACHEFSDIR)/cachefsd.h:
- cd $(@D); pwd; $(MAKE) $(TARGET);
- @pwd
-
-lint: lint_SRCS
-
-clean:
- $(RM) $(PROGOBJS) $(CLEANFILES)
-
-FRC:
diff --git a/usr/src/cmd/fs.d/cachefs/cachefslog/Makefile b/usr/src/cmd/fs.d/cachefs/cachefslog/Makefile
deleted file mode 100644
index 78cdeb65fc..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefslog/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989,2001 by Sun Microsystems, Inc.
-# All rights reserved.
-
-FSTYPE= cachefs
-LIBPROG= cachefslog
-ATTMK= $(LIBPROG)
-
-OTHERINSTALL= $(ROOTUSRSBIN)/$(LIBPROG)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cachefslog.o
-COMMONOBJS= $(CACHEFSDIR)/subr.o ../lib/libcachefs.a
-
-include ../Makefile.cachefs
-
-LDLIBS += -lnsl -lkstat
-CPPFLAGS += -I../common
-
-$(ROOTUSRSBIN)/$(LIBPROG):
- -$(RM) $@; $(SYMLINK) $(LINKVALUE) $@
diff --git a/usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c b/usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c
deleted file mode 100644
index 5e62c89828..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <libintl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <kstat.h>
-#include <locale.h>
-#include <sys/fs/cachefs_log.h>
-#include "stats.h"
-
-void usage(char *);
-void pr_err(char *, ...);
-
-static int hflag = 0;
-static char *fpath = NULL;
-static int vflag = 0;
-char *prog;
-
-static void log_show(char *, char *);
-
-int
-main(int argc, char **argv)
-{
- int rc = 0, c;
- int errflg = 0;
- stats_cookie_t *fs = NULL;
- char *logfile;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif /* TEXT_DOMAIN */
- (void) textdomain(TEXT_DOMAIN);
-
- if (prog = strrchr(argv[0], '/'))
- ++prog;
- else
- prog = argv[0];
-
- while ((c = getopt(argc, argv, "hf:v")) != EOF)
- switch (c) {
- case 'h':
- if (fpath != NULL)
- ++errflg;
- else
- ++hflag;
- break;
-
- case 'f':
- if (hflag)
- ++errflg;
- else
- fpath = optarg;
- break;
-
- case 'v':
- ++vflag;
- break;
-
- case '?':
- default:
- ++errflg;
- break;
- }
-
- if ((errflg) || (optind != (argc - 1))) {
- usage(NULL);
- rc = -1;
- goto out;
- }
-
- fs = stats_create_mountpath(argv[optind], prog);
- if (fs == NULL) {
- pr_err(gettext("Cannot initialize cachefs library\n"));
- rc = 1;
- goto out;
- }
-
- if (! stats_good(fs)) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- goto out;
- }
-
- if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- goto out;
- }
- if ((logfile[0] == '\0') && (hflag) && (! vflag)) {
- log_show(argv[optind], logfile);
- goto out;
- }
-
- if (fpath != NULL) {
- if ((stats_log_kernel_setname(fs, fpath) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_MOUNT, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_UMOUNT, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_REMOVE, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_RMDIR, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_TRUNCATE, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_CREATE, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_MKDIR, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_RENAME, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_SYMLINK, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_UALLOC, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_CSYMLINK, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_FILLDIR, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_MDCREATE, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_NOCACHE, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_CALLOC, 1) != 0) ||
- (stats_log_which(fs, CACHEFS_LOG_RFDIR, 1) != 0)) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- goto out;
- }
- } else if (hflag) {
- if (stats_log_kernel_setname(fs, NULL) != 0) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- goto out;
- }
- }
-
- if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- goto out;
- }
-
- log_show(argv[optind], logfile);
-
- /*
- * if they're changing state, inform them of other filesystems
- * that they're changing state for by way of sharing the
- * cache.
- *
- * or, if they're verbose (-v flag), tell them about the
- * others.
- */
-
- if (((fpath) || (hflag) || (vflag)) && (! stats_inerror(fs))) {
- cachefs_kstat_key_t *k, *origk;
- stats_cookie_t *sc;
- int before = 0;
-
- origk = stats_getkey(fs);
- sc = stats_create_unbound(prog);
- if (sc == NULL) {
- pr_err(gettext("Cannot create stats object"));
- rc = 1;
- goto out;
- }
-
- while ((k = stats_next(sc)) != NULL) {
- if (! k->ks_mounted) {
- free(k);
- continue;
- }
- if (strcmp((char *)(uintptr_t)origk->ks_cachedir,
- (char *)(uintptr_t)k->ks_cachedir) != 0) {
- free(k);
- continue;
- }
- if (origk->ks_id == k->ks_id) {
- free(k);
- continue;
- }
- if (! before)
- printf("\n");
- before = 1;
- log_show((char *)(uintptr_t)k->ks_mountpoint, logfile);
- free(k);
- }
- free(origk);
- stats_destroy(sc);
- }
-
- if (stats_inerror(fs)) {
- pr_err(stats_errorstr(fs));
- rc = stats_errno(fs);
- }
-
-out:
- stats_destroy(fs);
- return (rc);
-}
-
-static void
-log_show(char *mount, char *logfile)
-{
- if (logfile[0] == '\0')
- logfile = gettext("not logged");
- printf("%s: %s\n", logfile, mount);
-}
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a short usage message.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp) {
- pr_err("%s", msgp);
- }
-
- fprintf(stderr,
- gettext("Usage: "
- "cachefslog [ -v ] [-h | -f <logfile>] mountpoint\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cachefslog: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/Makefile b/usr/src/cmd/fs.d/cachefs/cachefspack/Makefile
deleted file mode 100644
index 0a8d7d3ec8..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/fs.d/cachefs/cachefspack
-#
-
-FSTYPE= cachefs
-LIBPROG= cachefspack
-ATTMK= $(LIBPROG)
-
-OTHERINSTALL= $(ROOTBIN)/$(LIBPROG)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= docmds.o elfrd.o funcs.o subr.o rules.o main.o
-
-include ../Makefile.cachefs
-
-CPPFLAGS += -D_LARGEFILE64_SOURCE -I../..
-LDLIBS += -lelf -lgen
-
-$(LIBPROG) : $(CFSLIB)
-
-$(PROGOBJS) : $(CACHEFSDIR)/subr.h $(CACHEFSDIR)/cachefsd.h
-
-$(ROOTBIN)/$(LIBPROG):
- -$(RM) $@; $(SYMLINK) $(LINKVALUE) $@
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/docmds.c b/usr/src/cmd/fs.d/cachefs/cachefspack/docmds.c
deleted file mode 100644
index 24a0055290..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/docmds.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <search.h>
-
-#include <dirent.h>
-#include <fnmatch.h>
-#include <sys/stat.h>
-
-#include "rules.h"
-
-extern char *mstrdup(const char *);
-
-/*
- * The do_base_dir() function is called when a BASE command is encountered
- * in the input directives or end-of-file is reach on the input directive
- * file. This function causes the commands associated with the previous
- * BASE command to be executed. for example,
- *
- * BASE a/b/c
- * LIST ...
- * IGNORE ...
- * BASE d/e/f (this command will cause do_base_dir() to be called for
- * base directory a/b/c)
- *
- * Input arguments:
- * dirpath - the BASE directory being operated on
- * incld_lst - A list of strings to be matched obtained from the
- * LIST commands associated with the BASE directory.
- * excld_lst - A list of strings to be matched obtained from the
- * IGNORE commands associated with the BASE directory.
- * func - A function to be called for each matched file. The
- * functions allow files to be packed, unpacked,
- * examined and filenames printed.
- */
-
-void
-do_base_dir(char *dirpath, struct item *incld_lst, struct item *excld_lst,
- int (*func)(char *, char *, DIR *, int))
-{
- struct item *iitem;
- int err;
- int files_processed = 0;
- struct item symlk_hd, *symlk, *symlk_sv;
- struct stat64 statbuf;
- char linkbuf[MAXPATHLEN];
- int sz;
- char *s;
- char *mk_base_dir(char *, char *);
-
-#ifdef DEBUG
- prtitem("Global IGNOREs", &gign_hd);
- prtitem("LIST cmds", &list_hd);
- prtitem("Local IGNOREs", &lign_hd);
-#endif /* DEBUG */
-
-
- symlk = &symlk_hd;
- symlk_hd.i_next = (struct item *)0;
-
- iitem = incld_lst->i_next;
- if (iitem == (struct item *)0)
- return;
- while (iitem != (struct item *)0) {
-#ifdef DEBUG
- printf("do_base_dir: iitem->i_str = %s iitem->i_flag = %x\n",
- iitem->i_str, iitem->i_flag);
- fflush(stdout);
-#endif /* DEBUG */
- err = do_list_item(dirpath, iitem->i_str,
- iitem->i_flag, excld_lst, 0, &symlk, func);
- if (err == 0) {
- fprintf(stderr,
- gettext("cachefspack: basedir = %s"),
- dirpath);
- fprintf(stderr,
- gettext(" %s - no file(s) selected\n"),
- iitem->i_str);
- }
- iitem = iitem->i_next;
- };
- /*
- * Invoke 'func' for each component of the BASE
- * directory.
- */
- func_dir_path(dirpath, func);
-
- if (lstat64(dirpath, &statbuf) < 0) {
- perror(gettext("Can't stat base directory"));
- } else {
- if (S_ISLNK(statbuf.st_mode)) {
- sz = readlink(dirpath, linkbuf, MAXPATHLEN-1);
- if (sz > 0) {
- linkbuf[sz] = '\0';
- s = mk_base_dir(dirpath, linkbuf);
- if (s != (char *)0) {
- func_dir_path(s, func);
- }
- }
- }
- }
-
-#ifdef DEBUG
- prtitem("Symbolic Links", &symlk_hd);
-#endif /* DEBUG */
- iitem = symlk_hd.i_next;
- if (iitem == (struct item *)0)
- return;
- while (iitem != (struct item *)0) {
-#ifdef DEBUG
- printf("do_bas sl: iitem->i_str = %s iitem->i_flag = %x\n",
- iitem->i_str, iitem->i_flag);
- fflush(stdout);
-#endif /* DEBUG */
- files_processed = do_list_item(iitem->i_str, "*",
- (LF_SYMLINK | LF_REGEX), excld_lst, 0, &symlk, func);
- if (files_processed) {
- /*
- * Invoke 'func' for each component of the BASE
- * directory.
- */
- func_dir_path(iitem->i_str, func);
- }
- symlk_sv = iitem;
- iitem = iitem->i_next;
- symlk_hd.i_next = iitem;
- free(symlk_sv);
-#ifdef DEBUG
- prtitem("Symbolic Links loop", &symlk_hd);
-#endif /* DEBUG */
- }
-}
-
-/*
- * The do_list_item() function is called for each LIST item associated with
- * a BASE directory. It does the work of descending directories and matching
- * filenames.
- *
- * Input arguments:
- * dirpath - the BASE directory being operated on
- * pat - The argument from the LIST command to match
- * flags - Flags which affect how patterns are matched:
- * LF_STRIP_DOTSLASH - means strip off "." and/or "/" at the
- * beginning of the pattern to match.
- * LF_REGEX - Means match the pattern as a regular expression.
- * Otherwise, an exact match of characters is required.
- * excld_lst - A list of strings to be matched obtained from the
- * IGNORE commands associated with the BASE directory.
- * func - A function to be called for each matched file. The
- * functions allow files to be packed, unpacked,
- * examined and filenames printed.
- *
- * Return values:
- * 0 - 'func' NOT invoked for any file
- * 1 - 'func' invoked for at least 1 file
- */
-int
-do_list_item(char *dirpath, char *pat, int flags, struct item *excld_lst,
- DIR *pdir, struct item **symlk_lst, int (*func)(char *, char *, DIR *, int))
-{
- static char statnam[MAXPATHLEN];
- static int glastpos = 0;
- static int basedir_lastpos;
- static int depth = 0;
- static int unwind = 0;
- static int do_dir = 0;
- static int sl_cnt;
- static int retval;
- static char linkbuf[MAXPATHLEN];
- DIR *dir, *parent_dir;
- struct dirent64 *dirent;
- int match;
- int err;
- struct stat64 statbuf;
- int llastpos;
- struct item *eitem;
- int excld_flag;
- char *p;
- int diropn;
- int len;
- int sz;
- void process_symlk();
-
- strcpy(&statnam[glastpos], dirpath);
- len = strlen(statnam) - 1;
- if (statnam[len] != '/') {
- strcat(statnam, "/");
- }
- parent_dir = pdir;
- llastpos = glastpos;
- glastpos = strlen(statnam);
- if (depth == 0) {
- basedir_lastpos = glastpos;
- sl_cnt = slash_cnt(pat);
- retval = 0;
- }
- depth++;
-
- diropn = 0;
- dir = opendir(statnam);
- if (dir == NULL) {
- fprintf(stderr, gettext("\ncachefspack: %s - "), statnam);
- perror(gettext("Can't open directory"));
- goto out;
- }
- diropn = 1;
-
- while (1) {
- dirent = readdir64(dir);
- if (dirent == NULL) { /* EOF */
- if ((depth-1) > do_dir) {
- do_dir = depth - 1;
- }
- break;
- }
- /*
- * If file is '..' skip it
- */
- if (strcmp(dirent->d_name, "..") == 0) {
- continue;
- }
- /*
- * Apply excludes if this is not a LISTed directory
- * NOTE: names from IGNORE commands are matched against the
- * component name(a name between '/' marks), not the
- * whole pathname.
- */
- if (flags & LF_SYMLINK) {
- match = ((depth-1) >= sl_cnt);
- } else {
- match = ((depth-1) > sl_cnt);
- }
- if (match) {
- eitem = excld_lst->i_next;
- excld_flag = 0;
- while (eitem != (struct item *)0) {
- match = gmatch(dirent->d_name, eitem->i_str);
- if (match == 1) {
- excld_flag = 1;
- break;
- }
- eitem = eitem->i_next;
- }
- if (excld_flag == 1) {
- continue;
- }
- }
- strcpy(&statnam[glastpos], dirent->d_name);
- err = lstat64(statnam, &statbuf);
- if (err < 0) {
- fprintf(stderr,
- gettext("cachefspack: %s - stat failed"),
- statnam);
- perror(gettext(" "));
- continue;
- }
- p = pat;
- if (flags & LF_STRIP_DOTSLASH) {
- if (strncmp(p, "./", 2) == 0) {
- p += 2;
- }
- }
- if (S_ISDIR(statbuf.st_mode)) {
-#ifdef DEBUG
- printf("directory: &statnam[basedir_lastpos] = %s\n",
- &statnam[basedir_lastpos]);
- printf("statbuf.st_mode = %o\n", statbuf.st_mode);
- printf("depth = %d sl_cnt = %d\n", depth, sl_cnt);
- fflush(stdout);
-#endif /* DEBUG */
- if ((depth-1) == sl_cnt) {
- if (flags & LF_REGEX) {
- match =
- gmatch(&statnam[basedir_lastpos],
- p);
- } else {
- match =
- (strcmp(&statnam[basedir_lastpos],
- p) == 0);
- }
- if (match) {
- /*
- * Don't descend '.' directory
- * but match it
- */
- if (strcmp(dirent->d_name, ".") != 0) {
- do_list_item(dirent->d_name,
- "*", flags, excld_lst,
- dir, symlk_lst, func);
- } else {
- if ((depth-1) > do_dir) {
- do_dir = depth - 1;
- }
- (void) func(statnam,
- dirent->d_name,
- dir, depth);
- }
- retval = 1;
- if (unwind = discont_srch(flags, p)) {
- goto out;
- }
- }
- continue;
- }
- /*
- * Don't descend '.' directory
- */
- if (strcmp(dirent->d_name, ".") != 0) {
- do_list_item(dirent->d_name, p, flags,
- excld_lst, dir, symlk_lst, func);
- }
- if (unwind) {
- goto out;
- }
- continue;
- }
- if (S_ISLNK(statbuf.st_mode)) {
- if (flags & LF_SYMLINK)
- continue;
-#ifdef DEBUG
- printf("sym link : &statnam[basedir_lastpos] = %s\n",
- &statnam[basedir_lastpos]);
- printf("statbuf.st_mode = %o\n", statbuf.st_mode);
- printf("statnam = %s\n", statnam);
-#endif /* DEBUG */
- /*
- * Symbolic link was explicitly specified or matches a
- * regular expression in a LIST item. Thus we follow
- * the link. Otherwise, just call 'func' for the link
- * name.
- */
-#ifdef DEBUG
- printf("depth = %d sl_cnt = %d\n", depth, sl_cnt);
- fflush(stdout);
-#endif /* DEBUG */
- if ((depth-1) == sl_cnt) {
- if (flags & LF_REGEX) {
- match =
- gmatch(&statnam[basedir_lastpos],
- p);
- } else {
- match =
- (strcmp(&statnam[basedir_lastpos],
- p) == 0);
- }
-#ifdef DEBUG
- printf("match = %d\n", match);
- fflush(stdout);
-#endif /* DEBUG */
- if (match) {
- if ((depth-1) > do_dir) {
- do_dir = depth - 1;
- }
- retval = 1;
- (void) func(statnam, dirent->d_name,
- dir, depth);
- sz = readlink(
- statnam, linkbuf, MAXPATHLEN-1);
-#ifdef DEBUG
- printf("linkbuf = %s\n", linkbuf);
- printf("sz = %d\n", sz);
- fflush(stdout);
-#endif /* DEBUG */
- if (sz < 0) {
- continue;
- }
- linkbuf[sz] = '\0';
- process_symlk(linkbuf, statnam,
- glastpos, symlk_lst, func);
- if (unwind = discont_srch(flags, p)) {
- goto out;
- }
- }
- }
- if ((depth-1) > sl_cnt) {
- if ((depth-1) > do_dir) {
- do_dir = depth - 1;
- }
- retval = 1;
- (void) func(statnam, dirent->d_name, dir,
- depth);
- sz = readlink(statnam, linkbuf, MAXPATHLEN-1);
-#ifdef DEBUG
- printf("linkbuf = %s\n", linkbuf);
- printf("sz = %d\n", sz);
- fflush(stdout);
-#endif /* DEBUG */
- if (sz < 0) {
- continue;
- }
- linkbuf[sz] = '\0';
- process_symlk(linkbuf, statnam, glastpos,
- symlk_lst, func);
- if (unwind = discont_srch(flags, p)) {
- goto out;
- }
- }
- continue;
- }
- /*
- * File must be a regular file -
- * Does it match the specified pattern?
- */
-#ifdef DEBUG
- printf("reg file : &statnam[basedir_lastpos] = %s p = %s\n",
- &statnam[basedir_lastpos], p);
- printf("statbuf.st_mode = %o\n", statbuf.st_mode);
- fflush(stdout);
-#endif /* DEBUG */
- if (flags & LF_REGEX) {
- match = gmatch(&statnam[basedir_lastpos], p);
- } else {
- match = (strcmp(&statnam[basedir_lastpos], p) == 0);
- }
- if (!match) {
- continue;
- }
- if ((depth - 1) > do_dir) {
- do_dir = depth - 1;
- }
- retval = 1;
- (void) func(statnam, dirent->d_name, dir, depth);
- /*
- * If the file is an executable, check to see if shared
- * libraries need to be packed.
- */
- if (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
- process_executable(statnam, func);
- }
-
- if (unwind = discont_srch(flags, p)) {
- goto out;
- }
- }
-out:
- depth--;
- if (depth == 0) {
- unwind = 0;
- }
- statnam[glastpos] = '\0';
- if (do_dir) {
- do_dir--;
-#ifdef DEBUG
- printf("out: call func\n");
- fflush(stdout);
- printf("out: statnam = %s\n", statnam);
- fflush(stdout);
- printf("out: &statnam[llastpos] = %s\n", &statnam[llastpos]);
- fflush(stdout);
-#endif /* DEBUG */
- if (func(statnam, &statnam[llastpos], parent_dir, depth) < 0) {
- do_dir = 0;
- }
- }
- glastpos = llastpos;
- if (diropn)
- closedir(dir);
- return (retval);
-}
-
-/*
- * Count all the '/' characters in the string except for those
- * in the first character position and last character position
- * of the string.
- */
-int
-slash_cnt(char *str)
-{
- char *p = str;
- int len;
- int i;
- int count = 0;
-
-#ifdef DEBUG
- printf("slash_cnt: str = %s", str);
-#endif /* DEBUG */
- /*
- * NOTE //a, /a and ./a are the same
- */
- if (*p == '.')
- p++;
- while (*p == '/')
- p++;
- len = strlen(str) - 1;
- for (i = 0; i < len; i++) {
- if (*p == '/') {
- count++;
- i--;
- while (*p == '/') {
- p++;
- i++;
- }
- } else {
- p++;
- }
- }
-#ifdef DEBUG
- printf(" count = %d\n", count);
- fflush(stdout);
-#endif /* DEBUG */
- return (count);
-}
-
-/*
- * For each directory in the path name, call 'func'.
- */
-int
-func_dir_path(char *path, int (*func)(char *, char *, DIR *, int))
-{
- char *dnam;
- char *fnam;
- char *pathtmp;
- DIR *dir;
- char *get_fname(char *);
- char *get_dirname(char *);
- ENTRY hitem, *hitemp;
-
-#ifdef DEBUG
- printf("func_dir_path: path = %s\n", path);
- fflush(stdout);
-#endif /* DEBUG */
- fnam = path;
- dnam = path;
- pathtmp = mstrdup(path);
- while (fnam != NULL) {
-
- fnam = get_fname(dnam);
- dnam = get_dirname(dnam);
- if (fnam != (char *)0) {
- if (strcmp(fnam, "..") == 0) {
- free(pathtmp);
- pathtmp = mstrdup(dnam);
- continue;
- }
- }
-#ifdef DEBUG
- if (fnam != (char *)0) {
- printf("func_dir_path: fnam = %s\n", fnam);
- }
- printf("func_dir_path: dnam = %s pathtmp = %s\n",
- dnam, pathtmp);
- fflush(stdout);
-#endif /* DEBUG */
-
- hitem.key = mstrdup(pathtmp);
- hitem.data = 0;
- hitemp = hsearch(hitem, FIND);
- if (hitemp != NULL) {
- /*
- * If hash item data is 0, item has not been packed.
- * If hash item data is 1, item has been packed.
- */
-#ifdef DEBUG
- printf("func_dir_path: key = %s hitemp->data = %x\n",
- hitemp->key, hitemp->data);
- fflush(stdout);
-#endif /* DEBUG */
- if (hitemp->data == (char *)1)
- break;
- hitemp->data = (char *)1;
- } else {
- hitem.key = mstrdup(pathtmp);
- hitem.data = (char *)1;
- if (hsearch(hitem, ENTER) == NULL) {
- fprintf(stderr,
- gettext("cachefspack: hash table full\n"));
- }
- }
-
- dir = opendir(dnam);
- if (dir != NULL) {
- if (func(pathtmp, fnam, dir, 0) < 0) {
-#ifdef DEBUG
- printf("func_dir_path: errno = %d\n", errno);
- fflush(stdout);
-#endif /* DEBUG */
- closedir(dir);
- return (-1);
- }
- closedir(dir);
- } else {
- printf(gettext("cachefspack: error opening dir -"));
- printf("%s\n", dnam);
- fflush(stdout);
- }
-
- free(pathtmp);
- pathtmp = mstrdup(dnam);
- }
- free(pathtmp);
- return (0);
-}
-void
-process_symlk(char *lkpath, char *relpath, int rel_lastpos,
- struct item **symlk, int (*func)(char *, char *, DIR *, int))
-{
- struct stat64 lstatbuf;
- char *l;
- struct item *add_item(struct item *, char *, int);
- int len;
-
- /*
- * if the link has a relative pathname, append the name to
- * current path.
- */
- if (*lkpath != '/') {
- len = strlen(lkpath);
- if ((len + rel_lastpos + 2) > MAXPATHLEN) {
- fprintf(stderr, gettext("can't process sym link - %s"),
- lkpath);
- return;
- }
- strcpy(&relpath[rel_lastpos], lkpath);
- l = relpath;
- } else {
- l = lkpath;
- }
-#ifdef DEBUG
- printf("process_symlk: lkpath = %s\n", lkpath);
- printf("process_symlk: l = %s\n", l);
- printf("lstatbuf.st_mode = %o\n", lstatbuf.st_mode);
- fflush(stdout);
-#endif /* DEBUG */
- if (lstat64(l, &lstatbuf) < 0) {
- fprintf(stderr, gettext("Can't lstat sym link - %s"), l);
- perror(" ");
- return;
- }
- if (S_ISDIR(lstatbuf.st_mode)) {
- *symlk = add_item(*symlk, l, 0);
- }
- if (S_ISREG(lstatbuf.st_mode)) {
- func_dir_path(l, func);
- }
-}
-
-int
-discont_srch(int flags, char *pat)
-{
- char *wild;
-
-#ifdef DEBUG
- printf("discont_srch: flags = %x pat = %s\n", flags, pat);
- fflush(stdout);
-#endif /* DEBUG */
-
- /*
- * if patterns are NOT being matched as regular expressions
- * we can have at most 1 match. We got it so quit.
- */
- if ((flags & LF_REGEX) != LF_REGEX) {
-#ifdef DEBUG
- printf("discont_srch: ! LF_REGEX\n");
- fflush(stdout);
-#endif /* DEBUG */
- return (1);
- }
- /*
- * if the pattern does not contain wildcard characters and
- * we have found a match we are done.
- */
- if (WILDCARD(wild, pat) == NULL) {
-#ifdef DEBUG
- printf("discont_srch: wild = %x\n", wild);
- fflush(stdout);
-#endif /* DEBUG */
- return (1);
- }
- return (0);
-}
-
-#ifdef DEBUG
-prtitem(char *str, struct item *hd)
-{
- struct item *p = hd->i_next;
-
- printf("\n%s\n\n", str);
- while (p != (struct item *)0) {
- printf("str = %s\n", p->i_str);
- p = p->i_next;
- }
-}
-#endif /* DEBUG */
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.c b/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.c
deleted file mode 100644
index 435b8dc4f7..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * 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 (c) 1996-1997, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <link.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <search.h>
-
-#include "libelf.h"
-#include "elfrd.h"
-
-extern int verbose;
-extern char *mstrdup(const char *);
-extern void *mmalloc(size_t size);
-
-/*
- * Given the name of an executable and a function call the function for
- * all shared objects needed to link the executable. The function will only
- * be called once. A list of filenames for which the function has been called
- * is maintained, this is used to exclude filenames.
- */
-void
-process_executable(char *pathname, int (*func)(char *, char *, DIR *, int))
-{
- struct sobj *get_share_obj(char *, struct libpath *, int);
- struct sobj *sop;
- struct sobj *psop;
-
-#ifdef DEBUG
- printf("process_executable: pathname = %s\n", pathname);
- fflush(stdout);
-#endif /* debug */
- sop = get_share_obj(pathname, &libp_hd, GSO_ADDEXCLD);
-#ifdef DEBUG
- printf("process_executable: sop = %x\n", sop);
- fflush(stdout);
-#endif /* debug */
- if (verbose) {
- if ((int)sop < 0) {
- fprintf(stderr,
- gettext(
- "cachefspack: unable to get shared objects - %s\n"),
- pathname);
- }
- }
- if ((int)sop > 0) {
- while (sop->so_next != (struct sobj *)0) {
-#ifdef DEBUG
- printf("process_executable: sop->so_name = %s\n",
- sop->so_name);
- fflush(stdout);
-#endif /* DEBUG */
- func_dir_path(sop->so_name, func);
-
- psop = sop;
- sop = sop->so_next;
- free(psop->so_name);
- free(psop);
- }
- }
-}
-
-/*
- * Given the name of an executable, a list of directories to use in the
- * library search and a list of library names to exclude, return all
- * shared object needed by the executable.
- *
- * RETURNS: A pointer to a list of shared objects
- */
-struct sobj *
-get_share_obj(char *fpath, struct libpath *libpath, int flag)
-{
- static int name_cnt = 0;
- static struct sobj *so, *hd_so;
- static int depth = 0;
- static struct libpath *rpath, hd_rpath;
- int found_file = 0;
- int error;
- int fd;
- Elf *elfp;
- Elf32_Ehdr *Ehdr;
- Elf_Scn *scn;
- Elf32_Shdr *shdr;
- Elf32_Dyn *dyn;
- size_t dynsz;
- char *name;
- void * get_scndata();
- struct sobj *alloc_sobj();
- struct sobj *add_so();
- char pathtmp[MAXPATHLEN];
- ENTRY hitem, *hitemp;
- int fileopn;
- int elfbgn = 0;
- Elf_Kind file_type;
- int buf;
-
- /*
- * Open a file and perform necessary operations to find the sections
- * in an elf format file. If the specified file is not elf format
- * return an error.
- */
- depth++;
- if (depth == 1) {
- /*
- * Find the ending exclude shared object element.
- */
- rpath = &hd_rpath;
-#ifdef DEBUG
- printf("dbg: rpath = %x\n", rpath);
-#endif /* DEBUG */
- rpath->lp_path = " ";
- rpath->lp_next = (struct libpath *)0;
- rpath->lp_level = 0;
- }
-
- fileopn = 0;
- error = ERR_NOERROR;
- fd = open(fpath, O_RDONLY);
- if (fd < 0) {
- error = ERR_NOFILE;
- goto out;
- }
- fileopn = 1;
-/* work around */
-/*
- * elf_begin() core dumps when passed a file descriptor for a file
- * which does not have read permission, but was opened RDONLY because the
- * user doing the open was root. To avoid this problem, make sure we can
- * read the first byte of the file. If we can't, skip the file. This is a
- * temporary workaround until elf_begin() is fixed.
- */
- if (read(fd, &buf, sizeof (buf)) < 0) {
-#ifdef DEBUG
- printf("read failed\n");
- fflush(stdout);
-#endif /* DEBUG */
- error = ERR_NOFILE;
- goto out;
- }
- lseek(fd, 0, SEEK_SET);
-/* work around end */
- if (elf_version(EV_CURRENT) == EV_NONE) {
- error = ERR_NOELFVER;
- goto out;
- }
- elfbgn = 0;
- if ((elfp = elf_begin(fd, ELF_C_READ, (Elf *)0)) == NULL) {
- error = ERR_NOELFBEG;
- goto out;
- }
- elfbgn = 1;
- file_type = elf_kind(elfp);
-#ifdef DEBUG
- printf("file_type = %x\n", file_type);
- fflush(stdout);
-#endif /* DEBUG */
-
- if (file_type != ELF_K_ELF) {
- goto out;
- }
- if ((Ehdr = elf32_getehdr(elfp)) == NULL) {
- error = ERR_NOELFBEG;
- goto out;
- }
-#ifdef DEBUG
- printf("dbg: depth = %d\n", depth);
-#endif /* DEBUG */
- /*
- * Scan all sections of the elf file to locate the dynamic section
- */
- scn = 0;
- while ((scn = elf_nextscn(elfp, scn)) != 0) {
- if ((shdr = elf32_getshdr(scn)) == NULL) {
- error = ERR_NOELFSHD;
- goto out;
- }
- if (shdr->sh_type != SHT_DYNAMIC) {
- continue;
- }
- /*
- * The first pass of the dynamic section locates all
- * directories specified by "ld -R..". A stack is created
- * for the search, this allows shared libraries, dependant
- * on other shared libraries, built with "ld -R" to work
- * properly.
- *
- */
- if ((dyn = (Elf32_Dyn *)get_scndata(scn, &dynsz)) == 0) {
- error = ERR_NOELFSDT;
- goto out;
- }
- while (dyn->d_tag != DT_NULL) {
- if (dyn->d_tag == DT_RPATH) {
- name = (char *)elf_strptr(elfp,
- (size_t)shdr->sh_link, dyn->d_un.d_ptr);
-#ifdef DEBUG
- printf("DT_RPATH: name = %s\n", name);
-#endif /* DEBUG */
- rpath = stk_libpath(rpath, name, depth);
- }
- dyn++;
- }
- /*
- * Find all needed shared objects. Do this recursively
- * so libraries dependant on other libraries are found.
- * Also, try a list of libraries to exclude. Since
- * this routine is used by cachefspack, it is only neccessary
- * to pack a library once. For example, libc is used by lots
- * of commands, we need not return its name to cachefspack
- * except the first time we find it.
- */
- if ((dyn = (Elf32_Dyn *)get_scndata(scn, &dynsz)) == 0) {
- error = ERR_NOELFSDT;
- goto out;
- }
- for (; dyn->d_tag != DT_NULL; dyn++) {
- if (dyn->d_tag == DT_NEEDED) {
- name = (char *)elf_strptr(elfp,
- (size_t)shdr->sh_link, dyn->d_un.d_ptr);
- if (name != 0) {
-#ifdef DEBUG
- printf("chk: %s\n", name);
- fflush(stdout);
-#endif /* DEBUG */
- found_file = libsrch(name, libpath,
- pathtmp);
-#ifdef DEBUG
- printf("dbg: 1 found_file = %d\n",
- found_file);
- fflush(stdout);
-#endif /* DEBUG */
- if (!found_file) {
- found_file = libsrch(name,
- rpath, pathtmp);
- }
-#ifdef DEBUG
- printf("dbg: 2 found_file = %d\n",
- found_file);
- fflush(stdout);
-#endif /* DEBUG */
- if (!found_file) {
- continue;
- }
- if (name_cnt == 0) {
- so = alloc_sobj();
- hd_so = so;
- }
- /*
- * See if file already in list
- */
- hitem.key = mstrdup(pathtmp);
- hitem.data = 0;
- hitemp = hsearch(hitem, FIND);
- if (hitemp != NULL) {
-#ifdef DEBUG
- printf("found so: %s\n",
- pathtmp);
- printf("hitemp.key = %s\n",
- hitemp->key);
-#endif /* DEBUG */
- continue;
- }
-#ifdef DEBUG
- printf("do : %s\n", pathtmp);
- fflush(stdout);
-#endif /* DEBUG */
- name_cnt++;
- so = add_so(so, pathtmp);
- if (flag & GSO_ADDEXCLD) {
-#ifdef DEBUG
- printf("adding so: %s\n",
- pathtmp);
-#endif /* DEBUG */
- hitem.key = mstrdup(pathtmp);
- hitem.data = 0;
- if (hsearch(hitem, ENTER) ==
- NULL) {
- error = ERR_HASHFULL;
- goto out;
- }
- }
- get_share_obj(pathtmp, libpath, flag);
- } else {
- if (name_cnt > 0) {
- goto out;
- } else {
- error = ERR_NOELFNAM;
- goto out;
- }
- }
- }
- }
- }
-
-out:
-#ifdef DEBUG
- printf("error = %x\n", error);
- fflush(stdout);
-#endif /* DEBUG */
- depth--;
-#ifdef DEBUG
- printf("ret: depth = %d\n", depth);
- fflush(stdout);
-#endif /* DEBUG */
- if (fileopn) {
- close(fd);
- if (elfbgn) {
- if ((error != ERR_NOFILE) && (error != ERR_NOELFVER)) {
- elf_end(elfp);
- }
- }
- }
- if (name_cnt == 0) {
- return ((struct sobj *)ERR_NOERROR);
- }
- while (rpath->lp_level > depth) {
-#ifdef DEBUG
- printf("ret: rpath->lp_level = %d\n", rpath->lp_level);
- fflush(stdout);
-#endif /* DEBUG */
- rpath = pop_libpath(rpath);
- }
- if (depth == 0) {
- name_cnt = 0;
- }
- if (error == ERR_NOERROR) {
- return (hd_so);
- } else {
- return ((struct sobj *)error);
- }
-}
-
-
-/*
- * Get the section descriptor and set the size of the
- * data returned. Data is byte-order converted.
- */
-
-void *
-get_scndata(fd_scn, size)
-Elf_Scn *fd_scn;
-size_t *size;
-{
- Elf_Data *p_data;
-
- p_data = 0;
- if ((p_data = elf_getdata(fd_scn, p_data)) == 0 ||
- p_data->d_size == 0)
- {
- return (NULL);
- }
-
- *size = p_data->d_size;
- return (p_data->d_buf);
-}
-
-/*
- * Allocate a shared object structure
- *
- * RETURNS: A pointer to the allocated structure
- */
-struct sobj *
-alloc_sobj()
-{
- struct sobj *so;
- so = (struct sobj *)mmalloc(sizeof (struct sobj));
- so->so_name = " ";
- so->so_next = (struct sobj *)0;
- return (so);
-}
-
-
-/*
- * Add an object to a shared object list
- *
- * RETURNS: The tail of the shared object list
- */
-struct sobj *
-add_so(struct sobj *so, char *path)
-{
- if (so == (struct sobj *)0) {
- so = alloc_sobj();
- }
- so->so_name = mstrdup(path);
- so->so_next = alloc_sobj();
- so = so->so_next;
- return (so);
-}
-
-/*
- * Determine if name concatenated with a library directory path yields
- * a file name that exists.
- *
- * RETURNS: True(1) or False(0)
- * if true - fullpath arg contains a pointer to the full path name
- * of the file
- */
-int
-libsrch(char *name, struct libpath *libpath, char *fullpath)
-{
- struct stat64 statbuf;
- struct libpath *lp;
-
-#ifdef DEBUG
- printf("libsrch: libpath = %x\n", libpath);
- fflush(stdout);
-#endif /* DEBUG */
- lp = libpath;
- if (lp == NULL) {
- return (0);
- }
-#ifdef DEBUG
- printf("libsrch: 1 lp->lp_next = %x\n", lp->lp_next);
- fflush(stdout);
-#endif /* DEBUG */
- while (lp->lp_next != (struct libpath *)0) {
- strcpy(fullpath, lp->lp_path);
- strcat(fullpath, "/");
- strcat(fullpath, name);
- lp = lp->lp_next;
-#ifdef DEBUG
- printf("libsrch: 2 lp->lp_next = %x\n", lp->lp_next);
- fflush(stdout);
-#endif /* DEBUG */
- /*
- * stat - if file break
- */
- if (stat64(fullpath, &statbuf)
- == 0) {
-#ifdef DEBUG
- printf("libsrch: found - %s\n", fullpath);
- fflush(stdout);
-#endif /* DEBUG */
- return (1);
- }
- }
-#ifdef DEBUG
- printf("libsrch: NOT found - %s\n", name);
- fflush(stdout);
-#endif /* DEBUG */
- return (0);
-}
-
-/*
- * Add path to the libpath list(add at the tail of the list).
- *
- * RETURNS: The new tail of the list
- */
-struct libpath *
-add_libpath(struct libpath *lp, char *path, int level)
-{
- char *s;
-
- lp->lp_level = level;
- s = mstrdup(path);
- if (s != (char *)0) {
- lp->lp_path = s;
- }
- lp->lp_next = (struct libpath *)mmalloc(sizeof (struct libpath));
- lp = lp->lp_next;
- lp->lp_next = (struct libpath *)0;
- lp->lp_level = 0;
- lp->lp_path = " ";
- return (lp);
-}
-
-/*
- * Add directory/directories in name to libpath stack(as head of the stack)
- * at the level specified.
- *
- * RETURNS: the new head of the stack
- */
-struct libpath *
-stk_libpath(struct libpath *hd, char *name, int level)
-{
- struct libpath *lp, *prev_lp;
- char *s, *t;
- char *tok;
- char *freeit;
-
-#ifdef DEBUG
- printf("stk_libpath: name = %s\n", name);
- fflush(stdout);
-#endif /* DEBUG */
- s = mstrdup(name);
- freeit = s;
- prev_lp = hd;
- while (1) {
- tok = strtok(s, ":");
- if (tok == (char *)NULL)
- break;
- s = (char *)0;
- lp = (struct libpath *)mmalloc(sizeof (struct libpath));
- lp->lp_level = level;
- t = mstrdup(tok);
- lp->lp_path = t;
- lp->lp_next = prev_lp;
- prev_lp = lp;
- }
-#ifdef DEBUG
- printf("stk_libpath: lp = %x\n", lp);
- fflush(stdout);
-#endif /* DEBUG */
- free(freeit);
- return (lp);
-}
-
-/*
- * Free up a libpath stack entry.
- *
- * RETURNS: the new head of the stack
- */
-struct libpath *
-pop_libpath(struct libpath *lp)
-{
- struct libpath *tlp;
-
- tlp = lp;
- lp = lp->lp_next;
- free(tlp->lp_path);
- free(tlp);
- return (lp);
-}
-
-/*
- * Crack the LD_LIBRARY_PATH environment variable. Make a list of libraries
- * to search.
- */
-void
-get_libsrch_path(struct libpath *libhd)
-{
- char *s;
- char *tok = (char *) 1;
- struct libpath *lp;
-
- lp = libhd;
- s = getenv("LD_LIBRARY_PATH");
- if (s != (char *)NULL) {
- while (1) {
- tok = strtok(s, ":");
- if (tok == (char *) NULL)
- break;
- s = (char *) 0;
- lp = add_libpath(lp, tok, 0);
- }
- }
- add_libpath(lp, "/usr/lib", 0);
-}
-
-
-#ifdef DEBUG
-prt_sop_lst(struct sobj *sop, char * str)
-{
- printf("\n\n\n%s - sop = %x\n", str, sop);
- fflush(stdout);
- if ((int)sop < 0) {
- fprintf(stderr, "get_share_obj: failed\n");
- exit(1);
- }
-
- if ((int)sop > 0) {
- while (sop->so_next != (struct sobj *) 0) {
- printf("sop->so_name = %s\n", sop->so_name);
- sop = sop->so_next;
- }
- }
-}
-#endif /* DEBUG */
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.h b/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.h
deleted file mode 100644
index 535ea0475a..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/elfrd.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 (c) 1996, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#ifndef _ELFRD_H
-#define _ELFRD_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-struct libpath *add_libpath(struct libpath *, char *, int);
-struct libpath *stk_libpath(struct libpath *, char *, int);
-struct libpath *pop_libpath(struct libpath *);
-
-
-struct sobj {
- char *so_name;
- struct sobj *so_next;
-};
-
-struct libpath {
- char *lp_path;
- struct libpath *lp_next;
- int lp_level;
-};
-
-
-#define ERR_NOERROR 0
-#define ERR_NOFILE -1
-#define ERR_NOELFVER -2
-#define ERR_NOELFBEG -3
-#define ERR_NOELFEHD -4
-#define ERR_NOELFSHD -5
-#define ERR_NOELFSDT -6
-#define ERR_NOELFNAM -7
-#define ERR_HASHFULL -8
-
-
-#define GSO_ADDEXCLD 1
-
-#ifdef MAIN
-#define EXTERN
-#else
-#define EXTERN extern
-#endif
-
-EXTERN struct libpath *libp, libp_hd;
-
-#undef EXTERN
-
-#endif /* _ELFRD_H */
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/funcs.c b/usr/src/cmd/fs.d/cachefs/cachefspack/funcs.c
deleted file mode 100644
index edb74c6bb5..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/funcs.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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 1996-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <sys/acl.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include <errno.h>
-#include <string.h>
-
-extern int verbose;
-
-/*
- * Function used by -d option to display pathname
- */
-int
-prtfn(char *pathnam, char *fnam, DIR *dirp, int depth)
-{
- printf("%s\n", pathnam);
- return (0);
-}
-
-/*
- * Function used by -p option to pack pathname
- */
-int
-packfn(char *pathnam, char *fnam, DIR *dirp, int depth)
-{
- cachefsio_pack_t pack;
- int xx;
- int len;
-
-#ifdef DEBUG
- printf("packfn: pathnam = %s", pathnam);
- fflush(stdout);
- if (fnam != NULL) {
- printf(" fnam = %s\n", fnam);
- } else {
- printf("\n");
- }
- printf("packfn: dirp = %x depth = %d\n", dirp, depth);
- fflush(stdout);
-#endif /* DEBUG */
- if (fnam != NULL) {
- len = strlen(fnam);
- if (len >= sizeof (pack.p_name)) {
- fprintf(stderr, gettext(
- "cachefspack: file name too long - %s\n"),
- pathnam);
- return (-1);
- }
-#ifdef DEBUG
- printf("packfn: len = %d\n", len);
- fflush(stdout);
-#endif /* DEBUG */
- while (fnam[len-1] == '/') {
- len--;
- }
- strncpy(pack.p_name, fnam, len);
- } else {
- len = 0;
- }
- pack.p_name[len] = '\0';
- pack.p_status = 0;
-#ifdef DEBUG
- printf("packfn: pack.p_name = %s pack.p_status = %x\n",
- pack.p_name, pack.p_status);
- fflush(stdout);
-#endif /* DEBUG */
-
- xx = ioctl(dirp->dd_fd, CACHEFSIO_PACK, &pack);
-#ifdef DEBUG
- printf("packfn: xx = %x errno = %d\n", xx, errno);
- fflush(stdout);
-#endif /* DEBUG */
- if (xx) {
- if (errno == ENOTTY) {
- return (0);
- }
- if (errno == ENOSYS) {
- return (0);
- }
- fprintf(stderr, gettext("cachefspack: %s - "), pathnam);
- perror(gettext("can't pack file"));
- return (-1);
- }
- return (0);
-}
-
-/*
- * Function used by -p option to unpack pathname
- */
-int
-unpackfn(char *pathnam, char *fnam, DIR *dirp, int depth)
-{
- cachefsio_pack_t pack;
- int xx;
- int len;
-
-#ifdef DEBUG
- printf("unpackfn: pathnam = %s ", pathnam);
- if (fnam != NULL) {
- printf(" fnam = %s\n", fnam);
- } else {
- printf("\n");
- }
- printf("unpackfn: dirp = %x depth = %d\n", dirp, depth);
- fflush(stdout);
-#endif /* DEBUG */
- if (fnam != NULL) {
- len = strlen(fnam);
- if (len >= sizeof (pack.p_name)) {
- fprintf(stderr, gettext(
- "cachefspack: file name too long - %s\n"), pathnam);
- return (-1);
- }
- while (fnam[len-1] == '/') {
- len--;
- }
- strncpy(pack.p_name, fnam, len);
- } else {
- len = 0;
- }
- pack.p_name[len] = '\0';
- pack.p_status = 0;
-#ifdef DEBUG
- printf("unpackfn: pack.p_name = %s pack.p_status = %x\n",
- pack.p_name, pack.p_status);
- fflush(stdout);
-#endif /* DEBUG */
-
- xx = ioctl(dirp->dd_fd, CACHEFSIO_UNPACK, &pack);
-#ifdef DEBUG
- printf("unpackfn: pack.p_name = %s pack.p_status = %x\n",
- pack.p_name, pack.p_status);
- fflush(stdout);
-#endif /* DEBUG */
- if (xx) {
- if (errno == ENOTTY) {
- return (0);
- }
- if (errno == ENOSYS) {
- return (0);
- }
- fprintf(stderr, gettext("cachefspack: %s - "), pathnam);
- perror(gettext("can't unpack file"));
- return (-1);
- }
- return (0);
-}
-
-/*
- * Function used by -i option to print status of pathname
- */
-int
-inquirefn(char *pathnam, char *fnam, DIR *dirp, int depth)
-{
- cachefsio_pack_t pack;
- int xx;
- int len;
-
-#ifdef DEBUG
- printf("inquirefn: pathnam = %s ", pathnam);
- if (fnam != NULL) {
- printf("fnam = %s\n", fnam);
- } else {
- printf("\n");
- }
- printf("inquirefn: dirp = %x depth = %d\n", dirp, depth);
- fflush(stdout);
-#endif /* DEBUG */
- if (fnam != NULL) {
- len = strlen(fnam);
- if (len >= sizeof (pack.p_name)) {
- fprintf(stderr,
- gettext("cachefspack: file name too long - %s\n"),
- pathnam);
- return (-1);
- }
- while (fnam[len-1] == '/') {
- len--;
- }
- strncpy(pack.p_name, fnam, len);
- } else {
- len = 0;
- }
- pack.p_name[len] = '\0';
- pack.p_status = 0;
-#ifdef DEBUG
- printf("inquirefn: pack.p_name = %s pack.p_status = %x\n",
- pack.p_name, pack.p_status);
- fflush(stdout);
-#endif /* DEBUG */
-
- xx = ioctl(dirp->dd_fd, CACHEFSIO_PACKINFO, &pack);
-#ifdef DEBUG
- printf("inquirefn: xx = %x errno = %d\n", xx, errno);
- fflush(stdout);
-#endif /* DEBUG */
- if (xx) {
- if ((errno == ENOTTY) || (errno == ENOSYS)) {
-#ifdef CFS_MSG
- fprintf(stderr, gettext("cachefspack: "));
- fprintf(stderr,
- gettext("%s - is not in a cacheFS file system\n"),
- pathnam);
-#endif /* CFS_MSG */
- return (-1);
- }
- fprintf(stderr, gettext("cachefspack: %s - "), pathnam);
- perror(gettext("can't get info"));
- return (-2);
- }
-
- printf(gettext("cachefspack: file %s "), pathnam);
- printf(gettext("marked packed %s, packed %s\n"),
- (pack.p_status & CACHEFS_PACKED_FILE) ? "YES" : "NO",
- (pack.p_status & CACHEFS_PACKED_DATA) ? "YES" : "NO");
- if (verbose) {
- printf(gettext(" nocache %s\n"),
- (pack.p_status & CACHEFS_PACKED_NOCACHE) ?
- "YES" : "NO");
- }
- return (0);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/main.c b/usr/src/cmd/fs.d/cachefs/cachefspack/main.c
deleted file mode 100644
index 530c812f07..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/main.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-#define MAIN 1
-#include "rules.h"
-#include "elfrd.h"
-
-int verbose = 0;
-struct libpath *libp, libp_hd;
-
-int
-main(int argc, char **argv)
-{
- int prtfn();
- int packfn();
- int unpackfn();
- int inquirefn();
- FILE *open_rulesfile();
- FILE *rfd;
- int c;
- int fflag = 0;
- int Bflag = 0;
- int index;
- char *rulesfile;
- int typearg = 0;
- int (*wrkfunc)();
- extern char *optarg;
- extern int optind, opterr;
- extern void bld_pack_list();
- extern void usage();
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- global_flags = LF_NULL;
-
- rfd = open_rulesfile();
-
- libp = &libp_hd;
- get_libsrch_path(libp);
-
- /* create hash table for tracking libraries */
- if (hcreate(10000) == 0) {
- /* unlikely this ever happens or I would work around it */
- fprintf(stderr,
- gettext("cachefspack: can't create hash table\n"));
- exit(1);
- }
-
- while ((c = getopt(argc, argv, "df:hiprsuvB:I:L:U:")) != -1) {
- switch (c) {
- case 'd':
- wrkfunc = prtfn;
- typearg++;
- break;
- case 'f':
- fflag++;
- rulesfile = strdup(optarg);
- break;
- case 'h':
- usage();
- exit(0);
- break;
- case 'i':
- wrkfunc = inquirefn;
- typearg++;
- break;
- case 'p':
- wrkfunc = packfn;
- typearg++;
- break;
- case 'r':
- global_flags |= LF_REGEX;
- break;
- case 's':
- global_flags |= LF_STRIP_DOTSLASH;
- break;
- case 'u':
- wrkfunc = unpackfn;
- typearg++;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'B':
- Bflag++;
- fprintf(rfd, "BASE %s\n", optarg);
- break;
- case 'I':
- fprintf(rfd, "IGNORE %s\n", optarg);
- break;
- case 'L':
- fprintf(rfd, "LIST %s\n", optarg);
- break;
- case 'U':
- typearg++;
- wrkfunc = unpackfn;
- bld_pack_list(rfd, optarg);
- break;
- default:
- usage();
- exit(1);
- }
- }
-
- def_lign_flags = LF_NULL;
- def_gign_flags = LF_NULL;
- def_list_flags = LF_REGEX;
- bang_list_flags = LF_STRIP_DOTSLASH;
- if (global_flags != 0) {
- def_list_flags = global_flags;
- bang_list_flags = global_flags;
- }
-
- if (fflag & Bflag) {
- fprintf(stderr, gettext(
- "cachefspack: B and f options are mutually exclusive\n"));
- exit(1);
- }
-
- if (fflag) {
- fclose(rfd);
- rfd = fopen(rulesfile, "r");
- if (rfd == NULL) {
- fprintf(stderr, gettext(
- "cachefspack: can't open file associated"
- " with -f\n"));
- exit(1);
- }
- }
-
- if (typearg != 1) {
- if (typearg == 0) {
- wrkfunc = packfn;
- } else {
- fprintf(stderr,
- gettext(
- "cachefspack: only one 'd', 'i', 'p' or 'u' "));
- fprintf(stderr,
- gettext(" option allowed\n"));
- exit(1);
- }
- }
- if (optind < argc) {
- if (fflag || Bflag) {
- fprintf(stderr,
- gettext(
- "cachefspack: 'B' or 'f' specified "));
- fprintf(stderr,
- gettext("with filenames\n"));
- exit(1);
- }
- for (index = optind; index < argc; index++) {
-#ifdef DEBUG
- printf("argv[%d] = %s\n", index, argv[index]);
-#endif /* DEBUG */
- bld_pack_list(rfd, argv[index]);
- }
- }
- rewind(rfd);
- read_rules(rfd, wrkfunc);
- fclose(rfd);
- return (0);
-}
-
-/*
- * The bld_pack_list() function is used to write the temporary packing
- * list function. When the BASE directory changes, a new BASE command is
- * generated. If the filename argument(fnam) starts with a '/', then the
- * filename is assumed to be an absolute pathname. Otherwise, the filename
- * is assumed to be realtive to the current directory.
- */
-void
-bld_pack_list(FILE *fd, char *filename)
-{
- static char last_base[MAXPATHLEN+1] = {" "};
- static char fnam[MAXPATHLEN+1];
- static int last_base_sz = 1;
- char *lastsl_pos;
- int sz;
- int endpos;
- char *cwd;
-
- /* strip off any trailing /'s */
- strcpy(fnam, filename);
- for (endpos = strlen(fnam) - 1; endpos > 0; endpos--) {
- if (fnam[endpos] == '/')
- fnam[endpos] = '\0';
- else
- break;
- }
-
- if (*fnam == '/') { /* absolute pathname */
- lastsl_pos = strrchr(fnam, '/');
- sz = (int)lastsl_pos - (int)fnam + 1;
- if ((last_base_sz != sz) ||
- (strncmp(last_base, fnam, sz) != 0)) {
- fprintf(fd, "BASE %.*s\n", (sz <= 1 ? sz : sz-1), fnam);
- last_base_sz = sz;
- strncpy(last_base, fnam, sz);
- }
- fprintf(fd, "LIST %s\n", &fnam[sz]);
- } else { /* relative pathname */
- /* Really only need to call this once, ... */
- cwd = getcwd(NULL, MAXPATHLEN+1);
- sz = strlen(cwd);
- if ((last_base_sz != sz) ||
- (strncmp(last_base, cwd, sz) != 0)) {
- fprintf(fd, "BASE %s\n", cwd);
- last_base_sz = sz;
- strncpy(last_base, cwd, sz);
- }
- free(cwd);
- fprintf(fd, "LIST %s\n", fnam);
- }
-}
-
-void
-usage()
-{
-#ifdef DEBUG
- printf(
- gettext("cachefspack -[dipu] -[fBIL] [-h] [-r] [-s] [-U dir]"));
-#else /* DEBUG */
- printf(
- gettext("cachefspack -[dipu] -[f] [-h] [-r] [-s] [-U dir]"));
-#endif /* DEBUG */
- printf(gettext(" [files]\n"));
- printf("\n");
- printf(
- gettext("Must select 1 and only 1 of the following 5 options\n"));
- printf(gettext("-d Display selected filenames\n"));
- printf(gettext("-i Display selected filenames packing status\n"));
- printf(gettext("-p Pack selected filenames\n"));
- printf(gettext("-u Unpack selected filenames\n"));
- printf(gettext("-U Unpack all files in directory 'dir'\n"));
- printf(gettext("\n"));
- printf(gettext("-f Specify input file containing rules\n"));
-#ifdef DEBUG
- printf(gettext("-B Specify BASE rule on command line\n"));
- printf(gettext("-I Specify IGNORE rule on command line\n"));
- printf(gettext("-L Specify LIST rule on command line\n"));
- printf(gettext("\n"));
-#endif /* DEBUG */
- printf(gettext("-h Print usage information\n"));
- printf(gettext(
- "-r Interpret strings in LIST rules as regular expressions\n"));
- printf(gettext("-s Strip './' from the beginning of a pattern name\n"));
- printf(gettext("-v Verbose option\n"));
- printf(gettext("files - a list of filenames to be packed/unpacked\n"));
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/rules.c b/usr/src/cmd/fs.d/cachefs/cachefspack/rules.c
deleted file mode 100644
index 7f58fdda69..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/rules.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * 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 (c) 1996, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-#include "rules.h"
-
-char * lex(FILE *);
-
-extern char *mstrdup(const char *);
-extern void *mmalloc(size_t size);
-
-void
-read_rules(FILE *file, int (*rulefunc)())
-{
- char *s;
- int base_active = 0;
- int list_ent_cnt = 0;
- int gign_ent_cnt = 0;
- int lign_ent_cnt = 0;
- struct item *add_item();
- struct item *fitem, *sitem;
- char version[20];
-
- last_gign = &gign_hd;
- gign_hd.i_next = (struct item *)0;
- gign_hd.i_str = (char *)0;
- list_hd.i_next = (struct item *)0;
- list_hd.i_str = (char *)0;
- while (s = lex(file)) {
- if (s == (char *)0)
- break;
- if (*s == '#')
- continue;
- if (*s == '*')
- continue;
- if (strcmp(s, BASE) == 0) {
-#ifdef DEBUG
- printf("BASE base_active = %d\n", base_active);
-#endif /* DEBUG */
- if (base_active) {
- /*
- * Tack local IGNORE strings to end of globals
- */
- if (lign_hd.i_next != (struct item *)0) {
- last_gign->i_next = &lign_hd;
- }
- /*
- * Process directives for previous BASE command
- * if there was one. Also free up LIST items
- * and local IGNORE items.
- */
- do_base_dir(basedir, &list_hd, &gign_hd,
- rulefunc);
- /*
- * Free up space from LIST item list
- */
- fitem = list_hd.i_next;
- if (fitem != (struct item *)0) {
- while (fitem != (struct item *)0) {
- free(fitem->i_str);
- sitem = fitem->i_next;
- free(fitem);
- fitem = sitem;
- }
- }
- /*
- * Free up space from local IGNORE item list
- */
- fitem = lign_hd.i_next;
- if (fitem != (struct item *)0) {
- while (fitem != (struct item *)0) {
- free(fitem->i_str);
- sitem = fitem->i_next;
- free(fitem);
- fitem = sitem;
- }
- }
- last_gign->i_next = (struct item *)0;
- }
- base_active = 1;
- /*
- * Reset LIST item list and local IGNORE item
- * list to be empty.
- */
- last_list = &list_hd;
- list_hd.i_next = (struct item *)0;
- list_hd.i_str = (char *)0;
- last_lign = &lign_hd;
- lign_hd.i_next = (struct item *)0;
- lign_hd.i_str = (char *)0;
- /*
- * Get BASE directory specified
- */
- s = lex(0);
- if (s == (char *)0) {
- fprintf(stderr, gettext("cachefspack: "));
- fprintf(stderr, gettext(
- "illegal BASE command\n"));
- return;
- }
-
- if (*s == '$') {
- /*
- * String starts with a '$', it must be an
- * environment variable
- */
- s = getenv(&s[1]);
- if (s == (char *)NULL) {
- fprintf(stderr,
- gettext("cachefspack: "));
- fprintf(stderr,
- gettext("Can't find "
- "environment variable\n"));
- exit(1);
- }
- }
- basedir = mstrdup(s);
-#ifdef DEBUG
- printf("basedir = %s\n", basedir);
-#endif /* DEBUG */
- continue;
- }
- if (strcmp(s, IGNORE) == 0) {
-#ifdef DEBUG
- printf("IGNORE - base_active = %d\n", base_active);
-#endif /* DEBUG */
- if (base_active) {
- /*
- * Local IGNORE rule
- */
- while ((s = lex(0))
- != 0) {
- last_lign = add_item(last_lign, s,
- def_lign_flags);
- }
- } else {
- /*
- * Global IGNORE rule
- */
- while ((s = lex(0)) != 0) {
- last_gign = add_item(last_gign, s,
- def_gign_flags);
- }
- }
- continue;
- }
- if (strcmp(s, LIST) == 0) {
-#ifdef DEBUG
- printf("LIST\n");
-#endif /* DEBUG */
- if (!base_active) {
- fprintf(stderr,
- gettext(
- "cachefspack: skipping LIST command - "));
- fprintf(stderr,
- gettext(" no active base\n"));
- continue;
- }
- while ((s = lex(0)) != 0) {
- last_list = add_item(last_list, s,
- def_list_flags);
- }
- continue;
- }
- if (strcmp(s, VERSION) == 0) {
- sprintf(version, "%d.%d", VERMAJOR, VERMINOR);
- s = lex(0);
- if (s == (char *)0) {
- fprintf(stderr, gettext("cachefspack: "));
- fprintf(stderr, gettext("missing version\n"));
- fprintf(stderr, gettext("cachefspack: "));
- fprintf(stderr, gettext(
- "version = %d.%d\n"), VERMAJOR, VERMINOR);
- exit(1);
- }
- if (strcmp(version, s) != 0) {
- fprintf(stderr, gettext(
- "cachefspack: "));
- fprintf(stderr, gettext(
- "WARNING - version of packing rules "));
- fprintf(stderr, gettext(
- "does not match cachefspack version\n"));
- fprintf(stderr, gettext(
- "version = %d.%d\n"), VERMAJOR, VERMINOR);
- }
- }
- }
- /*
- * Tack local IGNORE strings to end of globals
- */
- if (lign_hd.i_next != (struct item *)0) {
- last_gign->i_next = &lign_hd;
- }
- do_base_dir(basedir, &list_hd, &gign_hd, rulefunc);
-}
-
-struct item *
-add_item(struct item *last_item, char *str, int flags)
-{
- struct item * add_cmd_items();
-
- if (*str == CMDCHAR) {
- last_item = add_cmd_items(last_item, &str[1], bang_list_flags);
- } else {
- last_item->i_next = (struct item *)mmalloc(
- sizeof (struct item));
- last_item = last_item->i_next;
- last_item->i_str = mstrdup(str);
- last_item->i_flag = flags;
- last_item->i_next = (struct item *)0;
- }
- return (last_item);
-}
-
-struct item *
-add_cmd_items(struct item *last_item, char *str, int flags)
-{
- FILE *fd;
- char inbuf[MAX_RULE_SZ];
- char *olddir = NULL;
- char *s;
- void getcmd(char *, char *);
-
- if ((basedir != NULL) && (basedir[0] != '\0')) {
- olddir = getcwd(NULL, MAXPATHLEN + 1);
- if (olddir == NULL) {
- fprintf(stderr, gettext("cannot malloc buffer\n"));
- exit(1);
- }
-
- if (chdir(basedir) != 0) {
- fprintf(stderr, gettext("cannot chdir to %s: %s\n"),
- basedir, strerror(errno));
- exit(1);
- }
- }
-
- getcmd(str, inbuf);
- fd = popen(inbuf, "r");
- if (fd == NULL) {
- fprintf(stderr, gettext("cachefspack: LIST can't execute - "));
- fprintf(stderr, "%s\n", inbuf);
- exit(1);
- }
-
- while (s = lex(fd)) {
- last_item = add_item(last_item, s, flags);
- while (s = lex(0)) {
- last_item = add_item(last_item, s, flags);
- }
- }
- if (pclose(fd) < 0) {
- fprintf(stderr, gettext("cachefspack: can't close pipe\n"));
- }
-
- if (olddir != NULL) {
- if (chdir(olddir) != 0) {
- fprintf(stderr, gettext("cannot return to %s: %s\n"),
- olddir, strerror(errno));
- exit(1);
- }
- free(olddir);
- }
-
- return (last_item);
-}
-
-void
-getcmd(char *str, char *buf)
-{
- char *s;
-
- strcpy(buf, str);
- strcat(buf, " ");
- while (s = lex(0)) {
- strcat(buf, s);
- strcat(buf, " ");
- }
-#ifdef DEBUG
- printf("getcmd: cmd = %s\n", buf);
-#endif /* DEBUG */
-}
-
-/*
- * routine:
- * lex
- *
- * purpose:
- * my own version of strtok that handles quoting and escaping
- *
- * parameters:
- * string to be lexed (or 0 for same string)
- *
- * returns:
- * pointer to next token
- *
- * notes:
- * this routine makes no changes to the string it is passed,
- * copying tokens into a static buffer.
- */
-char *
-lex(FILE *fd)
-{ char c, delim;
- char *p;
- const char *s;
- static const char *savep = 0;
- static char namebuf[MAX_RULE_SZ];
- static char inbuf[MAX_RULE_SZ];
- int len, space_left;
- char *err;
-
- /*
- * if the file descriptor is non-zero read a new command. Otherwise
- * get fields from current line.
- */
- if (fd != 0) {
- len = 0;
- space_left = sizeof (inbuf);
- while ((err = fgets(&inbuf[len], space_left, fd)) != NULL) {
- len = strlen(inbuf);
- if (len == 1) {
- /*
- * must be a blank line starting command.
- * If a blank line occurs after the start of
- * a command, blanks will be included in the
- * command.
- */
- len = 0;
- continue;
- }
- len -= 2;
- space_left -= len;
- s = (char *)((int)inbuf + len);
- /*
- * Continuation character
- */
- if (strcmp(s, "\\\n") == 0) {
- continue;
- }
- break;
- }
- if (err == NULL) {
- return (err);
- }
- s = inbuf;
- } else {
- if (savep == 0)
- return (0);
- s = savep;
- }
- savep = 0;
-
- /* skip over leading white space */
- while (isspace(*s))
- s++;
- if (*s == 0) {
- return (0);
- }
-
- /* see if this is a quoted string */
- c = *s;
- if (c == '\'' || c == '"') {
- delim = c;
- s++;
- } else
- delim = 0;
-
- /* copy the token into the buffer */
- for (p = namebuf; (c = *s) != 0; s++) {
- if ((p - namebuf) >= sizeof (namebuf)) {
- savep = 0;
- return (0);
- }
- /* literal escape */
- if (c == '\\') {
- s++;
- *p++ = *s;
- continue;
- }
-
- /* closing delimiter */
- if (c == delim) {
- s++;
- break;
- }
-
- /* delimiting white space */
- if (delim == 0 && isspace(c))
- break;
-
- /* ordinary characters */
- *p++ = *s;
- }
-
-
- /* remember where we left off */
- savep = *s ? s : 0;
-
- /* null terminate and return the buffer */
- *p = 0;
- return (namebuf);
-}
-
-char *
-mk_base_dir(char *path, char *linkpath)
-{
- static char pathb[MAXPATHLEN];
- char *dnam;
- char *get_dirname(char *);
- int len;
-
- /*
- * absolute path name
- */
- if (*linkpath == '/') {
- strcpy(pathb, linkpath);
- } else {
- /*
- * relative path
- */
- dnam = get_dirname(path);
- if (dnam == (char *)0) {
- return ((char *) 0);
- }
- strcpy(pathb, dnam);
- len = strlen(pathb);
- if (len == 0)
- return (pathb);
- if (pathb[len-1] != '/')
- strcat(pathb, "/");
- if (strncmp(linkpath, "../", 3) == 0) {
- /*
- * path is relative to directory containing sym link
- * remove "../" from beginning of linkpath
- */
- strcat(pathb, &linkpath[3]);
- } else {
- /*
- * path is relative to directory containing sym link
- */
- strcat(pathb, linkpath);
- }
- }
- return (pathb);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/rules.h b/usr/src/cmd/fs.d/cachefs/cachefspack/rules.h
deleted file mode 100644
index 6fd4820cee..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/rules.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 (c) 1996, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#ifndef _RULES_H
-#define _RULES_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#define MAX_RULE_SZ MAXPATHLEN+80
-
-#define BASE "BASE"
-#define IGNORE "IGNORE"
-#define LIST "LIST"
-#define VERSION "PACKINGRULES"
-
-#define VERMAJOR 1
-#define VERMINOR 1
-
-#define TMPRULES ".packingrules"
-#define CMDCHAR '!'
-
-struct item {
- int i_flag;
- char *i_str;
- struct item *i_next;
-};
-
-#ifdef MAIN
-#define EXTERN
-#else
-#define EXTERN extern
-#endif
-
-EXTERN char *basedir;
-EXTERN struct item list_hd;
-EXTERN struct item gign_hd;
-EXTERN struct item lign_hd;
-EXTERN struct item *last_list;
-EXTERN struct item *last_gign;
-EXTERN struct item *last_lign;
-EXTERN int def_gign_flags;
-EXTERN int def_lign_flags;
-EXTERN int def_list_flags;
-EXTERN int bang_list_flags;
-
-EXTERN int global_flags;
-
-#undef EXTERN
-
-/*
- * Define values for item struct flags
- */
-#define LF_NULL 0
-#define LF_STRIP_DOTSLASH 1
-#define LF_REGEX 2
-#define LF_SYMLINK 4
-
-#define WILDCARD(x, y) (x = strpbrk(y, "*?.^[]{}$"))
-
-#endif /* _RULES_H */
diff --git a/usr/src/cmd/fs.d/cachefs/cachefspack/subr.c b/usr/src/cmd/fs.d/cachefs/cachefspack/subr.c
deleted file mode 100644
index f038f7f9e6..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefspack/subr.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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 (c) 1996, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/param.h>
-#include <stdlib.h>
-
-#include "rules.h"
-
-char *gettext(const char *);
-
-char *
-get_fname(char *fullpath)
-{
- static char buf[MAXPATHLEN];
- char *s;
- int len;
-
- strcpy(buf, fullpath);
- len = strlen(buf);
- if (len == 1) {
- return ((char *) NULL);
- }
- if (buf[len-1] == '/')
- buf[len-1] = (char)0;
- s = strrchr(buf, '/');
- if (s != (char *)0) {
- s++;
- return (s);
- }
- return ((char *) NULL);
-}
-
-char *
-get_dirname(char *fullpath)
-{
- static char buf[MAXPATHLEN];
- char *s;
- int len;
-
- strcpy(buf, fullpath);
- len = strlen(buf);
- if (len == 1)
- return (buf);
- if (buf[len-1] == '/')
- buf[len-1] = '\0';
- s = strrchr(buf, '/');
- if (s != (char *)0) {
- if (s != buf) {
- *s = '\0';
- } else {
- s++;
- *s = '\0';
- }
- return (buf);
- }
- return ((char *) NULL);
-}
-
-FILE *
-open_rulesfile()
-{
- int pid;
- char rulesnam[MAXPATHLEN];
- FILE *rfd;
- int err;
-
- pid = getpid();
-
-#ifdef CFS_PK_CURD
- /*
- * Try to creat file in current directory
- */
- sprintf(rulesnam, "./%s.%d", TMPRULES, pid);
- rfd = fopen(rulesnam, "w");
- if (rfd != NULL) fclose(rfd);
- rfd = fopen(rulesnam, "r+");
- if (rfd != NULL) {
-#ifdef DEBUG
- printf("open_rulesfile: tmp rules file = %s\n", rulesnam);
-#endif /* DEBUG */
- goto unlink;
- }
-#endif /* CFS_PK_CURD */
-
- /*
- * try to create file in /tmp directory
- */
- sprintf(rulesnam, "/tmp/%s.%d", TMPRULES, pid);
- rfd = fopen(rulesnam, "w");
- if (rfd != NULL) fclose(rfd);
- rfd = fopen(rulesnam, "r+");
- if (rfd != NULL) {
-#ifdef DEBUG
- printf("open_rulesfile: tmp rules file = %s\n", rulesnam);
-#endif /* DEBUG */
- goto unlink;
- }
- perror("cachefspack: Can't open packing rules file\n");
- exit(1);
-
-unlink:
-#ifndef DEBUG
- err = unlink(rulesnam);
- if (err < 0) {
- perror("error unlinking temporary packing rules file");
- exit(1);
- }
-#endif /* ! DEBUG */
-
- return (rfd);
-}
-
-/*
- * mstrdup - my strdup
- *
- * This is done so there is common error processing for all strdup(s).
- */
-char *
-mstrdup(const char *str)
-{
- char *s;
-
- s = strdup(str);
- if (s == (char *)0) {
- fprintf(stderr, gettext("strdup failed - no space"));
- exit(1);
- }
- return (s);
-}
-
-/*
- * mmalloc - my malloc
- *
- * This is done so there is common error processing for all malloc(s).
- */
-void *
-mmalloc(size_t size)
-{
- void *p;
-
- p = malloc(size);
- if (p == NULL) {
- fprintf(stderr, gettext("malloc failed - no space"));
- exit(1);
- }
- return (p);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefsstat/Makefile b/usr/src/cmd/fs.d/cachefs/cachefsstat/Makefile
deleted file mode 100644
index 8ae2a51ae4..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefsstat/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1994 by Sun Microsystems, Inc.
-#
-
-FSTYPE= cachefs
-LIBPROG= cachefsstat
-ATTMK= $(LIBPROG)
-
-OTHERINSTALL= $(ROOTBIN)/$(LIBPROG)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cachefsstat.o
-COMMONOBJS= $(CACHEFSDIR)/subr.o ../lib/libcachefs.a
-
-include ../Makefile.cachefs
-
-LDLIBS += -lkstat
-CPPFLAGS += -I../common
-
-$(ROOTBIN)/$(LIBPROG):
- -$(RM) $@; $(SYMLINK) $(LINKVALUE) $@
diff --git a/usr/src/cmd/fs.d/cachefs/cachefsstat/cachefsstat.c b/usr/src/cmd/fs.d/cachefs/cachefsstat/cachefsstat.c
deleted file mode 100644
index fb2247e8ad..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefsstat/cachefsstat.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <libintl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <kstat.h>
-#include <locale.h>
-#include <sys/fs/cachefs_log.h>
-#include "stats.h"
-
-void usage(char *);
-void pr_err(char *, ...);
-
-static int zflag;
-char *prog;
-
-static void print_stats(stats_cookie_t *, cachefs_kstat_key_t *, int);
-
-int
-main(int argc, char **argv)
-{
- int rc = 0;
- int i, c, errflg = 0;
- stats_cookie_t *sc = NULL;
- cachefs_kstat_key_t *key;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif /* TEXT_DOMAIN */
- (void) textdomain(TEXT_DOMAIN);
-
- if (prog = strrchr(argv[0], '/'))
- ++prog;
- else
- prog = argv[0];
-
- while ((c = getopt(argc, argv, "z")) != EOF)
- switch (c) {
- case 'z':
- ++zflag;
- break;
-
- case '?':
- default:
- ++errflg;
- break;
- }
-
- if (errflg) {
- usage(NULL);
- rc = -1;
- goto out;
- }
-
- /*
- * handle multiple mountpoints specified on command line
- */
-
- for (i = optind; i < argc; i++) {
- if ((sc = stats_create_mountpath(argv[i], prog)) == NULL) {
- pr_err(gettext("Cannot use %s"), argv[i]);
- rc = 1;
- continue;
- }
-
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- continue;
- }
- print_stats(sc, key = stats_getkey(sc), zflag);
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- }
-
- stats_destroy(sc);
- free(key);
- }
-
- /*
- * handle the case where no mountpoints were specified,
- * i.e. show stats for all.
- */
-
- if (optind >= argc) {
- sc = stats_create_unbound(prog);
-
- while ((key = stats_next(sc)) != NULL) {
- if (! key->ks_mounted) {
- free(key);
- continue;
- }
-
- print_stats(sc, key, zflag);
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- }
- free(key);
- }
- stats_destroy(sc);
- }
-
-out:
- return (rc);
-}
-
-static void
-print_stats(stats_cookie_t *sc, cachefs_kstat_key_t *key, int zero)
-{
- uint_t misses, passes, fails, modifies;
- uint_t hitp, passtotal;
- uint_t gccount;
- u_longlong_t hits;
-
- hits = (u_longlong_t)stats_hits(sc);
- misses = stats_misses(sc);
- if (hits + misses != 0)
- hitp = (uint_t)((100 * hits) / (hits + misses));
- else
- hitp = 100;
-
- passes = stats_passes(sc);
- fails = stats_fails(sc);
- passtotal = passes + fails;
-
- modifies = stats_modifies(sc);
-
- gccount = stats_gc_count(sc);
-
- printf("\n %s\n", (char *)(uintptr_t)key->ks_mountpoint);
- printf(gettext(
- "\t cache hit rate: %5u%% (%llu hits, %u misses)\n"),
- hitp, hits, misses);
- printf(gettext("\t consistency checks: %6d (%d pass, %d fail)\n"),
- passtotal, passes, fails);
- printf(gettext("\t modifies: %6d\n"), modifies);
- printf(gettext("\t garbage collection: %6d\n"), gccount);
- if (gccount != 0) {
- time_t gctime = stats_gc_time(sc);
- time_t before = stats_gc_before(sc);
- time_t after = stats_gc_after(sc);
-
- if (gctime != (time_t)0)
- printf(gettext("\tlast garbage collection: %s"),
- ctime(&gctime));
- }
-
- if (zero)
- (void) stats_zero_stats(sc);
-}
-
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a short usage message.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp) {
- pr_err("%s", msgp);
- }
-
- fprintf(stderr,
- gettext("Usage: cachefsstat [ -z ] [ path ... ]\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cachefsstat: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cachefswssize/Makefile b/usr/src/cmd/fs.d/cachefs/cachefswssize/Makefile
deleted file mode 100644
index 346473bdc5..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefswssize/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989,2001 by Sun Microsystems, Inc.
-# All rights reserved.
-
-FSTYPE= cachefs
-LIBPROG= cachefswssize
-ATTMK= $(LIBPROG)
-
-OTHERINSTALL= $(ROOTUSRSBIN)/$(LIBPROG)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cachefswssize.o
-COMMONOBJS= $(CACHEFSDIR)/subr.o ../lib/libcachefs.a
-
-include ../Makefile.cachefs
-
-LDLIBS += -lnsl -lkstat
-CPPFLAGS += -I../common
-
-$(ROOTUSRSBIN)/$(LIBPROG):
- -$(RM) $@; $(SYMLINK) $(LINKVALUE) $@
diff --git a/usr/src/cmd/fs.d/cachefs/cachefswssize/cachefswssize.c b/usr/src/cmd/fs.d/cachefs/cachefswssize/cachefswssize.c
deleted file mode 100644
index d4afcfe9e0..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cachefswssize/cachefswssize.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <libintl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <kstat.h>
-#include <sys/fs/cachefs_log.h>
-#include <string.h>
-#include <assert.h>
-#include <ndbm.h>
-#include <malloc.h>
-#include <locale.h>
-#include "stats.h"
-
-void usage(char *);
-void pr_err(char *, ...);
-
-static int aflag = 0;
-
-int
-main(int argc, char **argv)
-{
- int rc = 0;
- int c, errflg = 0;
- int len1, len2;
- char *ar, *progname;
- void *record;
- caddr_t vfsp;
- char *path;
-
- stats_cookie_t *sc = NULL;
-
- datum key;
- struct cachefs_log_logfile_header *lh;
-
- mount_info *mip;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif /* TEXT_DOMAIN */
- (void) textdomain(TEXT_DOMAIN);
-
- if (progname = strrchr(argv[0], '/'))
- ++progname;
- else
- progname = argv[0];
-
- if ((sc = stats_create_unbound(progname)) == NULL) {
- pr_err(gettext("Cannot initialize stats library\n"));
- rc = 1;
- goto out;
- }
-
- while ((c = getopt(argc, argv, "a")) != EOF)
- switch (c) {
- case 'a':
- ++aflag;
- break;
-
- case '?':
- default:
- ++errflg;
- break;
- }
-
- if (errflg) {
- usage(NULL);
- rc = -1;
- goto out;
- }
-
- path = argv[optind];
-
- if (stats_log_logfile_open(sc, path) != 0) {
- pr_err(stats_errorstr(sc));
- rc = 1;
- goto out;
- }
- lh = stats_log_getheader(sc);
-
- if (lh->lh_errno != 0)
- printf(gettext("warning: problem writing logfile: %s\n\n"),
- strerror(lh->lh_errno));
-
- if (aflag) {
- while (record = stats_log_logfile_read(sc, NULL)) {
- ar = stats_log_record_toascii(sc, record);
- if (ar == NULL)
- break;
- puts(ar);
- free(record);
- }
- if (stats_inerror(sc))
- pr_err(stats_errorstr(sc));
- goto out;
- }
-
- stats_dbm_open(sc);
- stats_dbm_rm(sc);
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- goto out;
- }
-
- stats_log_compute_wssize(sc);
-
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- goto out;
- }
-
- for (key = stats_dbm_firstkey(sc);
- key.dptr != NULL;
- key = stats_dbm_nextkey(sc)) {
- if (key.dsize != sizeof (vfsp))
- continue;
-
- memcpy((caddr_t) &vfsp, key.dptr, sizeof (vfsp));
- mip = stats_dbm_fetch_byvfsp(sc, vfsp);
- if (mip == NULL)
- continue;
- if (! mip->mi_used)
- continue;
-
- printf("\n %s\n", mip->mi_path);
- if (! mip->mi_mounted)
- printf(" (currently unmounted)\n");
- printf("\t end size: %17lldk\n", mip->mi_current / 1024);
- printf("\thigh water size: %17lldk\n", mip->mi_high / 1024);
- free(mip);
- }
-
- printf(gettext("\n total for cache\n"));
- printf(gettext("\t initial size: %17lldk\n"),
- (u_offset_t)(stats_log_wssize_init(sc) *
- lh->lh_maxbsize / (u_offset_t) 1024));
- printf(gettext("\t end size: %17lldk\n"),
- (u_offset_t)(stats_log_wssize_current(sc) / 1024));
- printf(gettext("\thigh water size: %17lldk\n"),
- (u_offset_t)(stats_log_wssize_high(sc) / 1024));
-
- if (stats_inerror(sc)) {
- pr_err(stats_errorstr(sc));
- rc = stats_errno(sc);
- }
-
-out:
- stats_dbm_close(sc);
- stats_destroy(sc);
-
- return (rc);
-}
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a short usage message.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp) {
- pr_err("%s", msgp);
- }
-
- fprintf(stderr,
- gettext("Usage: cachefswssize logfile\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cachefswssize: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsadmin/Makefile b/usr/src/cmd/fs.d/cachefs/cfsadmin/Makefile
deleted file mode 100644
index 1e6d364b5a..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsadmin/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989,1996,2001 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# cmd/fs.d/cachefs/cfsadmin
-#
-
-FSTYPE= cachefs
-LIBPROG= cfsadmin
-ATTMK= $(LIBPROG)
-
-OTHERINSTALL= $(ROOTUSRSBIN)/$(LIBPROG)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cfsadmin.o
-
-include ../Makefile.cachefs
-
-CPPFLAGS += -D_LARGEFILE64_SOURCE
-LDLIBS += -lnsl
-
-$(LIBPROG) : $(CFSLIB)
-
-$(PROGOBJS) : $(CACHEFSDIR)/subr.h $(CACHEFSDIR)/cachefsd.h
-
-$(ROOTUSRSBIN)/$(LIBPROG):
- -$(RM) $@; $(SYMLINK) $(LINKVALUE) $@
-
diff --git a/usr/src/cmd/fs.d/cachefs/cfsadmin/cfsadmin.c b/usr/src/cmd/fs.d/cachefs/cfsadmin/cfsadmin.c
deleted file mode 100644
index 6e4f244feb..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsadmin/cfsadmin.c
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * cfsadmin.c
- *
- * Cache FS admin utility.
- */
-
-#include <assert.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <dirent.h>
-#include <ftw.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/mman.h>
-#include <sys/mnttab.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dir.h>
-#include <sys/utsname.h>
-#include <rpc/rpc.h>
-#include <priv.h>
-#include "../common/subr.h"
-#include "../common/cachefsd.h"
-
-char *cfsadmin_opts[] = {
-#define COPT_MAXBLOCKS 0
- "maxblocks",
-#define COPT_MINBLOCKS 1
- "minblocks",
-#define COPT_THRESHBLOCKS 2
- "threshblocks",
-
-#define COPT_MAXFILES 3
- "maxfiles",
-#define COPT_MINFILES 4
- "minfiles",
-#define COPT_THRESHFILES 5
- "threshfiles",
-
-#define COPT_MAXFILESIZE 6
- "maxfilesize",
-
-#define COPT_HIBLOCKS 7
- "hiblocks",
-#define COPT_LOWBLOCKS 8
- "lowblocks",
-#define COPT_HIFILES 9
- "hifiles",
-#define COPT_LOWFILES 10
- "lowfiles",
- NULL
-};
-
-#define bad(val) ((val) == NULL || !isdigit(*(val)))
-
-/* numbers must be valid percentages ranging from 0 to 100 */
-#define badpercent(val) \
- ((val) == NULL || !isdigit(*(val)) || \
- atoi((val)) < 0 || atoi((val)) > 100)
-
-/* forward references */
-void usage(char *msg);
-void pr_err(char *fmt, ...);
-int cfs_get_opts(char *oarg, struct cachefs_user_values *uvp);
-int update_cachelabel(char *dirp, char *optionp);
-void user_values_defaults(struct cachefs_user_values *uvp);
-int check_user_values_for_sanity(const struct cachefs_user_values *uvp);
-int cache_stats(char *dirp);
-int resource_file_grow(char *dirp, int oldcnt, int newcnt);
-int resource_file_dirty(char *dirp);
-void simulate_disconnection(char *namep, int disconnect);
-
-/*
- *
- * main
- *
- * Description:
- * Main routine for the cfsadmin program.
- * Arguments:
- * argc number of command line arguments
- * argv command line arguments
- * Returns:
- * Returns 0 for failure, > 0 for an error.
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- int c;
- int xx;
- int lockid;
-
- char *cacheid;
- char *cachedir;
-
- int cflag;
- int uflag;
- int dflag;
- int sflag;
- int allflag;
- int lflag;
- char *optionp;
- int Cflag;
- int Dflag;
-
- priv_set_t *priv_needed, *priv_effective;
-
- (void) setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /* set defaults for command line options */
- cflag = 0;
- uflag = 0;
- dflag = 0;
- sflag = 0;
- allflag = 0;
- lflag = 0;
- optionp = NULL;
- Cflag = 0;
- Dflag = 0;
-
- /* parse the command line arguments */
- while ((c = getopt(argc, argv, "cCDuo:d:sl")) != EOF) {
- switch (c) {
-
- case 'c': /* create */
- cflag = 1;
- break;
-
- /*
- * -C and -D are undocumented calls used
- * to simulate disconnection on a file system.
- */
- case 'C': /* connect file system */
- Cflag = 1;
- break;
- case 'D': /* disconnect file system */
- Dflag = 1;
- break;
-
- case 'u': /* update */
- uflag = 1;
- break;
-
- case 'd': /* delete */
- dflag = 1;
- if (strcmp(optarg, "all") == 0)
- allflag = 1;
- else
- cacheid = optarg;
- break;
-
- case 's': /* consistency on demand */
- sflag = 1;
- break;
-
- case 'l': /* list cache ids */
- lflag = 1;
- break;
-
- case 'o': /* options for update and create */
- optionp = optarg;
- break;
-
- default:
- usage(gettext("illegal option"));
- return (1);
- }
- }
-
- if ((cflag + dflag + lflag + sflag + uflag + Cflag + Dflag) == 0) {
- usage(gettext("no options specified"));
- return (1);
- }
-
- if (cflag || uflag || dflag || Cflag || Dflag)
- priv_needed = priv_str_to_set("all", ",", NULL);
- if ((cflag || uflag) && getuid() != 0) {
- /* These options create files. We want them to be root owned */
- pr_err(gettext("must be run by root"));
- return (1);
- }
-
- else if (lflag)
- priv_needed = priv_str_to_set("file_dac_search,file_dac_read",
- ",", NULL);
-
- else if (sflag)
- priv_needed = priv_str_to_set("sys_config", ",", NULL);
-
- priv_effective = priv_allocset();
- (void) getppriv(PRIV_EFFECTIVE, priv_effective);
- if (priv_issubset(priv_needed, priv_effective) == 0) {
- pr_err(gettext("Not privileged."));
- return (1);
- }
- priv_freeset(priv_effective);
- priv_freeset(priv_needed);
-
- if ((sflag + Cflag + Dflag) == 0) {
- /* make sure cachedir is specified */
- if (argc - 1 != optind) {
- usage(gettext("cache directory not specified"));
- return (1);
- }
- cachedir = argv[argc-1];
- } else {
- /* make sure at least one mount point is specified */
- if (argc - 1 < optind) {
- usage(gettext("mount points not specified"));
- return (1);
- }
- }
-
- /* make sure a reasonable set of flags were specified */
- if ((cflag + uflag + dflag + sflag + lflag + Cflag + Dflag) != 1) {
- /* flags are mutually exclusive, at least one must be set */
- usage(gettext(
- "exactly one of -c, -u, -d, -s, -l must be specified"));
- return (1);
- }
-
- /* make sure -o specified with -c or -u */
- if (optionp && !(cflag|uflag)) {
- usage(gettext("-o can only be used with -c or -u"));
- return (1);
- }
-
- /* if creating a cache */
- if (cflag) {
- struct cachefs_user_values uv;
- struct cache_label clabel;
-
- /* get default cache paramaters */
- user_values_defaults(&uv);
-
- /* parse the options if specified */
- if (optionp) {
- xx = cfs_get_opts(optionp, &uv);
- if (xx)
- return (1);
- }
-
- /* verify options are reasonable */
- xx = check_user_values_for_sanity(&uv);
- if (xx)
- return (1);
-
- /* lock the cache directory non-shared */
- lockid = cachefs_dir_lock(cachedir, 0);
- if (lockid == -1) {
- /* quit if could not get the lock */
- return (1);
- }
-
- /* create the cache */
- xx = cachefs_create_cache(cachedir, &uv, &clabel);
- if (xx != 0) {
- if (xx == -2) {
- /* remove a partially created cache dir */
- (void) cachefs_delete_all_cache(cachedir);
- }
- cachefs_dir_unlock(lockid);
- return (1);
- }
- cachefs_dir_unlock(lockid);
- }
-
- /* else if updating resource parameters */
- else if (uflag) {
- /* lock the cache directory non-shared */
- lockid = cachefs_dir_lock(cachedir, 0);
- if (lockid == -1) {
- /* quit if could not get the lock */
- return (1);
- }
-
- xx = update_cachelabel(cachedir, optionp);
- cachefs_dir_unlock(lockid);
- if (xx != 0) {
- return (1);
- }
- }
-
- /* else if deleting a specific cacheID (or all caches) */
- else if (dflag) {
- /* lock the cache directory non-shared */
- lockid = cachefs_dir_lock(cachedir, 0);
- if (lockid == -1) {
- /* quit if could not get the lock */
- return (1);
- }
-
- /* if the cache is in use */
- if (cachefs_inuse(cachedir)) {
- pr_err(gettext("Cache %s is in use and "
- "cannot be modified."), cachedir);
- cachefs_dir_unlock(lockid);
- return (1);
- }
-
- if (allflag)
- xx = cachefs_delete_all_cache(cachedir);
- else {
- /* mark resource file as dirty */
- xx = resource_file_dirty(cachedir);
- if (xx == 0)
- xx = cachefs_delete_cache(cachedir, cacheid);
- }
- cachefs_dir_unlock(lockid);
- if (xx != 0) {
- return (1);
- }
- }
-
- /* else if listing cache statistics */
- else if (lflag) {
- xx = cache_stats(cachedir);
- if (xx != 0)
- return (1);
- }
-
- /* else if issuing a check event to cached file systems */
- else if (sflag) {
- for (xx = optind; xx < argc; xx++) {
- issue_cod(argv[xx]);
- }
- }
-
- /* else if simulating a disconnection */
- else if (Dflag) {
- for (xx = optind; xx < argc; xx++) {
- simulate_disconnection(argv[xx], 1);
- }
- }
-
- /* else if connection after a simulated disconnection */
- else if (Cflag) {
- for (xx = optind; xx < argc; xx++) {
- simulate_disconnection(argv[xx], 0);
- }
- }
-
- /* return success */
- return (0);
-}
-
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a usage message for this utility.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-
-void
-usage(char *msgp)
-{
- fprintf(stderr, gettext("cfsadmin: %s\n"), msgp);
- fprintf(stderr, gettext(
- "usage: cfsadmin -[cu] [-o parameter-list] cachedir\n"));
- fprintf(stderr, gettext(" cfsadmin -d [CacheID|all] cachedir\n"));
- fprintf(stderr, gettext(" cfsadmin -l cachedir\n"));
- fprintf(stderr, gettext(" cfsadmin -s [mntpnt1 ... | all]\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cfsadmin: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
-
-/*
- *
- * cfs_get_opts
- *
- * Description:
- * Decodes cfs options specified with -o.
- * Only the fields referenced by the options are modified.
- * Arguments:
- * oarg options from -o option
- * uvp place to put options
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(oarg)
- * precond(uvp)
- */
-
-int
-cfs_get_opts(char *oarg, struct cachefs_user_values *uvp)
-{
- char *optstr, *opts, *val;
- char *saveopts;
- int badopt;
-
- /* make a copy of the options because getsubopt modifies it */
- optstr = opts = strdup(oarg);
- if (opts == NULL) {
- pr_err(gettext("no memory"));
- return (-1);
- }
-
- /* process the options */
- badopt = 0;
- while (*opts && !badopt) {
- saveopts = opts;
- switch (getsubopt(&opts, cfsadmin_opts, &val)) {
- case COPT_MAXBLOCKS:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_maxblocks = atoi(val);
- break;
- case COPT_MINBLOCKS:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_minblocks = atoi(val);
- break;
- case COPT_THRESHBLOCKS:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_threshblocks = atoi(val);
- break;
-
- case COPT_MAXFILES:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_maxfiles = atoi(val);
- break;
- case COPT_MINFILES:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_minfiles = atoi(val);
- break;
- case COPT_THRESHFILES:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_threshfiles = atoi(val);
- break;
-
- case COPT_MAXFILESIZE:
- if (bad(val))
- badopt = 1;
- else
- uvp->uv_maxfilesize = atoi(val);
- break;
-
- case COPT_HIBLOCKS:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_hiblocks = atoi(val);
- break;
- case COPT_LOWBLOCKS:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_lowblocks = atoi(val);
- break;
- case COPT_HIFILES:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_hifiles = atoi(val);
- break;
- case COPT_LOWFILES:
- if (badpercent(val))
- badopt = 1;
- else
- uvp->uv_lowfiles = atoi(val);
- break;
- default:
- /* if a bad option argument */
- pr_err(gettext("Invalid option %s"), saveopts);
- return (-1);
- }
- }
-
- /* if a bad value for an option, display an error message */
- if (badopt) {
- pr_err(gettext("invalid argument to option: \"%s\""),
- saveopts);
- }
-
- /* free the duplicated option string */
- free(optstr);
-
- /* return the result */
- return (badopt ? -1 : 0);
-}
-
-/*
- *
- * update_cachelabel
- *
- * Description:
- * Changes the parameters of the cache_label.
- * If optionp is NULL then the cache_label is set to
- * default values.
- * Arguments:
- * dirp the name of the cache directory
- * optionp comma delimited options
- * Returns:
- * Returns 0 for success and -1 for an error.
- * Preconditions:
- * precond(dirp)
- */
-
-int
-update_cachelabel(char *dirp, char *optionp)
-{
- char path[CACHEFS_XMAXPATH];
- struct cache_label clabel_new;
- struct cache_label clabel_orig;
- struct cachefs_user_values uv_orig, uv_new;
- int xx;
-
- /* if the cache is in use */
- if (cachefs_inuse(dirp)) {
- pr_err(gettext("Cache %s is in use and cannot be modified."),
- dirp);
- return (-1);
- }
-
- /* make sure we don't overwrite path */
- if (strlen(dirp) > (size_t)PATH_MAX) {
- pr_err(gettext("name of label file %s is too long."),
- dirp);
- return (-1);
- }
-
- /* construct the pathname to the cach_label file */
- sprintf(path, "%s/%s", dirp, CACHELABEL_NAME);
-
- /* read the current set of parameters */
- xx = cachefs_label_file_get(path, &clabel_orig);
- if (xx == -1) {
- pr_err(gettext("reading %s failed"), path);
- return (-1);
- }
- xx = cachefs_label_file_vcheck(path, &clabel_orig);
- if (xx != 0) {
- pr_err(gettext("version mismatch on %s"), path);
- return (-1);
- }
-
- /* convert the cache_label to user values */
- xx = cachefs_convert_cl2uv(&clabel_orig, &uv_orig, dirp);
- if (xx) {
- return (-1);
- }
-
- /* if options were specified */
- if (optionp) {
- /* start with the original values */
- uv_new = uv_orig;
-
- /* parse the options */
- xx = cfs_get_opts(optionp, &uv_new);
- if (xx) {
- return (-1);
- }
-
- /* verify options are reasonable */
- xx = check_user_values_for_sanity(&uv_new);
- if (xx) {
- return (-1);
- }
- }
-
- /* else if options where not specified, get defaults */
- else {
- user_values_defaults(&uv_new);
- }
-
- /* convert user values to a cache_label */
- xx = cachefs_convert_uv2cl(&uv_new, &clabel_new, dirp);
- if (xx) {
- return (-1);
- }
-
- /* do not allow the cache size to shrink */
- if (uv_orig.uv_maxblocks > uv_new.uv_maxblocks) {
- pr_err(gettext("Cache size cannot be reduced,"
- " maxblocks current %d%%, requested %d%%"),
- uv_orig.uv_maxblocks, uv_new.uv_maxblocks);
- return (-1);
- }
- if (clabel_orig.cl_maxinodes > clabel_new.cl_maxinodes) {
- pr_err(gettext("Cache size cannot be reduced,"
- " maxfiles current %d%% requested %d%%"),
- uv_orig.uv_maxfiles, uv_new.uv_maxfiles);
- return (-1);
- }
-
- /* write back the new values */
- xx = cachefs_label_file_put(path, &clabel_new);
- if (xx == -1) {
- pr_err(gettext("writing %s failed"), path);
- return (-1);
- }
-
- /* put the new values in the duplicate cache label file also */
- sprintf(path, "%s/%s.dup", dirp, CACHELABEL_NAME);
- xx = cachefs_label_file_put(path, &clabel_new);
- if (xx == -1) {
- pr_err(gettext("writing %s failed"), path);
- return (-1);
- }
-
- /* grow resouces file if necessary */
- xx = 0;
- if (clabel_orig.cl_maxinodes != clabel_new.cl_maxinodes) {
- xx = resource_file_grow(dirp, clabel_orig.cl_maxinodes,
- clabel_new.cl_maxinodes);
- }
-
- /* return status */
- return (xx);
-}
-
-/*
- *
- * user_values_defaults
- *
- * Description:
- * Sets default values in the cachefs_user_values object.
- * Arguments:
- * uvp cachefs_user_values object to set values for
- * Returns:
- * Preconditions:
- * precond(uvp)
- */
-
-void
-user_values_defaults(struct cachefs_user_values *uvp)
-{
- uvp->uv_maxblocks = 90;
- uvp->uv_minblocks = 0;
- uvp->uv_threshblocks = 85;
- uvp->uv_maxfiles = 90;
- uvp->uv_minfiles = 0;
- uvp->uv_threshfiles = 85;
- uvp->uv_maxfilesize = 3;
- uvp->uv_hiblocks = 85;
- uvp->uv_lowblocks = 75;
- uvp->uv_hifiles = 85;
- uvp->uv_lowfiles = 75;
-}
-
-/*
- *
- * check_user_values_for_sanity
- *
- * Description:
- * Check the cachefs_user_values for sanity.
- * Arguments:
- * uvp cachefs_user_values object to check
- * Returns:
- * Returns 0 if okay, -1 if not.
- * Preconditions:
- * precond(uvp)
- */
-
-int
-check_user_values_for_sanity(const struct cachefs_user_values *uvp)
-{
- int ret;
-
- ret = 0;
-
- if (uvp->uv_lowblocks >= uvp->uv_hiblocks) {
- pr_err(gettext("lowblocks can't be >= hiblocks."));
- ret = -1;
- }
- if (uvp->uv_lowfiles >= uvp->uv_hifiles) {
- pr_err(gettext("lowfiles can't be >= hifiles."));
- ret = -1;
- }
-
- /* XXX more conditions to check here? */
-
- /* XXX make sure thresh values are between min and max values */
-
- /* return status */
- return (ret);
-}
-
-/*
- *
- * cache_stats
- *
- * Description:
- * Show each cache in the directory, cache resource statistics,
- * and, for each fs in the cache, the name of the fs, and the
- * cache resource parameters.
- * Arguments:
- * dirp name of the cache directory
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Errors:
- * Preconditions:
- */
-
-int
-cache_stats(char *dirp)
-{
- DIR *dp;
- struct dirent64 *dep;
- char path[CACHEFS_XMAXPATH];
- struct stat64 statinfo;
- int ret;
- int xx;
- struct cache_label clabel;
- struct cachefs_user_values uv;
-
- /* make sure cache dir name is not too long */
- if (strlen(dirp) > (size_t)PATH_MAX) {
- pr_err(gettext("path name %s is too long."), dirp);
- return (-1);
- }
-
- /* read the cache label file */
- sprintf(path, "%s/%s", dirp, CACHELABEL_NAME);
- xx = cachefs_label_file_get(path, &clabel);
- if (xx == -1) {
- pr_err(gettext("Reading %s failed."), path);
- return (-1);
- }
- xx = cachefs_label_file_vcheck(path, &clabel);
- if (xx != 0) {
- pr_err(gettext("Version mismatch on %s."), path);
- return (-1);
- }
-
- /* convert the cache_label to user values */
- xx = cachefs_convert_cl2uv(&clabel, &uv, dirp);
- if (xx)
- return (-1);
-
- /* display the parameters */
- printf(gettext("cfsadmin: list cache FS information\n"));
-#if 0
- printf(gettext(" Version %3d\n"), clabel.cl_cfsversion);
-#endif
- printf(gettext(" maxblocks %3d%%\n"), uv.uv_maxblocks);
- printf(gettext(" minblocks %3d%%\n"), uv.uv_minblocks);
- printf(gettext(" threshblocks %3d%%\n"), uv.uv_threshblocks);
- printf(gettext(" maxfiles %3d%%\n"), uv.uv_maxfiles);
- printf(gettext(" minfiles %3d%%\n"), uv.uv_minfiles);
- printf(gettext(" threshfiles %3d%%\n"), uv.uv_threshfiles);
- printf(gettext(" maxfilesize %3dMB\n"), uv.uv_maxfilesize);
-
- /* open the directory */
- if ((dp = opendir(dirp)) == NULL) {
- pr_err(gettext("opendir %s failed: %s"), dirp,
- strerror(errno));
- return (-1);
- }
-
- /* loop reading the contents of the directory */
- ret = 0;
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* stat the file */
- sprintf(path, "%s/%s", dirp, dep->d_name);
- xx = lstat64(path, &statinfo);
- if (xx == -1) {
- pr_err(gettext("lstat %s failed: %s"),
- path, strerror(errno));
- closedir(dp);
- return (-1);
- }
-
- /* ignore anything that is not a link */
- if (!S_ISLNK(statinfo.st_mode))
- continue;
-
- /* print the file system cache directory name */
- printf(gettext(" %s\n"), dep->d_name);
-
- /* XXX anything else */
- }
-
- /* XXX what about stats */
-
- /* return status */
- return (ret);
-}
-
-/*
- *
- * resource_file_grow
- *
- * Description:
- * Grows the resource file in the specified directory
- * to its new size.
- * Arguments:
- * dirp cache directory resource file is in
- * oldcnt previous number of files in resource file
- * newcnt new number of files in resource file
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(dirp)
- * precond(oldcnt <= newcnt)
- * precond(cache is locked exclusively)
- * precond(cache is not in use)
- */
-
-int
-resource_file_grow(char *dirp, int oldcnt, int newcnt)
-{
- int fd;
- char path[CACHEFS_XMAXPATH];
- int xx;
- struct stat64 st;
- static struct cachefs_rinfo rold, rnew;
- struct cache_usage cusage, *cusagep;
- char buf[MAXBSIZE];
- int cnt;
- caddr_t addrp;
- int dirty;
-
- /* get info about the resouce file for the various sizes */
- cachefs_resource_size(oldcnt, &rold);
- cachefs_resource_size(newcnt, &rnew);
-
- /* open the resource file for writing */
- /* this file is < 2GB */
- sprintf(path, "%s/%s", dirp, RESOURCE_NAME);
- fd = open(path, O_RDWR);
- if (fd == -1) {
- pr_err(gettext("Could not open %s: %s, run fsck"), path,
- strerror(errno));
- return (-1);
- }
-
- /* get info on the file */
- xx = fstat64(fd, &st);
- if (xx == -1) {
- pr_err(gettext("Could not stat %s: %s"), path,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* make sure the size is the correct */
- if ((off_t)st.st_size != rold.r_fsize) {
- pr_err(gettext("Resource file has wrong size %d %d, run fsck"),
- (off_t)st.st_size, rold.r_fsize);
- close(fd);
- return (-1);
- }
-
- /* read the cache usage structure */
- xx = read(fd, &cusage, sizeof (cusage));
- if (xx != sizeof (cusage)) {
- pr_err(gettext("Could not read cache_usage, %d, run fsck"),
- xx);
- close(fd);
- return (-1);
- }
-
- /* rewind */
- xx = lseek(fd, 0, SEEK_SET);
- if (xx == -1) {
- pr_err(gettext("Could not lseek %s: %s"), path,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* indicate cache is dirty if necessary */
- dirty = 1;
- if ((cusage.cu_flags & CUSAGE_ACTIVE) == 0) {
- dirty = 0;
- cusage.cu_flags |= CUSAGE_ACTIVE;
- xx = write(fd, &cusage, sizeof (cusage));
- if (xx != sizeof (cusage)) {
- pr_err(gettext(
- "Could not write cache_usage, %d, run fsck"),
- xx);
- close(fd);
- return (-1);
- }
- }
-
- /* go to the end of the file */
- xx = lseek(fd, 0, SEEK_END);
- if (xx == -1) {
- pr_err(gettext("Could not lseek %s: %s"), path,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* grow the file to the new size */
- memset(buf, 0, sizeof (buf));
- cnt = rnew.r_fsize - rold.r_fsize;
- assert((cnt % MAXBSIZE) == 0);
- cnt /= MAXBSIZE;
- while (cnt-- > 0) {
- xx = write(fd, buf, sizeof (buf));
- if (xx != sizeof (buf)) {
- pr_err(gettext("Could not write file, %d, run fsck"),
- xx);
- close(fd);
- return (-1);
- }
- }
-
- /* mmap the file into our address space */
- addrp = mmap(NULL, rnew.r_fsize, PROT_READ | PROT_WRITE, MAP_SHARED,
- fd, 0);
- if (addrp == (void *)-1) {
- pr_err(gettext("Could not mmap file %s: %s"), path,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* close the file descriptor, we do not need it anymore */
- close(fd);
-
- /* move the idents region to its new location */
- memmove(addrp + rnew.r_identoffset, addrp + rold.r_identoffset,
- rold.r_identsize);
-
- /* zero out the old idents region that is now in the pointers region */
- memset(addrp + rold.r_identoffset, 0,
- rnew.r_identoffset - rold.r_identoffset);
-
- /* sync the data to the file */
- xx = msync(addrp, rnew.r_fsize, MS_SYNC);
- if (xx == -1) {
- pr_err(gettext("Could not sync file %s: %s"), path,
- strerror(errno));
- munmap(addrp, rnew.r_fsize);
- return (-1);
- }
-
- /* mark the file as clean if it was not dirty originally */
- if (!dirty) {
- cusagep = (struct cache_usage *)addrp;
- cusagep->cu_flags &= ~CUSAGE_ACTIVE;
-
- /* sync the data to the file */
- xx = msync(addrp, rnew.r_fsize, MS_SYNC);
- if (xx == -1) {
- pr_err(gettext("Could not sync file %s: %s"), path,
- strerror(errno));
- munmap(addrp, rnew.r_fsize);
- return (-1);
- }
- }
-
- /* unmap the file */
- munmap(addrp, rnew.r_fsize);
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * resource_file_dirty
- *
- * Description:
- * Marks the resource file as dirty.
- * This will cause fsck to fix it up the next time it
- * is run.
- * Arguments:
- * dirp cache directory resource file is in
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(dirp)
- * precond(cache is locked exclusively)
- * precond(cache is not in use)
- */
-
-int
-resource_file_dirty(char *dirp)
-{
- int fd;
- char path[CACHEFS_XMAXPATH];
- int xx;
- struct cache_usage cusage;
-
- /* open the resource file for writing */
- /* this file is < 2GB */
- sprintf(path, "%s/%s", dirp, RESOURCE_NAME);
- fd = open(path, O_RDWR);
- if (fd == -1) {
- pr_err(gettext("Could not open %s: %s, run fsck"), path,
- strerror(errno));
- return (-1);
- }
-
- /* read the cache usage structure */
- xx = read(fd, &cusage, sizeof (cusage));
- if (xx != sizeof (cusage)) {
- pr_err(gettext("Could not read cache_usage, %d, run fsck"),
- xx);
- close(fd);
- return (-1);
- }
-
- /* rewind */
- xx = lseek(fd, 0, SEEK_SET);
- if (xx == -1) {
- pr_err(gettext("Could not lseek %s: %s"), path,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* indicate cache is dirty if necessary */
- if ((cusage.cu_flags & CUSAGE_ACTIVE) == 0) {
- cusage.cu_flags |= CUSAGE_ACTIVE;
- xx = write(fd, &cusage, sizeof (cusage));
- if (xx != sizeof (cusage)) {
- pr_err(gettext(
- "Could not write cache_usage, %d, run fsck"),
- xx);
- close(fd);
- return (-1);
- }
- }
-
- xx = close(fd);
- if (xx == -1) {
- pr_err(gettext("Could not successfully close %s: %s"), path,
- strerror(errno));
- }
- return (xx);
-}
-
-/*
- *
- * issue_cod
- *
- * Description:
- * Executes the _FIOCOD ioctl on the specified file.
- * Arguments:
- * name filename to issue ioctl on (or "all")
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(dirp)
- */
-
-int
-issue_cod(char *name)
-{
- int fd;
- int xx;
- int arg;
- char *dirp;
- FILE *mfp;
- struct mnttab mt, mtpref;
-
-#ifndef MNTTYPE_CACHEFS
-#define MNTTYPE_CACHEFS "cachefs"
-#endif
-
- arg = 0;
- if (strcmp(name, "all") == 0) {
- /*
- * if "all" was specified rather than a mount point,
- * we locate a cachefs mount in /etc/mnttab (any cachefs
- * mount will do). We issue the ioctl on this mount point,
- * and specify a non-zero argument to the ioctl. The non-zero
- * arg tells the kernel to do demandconst on all relevant
- * cachefs mounts
- */
- if ((mfp = fopen(MNTTAB, "r")) == NULL) {
- pr_err(gettext("Could not open %s."), MNTTAB);
- return (-1);
- }
- mtpref.mnt_special = NULL;
- mtpref.mnt_mountp = NULL;
- mtpref.mnt_mntopts = NULL;
- mtpref.mnt_time = NULL;
- mtpref.mnt_fstype = MNTTYPE_CACHEFS;
- if (getmntany(mfp, &mt, &mtpref) != 0) {
- (void) fclose(mfp);
- return (-1);
- }
- (void) fclose(mfp);
- dirp = mt.mnt_mountp;
- arg = 1;
- } else {
- dirp = name;
- }
-
- /* open the file */
- fd = open(dirp, O_RDONLY);
- if (fd == -1) {
- pr_err(gettext("Could not open %s, %s."),
- dirp, strerror(errno));
- return (-1);
- }
-
- /* issue the ioctl */
- xx = ioctl(fd, _FIOCOD, arg);
- if (xx) {
- if (errno == ENOTTY) {
- pr_err(gettext("%s is not a CacheFS file system"),
- dirp);
- } else if (errno == EBUSY) {
- if (arg == 0)
- /* we're quiet if "all" was specified */
- pr_err(gettext("CacheFS file system %s is not"
- " mounted demandconst."), dirp);
- } else {
- pr_err(gettext("Could not issue consistency request"
- " on %s\n %s."), dirp, strerror(errno));
- }
- }
- close(fd);
- return (xx);
-}
-
-/*
- *
- * simulate_disconnection
- *
- * Description:
- * Sends the rpc message to the cachefsd to turn simulated
- * disconnection on or off
- * Arguments:
- * namep name of file system or "all"
- * disconnect 1 means disconnect, 0 means connect
- * Returns:
- * Preconditions:
- * precond(name)
- */
-
-void
-simulate_disconnection(char *namep, int disconnect)
-{
- CLIENT *clnt;
- enum clnt_stat retval;
- int ret;
- int xx;
- int result;
- char *hostp;
- struct utsname info;
- struct cachefsd_disconnection_args args;
- char *msgp;
- struct timeval tval;
-
- /* get the host name */
- xx = uname(&info);
- if (xx == -1) {
- pr_err(gettext("cannot get host name, errno %d"), errno);
- return;
- }
- hostp = info.nodename;
-
- /* creat the connection to the daemon */
- clnt = clnt_create(hostp, CACHEFSDPROG, CACHEFSDVERS, "local");
- if (clnt == NULL) {
- pr_err(gettext("cachefsd is not running"));
- return;
- }
-
- /* give it a chance to complete */
- tval.tv_sec = 60 * 60 * 24;
- tval.tv_usec = 0;
- clnt_control(clnt, CLSET_TIMEOUT, (char *)&tval);
-
- /* perform the operation */
- args.cda_mntpt = namep;
- args.cda_disconnect = disconnect;
- retval = cachefsd_disconnection_1(&args, &ret, clnt);
- if (retval != RPC_SUCCESS) {
- clnt_perror(clnt, gettext("cachefsd is not responding"));
- clnt_destroy(clnt);
- return;
- }
-
- /* check for error from daemon */
- if (ret != 0) {
- if (disconnect) {
- switch (ret) {
- default:
- msgp = "unknown error";
- break;
- case 1:
- msgp = "not mounted disconnectable";
- break;
- case 2:
- msgp = "already disconnected";
- break;
- case 3:
- msgp = "not a cached file system";
- break;
- }
- pr_err(gettext("Could not disconnect %s: %s"),
- namep, msgp);
- } else {
- switch (ret) {
- default:
- msgp = "unknown error";
- break;
- case 1:
- msgp = "already connected";
- break;
- case 2:
- msgp = "not simulated disconnection";
- break;
- case 3:
- msgp = "not a cached file system";
- break;
- }
- pr_err(gettext("Could not reconnect %s: %s"),
- namep, msgp);
- }
- }
-
- ret = 0;
-
- clnt_destroy(clnt);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/Makefile b/usr/src/cmd/fs.d/cachefs/cfsd/Makefile
deleted file mode 100644
index 0b49a010cc..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# 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.
-#
-#
-# cmd/fs.d/cachefs/cfsd
-#
-
-FSTYPE= cachefs
-LIBPROG_C= cachefsd
-ATTMK= $(LIBPROG_C)
-LINKVALUE= ../lib/fs/$(FSTYPE)/$(LIBPROG_C)
-
-include ../../Makefile.fstype
-
-PROGOBJS = cfsd_main.o cfsd_svc.o cfsd_kmod.o cfsd_maptbl.o \
- cfsd_logelem.o cfsd_cache.o cfsd_fscache.o cfsd_all.o \
- cfsd_logfile.o cfsd_subr.o
-
-LDLIBSMT = $(LDLIBS.cmd) $(CFSLIBMT) $(MDBUGLIB) -lnsl
-include ../Makefile.cachefs
-
-MDBUGLIB= ../mdbug/libdbug.a
-CPPFLAGS += -I.. -D_REENTRANT
-RPCGENFLAGS= -M -C -T
-CLOBBERFILES += $(LIBPROG_C) cachefsd_tbl.i
-
-all : $(LIBPROG_C)
-
-install : $(ROOTLIBFSTYPE)/$(LIBPROG_C)
-
-$(LIBPROG_C): $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBSMT)
- $(POST_PROCESS)
-
-testmap : cfsd_maptbl.o testmap.o
- $(LINK.c) -o $@ cfsd_maptbl.o testmap.o $(LDLIBS)
-
-cachefsd_tbl.i : $(CACHEFSDIR)/cachefsd.x
- $(RPCGEN) $(RPCGENFLAGS) -t -o cachefsd_tbl.i \
- $(CACHEFSDIR)/cachefsd.x
-
-cfsd_main.o : cfsd_main.c cachefsd_tbl.i
-
-clobber : templates
-
-templates :
- rm -rf SunWS_cache
-
-$(LIBPROG_C) : $(CFSLIB) $(MDBUGLIB)
-
-$(MDBUGLIB) :
- cd $(@D); pwd; $(MAKE) $(TARGET);
- @pwd
-
-$(PROGOBJS) : $(CACHEFSDIR)/cachefsd.h ../mdbug/mdbug.h
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd.h
deleted file mode 100644
index 2caf5dfe0c..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * cfsd.h
- *
- * Include file for the cfsd
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#define CFSDStrMax 256
-void *cfsd_calloc(int size);
-void cfsd_free(void *free_ptr);
-void cfsd_sleep(int sec);
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.c
deleted file mode 100644
index 6cdc1fe58d..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * 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 (c) 1994-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods for the cfsd_all class.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <thread.h>
-#include <synch.h>
-#include <locale.h>
-#include <errno.h>
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/mnttab.h>
-#include <sys/vfstab.h>
-#include <mdbug/mdbug.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_fscache.h"
-#include "cfsd_cache.h"
-#include "cfsd_all.h"
-
-/*
- * ------------------------------------------------------------
- * cfsd_all_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-cfsd_all_object_t *
-cfsd_all_create(void)
-{
-
- /* get the host name */
- struct utsname info;
- cfsd_all_object_t *all_object_p;
- int xx;
- char buffer[MAXPATHLEN];
-
- dbug_enter("cfsd_all_create");
-
- all_object_p =
- (cfsd_all_object_t *)cfsd_calloc(sizeof (cfsd_all_object_t));
-
- xx = uname(&info);
- if (xx == -1) {
- dbug_print(("error", "cannot get host name"));
- strlcpy(all_object_p->i_machname, gettext("unknown"),
- sizeof (all_object_p->i_machname));
- } else {
- strlcpy(all_object_p->i_machname, info.nodename,
- sizeof (all_object_p->i_machname));
- }
-
- /* initialize the locking mutex */
- xx = mutex_init(&all_object_p->i_lock, USYNC_THREAD, NULL);
- dbug_assert(xx == 0);
-
- all_object_p->i_nextcacheid = 0;
- all_object_p->i_modify = 1;
- all_object_p->i_cachelist = NULL;
- all_object_p->i_cachecount = 0;
-
- /* all_object_p->i_hoardp = NULL; */
-
- snprintf(buffer, sizeof (buffer), gettext("host name is \"%s\""),
- all_object_p->i_machname);
- dbug_print(("info", buffer));
- dbug_leave("cfsd_all_create");
- return (all_object_p);
-}
-
-/*
- * ------------------------------------------------------------
- * cfsd_all_destroy
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-cfsd_all_destroy(cfsd_all_object_t *all_object_p)
-{
- cfsd_cache_object_t *cache_object_p;
- cfsd_cache_object_t *tmp_cache_object_p;
- int xx;
-
- dbug_enter("cfsd_all_destroy");
-
- /* dbug_assert(all_object_p->i_hoardp == NULL); */
-
- /* get rid of any cache objects */
- cache_object_p = all_object_p->i_cachelist;
-
- while (cache_object_p != NULL) {
- tmp_cache_object_p = cache_object_p->i_next;
- cfsd_cache_destroy(cache_object_p);
- cache_object_p = tmp_cache_object_p;
- }
-
- /* destroy the locking mutex */
- xx = mutex_destroy(&all_object_p->i_lock);
- dbug_assert(xx == 0);
- cfsd_free(all_object_p);
- dbug_leave("cfsd_all_destroy");
-}
-
-/*
- * ------------------------------------------------------------
- * all_lock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-all_lock(cfsd_all_object_t *all_object_p)
-{
- dbug_enter("all_lock");
-
- mutex_lock(&all_object_p->i_lock);
- dbug_leave("all_lock");
-}
-
-/*
- * ------------------------------------------------------------
- * all_unlock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-all_unlock(cfsd_all_object_t *all_object_p)
-{
- dbug_enter("all_unlock");
-
- mutex_unlock(&all_object_p->i_lock);
- dbug_leave("all_unlock");
-}
-
-/*
- * ------------------------------------------------------------
- * all_cachelist_at
- *
- * Description:
- * Arguments:
- * index
- * Returns:
- * Returns ...
- * Preconditions:
- */
-cfsd_cache_object_t *
-all_cachelist_at(cfsd_all_object_t *all_object_p, size_t index)
-{
- cfsd_cache_object_t *cache_object_p;
- int i = 0;
-
- dbug_enter("all_cachelist_at");
-
- /* find the correct cache object */
- cache_object_p = all_object_p->i_cachelist;
-
- while ((cache_object_p != NULL) && (i++ < index)) {
- cache_object_p = cache_object_p->i_next;
- }
-
- dbug_leave("all_cachelist_at");
- return (cache_object_p);
-}
-
-/*
- * ------------------------------------------------------------
- * all_cachelist_add
- *
- * Description:
- * Arguments:
- * cachep
- * Returns:
- * Preconditions:
- * precond(cachep)
- */
-void
-all_cachelist_add(cfsd_all_object_t *all_object_p,
- cfsd_cache_object_t *cache_object_p)
-{
- dbug_enter("all_cachelist_add");
-
- dbug_precond(cache_object_p);
-
- cache_object_p->i_next = all_object_p->i_cachelist;
- all_object_p->i_cachelist = cache_object_p;
- all_object_p->i_modify++;
- all_object_p->i_cachecount++;
- dbug_leave("all_cachelist_add");
-}
-
-/*
- * ------------------------------------------------------------
- * all_cachelist_find
- *
- * Description:
- * Arguments:
- * namep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(namep)
- */
-cfsd_cache_object_t *
-all_cachelist_find(cfsd_all_object_t *all_object_p, const char *namep)
-{
- cfsd_cache_object_t *cache_object_p;
-
- dbug_enter("all_cachelist_find");
-
- dbug_precond(namep);
-
- /* find the correct cache object */
- cache_object_p = all_object_p->i_cachelist;
-
- while ((cache_object_p != NULL) &&
- strcmp(namep, cache_object_p->i_cachedir)) {
- cache_object_p = cache_object_p->i_next;
- }
-
- dbug_leave("all_cachelist_find");
- return (cache_object_p);
-}
-
-/*
- * ------------------------------------------------------------
- * all_cachefstab_update
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-all_cachefstab_update(cfsd_all_object_t *all_object_p)
-{
- cfsd_cache_object_t *cache_object_p;
- FILE *fout;
-
- dbug_enter("all_cachefstab_update");
-
- fout = fopen(CACHEFSTAB, "w");
- if (fout == NULL) {
- dbug_print(("error", "cannot write %s", CACHEFSTAB));
- } else {
- cache_object_p = all_object_p->i_cachelist;
-
- while (cache_object_p != NULL) {
- dbug_assert(cache_object_p);
- fprintf(fout, "%s\n", cache_object_p->i_cachedir);
- cache_object_p = cache_object_p->i_next;
- }
- if (fclose(fout))
- dbug_print(("error", "cannot close %s error %d",
- CACHEFSTAB, errno));
- }
- dbug_leave("all_cachefstab_update");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.h
deleted file mode 100644
index 48dfd99431..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_all.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * all.h
- *
- * Include file for the cfsd_all class.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#ifndef CFSD_ALL
-#define CFSD_ALL
-
-/* get define for _SYS_NMLN */
-#include <sys/utsname.h>
-
-typedef struct cfsd_all_object {
- char i_machname[SYS_NMLN]; /* machine name */
- cfsd_cache_object_t *i_cachelist; /* list of caches */
- int i_cachecount; /* # of objs on list */
- mutex_t i_lock; /* synchro lock */
- int i_nextcacheid; /* for cache ids */
- int i_modify; /* changed when mod */
-#ifdef HOARD_CLASS
- cfsd_hoard *i_hoardp; /* hoarding class */
-#endif
-
-} cfsd_all_object_t;
-
-cfsd_all_object_t *cfsd_all_create(void);
-void cfsd_all_destroy(cfsd_all_object_t *cfsd_all_object_p);
-
-void all_lock(cfsd_all_object_t *all_object_p);
-void all_unlock(cfsd_all_object_t *all_object_p);
-
-cfsd_cache_object_t *all_cachelist_at(cfsd_all_object_t *all_object_p,
- size_t index);
-void all_cachelist_add(cfsd_all_object_t *all_object_p,
- cfsd_cache_object_t *cache_object_p);
-cfsd_cache_object_t *all_cachelist_find(cfsd_all_object_t *all_object_p,
- const char *namep);
-
-void all_cachefstab_update(cfsd_all_object_t *all_object_p);
-
-#endif /* CFSD_ALL */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.c
deleted file mode 100644
index c27f044250..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * 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 (c) 1994-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods of the cfsd_cache class.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <thread.h>
-#include <synch.h>
-#include <locale.h>
-#include <sys/utsname.h>
-#include <sys/stat.h>
-#include <mdbug/mdbug.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_fscache.h"
-#include "cfsd_cache.h"
-
-/*
- * -----------------------------------------------------------------
- * cfsd_cache_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_cache_object_t *
-cfsd_cache_create(void)
-{
- cfsd_cache_object_t *cache_object_p;
- int xx;
-
- dbug_enter("cfsd_cache_create");
-
- cache_object_p = cfsd_calloc(sizeof (cfsd_cache_object_t));
- strlcpy(cache_object_p->i_cachedir, gettext("unknown"),
- sizeof (cache_object_p->i_cachedir));
- cache_object_p->i_refcnt = 0;
- cache_object_p->i_nextfscacheid = 0;
- cache_object_p->i_cacheid = 0;
- cache_object_p->i_modify = 1;
- cache_object_p->i_fscachelist = NULL;
- cache_object_p->i_fscachecount = 0;
-
- /* initialize the locking mutex */
- xx = mutex_init(&cache_object_p->i_lock, USYNC_THREAD, NULL);
-
- dbug_assert(xx == 0);
- dbug_leave("cfsd_cache_create");
- return (cache_object_p);
-}
-
-/*
- * -----------------------------------------------------------------
- * cfsd_cache_destroy
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-
-void
-cfsd_cache_destroy(cfsd_cache_object_t *cache_object_p)
-{
-
- cfsd_fscache_object_t *fscache_object_p;
- cfsd_fscache_object_t *tmp_fscache_object_p;
- int xx;
-
- dbug_enter("cfsd_cache_destroy");
-
- /* get rid of any fscache objects */
- fscache_object_p = cache_object_p->i_fscachelist;
-
- while (fscache_object_p != NULL) {
- tmp_fscache_object_p = fscache_object_p->i_next;
- cfsd_fscache_destroy(fscache_object_p);
- fscache_object_p = tmp_fscache_object_p;
- }
-
- /* destroy the locking mutex */
- xx = mutex_destroy(&cache_object_p->i_lock);
- dbug_assert(xx == 0);
- cfsd_free(cache_object_p);
- dbug_leave("cfsd_cache_destroy");
-}
-
-/*
- * -----------------------------------------------------------------
- * cache_setup
- *
- * Description:
- * Performs setup for the cache.
- * Arguments:
- * cachedirp
- * cacheid
- * Returns:
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cache_setup(cfsd_cache_object_t *cache_object_p, const char *cachedirp,
- int cacheid)
-{
-
- /* XXX either need to prevent multiple calls to this or */
- /* clean up here. */
-
- int ret;
- struct stat64 sinfo;
- dbug_enter("cache_setup");
-
- if ((stat64(cachedirp, &sinfo) == -1) ||
- (!S_ISDIR(sinfo.st_mode)) ||
- (*cachedirp != '/')) {
- dbug_print(("info", "%s is not a cache directory", cachedirp));
- ret = 0;
- } else {
- strlcpy(cache_object_p->i_cachedir, cachedirp,
- sizeof (cache_object_p->i_cachedir));
- ret = 1;
- }
-
- cache_object_p->i_cacheid = cacheid;
- cache_object_p->i_modify++;
-
- dbug_leave("cache_setup");
- /* return result */
- return (ret);
-}
-/*
- * -----------------------------------------------------------------
- * cache_lock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-cache_lock(cfsd_cache_object_t *cache_object_p)
-{
- dbug_enter("cache_lock");
-
- mutex_lock(&cache_object_p->i_lock);
- dbug_leave("cache_lock");
-}
-
-/*
- * -----------------------------------------------------------------
- * cache_unlock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-cache_unlock(cfsd_cache_object_t *cache_object_p)
-{
- dbug_enter("cache_unlock");
-
- mutex_unlock(&cache_object_p->i_lock);
- dbug_leave("cache_unlock");
-}
-/*
- * -----------------------------------------------------------------
- * cache_fscachelist_at
- *
- * Description:
- * Arguments:
- * index
- * Returns:
- * Returns ...
- * Preconditions:
- */
-
-cfsd_fscache_object_t *
-cache_fscachelist_at(cfsd_cache_object_t *cache_object_p, size_t index)
-{
- cfsd_fscache_object_t *fscache_object_p;
- int i = 0;
-
- dbug_enter("cache_fscachelist_at");
-
- /* find the correct cache object */
- fscache_object_p = cache_object_p->i_fscachelist;
-
- while ((fscache_object_p != NULL) && (i++ < index)) {
- fscache_object_p = fscache_object_p->i_next;
- }
-
- dbug_leave("cache_fscachelist_at");
- return (fscache_object_p);
-}
-
-/*
- * -----------------------------------------------------------------
- * cache_fscachelist_add
- *
- * Description:
- * Arguments:
- * cachep
- * Returns:
- * Preconditions:
- * precond(fscachep)
- */
-
-void
-cache_fscachelist_add(cfsd_cache_object_t *cache_object_p,
- cfsd_fscache_object_t *fscache_object_p)
-{
- dbug_enter("cache_fscachelist_add");
-
- dbug_precond(fscache_object_p);
-
- fscache_object_p->i_next = cache_object_p->i_fscachelist;
- cache_object_p->i_fscachelist = fscache_object_p;
- cache_object_p->i_modify++;
- cache_object_p->i_fscachecount++;
- dbug_leave("cache_fscachelist_add");
-}
-
-/*
- * -----------------------------------------------------------------
- * cache_fscachelist_find
- *
- * Description:
- * Arguments:
- * namep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(namep)
- */
-
-cfsd_fscache_object_t *
-cache_fscachelist_find(cfsd_cache_object_t *cache_object_p,
- const char *namep)
-{
- cfsd_fscache_object_t *fscache_object_p;
-
- dbug_enter("cache_fscachelist_find");
-
- dbug_precond(namep);
-
- /* see if the fscache exists */
- fscache_object_p = cache_object_p->i_fscachelist;
-
- while ((fscache_object_p != NULL) &&
- strcmp(namep, fscache_object_p->i_name)) {
- fscache_object_p = fscache_object_p->i_next;
- }
-
- dbug_leave("cache_fscachelist_find");
- return (fscache_object_p);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.h
deleted file mode 100644
index 00899d7a9a..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_cache.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * cache.h
- *
- * Include file for the cache class.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#ifndef CFSD_CACHE
-#define CFSD_CACHE
-
-typedef struct cfsd_cache_object {
- char i_cachedir[MAXPATHLEN]; /* cache directory */
- int i_cacheid; /* cache id */
- cfsd_fscache_object_t *i_fscachelist; /* list of fscaches */
- int i_fscachecount; /* # of objs in list */
- mutex_t i_lock; /* synchro lock */
- int i_refcnt; /* refs to object */
- int i_nextfscacheid; /* for fscache ids */
- int i_modify; /* changes when mod */
- struct cfsd_cache_object *i_next; /* next cache object */
-} cfsd_cache_object_t;
-
-cfsd_cache_object_t *cfsd_cache_create(void);
-void cfsd_cache_destroy(cfsd_cache_object_t *cache_object_p);
-
-int cache_setup(cfsd_cache_object_t *cache_object_p, const char *cachedirp,
- int cacheid);
-void cache_lock(cfsd_cache_object_t *cache_object_p);
-void cache_unlock(cfsd_cache_object_t *cache_object_p);
-
-cfsd_fscache_object_t *cache_fscachelist_at(cfsd_cache_object_t *cache_object_p,
- size_t index);
-void cache_fscachelist_add(cfsd_cache_object_t *cache_object_p,
- cfsd_fscache_object_t *fscache_object_p);
-cfsd_fscache_object_t *cache_fscachelist_find(
- cfsd_cache_object_t *cache_object_p, const char *namep);
-
-#endif /* CFSD_CACHE */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.c
deleted file mode 100644
index d4cc0fbc5a..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.c
+++ /dev/null
@@ -1,1550 +0,0 @@
-/*
- * 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 1994-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods of the cfsd_fscache class.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <thread.h>
-#include <synch.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <nfs/nfs.h>
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <rpc/rpc.h>
-#include <mdbug/mdbug.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_logelem.h"
-#include "cfsd_fscache.h"
-
-/*
- * -----------------------------------------------------------------
- * cfsd_fscache_create
- *
- * Description:
- * Arguments:
- * name
- * cachepath
- * Returns:
- * Preconditions:
- * precond(name)
- * precond(cachepath)
- */
-cfsd_fscache_object_t *
-cfsd_fscache_create(const char *name, const char *cachepath,
- int fscacheid)
-{
- cfsd_fscache_object_t *fscache_object_p;
- int xx;
-
- dbug_enter("cfsd_fscache_create");
-
- dbug_precond(name);
- dbug_precond(cachepath);
-
- fscache_object_p = cfsd_calloc(sizeof (cfsd_fscache_object_t));
- strlcpy(fscache_object_p->i_name, name,
- sizeof (fscache_object_p->i_name));
- strlcpy(fscache_object_p->i_cachepath, cachepath,
- sizeof (fscache_object_p->i_cachepath));
- fscache_object_p->i_fscacheid = fscacheid;
- fscache_object_p->i_refcnt = 0;
- fscache_object_p->i_disconnectable = 0;
- fscache_object_p->i_mounted = 0;
- fscache_object_p->i_threaded = 0;
- fscache_object_p->i_connected = 0;
- fscache_object_p->i_reconcile = 0;
- fscache_object_p->i_changes = 0;
- fscache_object_p->i_simdis = 0;
- fscache_object_p->i_tryunmount = 0;
- fscache_object_p->i_backunmount = 0;
- fscache_object_p->i_time_state = 0;
- fscache_object_p->i_time_mnt = 0;
- fscache_object_p->i_modify = 1;
-
- fscache_object_p->i_threadid = 0;
- fscache_object_p->i_ofd = -1;
-
- fscache_object_p->i_next = NULL;
-
- /* initialize the locking mutex */
- xx = mutex_init(&fscache_object_p->i_lock, USYNC_THREAD, NULL);
- dbug_assert(xx == 0);
-
- xx = cond_init(&fscache_object_p->i_cvwait, USYNC_THREAD, 0);
- dbug_assert(xx == 0);
-
- dbug_leave("cfsd_fscache_create");
- return (fscache_object_p);
-}
-
-/*
- * -----------------------------------------------------------------
- * cfsd_fscache_destroy
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-cfsd_fscache_destroy(cfsd_fscache_object_t *fscache_object_p)
-{
- int xx;
-
- dbug_enter("cfsd_fscache_destroy");
-
- dbug_precond(fscache_object_p);
- /* dbug_assert(fscache_object_p->i_refcnt == 0); */
-
- /* close down the message file descriptor */
- if (fscache_object_p->i_ofd >= 0) {
- if (close(fscache_object_p->i_ofd))
- dbug_print(("error", "cannot close fscache fd error %d",
- errno));
- fscache_object_p->i_ofd = -1;
- }
-
- /* destroy the locking mutex */
- xx = mutex_destroy(&fscache_object_p->i_lock);
- dbug_assert(xx == 0);
-
- /* destroy the conditional variable */
- xx = cond_destroy(&fscache_object_p->i_cvwait);
- dbug_assert(xx == 0);
-
- cfsd_free(fscache_object_p);
-
- dbug_leave("cfsd_fscache_destroy");
-}
-
-/*
- * -----------------------------------------------------------------
- * fscache_lock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fscache_lock(cfsd_fscache_object_t *fscache_object_p)
-{
- dbug_enter("fscache_lock");
-
- dbug_precond(fscache_object_p);
- mutex_lock(&fscache_object_p->i_lock);
- dbug_leave("fscache_lock");
-}
-
-/*
- * -----------------------------------------------------------------
- * fscache_unlock
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fscache_unlock(cfsd_fscache_object_t *fscache_object_p)
-{
- dbug_enter("fscache_unlock");
-
- dbug_precond(fscache_object_p);
- mutex_unlock(&fscache_object_p->i_lock);
- dbug_leave("fscache_unlock");
-}
-
-/*
- * -----------------------------------------------------------------
- * fscache_setup
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fscache_setup(cfsd_fscache_object_t *fscache_object_p)
-{
- char *tmp;
- char cfs_mnt_filename[MAXPATHLEN];
- FILE *fin;
- /*
- * Line input buffer allows for type field (magic number size
- * of 50 is historic), the field separator ": ", a large value
- * (again historic) and a '\n' character.
- */
- char type[50];
- char value[MAXPATHLEN * 4];
- char buf[sizeof (type) + 2 + sizeof (value) + 1];
- int err = 0;
- int xx;
- char *options[] = { "snr", "disconnectable", NULL };
- char *strp = buf;
- char *dummy;
- struct stat64 sinfo;
- time_t mtime;
-
- dbug_enter("fscache_setup");
- dbug_precond(fscache_object_p);
-
- fscache_object_p->i_modify++;
- fscache_object_p->i_disconnectable = 0;
- fscache_object_p->i_connected = 0;
- fscache_object_p->i_reconcile = 0;
- fscache_object_p->i_changes = 0;
- fscache_object_p->i_time_state = 0;
- fscache_object_p->i_time_mnt = 0;
- fscache_object_p->i_mntpt[0] = '\0';
- fscache_object_p->i_backfs[0] = '\0';
- fscache_object_p->i_backpath[0] = '\0';
- fscache_object_p->i_backfstype[0] = '\0';
- fscache_object_p->i_cfsopt[0] = '\0';
- fscache_object_p->i_bfsopt[0] = '\0';
-
- snprintf(cfs_mnt_filename, sizeof (cfs_mnt_filename), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_MNT_FILE);
-
- /* open for reading the file with the mount information */
- fin = fopen(cfs_mnt_filename, "r");
- if (fin == NULL) {
- dbug_print(("err", "could not open %s, %d", cfs_mnt_filename,
- errno));
- dbug_leave("fscache_setup");
- return;
- }
- /* get the modify time of the mount file */
- if (fstat64(fileno(fin), &sinfo) == -1) {
- dbug_print(("err", "could not stat %s, %d", cfs_mnt_filename,
- errno));
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- cfs_mnt_filename, errno));
- dbug_leave("fscache_setup");
- return;
- }
- mtime = sinfo.st_mtime;
-
- /* read the mount information from the file */
- while (fgets(buf, sizeof (buf), fin) != NULL) {
- tmp = strtok(buf, ":");
- if (strlcpy(type, tmp, sizeof (type)) >= sizeof (type)) {
- /* Buffer Overflow */
- dbug_print(("err", "overflow in type field"
- " of file %s", cfs_mnt_filename));
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- cfs_mnt_filename, errno));
- dbug_leave("fscache_setup");
- return;
- }
- tmp = strtok(NULL, "\n");
- if (tmp != NULL && *tmp == ' ') {
- /*
- * There is a valid value string so skip
- * the space after the ":".
- */
- tmp++;
- if (strlcpy(value, tmp, sizeof (value))
- >= sizeof (value)) {
- /* Buffer Overflow */
- dbug_print(("err",
- "overflow in value field"
- " of file %s", cfs_mnt_filename));
- if (fclose(fin))
- dbug_print(("err",
- "cannot close %s, %d",
- cfs_mnt_filename, errno));
- dbug_leave("fscache_setup");
- return;
- }
- } else {
- value[0] = '\0';
- }
- dbug_print(("info", "\"%s\" \"%s\"", type, value));
- if (strcmp(type, "cachedir") == 0) {
- if (strcmp(fscache_object_p->i_cachepath, value) != 0) {
- err = 1;
- dbug_print(("err", "caches do not match %s, %s",
- fscache_object_p->i_cachepath, buf));
- }
- } else if (strcmp(type, "mnt_point") == 0) {
- strlcpy(fscache_object_p->i_mntpt, value,
- sizeof (fscache_object_p->i_mntpt));
- } else if (strcmp(type, "special") == 0) {
- strlcpy(fscache_object_p->i_backfs, value,
- sizeof (fscache_object_p->i_backfs));
- } else if (strcmp(type, "backpath") == 0) {
- strlcpy(fscache_object_p->i_backpath, value,
- sizeof (fscache_object_p->i_backpath));
- } else if (strcmp(type, "backfstype") == 0) {
- strlcpy(fscache_object_p->i_backfstype, value,
- sizeof (fscache_object_p->i_backfstype));
- } else if (strcmp(type, "cacheid") == 0) {
- if (strcmp(fscache_object_p->i_name, value) != 0) {
- err = 1;
- dbug_print(("err", "ids do not match %s, %s",
- fscache_object_p->i_name, value));
- }
- } else if (strcmp(type, "cachefs_options") == 0) {
- strlcpy(fscache_object_p->i_cfsopt, value,
- sizeof (fscache_object_p->i_cfsopt));
- } else if (strcmp(type, "backfs_options") == 0) {
- strlcpy(fscache_object_p->i_bfsopt, value,
- sizeof (fscache_object_p->i_bfsopt));
- } else if (strcmp(type, "mount_time") == 0) {
- continue;
- } else {
- dbug_print(("err", "unknown keyword \"%s\"", type));
- err = 1;
- }
- }
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- cfs_mnt_filename, errno));
-
- /* see if this is a file system that is disconnectable */
- if ((err == 0) &&
- (fscache_object_p->i_backfs[0] &&
- fscache_object_p->i_cfsopt[0])) {
- strlcpy(buf, fscache_object_p->i_cfsopt, sizeof (buf));
- while (*strp != '\0') {
- xx = getsubopt(&strp, options, &dummy);
- if (xx != -1) {
- fscache_object_p->i_disconnectable = 1;
- break;
- }
- }
- }
-
- /*
- * open up a fd on the sysmsg so we have a place to write
- * log rolling errors
- */
- if (fscache_object_p->i_disconnectable) {
- if (fscache_object_p->i_ofd < 0)
- fscache_object_p->i_ofd = open("/dev/sysmsg",
- O_WRONLY);
- if (fscache_object_p->i_ofd < 0) {
- fprintf(stderr,
- gettext("cachefsd: File system %s cannot be"
- " disconnected.\n"),
- fscache_object_p->i_mntpt);
- fprintf(stderr,
- gettext("cachefsd: Cannot open /dev/sysmsg\n"));
- fscache_object_p->i_disconnectable = 0;
- }
- }
-
- /* see if the file system is mounted */
- snprintf(cfs_mnt_filename, sizeof (cfs_mnt_filename), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_UNMNT_FILE);
- if (stat64(cfs_mnt_filename, &sinfo) == 0) {
- fscache_object_p->i_mounted = 0;
- mtime = sinfo.st_mtime;
- } else
- fscache_object_p->i_mounted = 1;
-
- /* save the time of the last mount or unmount */
- fscache_object_p->i_time_mnt = mtime;
-
- dbug_print(("info", "disconnectable == %d, mounted == %d",
- fscache_object_p->i_disconnectable,
- fscache_object_p->i_mounted));
- dbug_leave("fscache_setup");
-}
-
-/*
- * -----------------------------------------------------------------
- * fscache_process
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fscache_process(cfsd_fscache_object_t *fscache_object_p)
-{
- int xx;
- int changes;
- cfsd_kmod_object_t *kmod_object_p;
- int setup = 1;
- int state;
-
- dbug_enter("fscache_process");
- dbug_precond(fscache_object_p);
-
- kmod_object_p = cfsd_kmod_create();
- for (;;) {
- fscache_lock(fscache_object_p);
- fscache_object_p->i_time_state = time(NULL);
- fscache_object_p->i_modify++;
-
- /* if we should try to unmount the file system */
- if (fscache_object_p->i_tryunmount) {
- /* shut down the interface to the kmod */
- if (setup == 0) {
- kmod_shutdown(kmod_object_p);
- setup = 1;
- }
-
- /* try to unmount the file system */
- if (umount(fscache_object_p->i_mntpt) == -1) {
- xx = errno;
- dbug_print(("info", "unmount failed %s",
- strerror(xx)));
- } else {
- fscache_object_p->i_mounted = 0;
- }
-
- /* wake up thread blocked in fscache_unmount */
- fscache_object_p->i_tryunmount = 0;
- xx = cond_broadcast(&fscache_object_p->i_cvwait);
- dbug_assert(xx == 0);
-
- /* all done if unmount succeeded */
- if (fscache_object_p->i_mounted == 0) {
- fscache_unlock(fscache_object_p);
- break;
- }
- }
-
- if (setup) {
- setup = 0;
- /*
- * make an interface into the cachefs kmod for
- * this fs
- */
- xx = kmod_setup(kmod_object_p,
- fscache_object_p->i_mntpt);
- if (xx != 0) {
- dbug_print(("err",
- "setup of kmod interface failed %d", xx));
- fscache_object_p->i_disconnectable = 0;
- fscache_object_p->i_modify++;
- fscache_unlock(fscache_object_p);
- break;
- }
-
- /* verify that we got the file system we expected XXX */
- }
-
- /* get the current state of the file system */
- state = kmod_stateget(kmod_object_p);
-
- if (fscache_object_p->i_simdis && (state == CFS_FS_CONNECTED)) {
- dbug_print(("simdis", "simulating disconnection on %s",
- fscache_object_p->i_mntpt));
- xx = kmod_stateset(kmod_object_p, CFS_FS_DISCONNECTED);
- dbug_assert(xx == 0);
- state = kmod_stateget(kmod_object_p);
- dbug_assert(state == CFS_FS_DISCONNECTED);
- }
- fscache_unlock(fscache_object_p);
-
- switch (state) {
- case CFS_FS_CONNECTED:
- fscache_lock(fscache_object_p);
- fscache_object_p->i_connected = 1;
- fscache_object_p->i_reconcile = 0;
- fscache_object_p->i_modify++;
- fscache_unlock(fscache_object_p);
-
- /* wait for fs to switch to disconnecting */
- dbug_print(("info", "about to xwait"));
- xx = kmod_xwait(kmod_object_p);
- if (xx == EINTR) {
- dbug_print(("info", "a. EINTR from xwait"));
- continue;
- }
- dbug_assert(xx == 0);
- state = kmod_stateget(kmod_object_p);
- dbug_assert(state == CFS_FS_DISCONNECTED);
- break;
-
- case CFS_FS_DISCONNECTED:
- fscache_lock(fscache_object_p);
- fscache_object_p->i_connected = 0;
- fscache_object_p->i_reconcile = 0;
- fscache_object_p->i_modify++;
- fscache_unlock(fscache_object_p);
-
- /* wait until we are reconnected */
- fscache_server_alive(fscache_object_p, kmod_object_p);
- if (fscache_object_p->i_tryunmount)
- continue;
-
- /* switch to reconnecting mode */
- xx = kmod_stateset(kmod_object_p, CFS_FS_RECONNECTING);
- dbug_assert(xx == 0);
- break;
-
- case CFS_FS_RECONNECTING:
- fscache_lock(fscache_object_p);
- fscache_object_p->i_connected = 1;
- fscache_object_p->i_reconcile = 1;
- fscache_object_p->i_modify++;
- changes = fscache_object_p->i_changes;
- fscache_unlock(fscache_object_p);
-
- /* roll the log */
- xx = fscache_roll(fscache_object_p, kmod_object_p);
- if (xx) {
- dbug_assert(xx == ETIMEDOUT);
- /* switch to disconnected */
- xx = kmod_stateset(kmod_object_p,
- CFS_FS_DISCONNECTED);
- dbug_assert(xx == 0);
- } else {
- /* switch to connected */
- xx = kmod_stateset(kmod_object_p,
- CFS_FS_CONNECTED);
- dbug_assert(xx == 0);
- changes = 0;
- }
-
- fscache_lock(fscache_object_p);
- fscache_object_p->i_reconcile = 0;
- fscache_changes(fscache_object_p, changes);
- fscache_object_p->i_modify++;
- fscache_unlock(fscache_object_p);
-
- break;
-
- default:
- dbug_assert(0);
- break;
- }
- }
- cfsd_kmod_destroy(kmod_object_p);
- dbug_leave("fscache_process");
-}
-
-/*
- * fscache_simdisconnect
- *
- * Description:
- * Simulates disconnection or reconnects from a simulated disconnection.
- * Arguments:
- * disconnect 1 means disconnect, !1 means connect
- * Returns:
- * Returns 0 for success, !0 on an error
- * Preconditions:
- */
-int
-fscache_simdisconnect(cfsd_fscache_object_t *fscache_object_p, int disconnect)
-{
-
- int xx;
- int ret = 0;
- char *strp;
- int tcon;
- int trec;
-
- dbug_enter("fscache_simdisconnect");
- dbug_precond(fscache_object_p);
-
- strp = disconnect ? "disconnection" : "reconnection";
-
- dbug_print(("simdis", "About to simulate %s", strp));
-
- fscache_lock(fscache_object_p);
-
- if (disconnect) {
- /* if file system cannot be disconnected */
- if (fscache_object_p->i_disconnectable == 0) {
- ret = 1;
- goto out;
- }
-
- /* if file system is already disconnected */
- if (fscache_object_p->i_connected == 0) {
- ret = 2;
- goto out;
- }
- fscache_object_p->i_simdis = 1;
- } else {
- /* if file system is already connected */
- if (fscache_object_p->i_connected) {
- ret = 1;
- goto out;
- }
-
- /* if file system is not "simulated" disconnected */
- if (fscache_object_p->i_simdis == 0) {
- ret = 2;
- goto out;
- }
- fscache_object_p->i_simdis = 0;
- }
-
- /* if fs thread not running */
- if (fscache_object_p->i_threaded == 0) {
- if (fscache_object_p->i_mounted) {
- dbug_print(("simdis", "thread not running"));
- ret = -1;
- } else {
- if (fscache_object_p->i_simdis)
- fscache_object_p->i_connected = 0;
- else
- fscache_object_p->i_connected = 1;
- }
- goto out;
- }
-
- /* get the attention of the thread */
- dbug_print(("info", "thread %d, killing %d with sigusr1",
- thr_self(), fscache_object_p->i_threadid));
- xx = thr_kill(fscache_object_p->i_threadid, SIGUSR1);
- if (xx) {
- dbug_print(("simdis", "thr_kill failed %d, threadid %d",
- xx, fscache_object_p->i_threadid));
- ret = -1;
- }
-
-out:
- fscache_unlock(fscache_object_p);
-
- if (ret == 0) {
- for (;;) {
- dbug_print(("simdis", " waiting for simulated %s",
- strp));
- fscache_lock(fscache_object_p);
- tcon = fscache_object_p->i_connected;
- trec = fscache_object_p->i_reconcile;
- fscache_unlock(fscache_object_p);
- if (disconnect) {
- if (tcon == 0)
- break;
- } else {
- if ((tcon == 1) && (trec == 0))
- break;
- }
- cfsd_sleep(1);
- }
- dbug_print(("simdis", "DONE waiting for simulated %s", strp));
- } else {
- dbug_print(("simdis", "simulated %s failed %d", strp, ret));
- }
-
- dbug_leave("fscache_simdisconnect");
- return (ret);
-}
-
-/*
- * fscache_unmount
- *
- * Description:
- * Called to unmount the file system.
- * Arguments:
- * Returns:
- * Returns 0 if the unmount is successful
- * EIO if an error
- * EBUSY if did not unmount because busy
- * EAGAIN if umounted but should not unmount nfs mount
- * ENOTSUP - forced unmount is not supported by cachefs
- * Preconditions:
- */
-
-int
-fscache_unmount(cfsd_fscache_object_t *fscache_object_p, int flag)
-{
- int xx;
- int ret = 0;
-
- dbug_enter("fscache_unmount");
- dbug_precond(fscache_object_p);
-
- fscache_lock(fscache_object_p);
-
- /* if there is a thread running */
- if (fscache_object_p->i_threaded) {
- /* do not bother unmounting if rolling the log */
- if (fscache_object_p->i_reconcile) {
- ret = EBUSY;
- goto out;
- }
-
- /* inform the thread to try the unmount */
- fscache_object_p->i_tryunmount = 1;
- fscache_object_p->i_modify++;
-
- /* get the attention of the thread */
- dbug_print(("info", "about to do umount kill"));
- xx = thr_kill(fscache_object_p->i_threadid, SIGUSR1);
- if (xx) {
- dbug_print(("error", "thr_kill failed %d, threadid %d",
- xx, fscache_object_p->i_threadid));
- ret = EIO;
- goto out;
- }
-
- /* wait for the thread to wake us up */
- while (fscache_object_p->i_tryunmount) {
- xx = cond_wait(&fscache_object_p->i_cvwait,
- &fscache_object_p->i_lock);
- dbug_print(("info", "cond_wait woke up %d %d",
- xx, fscache_object_p->i_tryunmount));
- }
-
- /* if the file system is still mounted */
- if (fscache_object_p->i_mounted)
- ret = EBUSY;
- }
-
- /* else if there is no thread running */
- else {
- /* try to unmount the file system */
- if (umount2(fscache_object_p->i_mntpt, flag) == -1) {
- xx = errno;
- dbug_print(("info", "unmount failed %s",
- strerror(xx)));
- if (xx == EBUSY)
- ret = EBUSY;
- else if (xx == ENOTSUP)
- ret = ENOTSUP;
- else
- ret = EIO;
- } else {
- fscache_object_p->i_mounted = 0;
- fscache_object_p->i_modify++;
- }
- }
-out:
- fscache_unlock(fscache_object_p);
- dbug_leave("fscache_unmount");
- return (ret);
-}
-
-/*
- * -----------------------------------------------------------------
- * fscache_server_alive
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fscache_server_alive(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
-
- int xx;
- cfs_fid_t rootfid;
- dl_cred_t cr;
- cfs_vattr_t va;
- char cfsopt[CFS_MAXMNTOPTLEN];
- int child_pid;
- int stat_loc;
-
- dbug_enter("fscache_server_alive");
-
- dbug_precond(fscache_object_p);
- dbug_precond(kmod_object_p);
-
- for (;;) {
- /* wait for a little while */
- if (fscache_object_p->i_simdis == 0)
- cfsd_sleep(30);
- /* if simulating disconnect */
- fscache_lock(fscache_object_p);
- while (fscache_object_p->i_simdis &&
- !fscache_object_p->i_tryunmount) {
- dbug_print(("simdis", "before calling cond_wait"));
- xx = cond_wait(&fscache_object_p->i_cvwait,
- &fscache_object_p->i_lock);
- dbug_print(("simdis", "cond_wait woke up %d %d",
- xx, fscache_object_p->i_simdis));
- }
- fscache_unlock(fscache_object_p);
-
- if (fscache_object_p->i_tryunmount)
- break;
-
- /* see if the server is alive */
- if (fscache_pingserver(fscache_object_p) == -1) {
- /* dead server */
- continue;
- }
-
- /* try to mount the back file system if needed */
- if (fscache_object_p->i_backpath[0] == '\0') {
- dbug_precond(fscache_object_p->i_cfsopt[0]);
- dbug_precond(fscache_object_p->i_backfs[0]);
- dbug_precond(fscache_object_p->i_mntpt[0]);
-
- snprintf(cfsopt, sizeof (cfsopt), "%s,slide,remount",
- fscache_object_p->i_cfsopt);
- /*
- * Mounting of a cachefs file system is done by calling
- * out to /usr/lib/fs/cachefs/mount so that mounts
- * done by the user, autofs and by us here in cachefsd
- * are consistent.
- */
- switch ((child_pid = fork1())) {
- case -1:
- /*
- * The original code used system()
- * but never checked for an error
- * occurring. The rest of the code
- * would suggest that "continue" is
- * the correct thing to do.
- */
- dbug_print(("info", "unable to fork mount "
- "process for back fs %s %d",
- fscache_object_p->i_backfs, errno));
- continue;
- case 0:
- (void) setsid();
- execl("/usr/sbin/mount", "mount", "-F",
- "cachefs", "-o", cfsopt,
- fscache_object_p->i_backfs,
- fscache_object_p->i_mntpt, NULL);
- break;
- default:
- (void) waitpid(child_pid, &stat_loc, WUNTRACED);
- }
-
- }
-
- /* get the root fid of the file system */
- xx = kmod_rootfid(kmod_object_p, &rootfid);
- if (xx) {
- dbug_print(("info", "could not mount back fs %s %d",
- fscache_object_p->i_backfs, xx));
- continue;
- }
-
- /* dummy up a fake kcred */
- (void) memset(&cr, 0, sizeof (cr));
-
- /* try to get attrs on the root */
- xx = kmod_getattrfid(kmod_object_p, &rootfid, &cr, &va);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_print(("info", "Bogus error %d", xx));
- continue;
- }
- break;
- }
- dbug_leave("fscache_server_alive");
-}
-
-/*
- * fscache_pingserver
- *
- * Description:
- * Trys to ping the nfs server to see if it is alive.
- * Arguments:
- * Returns:
- * Returns 0 if it is alive, -1 if no answer.
- * Preconditions:
- */
-
-int
-fscache_pingserver(cfsd_fscache_object_t *fscache_object_p)
-{
-
- static struct timeval TIMEOUT = { 25, 0 };
- CLIENT *clnt;
- enum clnt_stat retval;
- int ret = 0;
- char hostname[sizeof (fscache_object_p->i_backfs)];
- char *cptr;
-
- dbug_enter("fscache_pingserver");
- dbug_precond(fscache_object_p);
-
- strlcpy(hostname, fscache_object_p->i_backfs, sizeof (hostname));
- if (cptr = strchr(hostname, ':'))
- *cptr = '\0';
-
- dbug_assert(cptr != NULL);
- dbug_print(("info", "remote host '%s' before clnt_create", hostname));
-
- dbug_print(("info", "before clnt_create"));
- /* XXX this takes 75 seconds to time out */
- /* XXX should use lower level routines to reduce overhead */
- clnt = clnt_create(hostname, NFS_PROGRAM, NFS_VERSION, "udp");
- if (clnt == NULL) {
- /* XXX what if this fails other than TIMEDOUT */
- /* clnt_pcreateerror(hostname); */
- dbug_print(("info", "clnt_create failed"));
- ret = -1;
- } else {
- dbug_print(("info", "before null rpc"));
- /* XXX this takes 45 seconds to time out */
- retval = clnt_call(clnt, 0, xdr_void, NULL, xdr_void, NULL,
- TIMEOUT);
- if (retval != RPC_SUCCESS) {
- /* clnt_perror(clnt, "null rpc call failed"); */
- dbug_print(("info", "null rpc call failed %d", retval));
- ret = -1;
- }
- clnt_destroy(clnt);
- }
- dbug_leave("fscache_pingserver");
- return (ret);
-}
-
-/*
- * fscache_roll
- *
- * Description:
- * Rolls the contents of the log to the server.
- * Arguments:
- * kmodp interface to kernel functions
- * Returns:
- * Returns 0 for success or ETIMEDOUT if a timeout error occurred.
- * Preconditions:
- * precond(kmodp)
- */
-int
-fscache_roll(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- int error = 0;
- cfsd_logelem_object_t *logelem_object_p;
- char namebuf[MAXPATHLEN];
- char backupfile[MAXPATHLEN];
- int xx;
- cfs_dlog_entry_t *entp;
- off_t next_offset;
- ulong_t curseq = 0;
- int eof = 0;
- char *xp;
- cfsd_logfile_object_t *logfile_object_p;
- cfsd_maptbl_object_t *maptbl_object_p;
-
- dbug_enter("fscache_roll");
-
- dbug_precond(fscache_object_p);
- dbug_precond(kmod_object_p);
-
- /* map in the log file */
- logfile_object_p = cfsd_logfile_create();
-
- snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_DLOG_FILE);
- xx = logfile_setup(logfile_object_p, namebuf, CFS_DLOG_ENTRY_MAXSIZE);
- if (xx) {
- if (xx == ENOENT) {
- cfsd_logfile_destroy(logfile_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
-
- fscache_lock(fscache_object_p);
- fscache_changes(fscache_object_p, 1);
- fscache_unlock(fscache_object_p);
-
- /* create a hashed mapping table for changes to cids */
- maptbl_object_p = cfsd_maptbl_create();
- snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_DMAP_FILE);
- xx = maptbl_setup(maptbl_object_p, namebuf);
- if (xx) {
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- cfsd_maptbl_destroy(maptbl_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
-
- /*
- * lock is not needed because they are only used when
- * rolling the log by fscache_roll and fscache_addagain
- */
- fscache_object_p->i_again_offset = 0;
- fscache_object_p->i_again_seq = 0;
-
- /* Pass 1: collect all cid to fid mappings */
- next_offset = LOGFILE_ENTRY_START;
- for (;;) {
- /* get a pointer to the next record */
- xx = logfile_entry(logfile_object_p, next_offset, &entp);
- if (xx == 1)
- break;
- if (xx == -1) {
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- cfsd_maptbl_destroy(maptbl_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
- next_offset += entp->dl_len;
-
- /* skip record if not valid */
- if (entp->dl_valid != CFS_DLOG_VAL_COMMITTED)
- continue;
-
- /* create an object for the appropriate log type */
- logelem_object_p = NULL;
- switch (entp->dl_op) {
- case CFS_DLOG_CREATE:
- case CFS_DLOG_REMOVE:
- case CFS_DLOG_LINK:
- case CFS_DLOG_RENAME:
- case CFS_DLOG_MKDIR:
- case CFS_DLOG_RMDIR:
- case CFS_DLOG_SYMLINK:
- case CFS_DLOG_SETATTR:
- case CFS_DLOG_SETSECATTR:
- case CFS_DLOG_MODIFIED:
- case CFS_DLOG_TRAILER:
- break;
-
- case CFS_DLOG_MAPFID:
- dbug_print(("info", "mapfid"));
- logelem_object_p = cfsd_logelem_mapfid_create(
- maptbl_object_p, logfile_object_p,
- kmod_object_p);
- break;
-
- default:
- dbug_assert(0);
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- break;
- }
-
- /* do not bother if ignoring the record */
- if (logelem_object_p == NULL)
- continue;
-
- /* debuggging */
- logelem_dump(logelem_object_p);
-
- /* roll the entry */
- xx = logelem_roll(logelem_object_p, (ulong_t *)NULL);
- if (xx) {
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- cfsd_logelem_destroy(logelem_object_p);
- cfsd_maptbl_destroy(maptbl_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
-
- /* mark record as completed */
- entp->dl_valid = CFS_DLOG_VAL_PROCESSED;
- xx = logfile_sync(logfile_object_p);
- if (xx) {
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- cfsd_logelem_destroy(logelem_object_p);
- cfsd_maptbl_destroy(maptbl_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
-
- /* destroy the object */
- cfsd_logelem_destroy(logelem_object_p);
- }
-
- /* Pass 2: modify the back file system */
- next_offset = LOGFILE_ENTRY_START;
- for (;;) {
- /* if we need the seq number of a deferred modify */
- if (fscache_object_p->i_again_offset &&
- (fscache_object_p->i_again_seq == 0)) {
-
- /* get a pointer to the next record */
- xx = logfile_entry(logfile_object_p,
- fscache_object_p->i_again_offset, &entp);
- if (xx == 1)
- break;
- if (xx == -1) {
- fscache_fsproblem(fscache_object_p,
- kmod_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- cfsd_maptbl_destroy(maptbl_object_p);
- dbug_leave("fscache_roll");
- return (0);
- }
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
- fscache_object_p->i_again_seq = entp->dl_seq;
- dbug_assert(fscache_object_p->i_again_seq != 0);
- }
-
- /* get a pointer to the next record to process */
- if (!eof) {
- xx = logfile_entry(logfile_object_p, next_offset,
- &entp);
- if (xx == 1) {
- eof = 1;
- curseq = ULONG_MAX;
- } else if (xx) {
- break;
- } else {
- curseq = entp->dl_seq;
- }
- }
-
- /* if its time to process a deferred modify entry */
- if (fscache_object_p->i_again_seq &&
- (eof || (fscache_object_p->i_again_seq < entp->dl_seq))) {
- xx = logfile_entry(logfile_object_p,
- fscache_object_p->i_again_offset, &entp);
- if (xx)
- break;
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
- curseq = entp->dl_seq;
- fscache_object_p->i_again_offset =
- entp->dl_u.dl_modify.dl_next;
- fscache_object_p->i_again_seq = 0;
- entp->dl_u.dl_modify.dl_next = -1;
- } else if (eof) {
- xx = 0;
- break;
- }
-
- /* else move the offset to the next record */
- else {
- next_offset += entp->dl_len;
- }
-
- /* skip record if not valid */
- if (entp->dl_valid != CFS_DLOG_VAL_COMMITTED)
- continue;
-
- /* process the record */
- xx = fscache_rollone(fscache_object_p, kmod_object_p,
- maptbl_object_p, logfile_object_p, curseq);
- if (xx == ETIMEDOUT) {
- /* timeout error, back to disconnected */
- cfsd_maptbl_destroy(maptbl_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- dbug_print(("info", "timeout error occurred"));
- dbug_leave("fscache_roll");
- return (xx);
- } else if (xx == EIO) {
- break;
- } else if (xx == EAGAIN) {
- continue;
- } else if (xx) {
- /* should never happen */
- dbug_assert(0);
- break;
- } else {
- /* mark record as completed */
- entp->dl_valid = CFS_DLOG_VAL_PROCESSED;
- xx = logfile_sync(logfile_object_p);
- if (xx)
- break;
- }
- }
-
- /* if an unrecoverable error occurred */
- if (xx) {
- dbug_print(("error", "error processing log file"));
- fscache_fsproblem(fscache_object_p, kmod_object_p);
- }
-
- /* dump stats about the hash table */
- maptbl_dumpstats(maptbl_object_p);
-
- /* dump stats about the log file */
- logfile_dumpstats(logfile_object_p);
-
- /* debugging hack, rename the log files */
-
- if (snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_DLOG_FILE) > ((sizeof (backupfile)) - (sizeof (".bak")))) {
- dbug_print(("error", "unable to create backup dlog_file "
- "for %s, path name is too long", namebuf));
- } else {
- /*
- * No need to check return value from snprintf() as
- * the previous check should suffice.
- */
- snprintf(backupfile, sizeof (backupfile), "%s.bak", namebuf);
- if (rename(namebuf, backupfile) == -1) {
- dbug_print(("error",
- "unable to create backup dlog_file"));
- }
- }
-
- if (snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
- fscache_object_p->i_cachepath, fscache_object_p->i_name,
- CACHEFS_DMAP_FILE) > ((sizeof (backupfile)) - (sizeof (".bak")))) {
- dbug_print(("error", "unable to create backup dmap_file "
- "for %s, path name is too long", namebuf));
- } else {
- /*
- * No need to check return value from snprintf() as
- * the previous check should suffice.
- */
- snprintf(backupfile, sizeof (backupfile), "%s.bak", namebuf);
- if (rename(namebuf, backupfile) == -1) {
- dbug_print(("error",
- "unable to create backup dmap_file"));
- }
- }
-
- /* delete the log file */
- /* XXX */
-
- cfsd_maptbl_destroy(maptbl_object_p);
- cfsd_logfile_destroy(logfile_object_p);
- dbug_leave("fscache_roll");
- return (error);
-}
-
-/*
- * fscache_rollone
- *
- * Description:
- * Arguments:
- * kmodp
- * tblp
- * lfp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(kmodp)
- * precond(tblp)
- * precond(lfp)
- */
-int
-fscache_rollone(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p,
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- ulong_t seq)
-{
- cfsd_logelem_object_t *logelem_object_p = NULL;
- cfs_dlog_entry_t *entp;
- int xx;
- char *strp;
-
- dbug_enter("fscache_rollone");
-
- dbug_precond(fscache_object_p);
- dbug_precond(kmod_object_p);
- dbug_precond(maptbl_object_p);
- dbug_precond(logfile_object_p);
-
- entp = logfile_object_p->i_cur_entry;
-
- /* create an object for the appropriate log type */
- switch (entp->dl_op) {
- case CFS_DLOG_CREATE:
- dbug_print(("info", "create"));
- logelem_object_p = cfsd_logelem_create_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_REMOVE:
- dbug_print(("info", "remove"));
- logelem_object_p = cfsd_logelem_remove_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_LINK:
- dbug_print(("info", "link"));
- logelem_object_p = cfsd_logelem_link_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_RENAME:
- dbug_print(("info", "rename"));
- logelem_object_p = cfsd_logelem_rename_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_MKDIR:
- dbug_print(("info", "mkdir"));
- logelem_object_p = cfsd_logelem_mkdir_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_RMDIR:
- dbug_print(("info", "rmdir"));
- logelem_object_p = cfsd_logelem_rmdir_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_SYMLINK:
- dbug_print(("info", "symlink"));
- logelem_object_p = cfsd_logelem_symlink_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_SETATTR:
- dbug_print(("info", "setattr"));
- logelem_object_p = cfsd_logelem_setattr_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_SETSECATTR:
- dbug_print(("info", "setsecattr"));
- logelem_object_p = cfsd_logelem_setsecattr_create(
- maptbl_object_p, logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_MODIFIED:
- dbug_print(("info", "modified"));
- logelem_object_p = cfsd_logelem_modified_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- break;
-
- case CFS_DLOG_MAPFID:
- dbug_print(("info", "mapfid"));
- break;
-
- case CFS_DLOG_TRAILER:
- dbug_print(("info", "trailer"));
- break;
-
- default:
- dbug_assert(0);
- dbug_leave("fscache_rollone");
- return (EIO);
- }
-
- /* do not bother if ignoring the record */
- if (logelem_object_p == NULL) {
- dbug_print(("info", "record ignored"));
- dbug_leave("fscache_rollone");
- return (0);
- }
-
- /* XXX debugging */
- logelem_dump(logelem_object_p);
-
- /* roll the entry */
- xx = logelem_roll(logelem_object_p, &seq);
-
- strp = logelem_object_p->i_messagep;
- if (strp) {
- write(fscache_object_p->i_ofd, strp, strlen(strp));
- dbug_print(("conflict", "%s", strp));
- }
-
- if (xx == EAGAIN) {
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
- xx = fscache_addagain(fscache_object_p, logfile_object_p, seq);
- if (xx == 0)
- xx = EAGAIN;
- }
-
- /* destroy the object */
- cfsd_logelem_destroy(logelem_object_p);
-
- dbug_leave("fscache_rollone");
- return (xx);
-}
-
-/*
- * fscache_addagain
- *
- * Description:
- * Arguments:
- * lfp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(lfp)
- */
-int
-fscache_addagain(cfsd_fscache_object_t *fscache_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- ulong_t nseq)
-{
- int xx;
- cfs_dlog_entry_t *entp;
- off_t noffset;
- off_t prevoff = 0;
- off_t toff;
-
- dbug_enter("fscache_addagain");
-
- dbug_precond(fscache_object_p);
- dbug_precond(logfile_object_p);
-
- entp = logfile_object_p->i_cur_entry;
-
- noffset = logfile_object_p->i_cur_offset;
-
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
- dbug_assert(nseq);
-
- /* both set or both zero */
- dbug_assert((!fscache_object_p->i_again_seq ^
- !fscache_object_p->i_again_offset) == 0);
-
- entp->dl_seq = nseq;
- /* simple case, first one on list */
- if ((fscache_object_p->i_again_seq == 0) ||
- (nseq < fscache_object_p->i_again_seq)) {
- entp->dl_u.dl_modify.dl_next = fscache_object_p->i_again_offset;
- fscache_object_p->i_again_seq = nseq;
- fscache_object_p->i_again_offset = noffset;
- dbug_leave("fscache_addagain");
- return (0);
- }
-
- /* Search until we find the element on the list prior to the */
- /* insertion point. */
- for (toff = fscache_object_p->i_again_offset; toff != 0;
- toff = entp->dl_u.dl_modify.dl_next) {
- /* get pointer to next element on the list */
- xx = logfile_entry(logfile_object_p, toff, &entp);
- if (xx) {
- dbug_leave("fscache_addagain");
- return (xx);
- }
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
-
- /* done if we found the element after the insertion point */
- if (nseq < entp->dl_seq)
- break;
- prevoff = toff;
- }
- dbug_assert(prevoff);
-
- /* get pointer to element prior to the insertion point */
- xx = logfile_entry(logfile_object_p, prevoff, &entp);
- if (xx) {
- dbug_leave("fscache_addagain");
- return (xx);
- }
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
- dbug_assert(entp->dl_u.dl_modify.dl_next == toff);
-
- /* set element to point to our new element */
- entp->dl_u.dl_modify.dl_next = noffset;
-
- /* get pointer to our new element */
- xx = logfile_entry(logfile_object_p, noffset, &entp);
- if (xx) {
- dbug_leave("fscache_addagain");
- return (xx);
- }
- dbug_assert(entp->dl_op == CFS_DLOG_MODIFIED);
-
- /* set it to point to next link or end of list */
- entp->dl_u.dl_modify.dl_next = toff;
-
- /* return success */
- dbug_leave("fscache_addagain");
- return (0);
-}
-
-/*
- * fscache_fsproblem
- *
- * Description:
- * Arguments:
- * kmodp
- * Returns:
- * Preconditions:
- * precond(kmodp)
- */
-void
-fscache_fsproblem(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
-#if 0
- int xx;
-#endif
-
- dbug_enter("fscache_fsproblem");
-
- dbug_precond(fscache_object_p);
- dbug_precond(kmod_object_p);
-
-#if 0
- /* first try to put all modified files in lost+found */
- xx = kmod_lostfoundall(kmod_object_p);
- if (xx) {
- /* if that failed, put file system in read-only mode */
- kmod_rofs(kmod_object_p);
-#endif
- fscache_lock(fscache_object_p);
- fscache_object_p->i_disconnectable = 0;
- fscache_object_p->i_modify++;
- fscache_unlock(fscache_object_p);
-#if 0
- }
-#endif
- dbug_leave("fscache_fsproblem");
-}
-
-/*
- * fscache_changes
- *
- * Description:
- * Used to specify whether or not there are changes to roll to the
- * server.
- * Arguments:
- * tt
- * Returns:
- * Preconditions:
- */
-void
-fscache_changes(cfsd_fscache_object_t *fscache_object_p, int tt)
-{
- dbug_enter("fscache_changes");
- dbug_precond(fscache_object_p);
- fscache_object_p->i_changes = tt;
- fscache_object_p->i_modify++;
- dbug_leave("fscache_changes");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.h
deleted file mode 100644
index 3c1b3c3902..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_fscache.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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 (c) 1994-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _CFSD_FSCACHE_H
-#define _CFSD_FSCACHE_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CFS_MAXMNTOPTLEN MAXPATHLEN * 4
-
-typedef struct cfsd_fscache_object {
- char i_name[MAXNAMELEN]; /* fscache name */
- char i_cachepath[MAXPATHLEN]; /* cache pathname */
- int i_fscacheid; /* fscache identifier */
-
- char i_mntpt[MAXPATHLEN]; /* mount point */
- char i_backfs[MAXPATHLEN * 2]; /* back file system */
- char i_backpath[MAXPATHLEN]; /* back file system path */
- char i_backfstype[MAXNAMELEN]; /* back file system type */
- char i_cfsopt[CFS_MAXMNTOPTLEN]; /* cachefs mount options */
- char i_bfsopt[CFS_MAXMNTOPTLEN]; /* backfs mount options */
-
- mutex_t i_lock; /* synchronizing lock */
- int i_refcnt; /* refs to object */
- volatile int i_disconnectable:1; /* 1 if okay to disconnect */
- volatile int i_mounted:1; /* 1 if fs is mounted */
- volatile int i_threaded:1; /* 1 if thread running */
- volatile int i_connected:1; /* 1 if connected */
- volatile int i_reconcile:1; /* 1 if reconciling */
- volatile int i_changes:1; /* 1 if changes to push back */
- volatile int i_simdis:1; /* 1 means sim disconnect */
- volatile int i_tryunmount:1; /* 1 if should try unmount */
- volatile int i_backunmount:1; /* 1 if need to umount backfs */
- time_t i_time_state; /* time of last dis/connect */
- time_t i_time_mnt; /* time of last u/mount */
- int i_modify; /* changed when modified */
-
- int i_ofd; /* message file descriptor */
-
- thread_t i_threadid; /* id of thread, if running */
- cond_t i_cvwait; /* cond var to wait on */
-
- off_t i_again_offset; /* offset to head modify op */
- int i_again_seq; /* seq num of head modify op */
- struct cfsd_fscache_object *i_next; /* next fscache object */
-} cfsd_fscache_object_t;
-
-cfsd_fscache_object_t *cfsd_fscache_create(const char *name,
- const char *cachepath, int fscacheid);
-void cfsd_fscache_destroy(cfsd_fscache_object_t *fscache_object_p);
-
-void fscache_lock(cfsd_fscache_object_t *fscache_object_p);
-void fscache_unlock(cfsd_fscache_object_t *fscache_object_p);
-
-void fscache_setup(cfsd_fscache_object_t *fscache_object_p);
-void fscache_process(cfsd_fscache_object_t *fscache_object_p);
-int fscache_simdisconnect(cfsd_fscache_object_t *fscache_object_p,
- int disconnect);
-int fscache_unmount(cfsd_fscache_object_t *fscache_object_p, int);
-void fscache_server_alive(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-int fscache_pingserver(cfsd_fscache_object_t *fscache_object_p);
-int fscache_roll(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-int fscache_rollone(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p,
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- ulong_t seq);
-int fscache_addagain(cfsd_fscache_object_t *fscache_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- ulong_t nseq);
-void fscache_fsproblem(cfsd_fscache_object_t *fscache_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-void fscache_changes(cfsd_fscache_object_t *fscache_object_p, int tt);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFSD_FSCACHE_H */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.c
deleted file mode 100644
index 29e49bf6be..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.c
+++ /dev/null
@@ -1,1593 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Source file for the cfsd_kmod class.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-#include <sys/cred.h>
-#include <sys/vnode.h>
-#include <sys/vfs.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include <mdbug/mdbug.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-
-/*
- * copy_cred (copy dl_cred_t followed by a list of gid_t)
- */
-
-static void
-copy_cred(dl_cred_t *dst, const dl_cred_t *src)
-{
- int n = src->cr_ngroups;
-
- if (n > NGROUPS_MAX_DEFAULT)
- n = NGROUPS_MAX_DEFAULT;
-
- (void) memcpy(dst, src, sizeof (*dst) + (n - 1) * sizeof (gid_t));
- dst->cr_ngroups = n;
-}
-
-/*
- * ------------------------------------------------------------
- * cfsd_kmod_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_kmod_object_t *
-cfsd_kmod_create(void)
-{
- cfsd_kmod_object_t *kmod_object_p;
-
- dbug_enter("cfsd_kmod_create");
- kmod_object_p = cfsd_calloc(sizeof (cfsd_kmod_object_t));
-
- kmod_object_p->i_fd = -1;
-
- dbug_leave("cfsd_kmod_create");
- return (kmod_object_p);
-}
-
-/*
- * ------------------------------------------------------------
- * cfsd_kmod_destory
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-
-void
-cfsd_kmod_destroy(cfsd_kmod_object_t *kmod_object_p)
-{
- dbug_enter("cfsd_kmod_destroy");
- dbug_precond(kmod_object_p);
-
- /* clean up old stuff */
- kmod_shutdown(kmod_object_p);
-
- cfsd_free(kmod_object_p);
- dbug_leave("cfsd_kmod_destroy");
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_setup
- *
- * Description:
- * Arguments:
- * path
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(path)
- */
-int
-kmod_setup(cfsd_kmod_object_t *kmod_object_p, const char *path)
-{
- int xx;
- int error;
-
- dbug_enter("kmod_setup");
- dbug_precond(kmod_object_p);
- dbug_precond(path);
-
- /* clean up old stuff */
- kmod_shutdown(kmod_object_p);
-
- /* try to open the file */
- dbug_assert(kmod_object_p->i_fd == -1);
- kmod_object_p->i_fd = open(path, O_RDONLY);
-
- /* return result */
- if (kmod_object_p->i_fd == -1) {
- xx = errno;
- dbug_print(("err", "open of %s failed %d", path, xx));
- } else {
- xx = 0;
- strlcpy(kmod_object_p->i_path, path,
- sizeof (kmod_object_p->i_path));
- dbug_print(("info", "opened %s on fd %d", path,
- kmod_object_p->i_fd));
-
- /* tell the cachefs kmod we are here */
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_DAEMONID,
- NULL, 0, NULL, 0);
- if (xx) {
- error = errno;
- dbug_print(("ioctl", "daemonid error %d", error));
- }
- }
-
- dbug_leave("kmod_setup");
- return (xx);
-}
-
-/*
- * kmod_shutdown
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-kmod_shutdown(cfsd_kmod_object_t *kmod_object_p)
-{
- dbug_enter("kmod_shutdown");
- dbug_precond(kmod_object_p);
-
- /* close down the old fd if necessary */
- if (kmod_object_p->i_fd >= 0) {
- if (close(kmod_object_p->i_fd))
- dbug_print(("err", "cannot close kmod fd, %d", errno));
- }
- kmod_object_p->i_fd = -1;
- dbug_leave("kmod_shutdown");
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_xwait
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns ...
- * Preconditions:
- */
-int
-kmod_xwait(cfsd_kmod_object_t *kmod_object_p)
-{
- int xx;
- int error = 0;
-
- dbug_enter("kmod_xwait");
- dbug_precond(kmod_object_p);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_XWAIT, NULL, 0, NULL, 0);
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_leave("kmod_xwait");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_stateget
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns ...
- * Preconditions:
- */
-int
-kmod_stateget(cfsd_kmod_object_t *kmod_object_p)
-{
- int state;
- int xx;
-
- dbug_enter("kmod_stateget");
- dbug_precond(kmod_object_p);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATEGET, NULL, 0, &state,
- sizeof (state));
- dbug_print(("ioctl", "returns %d, state %d", xx, state));
- if (xx == -1) {
- /* XXX do what? */
- dbug_assert(0);
- }
- dbug_leave("kmod_stateget");
- return (state);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_stateset
- *
- * Description:
- * Arguments:
- * state
- * Returns:
- * Returns ...
- * Preconditions:
- */
-int
-kmod_stateset(cfsd_kmod_object_t *kmod_object_p, int state)
-{
- int xx;
- int error = 0;
-
- dbug_enter("kmod_stateset");
- dbug_precond(kmod_object_p);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_STATESET, &state,
- sizeof (state), NULL, 0);
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, state set to %d", xx, state));
- dbug_leave("kmod_stateset");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_exists
- *
- * Description:
- * Arguments:
- * cidp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(cidp)
- */
-int
-kmod_exists(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp)
-{
- int xx;
- int error = 0;
-
- dbug_enter("kmod_exists");
- dbug_precond(kmod_object_p);
- dbug_precond(cidp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_EXISTS, cidp,
- sizeof (cfs_cid_t), NULL, 0);
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " cid %08x", cidp->cid_fileno));
- dbug_leave("kmod_exists");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_lostfound
- *
- * Description:
- * Arguments:
- * cidp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(cidp)
- */
-int
-kmod_lostfound(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp,
- const char *namep, char *newnamep)
-{
- cachefsio_lostfound_arg_t info;
- cachefsio_lostfound_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_lostfound");
- dbug_precond(kmod_object_p);
- dbug_precond(cidp);
- dbug_precond(namep);
- dbug_precond(newnamep);
- dbug_precond(strlen(namep) < (size_t)MAXNAMELEN);
-
- info.lf_cid = *cidp;
- strlcpy(info.lf_name, namep, sizeof (info.lf_name));
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_LOSTFOUND, &info,
- sizeof (info), &ret, sizeof (ret));
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " cid %08x", cidp->cid_fileno));
- dbug_print(("ioctl", " suggested name '%s'", namep));
- if (xx == 0) {
- dbug_print(("ioctl", " new name '%s'", ret.lf_name));
- dbug_assert(strlen(ret.lf_name) < (size_t)MAXNAMELEN);
- if (newnamep)
- strlcpy(newnamep, ret.lf_name, MAXNAMELEN);
- }
- dbug_leave("kmod_lostfound");
- return (error);
-}
-
-#if 0
-/*
- * ------------------------------------------------------------
- * kmod_lostfoundall
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns ...
- * Preconditions:
- */
-int
-kmod_lostfoundall(cfsd_kmod_object_t *kmod_object_p)
-{
- int error = 0;
- int xx = -1;
-
- dbug_enter("kmod_lostfoundall");
- dbug_precond(kmod_object_p);
-
- /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_LOSTFOUNDALL, 0); */
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_leave("kmod_lostfoundall");
- return (error);
-}
-/*
- * kmod_rofs
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns ...
- * Preconditions:
- */
-int
-kmod_rofs(cfsd_kmod_object_t *kmod_object_p)
-{
- int error = 0;
- int xx = -1;
-
- dbug_enter("kmod_rofs");
- dbug_precond(kmod_object_p);
-
- /* xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_ROFS, 0); */
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_leave("kmod_rofs");
- return (error);
-}
-#endif
-
-/*
- * kmod_rootfid
- *
- * Description:
- * Fills in fidp with the fid of the root of the file system.
- * Arguments:
- * fidp
- * Returns:
- * Returns 0 for success, errno value for an error
- * Preconditions:
- * precond(fidp)
- */
-int
-kmod_rootfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp)
-{
- int error = 0;
- int xx;
-
- dbug_enter("kmod_rootfid");
- dbug_precond(kmod_object_p);
- dbug_precond(fidp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_ROOTFID, NULL, 0, fidp,
- sizeof (*fidp));
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_leave("kmod_rootfid");
- return (error);
-}
-
-
-/*
- * kmod_getstats
- *
- * Description:
- * Arguments:
- * gsp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(gsp)
- */
-int
-kmod_getstats(cfsd_kmod_object_t *kmod_object_p, cachefsio_getstats_t *gsp)
-{
- int error = 0;
- int xx;
-
- dbug_enter("kmod_getstats");
- dbug_precond(kmod_object_p);
-
- dbug_precond(gsp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETSTATS, NULL, 0, gsp,
- sizeof (*gsp));
- if (xx)
- error = errno;
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", "total blocks %d", gsp->gs_total));
- dbug_print(("ioctl", "gc blocks %d", gsp->gs_gc));
- dbug_print(("ioctl", "active blocks %d", gsp->gs_active));
- dbug_print(("ioctl", "packed blocks %d", gsp->gs_packed));
- dbug_print(("ioctl", "free blocks %d", gsp->gs_free));
- dbug_print(("ioctl", "gctime %x", gsp->gs_gctime));
- dbug_leave("kmod_getstats");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_getinfo
- *
- * Description:
- * Arguments:
- * filep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(filep)
- * precond(infop)
- */
-int
-kmod_getinfo(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep,
- cachefsio_getinfo_t *infop)
-{
- int error = 0;
- int xx;
-
- dbug_enter("kmod_getinfo");
- dbug_precond(kmod_object_p);
-
- dbug_precond(filep);
- dbug_precond(infop);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETINFO, filep,
- sizeof (*filep), infop, sizeof (*infop));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " file cid %08x", filep->cid_fileno));
- if (xx == 0) {
- dbug_print(("ioctl", " modified %d seq %d",
- infop->gi_modified, infop->gi_seq));
- dbug_print(("ioctl", " name \"%s\"", infop->gi_name));
- dbug_print(("ioctl", " parent cid %08x",
- infop->gi_pcid.cid_fileno));
- infop->gi_attr.va_mask = AT_ALL;
- kmod_print_attr(&infop->gi_attr);
- }
- dbug_leave("kmod_getinfo");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_cidtofid
- *
- * Description:
- * Arguments:
- * cidp
- * fidp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(cidp)
- * precond(fidp)
- */
-int
-kmod_cidtofid(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp,
- cfs_fid_t *fidp)
-{
- int error = 0;
- int xx;
-
- dbug_enter("kmod_cidtofid");
- dbug_precond(kmod_object_p);
-
- dbug_precond(cidp);
- dbug_precond(fidp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_CIDTOFID, cidp, sizeof (*cidp),
- fidp, sizeof (*fidp));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " cid %08x", cidp->cid_fileno));
- if (xx == 0) {
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf));
- }
- dbug_leave("kmod_cidtofid");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_getattrfid
- *
- * Description:
- * Arguments:
- * fidp
- * credp
- * vattrp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(fidp)
- * precond(credp)
- * precond(vattrp)
- */
-int
-kmod_getattrfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp,
- dl_cred_t *credp, vattr_t *vattrp)
-{
- int error = 0;
- int xx;
- cachefsio_getattrfid_t info;
-
- dbug_enter("kmod_getattrfid");
- dbug_precond(kmod_object_p);
-
- dbug_precond(fidp);
- dbug_precond(credp);
- dbug_precond(vattrp);
-
- info.cg_backfid = *fidp;
-
- copy_cred(&info.cg_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRFID, &info,
- sizeof (info), vattrp, sizeof (*vattrp));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf));
- kmod_print_cred(credp);
- if (xx == 0) {
- vattrp->va_mask = AT_ALL;
- kmod_print_attr(vattrp);
- }
- dbug_leave("kmod_getattrfid");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_getattrname
- *
- * Description:
- * Arguments:
- * dirp
- * name
- * credp
- * vattrp
- * filep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirp)
- * precond(name)
- * precond(credp)
- */
-int
-kmod_getattrname(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp,
- const char *name, dl_cred_t *credp, vattr_t *vattrp, cfs_fid_t *filep)
-{
- cachefsio_getattrname_arg_t info;
- cachefsio_getattrname_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_getattrname");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirp);
- dbug_precond(name);
- dbug_precond(credp);
-
- info.cg_dir = *dirp;
- dbug_assert(strlen(name) < (size_t)MAXNAMELEN);
- strlcpy(info.cg_name, name, sizeof (info.cg_name));
- copy_cred(&info.cg_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_GETATTRNAME, &info,
- sizeof (info), &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirp);
- dbug_print(("ioctl", " dir fid \"%s\"", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", info.cg_name));
- kmod_print_cred(credp);
- if (xx == 0) {
- ret.cg_attr.va_mask = AT_ALL;
- kmod_print_attr(&ret.cg_attr);
- kmod_format_fid(kmod_object_p, &ret.cg_fid);
- dbug_print(("ioctl", " file fid \"%s\"",
- kmod_object_p->i_fidbuf));
- if (vattrp)
- *vattrp = ret.cg_attr;
- if (filep)
- *filep = ret.cg_fid;
- }
- dbug_leave("kmod_getattrname");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_create
- *
- * Description:
- * Arguments:
- * dirp
- * namep
- * vattrp
- * exclusive
- * mode
- * credp
- * newfidp
- * mtimep
- * ctimep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirp)
- * precond(namep)
- * precond(vattrp)
- * precond(credp)
- */
-int
-kmod_create(cfsd_kmod_object_t *kmod_object_p,
- cfs_fid_t *dirp,
- const char *namep,
- const cfs_cid_t *cidp,
- vattr_t *vattrp,
- int exclusive,
- int mode,
- dl_cred_t *credp,
- cfs_fid_t *newfidp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *mtimep)
-{
- cachefsio_create_arg_t info;
- cachefsio_create_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_create");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirp);
- dbug_precond(namep);
- dbug_precond(vattrp);
- dbug_precond(credp);
-
- info.cr_backfid = *dirp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.cr_name, namep, sizeof (info.cr_name));
- if (cidp) {
- info.cr_cid = *cidp;
- } else {
- info.cr_cid.cid_fileno = 0;
- info.cr_cid.cid_flags = 0;
- }
- info.cr_va = *vattrp;
- info.cr_exclusive = exclusive;
- info.cr_mode = mode;
- copy_cred(&info.cr_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_CREATE, &info, sizeof (info),
- &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirp);
- dbug_print(("ioctl", " dir fid \"%s\"", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s', exclusive %d, mode 0%o",
- namep, exclusive, mode));
- kmod_print_attr(vattrp);
- kmod_print_cred(credp);
- if (xx == 0) {
- if (newfidp)
- *newfidp = ret.cr_newfid;
- if (ctimep)
- *ctimep = ret.cr_ctime;
- if (mtimep)
- *mtimep = ret.cr_mtime;
- kmod_format_fid(kmod_object_p, &ret.cr_newfid);
- dbug_print(("ioctl", " created file fid \"%s\"",
- kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " ctime %x %x",
- ret.cr_ctime.tv_sec, ret.cr_ctime.tv_nsec));
- dbug_print(("ioctl", " mtime %x %x",
- ret.cr_mtime.tv_sec, ret.cr_mtime.tv_nsec));
- }
- dbug_leave("kmod_create");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_pushback
- *
- * Description:
- * Arguments:
- * filep
- * fidp
- * credp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(filep)
- * precond(fidp)
- * precond(credp)
- */
-int
-kmod_pushback(cfsd_kmod_object_t *kmod_object_p,
- cfs_cid_t *filep,
- cfs_fid_t *fidp,
- dl_cred_t *credp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *mtimep,
- int update)
-{
- cachefsio_pushback_arg_t info;
- cachefsio_pushback_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_pushback");
- dbug_precond(kmod_object_p);
-
- dbug_precond(filep);
- dbug_precond(fidp);
- dbug_precond(credp);
-
- /* note: update is no longer used */
-
- info.pb_cid = *filep;
- info.pb_fid = *fidp;
- copy_cred(&info.pb_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_PUSHBACK, &info, sizeof (info),
- &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " cid %08x", filep->cid_fileno));
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf));
- kmod_print_cred(credp);
- if (xx == 0) {
- if (ctimep)
- *ctimep = ret.pb_ctime;
- if (mtimep)
- *mtimep = ret.pb_mtime;
- dbug_print(("ioctl", " ctime %x %x",
- ret.pb_ctime.tv_sec, ret.pb_ctime.tv_nsec));
- dbug_print(("ioctl", " mtime %x %x",
- ret.pb_mtime.tv_sec, ret.pb_mtime.tv_nsec));
- }
- dbug_leave("kmod_pushback");
- return (error);
-}
-
-
-/*
- * ------------------------------------------------------------
- * kmod_rename
- *
- * Description:
- * Arguments:
- * olddir
- * oldname
- * newdir
- * newname
- * credp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(olddir)
- * precond(oldname)
- * precond(newdir)
- * precond(newname)
- * precond(credp)
- */
-int
-kmod_rename(cfsd_kmod_object_t *kmod_object_p,
- cfs_fid_t *olddir,
- const char *oldname,
- cfs_fid_t *newdir,
- const char *newname,
- const cfs_cid_t *cidp,
- dl_cred_t *credp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *delctimep,
- const cfs_cid_t *delcidp)
-{
- cachefsio_rename_arg_t info;
- cachefsio_rename_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_rename");
- dbug_precond(kmod_object_p);
-
- dbug_precond(olddir);
- dbug_precond(oldname);
- dbug_precond(newdir);
- dbug_precond(newname);
- dbug_precond(credp);
- dbug_precond(ctimep);
-
- info.rn_olddir = *olddir;
- dbug_assert(strlen(oldname) < (size_t)MAXNAMELEN);
- strlcpy(info.rn_oldname, oldname, sizeof (info.rn_oldname));
- info.rn_newdir = *newdir;
- dbug_assert(strlen(newname) < (size_t)MAXNAMELEN);
- strlcpy(info.rn_newname, newname, sizeof (info.rn_newname));
- info.rn_cid = *cidp;
- copy_cred(&info.rn_cred, credp);
- info.rn_del_getctime = delctimep ? 1 : 0;
- info.rn_del_cid = *delcidp;
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_RENAME, &info, sizeof (info),
- &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, olddir);
- dbug_print(("ioctl", " old dir fid \"%s\"", kmod_object_p->i_fidbuf));
- kmod_format_fid(kmod_object_p, newdir);
- dbug_print(("ioctl", " new dir fid \"%s\"", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " old name '%s' new name '%s'",
- oldname, newname));
- kmod_print_cred(credp);
- if (xx == 0) {
- *ctimep = ret.rn_ctime;
- dbug_print(("ioctl", " ctime %x %x",
- ctimep->tv_sec, ctimep->tv_nsec));
- if (delctimep) {
- *delctimep = ret.rn_del_ctime;
- dbug_print(("ioctl", " del ctime %x %x",
- delctimep->tv_sec, delctimep->tv_nsec));
- }
- }
- dbug_leave("kmod_rename");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_setattr
- *
- * Description:
- * Arguments:
- * fidp
- * vattrp
- * flags
- * credp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(fidp)
- * precond(vattrp)
- * precond(credp)
- */
-int
-kmod_setattr(cfsd_kmod_object_t *kmod_object_p,
- cfs_fid_t *fidp,
- const cfs_cid_t *cidp,
- vattr_t *vattrp,
- int flags,
- dl_cred_t *credp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *mtimep)
-{
- cachefsio_setattr_arg_t info;
- cachefsio_setattr_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_setattr");
- dbug_precond(kmod_object_p);
-
- dbug_precond(fidp);
- dbug_precond(cidp);
- dbug_precond(vattrp);
- dbug_precond(credp);
- dbug_precond(ctimep);
- dbug_precond(mtimep);
-
- info.sa_backfid = *fidp;
- info.sa_cid = *cidp;
- info.sa_vattr = *vattrp;
- info.sa_flags = flags;
- copy_cred(&info.sa_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETATTR, &info, sizeof (info),
- &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- dbug_print(("ioctl", " flags 0x%x", flags));
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf));
- kmod_print_attr(vattrp);
- kmod_print_cred(credp);
- if (xx == 0) {
- *ctimep = ret.sa_ctime;
- *mtimep = ret.sa_mtime;
- dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec,
- ctimep->tv_nsec));
- dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec,
- mtimep->tv_nsec));
- }
- dbug_leave("kmod_setattr");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_setsecattr
- *
- * Description:
- * Arguments:
- * fidp
- * aclcnt
- * dfaclcnt
- * acl
- * flags
- * credp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(fidp)
- * precond(acl)
- * precond(credp)
- * precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES)
- */
-int
-kmod_setsecattr(cfsd_kmod_object_t *kmod_object_p,
- cfs_fid_t *fidp,
- const cfs_cid_t *cidp,
- ulong_t mask,
- int aclcnt,
- int dfaclcnt,
- const aclent_t *acl,
- dl_cred_t *credp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *mtimep)
-{
- cachefsio_setsecattr_arg_t info;
- cachefsio_setsecattr_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_setsecattr");
- dbug_precond(kmod_object_p);
-
- dbug_precond(fidp);
- dbug_precond(cidp);
- dbug_precond(acl);
- dbug_precond(credp);
- dbug_precond(ctimep);
- dbug_precond(mtimep);
- dbug_precond(aclcnt + dfaclcnt <= MAX_ACL_ENTRIES);
-
- info.sc_backfid = *fidp;
- info.sc_cid = *cidp;
- info.sc_mask = mask;
- info.sc_aclcnt = aclcnt;
- info.sc_dfaclcnt = dfaclcnt;
- memcpy(&info.sc_acl, acl, (aclcnt + dfaclcnt) * sizeof (aclent_t));
- copy_cred(&info.sc_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_SETSECATTR, &info,
- sizeof (info), &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid \"%s\"", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " aclcnt %d dfaclcnt %d", aclcnt, dfaclcnt));
- kmod_print_cred(credp);
- if (xx == 0) {
- *ctimep = ret.sc_ctime;
- *mtimep = ret.sc_mtime;
- dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec,
- ctimep->tv_nsec));
- dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec,
- mtimep->tv_nsec));
- }
- dbug_leave("kmod_setsecattr");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_remove
- *
- * Description:
- * Arguments:
- * fidp
- * namep
- * credp
- * ctimep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(fidp)
- * precond(namep)
- * precond(credp)
- */
-int
-kmod_remove(cfsd_kmod_object_t *kmod_object_p,
- const cfs_fid_t *fidp,
- const cfs_cid_t *cidp,
- const char *namep,
- const dl_cred_t *credp,
- cfs_timestruc_t *ctimep)
-{
- cachefsio_remove_t info;
- int len;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_remove");
- dbug_precond(kmod_object_p);
-
- dbug_precond(fidp);
- dbug_precond(cidp);
- dbug_precond(namep);
- dbug_precond(credp);
-
- info.rm_fid = *fidp;
- info.rm_cid = *cidp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.rm_name, namep, sizeof (info.rm_name));
- copy_cred(&info.rm_cred, credp);
- info.rm_getctime = ctimep ? 1 : 0;
-
- if (ctimep)
- len = sizeof (*ctimep);
- else
- len = 0;
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_REMOVE, &info, sizeof (info),
- ctimep, len);
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, fidp);
- dbug_print(("ioctl", " fid '%s'", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", namep));
- kmod_print_cred(credp);
- if ((xx == 0) && ctimep) {
- dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec,
- ctimep->tv_nsec));
- }
- dbug_leave("kmod_remove");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_link
- *
- * Description:
- * Arguments:
- * dirfidp
- * namep
- * filefidp
- * credp
- * ctimep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirfidp)
- * precond(namep)
- * precond(filefidp)
- * precond(credp)
- */
-int
-kmod_link(cfsd_kmod_object_t *kmod_object_p,
- const cfs_fid_t *dirfidp,
- const char *namep,
- const cfs_fid_t *filefidp,
- const cfs_cid_t *cidp,
- const dl_cred_t *credp,
- cfs_timestruc_t *ctimep)
-{
- cachefsio_link_t info;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_link");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirfidp);
- dbug_precond(namep);
- dbug_precond(filefidp);
- dbug_precond(cidp);
- dbug_precond(credp);
- dbug_precond(ctimep);
-
- info.ln_dirfid = *dirfidp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.ln_name, namep, sizeof (info.ln_name));
- info.ln_filefid = *filefidp;
- info.ln_cid = *cidp;
- copy_cred(&info.ln_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_LINK, &info, sizeof (info),
- ctimep, sizeof (*ctimep));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirfidp);
- dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", namep));
- kmod_format_fid(kmod_object_p, filefidp);
- dbug_print(("ioctl", " file fid '%s'", kmod_object_p->i_fidbuf));
- kmod_print_cred(credp);
- if (xx == 0) {
- dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec,
- ctimep->tv_nsec));
- }
- dbug_leave("kmod_link");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_mkdir
- *
- * Description:
- * Arguments:
- * dirfidp
- * namep
- * vattrp
- * credp
- * newfidp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirfidp)
- * precond(namep)
- * precond(vattrp)
- * precond(credp)
- * precond(newfidp)
- */
-int
-kmod_mkdir(cfsd_kmod_object_t *kmod_object_p,
- const cfs_fid_t *dirfidp,
- const char *namep,
- const cfs_cid_t *cidp,
- const vattr_t *vattrp,
- const dl_cred_t *credp,
- cfs_fid_t *newfidp)
-{
- cachefsio_mkdir_t info;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_mkdir");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirfidp);
- dbug_precond(namep);
- dbug_precond(cidp);
- dbug_precond(vattrp);
- dbug_precond(credp);
- dbug_precond(newfidp);
-
- info.md_dirfid = *dirfidp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.md_name, namep, sizeof (info.md_name));
- info.md_cid = *cidp;
- info.md_vattr = *vattrp;
- copy_cred(&info.md_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_MKDIR, &info, sizeof (info),
- newfidp, sizeof (*newfidp));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirfidp);
- dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", namep));
- kmod_print_attr(vattrp);
- kmod_print_cred(credp);
- if (xx == 0) {
- kmod_format_fid(kmod_object_p, newfidp);
- dbug_print(("ioctl", " file fid '%s'",
- kmod_object_p->i_fidbuf));
- }
- dbug_leave("kmod_mkdir");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_rmdir
- *
- * Description:
- * Arguments:
- * dirfidp
- * namep
- * credp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirfidp)
- * precond(namep)
- * precond(credp)
- */
-int
-kmod_rmdir(cfsd_kmod_object_t *kmod_object_p,
- const cfs_fid_t *dirfidp,
- const char *namep,
- const dl_cred_t *credp)
-{
- cachefsio_rmdir_t info;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_rmdir");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirfidp);
- dbug_precond(namep);
- dbug_precond(credp);
-
- info.rd_dirfid = *dirfidp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.rd_name, namep, sizeof (info.rd_name));
- copy_cred(&info.rd_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_RMDIR, &info, sizeof (info),
- NULL, 0);
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirfidp);
- dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", namep));
- kmod_print_cred(credp);
- dbug_leave("kmod_rmdir");
- return (error);
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_symlink
- *
- * Description:
- * Arguments:
- * dirfidp
- * namep
- * linkvalp
- * vattrp
- * credp
- * ctimep
- * mtimep
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(dirfidp)
- * precond(namep)
- * precond(linkvalp)
- * precond(vattrp)
- * precond(credp)
- * precond(ctimep)
- * precond(mtimep)
- */
-int
-kmod_symlink(cfsd_kmod_object_t *kmod_object_p,
- const cfs_fid_t *dirfidp,
- const char *namep,
- const cfs_cid_t *cidp,
- const char *linkvalp,
- const vattr_t *vattrp,
- const dl_cred_t *credp,
- cfs_fid_t *newfidp,
- cfs_timestruc_t *ctimep,
- cfs_timestruc_t *mtimep)
-{
- cachefsio_symlink_arg_t info;
- cachefsio_symlink_return_t ret;
- int error = 0;
- int xx;
-
- dbug_enter("kmod_symlink");
- dbug_precond(kmod_object_p);
-
- dbug_precond(dirfidp);
- dbug_precond(namep);
- dbug_precond(cidp);
- dbug_precond(linkvalp);
- dbug_precond(vattrp);
- dbug_precond(credp);
- dbug_precond(newfidp);
- dbug_precond(ctimep);
- dbug_precond(mtimep);
-
- info.sy_dirfid = *dirfidp;
- dbug_assert(strlen(namep) < (size_t)MAXNAMELEN);
- strlcpy(info.sy_name, namep, sizeof (info.sy_name));
- dbug_assert(strlen(linkvalp) < (size_t)MAXPATHLEN);
- info.sy_cid = *cidp;
- strlcpy(info.sy_link, linkvalp, sizeof (info.sy_link));
- info.sy_vattr = *vattrp;
- copy_cred(&info.sy_cred, credp);
-
- xx = kmod_doioctl(kmod_object_p, CFSDCMD_SYMLINK, &info, sizeof (info),
- &ret, sizeof (ret));
- if (xx)
- error = errno;
-
- dbug_print(("ioctl", "returns %d, error %d", xx, error));
- kmod_format_fid(kmod_object_p, dirfidp);
- dbug_print(("ioctl", " dir fid '%s'", kmod_object_p->i_fidbuf));
- dbug_print(("ioctl", " name '%s'", namep));
- dbug_print(("ioctl", " link '%s'", linkvalp));
- kmod_print_attr(vattrp);
- kmod_print_cred(credp);
- if (xx == 0) {
- *ctimep = ret.sy_ctime;
- *mtimep = ret.sy_mtime;
- *newfidp = ret.sy_newfid;
- dbug_print(("ioctl", " ctime %x %x", ctimep->tv_sec,
- ctimep->tv_nsec));
- dbug_print(("ioctl", " mtime %x %x", mtimep->tv_sec,
- mtimep->tv_nsec));
- kmod_format_fid(kmod_object_p, newfidp);
- dbug_print(("ioctl", " child fid '%s'",
- kmod_object_p->i_fidbuf));
- }
- dbug_leave("kmod_symlink");
- return (error);
-}
-#ifndef DBUG_OFF
-/*
- * ------------------------------------------------------------
- * kmod_format_fid
- *
- * Description:
- * Arguments:
- * fidp
- * Returns:
- * Preconditions:
- * precond(fidp)
- */
-void
-kmod_format_fid(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp)
-{
- uint_t val;
- int index;
- char format[10];
- kmod_object_p->i_fidbuf[0] = '\0';
-
- for (index = 0; index < (int)fidp->fid_len; index += sizeof (uint_t)) {
- memcpy(&val, &fidp->fid_data[index], sizeof (uint_t));
- snprintf(format, sizeof (format), "%08x ", val);
- strlcat(kmod_object_p->i_fidbuf, format,
- sizeof (kmod_object_p->i_fidbuf));
- }
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_print_cred
- *
- * Description:
- * Arguments:
- * credp
- * Returns:
- * Preconditions:
- * precond(credp)
- */
-void
-kmod_print_cred(const dl_cred_t *credp)
-{
- char buf[100];
- char format[10];
- int xx;
-
- dbug_enter("kmod_print_cred");
- dbug_precond(credp);
-
- buf[0] = '\0';
- dbug_print(("ioctl", "credentials"));
- dbug_print(("ioctl", " uid %d, gid %d",
- credp->cr_uid, credp->cr_gid));
- dbug_print(("ioctl", " ruid %d, rgid %d, suid %d, sgid %d",
- credp->cr_ruid, credp->cr_rgid,
- credp->cr_suid, credp->cr_sgid));
-
- for (xx = 0; xx < credp->cr_ngroups; xx++) {
- snprintf(format, sizeof (format), " %d", credp->cr_groups[xx]);
- strlcat(buf, format, sizeof (buf));
- }
-
- dbug_print(("ioctl", " ngroups %d, %s", credp->cr_ngroups, buf));
- dbug_leave("kmod_print_cred");
-}
-
-/*
- * ------------------------------------------------------------
- * kmod_print_attr
- *
- * Description:
- * Arguments:
- * vattrp
- * Returns:
- * Preconditions:
- * precond(vattrp)
- */
-void
-kmod_print_attr(const vattr_t *vp)
-{
- dbug_enter("kmod_print_attr");
- dbug_precond(vp);
-
- dbug_print(("ioctl", "attributes"));
- dbug_print(("ioctl", " mask 0x%x", vp->va_mask));
- if (vp->va_mask & AT_TYPE)
- dbug_print(("ioctl", " type %d", vp->va_type));
- if (vp->va_mask & AT_MODE)
- dbug_print(("ioctl", " mode 0%o", vp->va_mode));
- if (vp->va_mask & AT_UID)
- dbug_print(("ioctl", " uid %d", vp->va_uid));
- if (vp->va_mask & AT_GID)
- dbug_print(("ioctl", " gid %d", vp->va_gid));
- if (vp->va_mask & AT_FSID)
- dbug_print(("ioctl", " fsid %08x", vp->va_fsid));
- if (vp->va_mask & AT_NODEID)
- dbug_print(("ioctl", " nodeid %08x", vp->va_nodeid));
- if (vp->va_mask & AT_NLINK)
- dbug_print(("ioctl", " nlink %d", vp->va_nlink));
- if (vp->va_mask & AT_SIZE)
- dbug_print(("ioctl", " size %d", vp->va_size));
- if (vp->va_mask & AT_ATIME)
- dbug_print(("ioctl", " atime %08x %08x",
- vp->va_atime.tv_sec, vp->va_atime.tv_nsec));
- if (vp->va_mask & AT_MTIME)
- dbug_print(("ioctl", " mtime %08x %08x",
- vp->va_mtime.tv_sec, vp->va_mtime.tv_nsec));
- if (vp->va_mask & AT_CTIME)
- dbug_print(("ioctl", " ctime %08x %08x",
- vp->va_ctime.tv_sec, vp->va_ctime.tv_nsec));
- if (vp->va_mask & AT_RDEV)
- dbug_print(("ioctl", " rdev %08x", vp->va_rdev));
- if (vp->va_mask & AT_BLKSIZE)
- dbug_print(("ioctl", " blksize %08x", vp->va_blksize));
- if (vp->va_mask & AT_NBLOCKS)
- dbug_print(("ioctl", " nblocks %d", vp->va_nblocks));
- if (vp->va_mask & AT_SEQ)
- dbug_print(("ioctl", " seq %d", vp->va_seq));
- dbug_leave("kmod_print_attr");
-}
-#endif /* DBUG_OFF */
-/*
- * kmod_doioctl
- *
- * Description:
- * Helper routine for others in this file. Just packages up
- * arguments and does the ioctl operation.
- * Arguments:
- * cmd
- * sdata
- * slen
- * rdata
- * rlen
- * Returns:
- * Returns the result of the ioctl operation.
- * Preconditions:
- */
-int
-kmod_doioctl(cfsd_kmod_object_t *kmod_object_p,
- enum cfsdcmd_cmds cmd,
- void *sdata,
- int slen,
- void *rdata,
- int rlen)
-{
- cachefsio_dcmd_t dcmd;
- int xx;
-
- dbug_enter("kmod_doioctl");
- dbug_precond(kmod_object_p);
- dcmd.d_cmd = cmd;
- dcmd.d_sdata = sdata;
- dcmd.d_slen = slen;
- dcmd.d_rdata = rdata;
- dcmd.d_rlen = rlen;
- dbug_print(("ioctl", "about to do cmd = %d", cmd));
- xx = ioctl(kmod_object_p->i_fd, CACHEFSIO_DCMD, &dcmd);
- if (xx) {
- dbug_print(("ioctl", "ioctl errno = %d", errno));
- }
- dbug_leave("kmod_doioctl");
- return (xx);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.h
deleted file mode 100644
index 425ca12dc0..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_kmod.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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 1994-1997,2002-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * cfsd_kmod.h
- *
- * Include file for the cfsd_kmod class.
- *
- */
-
-#ifndef _CFSD_KMOD
-#define _CFSD_KMOD
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-typedef struct cfsd_kmod_object {
- char i_path[MAXPATHLEN]; /* path to root of file system */
- int i_fd; /* file descriptor of i_path */
-#ifndef DBUG_OFF
- char i_fidbuf[1024]; /* for formatted fid */
-#endif
-}cfsd_kmod_object_t;
-
-cfsd_kmod_object_t *cfsd_kmod_create(void);
-void cfsd_kmod_destroy(cfsd_kmod_object_t *kmod_object_p);
-int kmod_setup(cfsd_kmod_object_t *kmod_object_p, const char *path);
-void kmod_shutdown(cfsd_kmod_object_t *kmod_object_p);
-int kmod_xwait(cfsd_kmod_object_t *kmod_object_p);
-int kmod_stateget(cfsd_kmod_object_t *kmod_object_p);
-int kmod_stateset(cfsd_kmod_object_t *kmod_object_p, int state);
-int kmod_exists(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp);
-int kmod_lostfound(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *cidp,
- const char *namep, char *newnamep);
-int kmod_lostfoundall(cfsd_kmod_object_t *kmod_object_p);
-int kmod_rofs(cfsd_kmod_object_t *kmod_object_p);
-int kmod_rootfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp);
-int kmod_getstats(cfsd_kmod_object_t *kmod_object_p, cachefsio_getstats_t *gsp);
-int kmod_getinfo(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep,
- cachefsio_getinfo_t *infop);
-int kmod_cidtofid(cfsd_kmod_object_t *kmod_object_p,
- cfs_cid_t *cidp, cfs_fid_t *fidp);
-int kmod_getattrfid(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp,
- dl_cred_t *credp, cfs_vattr_t *vattrp);
-int kmod_getattrname(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp,
- const char *name, dl_cred_t *credp, cfs_vattr_t *vattrp, cfs_fid_t *filep);
-int kmod_create(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *dirp,
- const char *namep, const cfs_cid_t *cidp, cfs_vattr_t *vattrp,
- int exclusive, int mode, dl_cred_t *credp, cfs_fid_t *newfidp,
- timestruc_t *ctimep, timestruc_t *mtimep);
-int kmod_pushback(cfsd_kmod_object_t *kmod_object_p, cfs_cid_t *filep,
- cfs_fid_t *fidp, dl_cred_t *credp, timestruc_t *ctimep, timestruc_t *mtimep,
- int update);
-int kmod_rename(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *olddir,
- const char *oldname, cfs_fid_t *newdir, const char *newname,
- const cfs_cid_t *cidp, dl_cred_t *credp, timestruc_t *ctimep,
- timestruc_t *delctimep, const cfs_cid_t *delcidp);
-int kmod_setattr(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp,
- const cfs_cid_t *cidp, cfs_vattr_t *vattrp, int flags, dl_cred_t *credp,
- timestruc_t *ctimep, timestruc_t *mtimep);
-int kmod_setsecattr(cfsd_kmod_object_t *kmod_object_p, cfs_fid_t *fidp,
- const cfs_cid_t *cidp, ulong_t mask, int aclcnt, int dfaclcnt,
- const aclent_t *acl, dl_cred_t *credp, timestruc_t *ctimep,
- timestruc_t *mtimep);
-int kmod_remove(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp,
- const cfs_cid_t *cidp, const char *namep, const dl_cred_t *credp,
- timestruc_t *ctimep);
-int kmod_link(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp,
- const char *namep, const cfs_fid_t *filefidp, const cfs_cid_t *cidp,
- const dl_cred_t *credp, timestruc_t *ctimep);
-int kmod_mkdir(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp,
- const char *namep, const cfs_cid_t *cidp, const cfs_vattr_t *vattrp,
- const dl_cred_t *credp, cfs_fid_t *newfidp);
-int kmod_rmdir(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp,
- const char *namep, const dl_cred_t *credp);
-int kmod_symlink(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *dirfidp,
- const char *namep, const cfs_cid_t *cidp, const char *linkvalp,
- const cfs_vattr_t *vattrp, const dl_cred_t *credp, cfs_fid_t *newfidp,
- timestruc_t *ctimep, timestruc_t *mtimep);
-#ifndef DBUG_OFF
-void kmod_format_fid(cfsd_kmod_object_t *kmod_object_p, const cfs_fid_t *fidp);
-void kmod_print_cred(const dl_cred_t *credp);
-void kmod_print_attr(const vattr_t *vp);
-#else
-#define kmod_format_fid(A, B) 0
-#define kmod_print_cred(A) 0
-#define kmod_print_attr(A) 0
-#endif /* DBUG_OFF */
-int kmod_doioctl(cfsd_kmod_object_t *kmod_object_p, enum cfsdcmd_cmds cmd,
- void *sdata, int slen, void *rdata, int rlen);
-
-#endif /* _CFSD_KMOD */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.c
deleted file mode 100644
index 010e69137c..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.c
+++ /dev/null
@@ -1,3422 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods of the cfsd_logelem* classes.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <synch.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libintl.h>
-#include <errno.h>
-#include <locale.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
-#include <sys/cred.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include <mdbug/mdbug.h>
-
-#include "cfsd.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_kmod.h"
-#include "cfsd_logelem.h"
-
-
-#define dl_ctime dl_times.tm_ctime
-#define dl_mtime dl_times.tm_mtime
-#define TIMECHANGE(A, B) (memcmp(&A, &B, sizeof (A)) != 0)
-#define X_OPTIMIZED -2
-#define X_CONFLICT -3
-
-
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_create
- *
- * Description:
- * Constructor for the cfsd_logelem abstract base class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
-
- dbug_enter("cfsd_logelem_create");
-
- logelem_object_p = cfsd_calloc(sizeof (cfsd_logelem_object_t));
- logelem_object_p->i_maptbl_object_p = maptbl_object_p;
- logelem_object_p->i_logfile_object_p = logfile_object_p;
- logelem_object_p->i_kmod_object_p = kmod_object_p;
-
- logelem_object_p->i_entp = logfile_object_p->i_cur_entry;
- logelem_object_p->i_offset = logfile_object_p->i_cur_offset;
- dbug_assert(logelem_object_p->i_entp);
- logelem_object_p->i_messagep[0] = '\0';
- logelem_object_p->i_type = NO_OBJECT_TYPE;
-
- dbug_leave("cfsd_logelem_create");
- return (logelem_object_p);
-}
-
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_destroy
- *
- * Description:
- * Destructor for the cfsd_logelem abstract base class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-
-void
-cfsd_logelem_destroy(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("cfsd_logelem_destroy");
- cfsd_free(logelem_object_p);
- dbug_leave("cfsd_logelem_destroy");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_print_cred
- *
- * Description:
- * Arguments:
- * credp
- * Returns:
- * Preconditions:
- * precond(credp)
- */
-
-void
-logelem_print_cred(dl_cred_t *credp)
-{
- char buf[12 * NGROUPS_MAX_DEFAULT];
- char format[10];
- int xx;
-
- dbug_enter("logelem_print_cred");
- dbug_precond(credp);
-
- buf[0] = '\0';
- dbug_print(("dump", "credentials"));
- dbug_print(("dump", " uid %d, gid %d",
- credp->cr_uid, credp->cr_gid));
- dbug_print(("dump", " ruid %d, rgid %d, suid %d, sgid %d",
- credp->cr_ruid, credp->cr_rgid,
- credp->cr_suid, credp->cr_sgid));
-
- for (xx = 0; xx < credp->cr_ngroups; xx++) {
- sprintf(format, " %d", credp->cr_groups[xx]);
- strlcat(buf, format, sizeof (buf));
- }
- dbug_print(("dump", " ngroups %d, %s", credp->cr_ngroups, buf));
- dbug_leave("logelem_print_cred");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_print_attr
- *
- * Description:
- * Arguments:
- * vattrp
- * Returns:
- * Preconditions:
- * precond(vattrp)
- */
-
-void
-logelem_print_attr(cfs_vattr_t *vp)
-{
- dbug_enter("logelem_print_attr");
- dbug_precond(vp);
-
- dbug_print(("dump", "attributes"));
- dbug_print(("dump", " mask 0x%x", vp->va_mask));
- if (vp->va_mask & AT_TYPE)
- dbug_print(("dump", " type %d", vp->va_type));
- if (vp->va_mask & AT_MODE)
- dbug_print(("dump", " mode 0%o", vp->va_mode));
- if (vp->va_mask & AT_UID)
- dbug_print(("dump", " uid %d", vp->va_uid));
- if (vp->va_mask & AT_GID)
- dbug_print(("dump", " gid %d", vp->va_gid));
- if (vp->va_mask & AT_FSID)
- dbug_print(("dump", " fsid %08x", vp->va_fsid));
- if (vp->va_mask & AT_NODEID)
- dbug_print(("dump", " nodeid %08x", vp->va_nodeid));
- if (vp->va_mask & AT_NLINK)
- dbug_print(("dump", " nlink %d", vp->va_nlink));
- if (vp->va_mask & AT_SIZE)
- dbug_print(("dump", " size %d", vp->va_size));
- if (vp->va_mask & AT_ATIME)
- dbug_print(("dump", " atime %08x %08x",
- vp->va_atime.tv_sec, vp->va_atime.tv_nsec));
- if (vp->va_mask & AT_MTIME)
- dbug_print(("dump", " mtime %08x %08x",
- vp->va_mtime.tv_sec, vp->va_mtime.tv_nsec));
- if (vp->va_mask & AT_CTIME)
- dbug_print(("dump", " ctime %08x %08x",
- vp->va_ctime.tv_sec, vp->va_ctime.tv_nsec));
- if (vp->va_mask & AT_RDEV)
- dbug_print(("dump", " rdev %08x", vp->va_rdev));
- if (vp->va_mask & AT_BLKSIZE)
- dbug_print(("dump", " blksize %08x", vp->va_blksize));
- if (vp->va_mask & AT_NBLOCKS)
- dbug_print(("dump", " nblocks %d", vp->va_nblocks));
- if (vp->va_mask & AT_SEQ)
- dbug_print(("dump", " seq %d", vp->va_seq));
- dbug_leave("logelem_print_attr");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_format_fid
- *
- * Description:
- * Arguments:
- * fidp
- * Returns:
- * Preconditions:
- * precond(fidp)
- */
-
-void
-logelem_format_fid(cfsd_logelem_object_t *logelem_object_p, cfs_fid_t *fidp)
-{
- uint_t val;
- int index;
- char format[10];
- logelem_object_p->i_fidbuf[0] = '\0';
-
- for (index = 0; index < (int)fidp->fid_len; index += sizeof (uint_t)) {
- memcpy(&val, &fidp->fid_data[index], sizeof (uint_t));
- snprintf(format, sizeof (format), "%08x ", val);
- strlcat(logelem_object_p->i_fidbuf, format,
- sizeof (logelem_object_p->i_fidbuf));
- }
-}
-
-
-/*
- * -----------------------------------------------------------------
- * logelem_lostfound
- *
- * Description:
- * Called when there is a conflict on a file.
- * Arguments:
- * cidp cid of file to move to lost+found
- * pcidp parent cid if known, else null
- * namep name of file if known, else null
- * Returns:
- * Returns 0 for success, EIO if file could not be moved.
- * Preconditions:
- * precond(cidp)
- */
-
-int
-logelem_lostfound(cfsd_logelem_object_t *logelem_object_p,
- cfs_cid_t *cidp,
- cfs_cid_t *pcidp,
- const char *namep,
- dl_cred_t *cred)
-{
- struct cfs_dlog_mapping_space map;
- int xx;
- cfs_fid_t *fp, dirfid;
- cachefsio_getinfo_t ginfo;
- char namebuf[MAXNAMELEN];
- int gotdirfid = 0;
- int wrotefile = 0;
- char *np;
- char namebuf2[MAXNAMELEN * 3];
- int foundname = 0;
- int index;
- char *machnamep;
- struct utsname info;
- int len;
- cfs_fid_t filefid;
- struct cfs_vattr vattr;
- char newname[MAXNAMELEN];
- char mesgbuf[MAXNAMELEN * 3];
-#define MAXTRIES 10
-
- dbug_enter("logelem_lostfound");
- dbug_precond(cidp);
- dbug_precond(cred);
-
- /* make an alternate name for the file */
- if (namep == NULL)
- sprintf(namebuf, "fileno_%"PRIx64, cidp->cid_fileno);
-
- /* get info about the file from the cache */
- xx = kmod_getinfo(logelem_object_p->i_kmod_object_p, cidp, &ginfo);
- if (xx) {
- if (namep == NULL) {
- namep = namebuf;
- }
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (0);
- }
-
- /* determine what we want to call this file */
- if (namep == NULL) {
- if (ginfo.gi_name[0] == '\0')
- namep = namebuf;
- else
- namep = ginfo.gi_name;
- }
-
- /* if not a regular file or not modified */
- if ((ginfo.gi_attr.va_type != VREG) || !ginfo.gi_modified) {
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (0);
- }
-
- /* get the fid of the parent directory from the passed in cid */
- if (pcidp) {
- /* see if we have a valid mapping for the parent cid */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- *pcidp, &map);
- if (xx == -1) {
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (EIO);
- }
- if ((xx == 0) && (0 < map.ms_fid)) {
- xx = logfile_offset(
- logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (EIO);
- }
- if (fp->fid_len) {
- gotdirfid = 1;
- dirfid = *fp;
- }
- }
-
- /* otherwise try to get the fid from the cache */
- if (gotdirfid == 0) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- pcidp, &dirfid);
- if (xx == 0)
- gotdirfid = 1;
- }
- }
-
- /* if not parent fid yet, try to get one from the dir in the cache */
- if ((gotdirfid == 0) && ginfo.gi_pcid.cid_fileno) {
- /* see if we have a valid mapping for the cache parent cid */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- ginfo.gi_pcid, &map);
- if (xx == -1) {
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (EIO);
- }
- if ((xx == 0) && (0 < map.ms_fid)) {
- xx = logfile_offset(
- logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (EIO);
- }
- if (fp->fid_len) {
- gotdirfid = 1;
- dirfid = *fp;
- }
- }
-
- /* otherwise try to get the fid from the cache */
- if (gotdirfid == 0) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &ginfo.gi_pcid, &dirfid);
- if (xx == 0)
- gotdirfid = 1;
- }
- }
-
-
- /* if we found a parent directory */
- if (gotdirfid) {
- /* get the host name */
- xx = uname(&info);
- if (xx == -1)
- machnamep = "client";
- else
- machnamep = info.nodename;
-
- /* find a name we can call this file */
- for (index = 0; index < MAXTRIES; index++) {
- /* construct the name */
- snprintf(namebuf2, sizeof (namebuf2),
- "%s.conflict.%s.%x", machnamep, namep, index);
- len = strlen(namebuf2) + 1;
- if (len > MAXNAMELEN)
- np = &namebuf2[len - MAXNAMELEN];
- else
- np = namebuf2;
-
- /* see if it exists */
- xx = kmod_getattrname(
- logelem_object_p->i_kmod_object_p,
- &dirfid, np, cred, NULL, NULL);
-
- /* timeout error, pass the error back up */
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_lostfound");
- return (ETIMEDOUT);
- }
- /* file does not exist, so try to use it */
- if (xx == ENOENT) {
- foundname = 1;
- break;
- }
-
- /* any other error on the directory, give up */
- if (xx)
- break;
- }
-
- /* if we found a name */
- if (foundname) {
- /* set up attributes for the file */
- vattr.va_type = VREG;
- vattr.va_mode = ginfo.gi_attr.va_mode;
- vattr.va_mask = AT_TYPE | AT_MODE | AT_SIZE;
- vattr.va_size = 0;
-
- /* create the file */
- xx = kmod_create(logelem_object_p->i_kmod_object_p,
- &dirfid, np, NULL, &vattr, NONEXCL, VWRITE,
- cred, &filefid, NULL, NULL);
- if (xx == 0) {
- /* write the file */
- xx = kmod_pushback(
- logelem_object_p->i_kmod_object_p,
- cidp, &filefid, cred, NULL, NULL, 0);
- if (xx == 0) {
- wrotefile = 1;
- snprintf(mesgbuf, sizeof (mesgbuf),
- gettext("File %s renamed as %s on "
- "server."),
- namep, np);
- logelem_resolution(logelem_object_p,
- mesgbuf);
- }
- }
- }
-
- }
-
- /* if we could not write the file to the server, move to lost+found */
- if (wrotefile == 0) {
-
- /* move the file to lost+found */
- xx = kmod_lostfound(logelem_object_p->i_kmod_object_p,
- cidp, namep, newname);
- if (xx == EINVAL) {
- dbug_assert(0);
- logelem_log_opskipped(logelem_object_p, namep);
- dbug_leave("logelem_lostfound");
- return (0);
- } else if (xx) {
- snprintf(mesgbuf, sizeof (mesgbuf),
- gettext("Cannot move %s to lost+found. "),
- namep);
- strlcat(mesgbuf,
- gettext("Run cachefs fsck on the file system."),
- sizeof (mesgbuf));
- logelem_resolution(logelem_object_p, mesgbuf);
- return (EIO);
- } else {
- snprintf(mesgbuf, sizeof (mesgbuf),
- gettext("Moved %s to %s/%s/%s."), namep,
- logelem_object_p->i_kmod_object_p->i_path,
- CACHEFS_LOSTFOUND_NAME, newname);
- logelem_resolution(logelem_object_p, mesgbuf);
- }
- }
-
- /* set the mapping to indicate conflict */
- map.ms_cid = *cidp;
- map.ms_fid = X_CONFLICT;
- map.ms_times = 0;
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_lostfound");
- return (EIO);
- }
- dbug_leave("logelem_lostfound");
- return (xx);
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_problem
- *
- * Description:
- * Specifies the problem string.
- * Pass a variable number of strings.
- * They are concatinated together to form the message.
- * Terminate the argument list with NULL.
- * Arguments:
- * strp
- * Returns:
- * Preconditions:
- * precond(strp)
- */
-
-void
-logelem_problem(cfsd_logelem_object_t *logelem_object_p, char *strp)
-{
- dbug_enter("logelem_problem");
- dbug_precond(strp);
-
- logelem_message(logelem_object_p, gettext("cachefsd: Problem: "), strp);
- dbug_leave("logelem_problem");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_resolution
- *
- * Description:
- * Specifies the resolution string.
- * Pass a variable number of strings.
- * They are concatinated together to form the message.
- * Terminate the argument list with NULL.
- * Arguments:
- * strp
- * Returns:
- * Preconditions:
- * precond(strp)
- */
-
-void
-logelem_resolution(cfsd_logelem_object_t *logelem_object_p, char *strp)
-{
- dbug_enter("logelem_resolution");
- dbug_precond(strp);
-
- logelem_message(logelem_object_p, gettext("cachefsd: Resolution: "),
- strp);
- dbug_leave("logelem_resolution");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_message_append
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- * precond(strp1)
- * precond(strp1)
- */
-
-void
-logelem_message_append(char *strp1, char *strp2)
-{
- dbug_enter("logelem_message_append");
- if ((strlen(strp1) + strlen(strp2)) < (size_t)CFSDMesgMax)
- strcat(strp1, strp2);
- else {
- fprintf(stderr,
- gettext("cachefsd: log element message truncated\n"));
- strncat(strp1, strp2, CFSDMesgMax - (strlen(strp1) + 1));
- }
- dbug_leave("logelem_message_append");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_message
- *
- * Description:
- * Arguments:
- * prefix
- * strp
- * Returns:
- * Preconditions:
- * precond(prefix)
- * precond(strp)
- */
-
-void
-logelem_message(cfsd_logelem_object_t *logelem_object_p,
- char *prefix,
- char *strp)
-{
- dbug_enter("logelem_message");
-
- dbug_precond(prefix);
- dbug_precond(strp);
-
- logelem_message_append(logelem_object_p->i_messagep, prefix);
- logelem_message_append(logelem_object_p->i_messagep, strp);
- logelem_message_append(logelem_object_p->i_messagep, "\n");
- dbug_leave("logelem_message");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_log_opfailed
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_log_opfailed(cfsd_logelem_object_t *logelem_object_p,
- char *opp, char *info, const char *namep, int xx)
-{
- char mesgbuf[CFSDStrMax];
- char errorbuf[CFSDStrMax];
-
- /*
- * XXX need to change this so we don't assemble the message,
- * this violates localization.
- */
- snprintf(mesgbuf, sizeof (mesgbuf), gettext("%s failed"), opp);
- if (namep) {
- strlcat(mesgbuf, gettext(" on "), sizeof (mesgbuf));
- strlcat(mesgbuf, namep, sizeof (mesgbuf));
- }
- strlcat(mesgbuf, ".", sizeof (mesgbuf));
- if (info) {
- strlcat(mesgbuf, " ", sizeof (mesgbuf));
- strlcat(mesgbuf, info, sizeof (mesgbuf));
- strlcat(mesgbuf, ".", sizeof (mesgbuf));
- }
- if (xx) {
- snprintf(errorbuf, sizeof (errorbuf),
- gettext(" Error: %s."), strerror(xx));
- strlcat(mesgbuf, errorbuf, sizeof (mesgbuf));
- }
- logelem_problem(logelem_object_p, mesgbuf);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_log_opskipped
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_log_opskipped(cfsd_logelem_object_t *logelem_object_p,
- const char *namep)
-{
- char mesgbuf[CFSDStrMax];
-
- snprintf(mesgbuf, sizeof (mesgbuf),
- gettext("Operation on %s skipped."), namep);
- logelem_resolution(logelem_object_p, mesgbuf);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_log_timelogmesg
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_log_timelogmesg(cfsd_logelem_object_t *logelem_object_p,
- char *opp, const char *namep, char *mesgp, int time_log)
-{
- char mesgbuf[CFSDStrMax];
-
- /*
- * XXX need to change this so we don't assemble the message,
- * this violates localization.
- */
- snprintf(mesgbuf, sizeof (mesgbuf), gettext("%s failed"), opp);
- if (namep) {
- strlcat(mesgbuf, gettext(" on "), sizeof (mesgbuf));
- strlcat(mesgbuf, namep, sizeof (mesgbuf));
- }
- strlcat(mesgbuf, ".", sizeof (mesgbuf));
- if (mesgp) {
- strlcat(mesgbuf, mesgp, sizeof (mesgbuf));
- strlcat(mesgbuf, ".", sizeof (mesgbuf));
- }
- strlcat(mesgbuf, " ", sizeof (mesgbuf));
- switch (time_log) {
- case 0:
- strlcat(mesgbuf, gettext("while rolling log."),
- sizeof (mesgbuf));
- break;
- case 1:
- strlcat(mesgbuf, gettext("while disconnected."),
- sizeof (mesgbuf));
- break;
-
- default:
- strlcat(mesgbuf, gettext("while unknown operation."),
- sizeof (mesgbuf));
- break;
- }
-
- logelem_problem(logelem_object_p, mesgbuf);
-}
-
-/*
- * cfsd_logelem_setattr_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-
-cfsd_logelem_object_t *
-cfsd_logelem_setattr_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_setattr_object_t *setattr_object_p;
-
- dbug_enter("cfsd_logelem_setattr_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = SETATTR_OBJECT_TYPE;
-
- setattr_object_p = SETATTR_OBJECT_PTR(logelem_object_p);
- setattr_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_setattr;
- dbug_leave("cfsd_logelem_setattr_create");
- return (logelem_object_p);
-}
-
-/*
- * cfsd_logelem_setsecattr_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-cfsd_logelem_object_t *
-cfsd_logelem_setsecattr_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_setsecattr_object_t *setsecattr_object_p;
-
- dbug_enter("cfsd_logelem_setsecattr_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = SETSECATTR_OBJECT_TYPE;
-
- setsecattr_object_p = SETSECATTR_OBJECT_PTR(logelem_object_p);
- setsecattr_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_setsecattr;
- setsecattr_object_p->i_acl =
- (const aclent_t *)
- ((caddr_t)setsecattr_object_p->i_up->dl_buffer +
- ((off_t)(setsecattr_object_p->i_up->dl_cred.cr_ngroups - 1)
- * (off_t)sizeof (gid_t)));
- dbug_leave("cfsd_logelem_setsecattr_create");
- return (logelem_object_p);
-}
-/*
- * cfsd_logelem_create_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_create_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_create_object_t *create_object_p;
-
- dbug_enter("cfsd_logelem_create_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = CREATE_OBJECT_TYPE;
-
- create_object_p = CREATE_OBJECT_PTR(logelem_object_p);
- create_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_create;
- create_object_p->i_namep =
- create_object_p->i_up->dl_buffer +
- ((create_object_p->i_up->dl_cred.cr_ngroups - 1) *
- sizeof (gid_t));
- dbug_leave("cfsd_logelem_create_create");
- return (logelem_object_p);
-}
-
-/*
- * cfsd_logelem_remove_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_remove_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_remove_object_t *remove_object_p;
-
- dbug_enter("cfsd_logelem_remove_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = REMOVE_OBJECT_TYPE;
-
- remove_object_p = REMOVE_OBJECT_PTR(logelem_object_p);
- remove_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_remove;
- remove_object_p->i_namep =
- remove_object_p->i_up->dl_buffer +
- ((remove_object_p->i_up->dl_cred.cr_ngroups - 1) *
- sizeof (gid_t));
- dbug_leave("cfsd_logelem_remove_create");
- return (logelem_object_p);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_rmdir_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_rmdir_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_rmdir_object_t *rmdir_object_p;
-
- dbug_enter("cfsd_logelem_rmdir_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = RMDIR_OBJECT_TYPE;
-
- rmdir_object_p = RMDIR_OBJECT_PTR(logelem_object_p);
- rmdir_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_rmdir;
- rmdir_object_p->i_namep =
- rmdir_object_p->i_up->dl_buffer +
- ((rmdir_object_p->i_up->dl_cred.cr_ngroups - 1)
- * sizeof (gid_t));
- dbug_leave("cfsd_logelem_rmdir_create");
- return (logelem_object_p);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_mkdir_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_mkdir_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_mkdir_object_t *mkdir_object_p;
-
- dbug_enter("cfsd_logelem_mkdir_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = MKDIR_OBJECT_TYPE;
-
- mkdir_object_p = MKDIR_OBJECT_PTR(logelem_object_p);
- mkdir_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_mkdir;
- mkdir_object_p->i_namep =
- mkdir_object_p->i_up->dl_buffer +
- ((mkdir_object_p->i_up->dl_cred.cr_ngroups - 1) *
- sizeof (gid_t));
- dbug_leave("cfsd_logelem_mkdir_create");
- return (logelem_object_p);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_link_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_link_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_link_object_t *link_object_p;
-
- dbug_enter("cfsd_logelem_link_create");
-
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = LINK_OBJECT_TYPE;
-
- link_object_p = LINK_OBJECT_PTR(logelem_object_p);
- link_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_link;
- link_object_p->i_namep =
- link_object_p->i_up->dl_buffer +
- ((link_object_p->i_up->dl_cred.cr_ngroups - 1)
- * sizeof (gid_t));
- dbug_leave("cfsd_logelem_link_create");
- return (logelem_object_p);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_symlink_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_symlink_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_symlink_object_t *symlink_object_p;
-
- dbug_enter("cfsd_logelem_symlink_create");
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = SYMLINK_OBJECT_TYPE;
-
- symlink_object_p = SYMLINK_OBJECT_PTR(logelem_object_p);
- symlink_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_symlink;
- symlink_object_p->i_namep =
- symlink_object_p->i_up->dl_buffer +
- ((symlink_object_p->i_up->dl_cred.cr_ngroups - 1) *
- sizeof (gid_t));
- symlink_object_p->i_contentsp =
- symlink_object_p->i_namep +
- strlen(symlink_object_p->i_namep) + 1;
- dbug_leave("cfsd_logelem_symlink_create");
- return (logelem_object_p);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_logelem_rename_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_rename_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_rename_object_t *rename_object_p;
-
- dbug_enter("cfsd_logelem_rename_create");
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = RENAME_OBJECT_TYPE;
-
- rename_object_p = RENAME_OBJECT_PTR(logelem_object_p);
- rename_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_rename;
- rename_object_p->i_orignamep =
- rename_object_p->i_up->dl_buffer +
- ((rename_object_p->i_up->dl_cred.cr_ngroups - 1) *
- sizeof (gid_t));
- rename_object_p->i_newnamep =
- rename_object_p->i_orignamep +
- strlen(rename_object_p->i_orignamep) + 1;
- dbug_leave("cfsd_logelem_rename_create");
- return (logelem_object_p);
-}
-/*
- * cfsd_logelem_modified_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_modified_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_modified_object_t *modified_object_p;
-
- dbug_enter("cfsd_logelem_modified_create");
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = MODIFIED_OBJECT_TYPE;
-
- modified_object_p = MODIFIED_OBJECT_PTR(logelem_object_p);
- modified_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_modify;
- dbug_leave("cfsd_logelem_modified_create");
- return (logelem_object_p);
-}
-/*
- * cfsd_logelem_mapfid
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-cfsd_logelem_object_t *
-cfsd_logelem_mapfid_create(cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p)
-{
- cfsd_logelem_object_t *logelem_object_p;
- cfsd_logelem_mapfid_object_t *mapfid_object_p;
-
- dbug_enter("cfsd_logelem_mapfid_create");
- logelem_object_p = cfsd_logelem_create(maptbl_object_p,
- logfile_object_p, kmod_object_p);
- logelem_object_p->i_type = MAPFID_OBJECT_TYPE;
-
- mapfid_object_p = MAPFID_OBJECT_PTR(logelem_object_p);
- mapfid_object_p->i_up =
- &logelem_object_p->i_entp->dl_u.dl_mapfid;
- dbug_leave("cfsd_logelem_mapfid_create");
- return (logelem_object_p);
-}
-/*
- * logelem_roll
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int retval = 0;
-
- dbug_enter("logelem_roll");
-
- switch (logelem_object_p->i_type) {
-
- case NO_OBJECT_TYPE:
- dbug_assert(0);
- retval = EIO;
- break;
-
- case SETATTR_OBJECT_TYPE:
- retval = logelem_roll_setattr(logelem_object_p, seqp);
- break;
-
- case SETSECATTR_OBJECT_TYPE:
- retval = logelem_roll_setsecattr(logelem_object_p, seqp);
- break;
-
- case CREATE_OBJECT_TYPE:
- retval = logelem_roll_create(logelem_object_p, seqp);
- break;
-
- case REMOVE_OBJECT_TYPE:
- retval = logelem_roll_remove(logelem_object_p, seqp);
- break;
-
- case RMDIR_OBJECT_TYPE:
- retval = logelem_roll_rmdir(logelem_object_p, seqp);
- break;
-
- case MKDIR_OBJECT_TYPE:
- retval = logelem_roll_mkdir(logelem_object_p, seqp);
- break;
-
- case LINK_OBJECT_TYPE:
- retval = logelem_roll_link(logelem_object_p, seqp);
- break;
-
- case SYMLINK_OBJECT_TYPE:
- retval = logelem_roll_symlink(logelem_object_p, seqp);
- break;
-
- case RENAME_OBJECT_TYPE:
- retval = logelem_roll_rename(logelem_object_p, seqp);
- break;
-
- case MODIFIED_OBJECT_TYPE:
- retval = logelem_roll_modified(logelem_object_p, seqp);
- break;
-
- case MAPFID_OBJECT_TYPE:
- retval = logelem_roll_mapfid(logelem_object_p);
- break;
-
- default:
- dbug_assert(0);
- retval = EIO;
- }
- dbug_leave("logelem_roll");
- return (retval);
-}
-/*
- * logelem_roll_setattr
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_setattr(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
-
- int xx;
- cfs_fid_t filefid, *fp;
- struct cfs_dlog_mapping_space map;
- cfs_dlog_tm_t *tmp;
- cfs_timestruc_t ctime, mtime;
- int time_log;
- cfs_vattr_t va;
- int conflict = 0;
-
- dbug_enter("logelem_roll_setattr");
-
- /* get the mapping for this cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_setattr");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = SETATTR_OBJECT(logelem_object_p).i_up->dl_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_setattr");
- return (0);
- }
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_setattr");
- return (0);
- }
- /* if we have a fid in the mapping */
- if (map.ms_fid) {
- /* get the fid */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("error getting logfile offset"), NULL, xx);
- dbug_leave("logelem_roll_setattr");
- return (EIO);
- }
- filefid = *fp;
- dbug_assert(filefid.fid_len);
- }
-
- /* else get the fid from the cache */
- else {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid, &filefid);
- if (xx == ENOENT) {
- dbug_leave("logelem_roll_setattr");
- return (0);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("File is no longer in the cache"),
- NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setattr");
- return (xx);
- }
- }
-
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("error getting logfile offset"), NULL, xx);
- dbug_leave("logelem_roll_setattr");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = SETATTR_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = SETATTR_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the attributes of the file from the back fs */
- xx = kmod_getattrfid(logelem_object_p->i_kmod_object_p, &filefid,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred, &va);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_setattr");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("error getting attributes"), NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setattr");
- return (xx);
- }
-
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Setattr",
- NULL, gettext("File modified"), time_log);
- conflict = 1;
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Setattr",
- NULL, gettext("File changed"), time_log);
- conflict = 1;
- }
-
- /* if a conflict was detected */
- if (conflict) {
- logelem_log_opfailed(logelem_object_p, "Setattr",
- gettext("file conflict"), NULL, 0);
- xx = logelem_lostfound(logelem_object_p,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setattr");
- return (xx);
- }
-
- /* now do the setattr, get the new times */
- xx = kmod_setattr(logelem_object_p->i_kmod_object_p,
- &filefid, &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_attrs,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_flags,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_ctime,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_mtime);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_setattr");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setattr", NULL,
- NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setattr");
- return (xx);
- }
-
- /* update the mapping to point to the new times */
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_setattr.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_setattr");
- return (EIO);
- }
- dbug_leave("logelem_roll_setattr");
- return (0);
-}
-
-/*
- * logelem_roll_setsecattr
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_setsecattr(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t filefid, *fp;
- struct cfs_dlog_mapping_space map;
- cfs_dlog_tm_t *tmp;
- cfs_timestruc_t ctime, mtime;
- int time_log;
- cfs_vattr_t va;
- int conflict = 0;
-
- dbug_enter("logelem_roll_setsecattr");
- /* get the mapping for this cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_setsecattr");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_setsecattr");
- return (0);
- }
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_setsecattr");
- return (0);
- }
- /* if we have a fid in the mapping */
- if (map.ms_fid) {
- /* get the fid */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_setsecattr");
- return (EIO);
- }
- filefid = *fp;
- dbug_assert(filefid.fid_len);
- }
-
- /* else get the fid from the cache */
- else {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- &filefid);
- if (xx == ENOENT) {
- dbug_leave("logelem_roll_setsecattr");
- return (0);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("File is no longer in the cache"),
- NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setsecattr");
- return (xx);
- }
- }
-
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_setsecattr");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = SETSECATTR_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = SETSECATTR_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the attributes of the file from the back fs */
- xx = kmod_getattrfid(logelem_object_p->i_kmod_object_p, &filefid,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred, &va);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_setsecattr");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("error getting attributes"), NULL, 0);
- xx = logelem_lostfound(logelem_object_p,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setsecattr");
- return (xx);
- }
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Setsecattr",
- NULL, gettext("File modified"), time_log);
- conflict = 1;
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Setsecattr",
- NULL, gettext("File changed"), time_log);
- conflict = 1;
- }
-
- /* if a conflict was detected */
- if (conflict) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr",
- gettext("file conflict"), NULL, 0);
- xx = logelem_lostfound(logelem_object_p,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setsecattr");
- return (xx);
- }
-
- /* now do the setsecattr, get the new times */
- xx = kmod_setsecattr(logelem_object_p->i_kmod_object_p, &filefid,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_mask,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_aclcnt,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_dfaclcnt,
- SETSECATTR_OBJECT(logelem_object_p).i_acl,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_ctime,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_mtime);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_setsecattr");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Setsecattr", NULL,
- NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_setsecattr");
- return (xx);
- }
-
- /* update the mapping to point to the new times */
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_setsecattr.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_setsecattr");
- return (EIO);
- }
- dbug_leave("logelem_roll_setsecattr");
- return (0);
-}
-
-/*
- * logelem_roll_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_create(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid;
- struct cfs_dlog_mapping_space map;
- cfs_fid_t filefid2;
- cfs_vattr_t va;
-
- dbug_enter("logelem_roll_create");
- /* if the file existed at the time of this operation */
- dbug_assert(CREATE_OBJECT(logelem_object_p).i_up->dl_exists == 0);
-
- /* see if the file no longer exists in the cache */
-#if 0
- xx = kmod_exists(logelem_object_p->i_kmod_object_p,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid);
- if (xx) {
- dbug_assert(xx == ENOENT);
-
- /* indicate ignore future operations on file */
- map.ms_cid = CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid;
- map.ms_fid = X_OPTIMIZED;
- map.ms_times = 0;
- xx = maptbl_set(maptbl_object_p, &map, 1);
- dbug_leave("logelem_roll_create");
- if (xx) {
- dbug_leave("logelem_roll_create");
- return (EIO);
- }
- dbug_leave("logelem_roll_create");
- return (0);
- }
-#endif
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Create",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_create");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (map.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Create",
- gettext("Parent directory no longer exists"),
- CREATE_OBJECT(logelem_object_p).i_namep, xx);
- xx = logelem_lostfound(logelem_object_p,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid,
- &
- CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- CREATE_OBJECT(logelem_object_p).i_namep,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_create");
- return (xx);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Create",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_create");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* if the file exists on the back fs */
- xx = kmod_getattrname(logelem_object_p->i_kmod_object_p, &dirfid,
- CREATE_OBJECT(logelem_object_p).i_namep,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_cred, &va, &filefid2);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_create");
- return (ETIMEDOUT);
- }
-
- /* if the file exists on the back file system */
- if (xx == 0) {
- logelem_log_opfailed(logelem_object_p, "Create",
- gettext("File created while disconnected"),
- CREATE_OBJECT(logelem_object_p).i_namep, xx);
- xx = logelem_lostfound(logelem_object_p,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- CREATE_OBJECT(logelem_object_p).i_namep,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_create");
- return (xx);
- }
-
- /* do the create */
- xx = kmod_create(logelem_object_p->i_kmod_object_p, &dirfid,
- CREATE_OBJECT(logelem_object_p).i_namep,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_attrs, NONEXCL,
- CREATE_OBJECT(logelem_object_p).i_up->dl_mode,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_cred,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_fid,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_ctime,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_mtime);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_create");
- return (ETIMEDOUT);
- }
- /* create failed move to lost and found */
- logelem_log_opfailed(logelem_object_p, "Create", NULL,
- CREATE_OBJECT(logelem_object_p).i_namep, xx);
- xx = logelem_lostfound(logelem_object_p,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- CREATE_OBJECT(logelem_object_p).i_namep,
- &CREATE_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_create");
- return (xx);
- }
-
- /* update the mapping to point to the new fid and times */
- map.ms_cid = CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid;
- map.ms_fid = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_create.dl_fid);
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_create.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_create");
- return (EIO);
- }
- dbug_leave("logelem_roll_create");
- return (0);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_roll_remove
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-
-int
-logelem_roll_remove(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
-
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid;
- struct cfs_dlog_mapping_space map, dirmap;
- cfs_timestruc_t ctime, mtime;
- int time_log;
- cfs_dlog_tm_t *tmp;
- cfs_fid_t filefid2;
- cfs_vattr_t va;
- cfs_timestruc_t *ctimep;
-
- dbug_enter("logelem_roll_remove");
- /* get the mapping for this cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_child_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_remove");
- return (EIO);
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = REMOVE_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_remove");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = REMOVE_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = REMOVE_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_parent_cid, &dirmap);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_remove");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (dirmap.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &REMOVE_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("Parent directory no longer exists"),
- REMOVE_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- dirmap.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_remove");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* get file attributes */
- xx = kmod_getattrname(logelem_object_p->i_kmod_object_p, &dirfid,
- REMOVE_OBJECT(logelem_object_p).i_namep,
- &REMOVE_OBJECT(logelem_object_p).i_up->dl_cred,
- &va, &filefid2);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_remove");
- return (ETIMEDOUT);
- }
-
- /* if the file no longer exists on the back fs */
- if (xx == ENOENT) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("File no longer exists."),
- REMOVE_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- } else if (xx) {
- logelem_log_opfailed(logelem_object_p, "Remove",
- gettext("Cannot get file attributes from server"),
- REMOVE_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Remove",
- REMOVE_OBJECT(logelem_object_p).i_namep,
- gettext("File modified"), time_log);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Remove",
- REMOVE_OBJECT(logelem_object_p).i_namep,
- gettext("File changed"), time_log);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- ctimep = (va.va_nlink > 1) ?
- &REMOVE_OBJECT(logelem_object_p).i_up->dl_ctime : NULL;
-
- /* do the remove */
- xx = kmod_remove(logelem_object_p->i_kmod_object_p, &dirfid,
- &REMOVE_OBJECT(logelem_object_p).i_up->dl_child_cid,
- REMOVE_OBJECT(logelem_object_p).i_namep,
- &REMOVE_OBJECT(logelem_object_p).i_up->dl_cred, ctimep);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_remove");
- return (ETIMEDOUT);
- }
-
- /* remove failed */
- logelem_log_opfailed(logelem_object_p, "Remove", NULL,
- REMOVE_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- REMOVE_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_remove");
- return (0);
- }
-
- /* record new ctime if multiple links to file */
- if (ctimep) {
- REMOVE_OBJECT(logelem_object_p).i_up->dl_mtime = mtime;
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_remove.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_remove");
- return (EIO);
- }
- }
-
- dbug_leave("logelem_roll_remove");
- return (0);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_roll_rmdir
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_rmdir(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid;
- struct cfs_dlog_mapping_space map;
-
- dbug_enter("logelem_roll_rmdir");
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- RMDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Remove Directory",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_rmdir");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (map.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &RMDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p,
- gettext("Remove Directory"),
- gettext("Parent directory no longer exists"),
- RMDIR_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- RMDIR_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_rmdir");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p,
- "Remove Directory",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_rmdir");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* perform the rmdir */
- xx = kmod_rmdir(logelem_object_p->i_kmod_object_p, &dirfid,
- RMDIR_OBJECT(logelem_object_p).i_namep,
- &RMDIR_OBJECT(logelem_object_p).i_up->dl_cred);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_rmdir");
- return (ETIMEDOUT);
- }
-
- logelem_log_opfailed(logelem_object_p, "Remove Directory", NULL,
- RMDIR_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- RMDIR_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_rmdir");
- return (0);
- }
- dbug_leave("logelem_roll_rmdir");
- return (0);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_roll_mkdir
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_mkdir(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid;
- struct cfs_dlog_mapping_space map;
-
- dbug_enter("logelem_roll_mkdir");
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- MKDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Create Directory",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_mkdir");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (map.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &MKDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p,
- "Create Directory",
- gettext("Parent directory no longer exists"),
- MKDIR_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- MKDIR_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_mkdir");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p,
- "Create Directory",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_mkdir");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* perform the mkdir */
- xx = kmod_mkdir(logelem_object_p->i_kmod_object_p, &dirfid,
- MKDIR_OBJECT(logelem_object_p).i_namep,
- &MKDIR_OBJECT(logelem_object_p).i_up->dl_child_cid,
- &MKDIR_OBJECT(logelem_object_p).i_up->dl_attrs,
- &MKDIR_OBJECT(logelem_object_p).i_up->dl_cred,
- &MKDIR_OBJECT(logelem_object_p).i_up->dl_fid);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_mkdir");
- return (ETIMEDOUT);
- }
-
- logelem_log_opfailed(logelem_object_p, "Create Directory", NULL,
- MKDIR_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- MKDIR_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_mkdir");
- return (0);
- }
-
- /* update the mapping to point to the new fid */
- map.ms_cid = MKDIR_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_mkdir.dl_fid);
- map.ms_times = 0;
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_mkdir");
- return (EIO);
- }
-
- dbug_leave("logelem_roll_mkdir");
- return (0);
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_roll_link
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_link(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid, linkfid;
- struct cfs_dlog_mapping_space map, dirmap;
- cfs_timestruc_t ctime, mtime;
- cfs_dlog_tm_t *tmp;
- int time_log;
- cfs_vattr_t va;
-
- dbug_enter("logelem_roll_link");
-
- /* get the mapping for the child cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- LINK_OBJECT(logelem_object_p).i_up->dl_child_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = LINK_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (0);
- }
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_link");
- return (0);
- }
- /* if we have a fid in the mapping */
- if (map.ms_fid) {
- /* get the fid */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- linkfid = *fp;
- dbug_assert(linkfid.fid_len);
- }
-
- /* else get the fid from the cache */
- else {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &LINK_OBJECT(logelem_object_p).i_up->dl_child_cid,
- &linkfid);
- if (xx == ENOENT) {
- dbug_leave("logelem_roll_link");
- return (0);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("File is no longer in the cache"),
- LINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
- }
-
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = LINK_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = LINK_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the attributes of the file from the back fs */
- xx = kmod_getattrfid(logelem_object_p->i_kmod_object_p, &linkfid,
- &LINK_OBJECT(logelem_object_p).i_up->dl_cred, &va);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_link");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error getting attributes"), NULL, xx);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Link",
- LINK_OBJECT(logelem_object_p).i_namep,
- gettext("File modified"), time_log);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Link",
- LINK_OBJECT(logelem_object_p).i_namep,
- gettext("File changed"), time_log);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- LINK_OBJECT(logelem_object_p).i_up->dl_parent_cid, &dirmap);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (dirmap.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &LINK_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("Parent directory no longer exists"),
- LINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- dirmap.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Link",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* do the link */
- xx = kmod_link(logelem_object_p->i_kmod_object_p, &dirfid,
- LINK_OBJECT(logelem_object_p).i_namep, &linkfid,
- &LINK_OBJECT(logelem_object_p).i_up->dl_child_cid,
- &LINK_OBJECT(logelem_object_p).i_up->dl_cred,
- &LINK_OBJECT(logelem_object_p).i_up->dl_ctime);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_link");
- return (ETIMEDOUT);
- }
-
- logelem_log_opfailed(logelem_object_p, "Link", NULL,
- LINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- LINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_link");
- return (0);
- }
-
- /* update the mapping with the new time */
- LINK_OBJECT(logelem_object_p).i_up->dl_mtime = mtime;
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_link.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_link");
- return (EIO);
- }
- dbug_leave("logelem_roll_link");
- return (0);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_roll_symlink
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_symlink(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t dirfid;
- struct cfs_dlog_mapping_space map;
-
- dbug_enter("logelem_roll_symlink");
-
- /* see if the symlink no longer exists in the cache */
-#if 0
- xx = kmod_exists(logelem_object_p->i_kmod_object_p,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_child_cid);
- if (xx) {
- dbug_assert(xx == ENOENT);
-
- /* indicate ignore future operations on symlink */
- map.ms_cid =
- SYMLINK_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = X_OPTIMIZED;
- map.ms_times = 0;
- xx = maptbl_set(maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_symlink");
- return (EIO);
- }
- dbug_leave("logelem_roll_symlink");
- return (0);
- }
-#endif
-
- /* get the fid of the parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- SYMLINK_OBJECT(logelem_object_p).i_up->dl_parent_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Symink",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_symlink");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (map.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_parent_cid,
- &dirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Symlink",
- gettext("Parent directory no longer exists"),
- SYMLINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- SYMLINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_symlink");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Symlink",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_symlink");
- return (EIO);
- }
- dirfid = *fp;
- dbug_assert(dirfid.fid_len);
- }
-
- /* if the file exists on the back fs */
- xx = kmod_getattrname(logelem_object_p->i_kmod_object_p, &dirfid,
- SYMLINK_OBJECT(logelem_object_p).i_namep,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_cred,
- NULL, NULL);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_symlink");
- return (ETIMEDOUT);
- }
- /* if the file exists on the back file system */
- if (xx == 0) {
- logelem_log_opfailed(logelem_object_p, "Symlink",
- gettext("File created while disconnected"),
- SYMLINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- SYMLINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_symlink");
- return (0);
- }
-
- /* do the symlink */
- xx = kmod_symlink(logelem_object_p->i_kmod_object_p, &dirfid,
- SYMLINK_OBJECT(logelem_object_p).i_namep,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_child_cid,
- SYMLINK_OBJECT(logelem_object_p).i_contentsp,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_attrs,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_cred,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_fid,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_ctime,
- &SYMLINK_OBJECT(logelem_object_p).i_up->dl_mtime);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_symlink");
- return (ETIMEDOUT);
- }
- logelem_log_opfailed(logelem_object_p, "Symlink", NULL,
- SYMLINK_OBJECT(logelem_object_p).i_namep, xx);
- logelem_log_opskipped(logelem_object_p,
- SYMLINK_OBJECT(logelem_object_p).i_namep);
- dbug_leave("logelem_roll_symlink");
- return (0);
- }
-
- /* update the mapping to point to the new fid and times */
- map.ms_cid = SYMLINK_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_symlink.dl_fid);
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_symlink.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_symlink");
- return (EIO);
- }
- dbug_leave("logelem_roll_symlink");
- return (0);
-}
-/*
- * -----------------------------------------------------------------
- * logelem_roll_rename
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_rename(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t *fp;
- cfs_fid_t odirfid, ndirfid;
- struct cfs_dlog_mapping_space map, dirmap, delmap;
- cfs_dlog_tm_t *tmp;
- cfs_vattr_t va;
- cfs_timestruc_t mtime, ctime;
- cfs_timestruc_t delmtime, delctime;
- cfs_timestruc_t *delctimep = NULL;
- int time_log;
-
- dbug_enter("logelem_roll_rename");
-
- /* get the mapping for the child cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- RENAME_OBJECT(logelem_object_p).i_up->dl_child_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = RENAME_OBJECT(logelem_object_p).i_up->dl_child_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_rename");
- return (0);
- }
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = RENAME_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = RENAME_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the fid of the old parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- RENAME_OBJECT(logelem_object_p).i_up->dl_oparent_cid, &dirmap);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (dirmap.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_oparent_cid,
- &odirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("Original directory no longer exists"),
- RENAME_OBJECT(logelem_object_p).i_orignamep, xx);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- dirmap.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- odirfid = *fp;
- dbug_assert(odirfid.fid_len);
- }
-
- /* get the fid of the new parent directory */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- RENAME_OBJECT(logelem_object_p).i_up->dl_nparent_cid, &dirmap);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error mapping fid"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- /* if error from getting map or no fid in map (ms_fid == 0) */
- if (xx || (dirmap.ms_fid <= 0)) {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_nparent_cid,
- &ndirfid);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("Target directory no longer exists"),
- RENAME_OBJECT(logelem_object_p).i_orignamep, xx);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
- } else {
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- dirmap.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- ndirfid = *fp;
- dbug_assert(ndirfid.fid_len);
- }
-
- /* get the attributes of the file from the back fs */
- xx = kmod_getattrname(logelem_object_p->i_kmod_object_p, &odirfid,
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_cred,
- &va, NULL);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_rename");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("Cannot get attributes on file"),
- RENAME_OBJECT(logelem_object_p).i_orignamep, xx);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Rename",
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- gettext("File modified"), time_log);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Rename",
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- gettext("File changed"), time_log);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- /* if we are also deleting a file */
- if (RENAME_OBJECT(logelem_object_p).i_up->dl_del_cid.cid_fileno != 0) {
- /* get the mapping for the deleted cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_cid, &delmap);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- delmap.ms_cid =
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_cid;
- delmap.ms_fid = 0;
- delmap.ms_times = 0;
- }
-
- /* if we have timestamps in the mapping */
- if (delmap.ms_times) {
- /* get the times */
- xx = logfile_offset(
- logelem_object_p->i_logfile_object_p,
- delmap.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("error getting logfile offset"),
- NULL, 0);
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- delctime = tmp->tm_ctime;
- delmtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- delctime = RENAME_OBJECT(logelem_object_p).
- i_up->dl_del_times.tm_ctime;
- delmtime = RENAME_OBJECT(logelem_object_p).
- i_up->dl_del_times.tm_mtime;
- time_log = 1;
- }
-
- /* get the attributes of the target file from the back fs */
- xx = kmod_getattrname(logelem_object_p->i_kmod_object_p,
- &ndirfid,
- RENAME_OBJECT(logelem_object_p).i_newnamep,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_cred,
- &va, NULL);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_rename");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Rename",
- gettext("Cannot get attributes on file"),
- RENAME_OBJECT(logelem_object_p).i_orignamep, xx);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- /* conflict if mtime changed */
- if (TIMECHANGE(delmtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Rename",
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- gettext("Target modified"), time_log);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
-
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(delctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Rename",
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- gettext("Target changed"), time_log);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- delctimep = (va.va_nlink > 1) ?
- &RENAME_OBJECT(logelem_object_p).
- i_up->dl_del_times.tm_ctime : NULL;
- }
-
- /* perform the rename */
- xx = kmod_rename(logelem_object_p->i_kmod_object_p, &odirfid,
- RENAME_OBJECT(logelem_object_p).i_orignamep, &ndirfid,
- RENAME_OBJECT(logelem_object_p).i_newnamep,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_child_cid,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_cred,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_ctime, delctimep,
- &RENAME_OBJECT(logelem_object_p).i_up->dl_del_cid);
- if (xx) {
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_rename");
- return (ETIMEDOUT);
- }
- logelem_log_opfailed(logelem_object_p, "Rename", NULL,
- RENAME_OBJECT(logelem_object_p).i_orignamep, xx);
- logelem_log_opskipped(logelem_object_p,
- RENAME_OBJECT(logelem_object_p).i_orignamep);
- dbug_leave("logelem_roll_rename");
- return (0);
- }
-
- /* update the mapping to point to the new times for the file */
- RENAME_OBJECT(logelem_object_p).i_up->dl_mtime = mtime;
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_rename.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- /* if we deleted a file with links left */
- if (delctimep) {
- /* update the mapping to the new times for the deleted file */
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_times.tm_mtime =
- delmtime;
- delmap.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_rename.dl_del_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p,
- &delmap, 1);
- if (xx) {
- dbug_leave("logelem_roll_rename");
- return (EIO);
- }
- }
-
- dbug_leave("logelem_roll_rename");
- return (0);
-}
-/*
- * logelem_roll_modified
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_modified(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp)
-{
- int xx;
- cfs_fid_t filefid, *fp;
- struct cfs_dlog_mapping_space map;
- cfs_dlog_tm_t *tmp;
- cfs_timestruc_t ctime, mtime;
- int time_log;
- cachefsio_getinfo_t ginfo;
- cfs_vattr_t va;
- int conflict = 0;
-
- dbug_enter("logelem_roll_modified");
-
- dbug_precond(seqp);
-
- /* get the mapping for this cid if it exists */
- xx = maptbl_get(logelem_object_p->i_maptbl_object_p,
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid, &map);
- if (xx == -1) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("error mapping cid"), NULL, 0);
- dbug_leave("logelem_roll_modified");
- return (EIO);
- }
- /* if a mapping was not found */
- if (xx) {
- /* dummy up mapping so we get values from the cache */
- map.ms_cid = MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid;
- map.ms_fid = 0;
- map.ms_times = 0;
- }
-
- /* done if there was a conflict on the file */
- if (map.ms_fid == X_CONFLICT) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("file conflict"), NULL, 0);
- dbug_leave("logelem_roll_modified");
- return (0);
- }
- /* done if the file is optimized out */
- if (map.ms_fid == X_OPTIMIZED) {
- dbug_leave("logelem_roll_modified");
- return (0);
- }
- /* if we have a fid in the mapping */
- if (map.ms_fid) {
- /* get the fid */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_fid, (caddr_t *)&fp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_modified");
- return (EIO);
- }
- filefid = *fp;
- dbug_assert(filefid.fid_len);
- }
-
- /* else get the fid from the cache */
- else {
- xx = kmod_cidtofid(logelem_object_p->i_kmod_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid, &filefid);
- if (xx == ENOENT) {
- dbug_leave("logelem_roll_modified");
- return (0);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Write",
- gettext("File is no longer in the cache"),
- NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_modified");
- return (xx);
- }
- }
-
- /* get info about the file from the cache */
- xx = kmod_getinfo(logelem_object_p->i_kmod_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid, &ginfo);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Write",
- gettext("File is no longer in the cache"), NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_modified");
- return (xx);
- }
-
- /* if we are not ready to process this write yet */
- if (*seqp < ginfo.gi_seq) {
- dbug_print(("info", "Defering writing of file '%s' "
- "current seq %d, metadata seq %d",
- ginfo.gi_name, *seqp, ginfo.gi_seq));
- *seqp = ginfo.gi_seq;
- dbug_leave("logelem_roll_modified");
- return (EAGAIN);
- } else {
- dbug_print(("info", "Continue writing of file '%s' "
- "current seq %d, metadata seq %d",
- ginfo.gi_name, *seqp, ginfo.gi_seq));
- }
-
- /* if we have timestamps in the mapping */
- if (map.ms_times) {
- /* get the times */
- xx = logfile_offset(logelem_object_p->i_logfile_object_p,
- map.ms_times, (caddr_t *)&tmp);
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("error getting logfile offset"), NULL, 0);
- dbug_leave("logelem_roll_modified");
- return (EIO);
- }
- ctime = tmp->tm_ctime;
- mtime = tmp->tm_mtime;
- time_log = 0;
- }
-
- /* else get the timestamps from the log entry */
- else {
- ctime = MODIFIED_OBJECT(logelem_object_p).i_up->dl_ctime;
- mtime = MODIFIED_OBJECT(logelem_object_p).i_up->dl_mtime;
- time_log = 1;
- }
-
- /* get the attributes of the file from the back fs */
- xx = kmod_getattrfid(logelem_object_p->i_kmod_object_p, &filefid,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred, &va);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_modified");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("error getting attributes"), NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_modified");
- return (xx);
- }
-
-
- /* conflict if mtime changed */
- if (TIMECHANGE(mtime, va.va_mtime)) {
- logelem_log_timelogmesg(logelem_object_p, "Write", NULL,
- gettext("File modified"), time_log);
- conflict = 1;
- }
-
- /* conflict if ctime changed */
- else if (TIMECHANGE(ctime, va.va_ctime)) {
- logelem_log_timelogmesg(logelem_object_p, "Write", NULL,
- gettext("File changed"), time_log);
- conflict = 1;
- }
-
- /* if a conflict was detected */
- if (conflict) {
- logelem_log_opfailed(logelem_object_p, "Modified",
- gettext("file conflict"), NULL, 0);
- xx = logelem_lostfound(logelem_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_modified");
- return (xx);
- }
-
- /* now do the write, get the new times */
- xx = kmod_pushback(logelem_object_p->i_kmod_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid, &filefid,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_ctime,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_mtime, 1);
- if ((xx == ETIMEDOUT) || (xx == EIO)) {
- dbug_leave("logelem_roll_modified");
- return (ETIMEDOUT);
- }
- if (xx) {
- logelem_log_opfailed(logelem_object_p, "Write", NULL, NULL, xx);
- xx = logelem_lostfound(logelem_object_p,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid,
- NULL, NULL,
- &MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_roll_modified");
- return (xx);
- }
-
- /* update the mapping to point to the new times */
- map.ms_times = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_modify.dl_times);
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_modified");
- return (EIO);
- }
- dbug_leave("logelem_roll_modified");
- return (0);
-}
-/*
- * logelem_roll_mapfid
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-int
-logelem_roll_mapfid(cfsd_logelem_object_t *logelem_object_p)
-{
- int xx;
- struct cfs_dlog_mapping_space map;
-
- dbug_enter("logelem_roll_mapfid");
-
- /* map the cid to the fid */
- dbug_assert(MAPFID_OBJECT(logelem_object_p).i_up->dl_fid.fid_len);
- map.ms_cid = MAPFID_OBJECT(logelem_object_p).i_up->dl_cid;
- map.ms_fid = logelem_object_p->i_offset +
- offsetof(cfs_dlog_entry_t, dl_u.dl_mapfid.dl_fid);
- map.ms_times = 0;
-
- xx = maptbl_set(logelem_object_p->i_maptbl_object_p, &map, 1);
- if (xx) {
- dbug_leave("logelem_roll_mapfid");
- return (EIO);
- }
- dbug_leave("logelem_roll_mapfid");
- return (0);
-}
-/*
- * logelem_dump
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump");
-
- switch (logelem_object_p->i_type) {
-
- case NO_OBJECT_TYPE:
- dbug_assert(0);
- break;
-
- case SETATTR_OBJECT_TYPE:
- logelem_dump_setattr(logelem_object_p);
- break;
-
- case SETSECATTR_OBJECT_TYPE:
- logelem_dump_setsecattr(logelem_object_p);
- break;
-
- case CREATE_OBJECT_TYPE:
- logelem_dump_create(logelem_object_p);
- break;
-
- case REMOVE_OBJECT_TYPE:
- logelem_dump_remove(logelem_object_p);
- break;
-
- case RMDIR_OBJECT_TYPE:
- logelem_dump_rmdir(logelem_object_p);
- break;
-
- case MKDIR_OBJECT_TYPE:
- logelem_dump_mkdir(logelem_object_p);
- break;
-
- case LINK_OBJECT_TYPE:
- logelem_dump_link(logelem_object_p);
- break;
-
- case SYMLINK_OBJECT_TYPE:
- logelem_dump_symlink(logelem_object_p);
- break;
-
- case RENAME_OBJECT_TYPE:
- logelem_dump_rename(logelem_object_p);
- break;
-
- case MODIFIED_OBJECT_TYPE:
- logelem_dump_modified(logelem_object_p);
- break;
-
- case MAPFID_OBJECT_TYPE:
- logelem_dump_mapfid(logelem_object_p);
- break;
-
- default:
- dbug_assert(0);
- }
- dbug_leave("logelem_dump");
-}
-/*
- * logelem_dump_setattr
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_setattr(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_setattr");
-
- dbug_print(("dump", "SETATTR"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "file cid %"PRIx64", flags 0x%x",
- SETATTR_OBJECT(logelem_object_p).i_up->dl_cid.cid_fileno,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_flags));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- SETATTR_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- SETATTR_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_attr(&SETATTR_OBJECT(logelem_object_p).i_up->dl_attrs);
- logelem_print_cred(&SETATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_setattr");
-}
-
-/*
- * logelem_dump_setsecattr
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_setsecattr(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_setsecattr");
-
- dbug_print(("dump", "SETSECATTR"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "file cid %"PRIx64,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cid.cid_fileno));
- dbug_print(("dump", "aclcnt %d dfaclcnt %d",
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_aclcnt,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_dfaclcnt));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- SETSECATTR_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_cred(&SETSECATTR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_setsecattr");
-}
-
-
-/*
- * logelem_dump_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_create(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_create");
-
- dbug_print(("dump", "CREATE"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "directory cid %"PRIx64,
- CREATE_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- dbug_print(("dump", "file cid %"PRIx64,
- CREATE_OBJECT(logelem_object_p).i_up->dl_new_cid.cid_fileno));
- dbug_print(("dump", "name \"%s\"",
- CREATE_OBJECT(logelem_object_p).i_namep));
- dbug_print(("dump", "exclusive %d, mode 0%o, destexists %d",
- CREATE_OBJECT(logelem_object_p).i_up->dl_excl,
- CREATE_OBJECT(logelem_object_p).i_up->dl_mode,
- CREATE_OBJECT(logelem_object_p).i_up->dl_exists));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- CREATE_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- CREATE_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- CREATE_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- CREATE_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_attr(&CREATE_OBJECT(logelem_object_p).i_up->dl_attrs);
- logelem_print_cred(&CREATE_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_create");
-}
-
-
-/*
- * -----------------------------------------------------------------
- * logelem_dump_remove
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_remove(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_remove");
-
- dbug_print(("dump", "REMOVE"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "file %s cid %"PRIx64", dir cid %"PRIx64,
- REMOVE_OBJECT(logelem_object_p).i_namep,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_child_cid.cid_fileno,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- REMOVE_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- REMOVE_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_cred(&REMOVE_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_remove");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_dump_rmdir
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_rmdir(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_rmdir");
-
- dbug_print(("dump", "RMDIR"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "dir name %s, dir cid %"PRIx64,
- RMDIR_OBJECT(logelem_object_p).i_namep,
- RMDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- logelem_print_cred(&RMDIR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_rmdir");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_dump_mkdir
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_mkdir(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_mkdir");
-
- dbug_print(("dump", "MKDIR"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "file %s cid %"PRIx64", dir cid %"PRIx64,
- MKDIR_OBJECT(logelem_object_p).i_namep,
- MKDIR_OBJECT(logelem_object_p).i_up->dl_child_cid.cid_fileno,
- MKDIR_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- logelem_print_attr(&MKDIR_OBJECT(logelem_object_p).i_up->dl_attrs);
- logelem_print_cred(&MKDIR_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_mkdir");
-}
-
-/*
- * -----------------------------------------------------------------
- * logelem_dump_link
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_link(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_link");
-
- dbug_print(("dump", "LINK"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "name %s, cid to link %"PRIx64", dir cid %"PRIx64,
- LINK_OBJECT(logelem_object_p).i_namep,
- LINK_OBJECT(logelem_object_p).i_up->dl_child_cid.cid_fileno,
- LINK_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- LINK_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- LINK_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- LINK_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- LINK_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_cred(&LINK_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_link");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_dump_symlink
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_symlink(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_symlink");
-
- dbug_print(("dump", "SYMLINK"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "dir cid %"PRIx64,
- SYMLINK_OBJECT(logelem_object_p).i_up->dl_parent_cid.cid_fileno));
- dbug_print(("dump", "name %s, contents %s, file cid %"PRIx64,
- SYMLINK_OBJECT(logelem_object_p).i_namep,
- SYMLINK_OBJECT(logelem_object_p).i_contentsp,
- SYMLINK_OBJECT(logelem_object_p).i_up->dl_child_cid.cid_fileno));
- logelem_print_attr(&SYMLINK_OBJECT(logelem_object_p).i_up->dl_attrs);
- logelem_print_cred(&SYMLINK_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_symlink");
-}
-/*
- * -----------------------------------------------------------------
- * logelem_dump_rename
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_rename(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_rename");
-
- dbug_print(("dump", "RENAME"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "orig dir cid %"PRIx64", new dir cid %"PRIx64,
- RENAME_OBJECT(logelem_object_p).i_up->dl_oparent_cid.cid_fileno,
- RENAME_OBJECT(logelem_object_p).i_up->dl_nparent_cid.cid_fileno));
- dbug_print(("dump", "file cid %"PRIx64,
- RENAME_OBJECT(logelem_object_p).i_up->dl_child_cid.cid_fileno));
- dbug_print(("dump", "orig name '%s', new name '%s'",
- RENAME_OBJECT(logelem_object_p).i_orignamep,
- RENAME_OBJECT(logelem_object_p).i_newnamep));
- dbug_print(("dump", "file ctime %x %x, mtime %x %x",
- RENAME_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- dbug_print(("dump", "deleted cid %"PRIx64,
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_cid.cid_fileno));
- dbug_print(("dump", "deleted ctime %x %x, mtime %x %x",
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_times.tm_ctime.tv_sec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_times.tm_ctime.tv_nsec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_times.tm_mtime.tv_sec,
- RENAME_OBJECT(logelem_object_p).i_up->dl_del_times.tm_mtime.
- tv_nsec));
- logelem_print_cred(&RENAME_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_rename");
-}
-/*
- * logelem_dump_modified
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_modified(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_modified");
-
- dbug_print(("dump", "MODIFIED"));
- dbug_print(("dump", "len %d, valid %d, seq %d",
- logelem_object_p->i_entp->dl_len,
- logelem_object_p->i_entp->dl_valid,
- logelem_object_p->i_entp->dl_seq));
- dbug_print(("dump", "file cid %"PRIx64,
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_cid.cid_fileno));
- dbug_print(("dump", "ctime %x %x, mtime %x %x",
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_ctime.tv_sec,
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_ctime.tv_nsec,
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_mtime.tv_sec,
- MODIFIED_OBJECT(logelem_object_p).i_up->dl_mtime.tv_nsec));
- logelem_print_cred(&MODIFIED_OBJECT(logelem_object_p).i_up->dl_cred);
- dbug_leave("logelem_dump_modified");
-}
-/*
- * logelem_dump_mapfid
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-logelem_dump_mapfid(cfsd_logelem_object_t *logelem_object_p)
-{
- dbug_enter("logelem_dump_mapfid");
- dbug_print(("dump", "MAPFID"));
- dbug_print(("dump", "file cid %"PRIx64,
- MAPFID_OBJECT(logelem_object_p).i_up->dl_cid.cid_fileno));
- logelem_format_fid(logelem_object_p,
- &MAPFID_OBJECT(logelem_object_p).i_up->dl_fid);
- dbug_print(("dump", "fid '%s'", logelem_object_p->i_fidbuf));
- dbug_enter("logelem_dump_mapfid");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.h
deleted file mode 100644
index aba745a3b6..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logelem.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * 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 1994-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CFSD_LOGELEM_H
-#define _CFSD_LOGELEM_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Include file for the logelem class.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* typedefs for logelem type */
-#define NO_OBJECT_TYPE 0
-#define SETATTR_OBJECT_TYPE 1
-#define SETSECATTR_OBJECT_TYPE 2
-#define CREATE_OBJECT_TYPE 3
-#define REMOVE_OBJECT_TYPE 4
-#define RMDIR_OBJECT_TYPE 5
-#define MKDIR_OBJECT_TYPE 6
-#define LINK_OBJECT_TYPE 7
-#define SYMLINK_OBJECT_TYPE 8
-#define RENAME_OBJECT_TYPE 9
-#define MODIFIED_OBJECT_TYPE 10
-#define MAPFID_OBJECT_TYPE 11
-
-#define CFSDMesgMax 4096
-/* BEGIN CSTYLED */
-/* defines for refrencing objects */
-#define SETATTR_OBJECT(ptr) ptr->i_operation.i_setattr_object
-#define SETATTR_OBJECT_PTR(ptr) &(ptr->i_operation.i_setattr_object)
-#define SETSECATTR_OBJECT(ptr) ptr->i_operation.i_setsecattr_object
-#define SETSECATTR_OBJECT_PTR(ptr) &(ptr->i_operation.i_setsecattr_object)
-#define CREATE_OBJECT(ptr) ptr->i_operation.i_create_object
-#define CREATE_OBJECT_PTR(ptr) &(ptr->i_operation.i_create_object)
-#define REMOVE_OBJECT(ptr) ptr->i_operation.i_remove_object
-#define REMOVE_OBJECT_PTR(ptr) &(ptr->i_operation.i_remove_object)
-#define RMDIR_OBJECT(ptr) ptr->i_operation.i_rmdir_object
-#define RMDIR_OBJECT_PTR(ptr) &(ptr->i_operation.i_rmdir_object)
-#define MKDIR_OBJECT(ptr) ptr->i_operation.i_mkdir_object
-#define MKDIR_OBJECT_PTR(ptr) &(ptr->i_operation.i_mkdir_object)
-#define LINK_OBJECT(ptr) ptr->i_operation.i_link_object
-#define LINK_OBJECT_PTR(ptr) &(ptr->i_operation.i_link_object)
-#define SYMLINK_OBJECT(ptr) ptr->i_operation.i_symlink_object
-#define SYMLINK_OBJECT_PTR(ptr) &(ptr->i_operation.i_symlink_object)
-#define RENAME_OBJECT(ptr) ptr->i_operation.i_rename_object
-#define RENAME_OBJECT_PTR(ptr) &(ptr->i_operation.i_rename_object)
-#define MODIFIED_OBJECT(ptr) ptr->i_operation.i_modified_object
-#define MODIFIED_OBJECT_PTR(ptr) &(ptr->i_operation.i_modified_object)
-#define MAPFID_OBJECT(ptr) ptr->i_operation.i_mapfid_object
-#define MAPFID_OBJECT_PTR(ptr) &(ptr->i_operation.i_mapfid_object)
-/* END CSTYLED */
-
-/* setattr */
-typedef struct cfsd_logelem_setattr_object {
- struct cfs_dlog_setattr *i_up;
-} cfsd_logelem_setattr_object_t;
-
-/* setsecattr */
-typedef struct cfsd_logelem_setsecattr_oject {
- struct cfs_dlog_setsecattr *i_up;
- const aclent_t *i_acl;
-} cfsd_logelem_setsecattr_object_t;
-
-/* create */
-typedef struct cfsd_logelem_create_object {
- struct cfs_dlog_create *i_up;
- const char *i_namep; /* name of file to create */
-} cfsd_logelem_create_object_t;
-
-/* remove */
-typedef struct cfsd_logelem_remove_object {
- struct cfs_dlog_remove *i_up;
- const char *i_namep; /* name of file to remove */
-} cfsd_logelem_remove_object_t;
-
-/* rmdir */
-typedef struct cfsd_logelem_rmdir_object {
- struct cfs_dlog_rmdir *i_up;
- const char *i_namep; /* name of dir to rmdir */
-} cfsd_logelem_rmdir_object_t;
-
-/* mkdir */
-typedef struct cfsd_logelem_mkdir_object {
- struct cfs_dlog_mkdir *i_up;
- const char *i_namep; /* name of dir to mkdir */
-} cfsd_logelem_mkdir_object_t;
-
-/* link */
-typedef struct cfsd_logelem_link_object {
- struct cfs_dlog_link *i_up;
- const char *i_namep; /* name of link */
-} cfsd_logelem_link_object_t;
-
-/* symlink */
-typedef struct cfsd_logelem_symlink_object {
- struct cfs_dlog_symlink *i_up;
- const char *i_namep; /* name of symlink */
- const char *i_contentsp; /* contents of symlink */
-} cfsd_logelem_symlink_object_t;
-
-/* rename */
-typedef struct cfsd_logelem_rename_object {
- struct cfs_dlog_rename *i_up;
- const char *i_orignamep; /* original name */
- const char *i_newnamep; /* new name */
-} cfsd_logelem_rename_object_t;
-
-/* modify */
-typedef struct cfsd_logelem_modified_object {
- struct cfs_dlog_modify *i_up;
-} cfsd_logelem_modified_object_t;
-
-/* mapfid */
-typedef struct cfsd_logelem_mapfid_object {
- struct cfs_dlog_mapfid *i_up;
-} cfsd_logelem_mapfid_object_t;
-
-/* Abstract base class used by the other logelem classes. */
-#define LOGELM_FIDBUFLEN 1024
-typedef struct cfsd_logelem_object {
-
- cfsd_maptbl_object_t *i_maptbl_object_p;
- cfsd_logfile_object_t *i_logfile_object_p;
- cfsd_kmod_object_t *i_kmod_object_p;
- char i_messagep[CFSDMesgMax]; /* message */
- char i_fidbuf[LOGELM_FIDBUFLEN]; /* debugging */
- cfs_dlog_entry_t *i_entp;
- off_t i_offset;
- int i_type;
- union {
- cfsd_logelem_setattr_object_t i_setattr_object;
- cfsd_logelem_setsecattr_object_t i_setsecattr_object;
- cfsd_logelem_create_object_t i_create_object;
- cfsd_logelem_remove_object_t i_remove_object;
- cfsd_logelem_rmdir_object_t i_rmdir_object;
- cfsd_logelem_mkdir_object_t i_mkdir_object;
- cfsd_logelem_link_object_t i_link_object;
- cfsd_logelem_symlink_object_t i_symlink_object;
- cfsd_logelem_rename_object_t i_rename_object;
- cfsd_logelem_modified_object_t i_modified_object;
- cfsd_logelem_mapfid_object_t i_mapfid_object;
- }i_operation;
-}cfsd_logelem_object_t;
-
-cfsd_logelem_object_t *cfsd_logelem_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-void cfsd_logelem_destroy(cfsd_logelem_object_t *logelem_object_p);
-void logelem_print_cred(dl_cred_t *credp);
-void logelem_print_attr(vattr_t *vp);
-void logelem_format_fid(cfsd_logelem_object_t *logelem_object_p, fid_t *fidp);
-int logelem_lostfound(cfsd_logelem_object_t *logelem_object_p,
- cfs_cid_t *cidp,
- cfs_cid_t *pcidp,
- const char *namep,
- dl_cred_t *cred);
-void logelem_problem(cfsd_logelem_object_t *logelem_object_p,
- char *strp);
-void logelem_resolution(cfsd_logelem_object_t *logelem_object_p,
- char *strp);
-void logelem_message_append(char *strp1, char *strp2);
-void logelem_message(cfsd_logelem_object_t *logelem_object_p,
- char *prefix, char *strp);
-void logelem_log_opfailed(cfsd_logelem_object_t *logelem_object_p,
- char *opp, char *info, const char *namep, int xx);
-void logelem_log_opskipped(cfsd_logelem_object_t *logelem_object_p,
- const char *namep);
-void logelem_log_timelogmesg(cfsd_logelem_object_t *logelem_object_p,
- char *opp, const char *namep, char *mesgp, int time_log);
-
-
-cfsd_logelem_object_t *cfsd_logelem_setattr_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_setsecattr_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_create_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_remove_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_rmdir_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_mkdir_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_link_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_symlink_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_rename_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_modified_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-cfsd_logelem_object_t *cfsd_logelem_mapfid_create(
- cfsd_maptbl_object_t *maptbl_object_p,
- cfsd_logfile_object_t *logfile_object_p,
- cfsd_kmod_object_t *kmod_object_p);
-
-int logelem_roll(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-
-int logelem_roll_setattr(cfsd_logelem_object_t *logelem_object_p,
- ulong_t *seqp);
-int logelem_roll_setsecattr(cfsd_logelem_object_t *logelem_object_p,
- ulong_t *seqp);
-int logelem_roll_create(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_remove(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_rmdir(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_mkdir(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_link(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_symlink(cfsd_logelem_object_t *logelem_object_p,
- ulong_t *seqp);
-int logelem_roll_rename(cfsd_logelem_object_t *logelem_object_p, ulong_t *seqp);
-int logelem_roll_modified(cfsd_logelem_object_t *logelem_object_p,
- ulong_t *seqp);
-int logelem_roll_mapfid(cfsd_logelem_object_t *logelem_object_p);
-
-void logelem_dump(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_setattr(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_setsecattr(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_create(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_remove(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_rmdir(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_mkdir(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_link(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_symlink(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_rename(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_modified(cfsd_logelem_object_t *logelem_object_p);
-void logelem_dump_mapfid(cfsd_logelem_object_t *logelem_object_p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFSD_LOGELEM_H */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.c
deleted file mode 100644
index 7eab4a7289..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * 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 1994-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods of the cfsd_maptbl classes.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <synch.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
-#include <sys/cred.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <mdbug/mdbug.h>
-#include "cfsd.h"
-#include "cfsd_logfile.h"
-
-/*
- * cfsd_logfile_create
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-cfsd_logfile_object_t *
-cfsd_logfile_create(void)
-{
- cfsd_logfile_object_t *logfile_object_p;
-
- dbug_enter("cfsd_logfile_create");
-
- logfile_object_p = cfsd_calloc(sizeof (cfsd_logfile_object_t));
- logfile_object_p->i_fid = -1;
- logfile_object_p->i_map_entry.i_pa = NULL;
- logfile_object_p->i_map_entry.i_paoff = 0;
- logfile_object_p->i_map_entry.i_paend = 0;
- logfile_object_p->i_map_entry.i_palen = 0;
- logfile_object_p->i_map_offset.i_pa = NULL;
- logfile_object_p->i_map_offset.i_paoff = 0;
- logfile_object_p->i_map_offset.i_paend = 0;
- logfile_object_p->i_map_offset.i_palen = 0;
- logfile_object_p->i_cur_offset = 0;
- logfile_object_p->i_cur_entry = NULL;
- dbug_leave("cfsd_logfile_create");
- return (logfile_object_p);
-}
-
-/*
- * cfsd_logfile_destroy
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-cfsd_logfile_destroy(cfsd_logfile_object_t *logfile_object_p)
-{
- dbug_enter("cfsd_logfile_destroy");
- logfile_sync(logfile_object_p);
- logfile_teardown(logfile_object_p);
- cfsd_free(logfile_object_p);
- dbug_leave("cfsd_logfile_destroy");
-}
-
-/*
- * logfile_domap
- *
- * Description:
- * Maps in the specified section of the file.
- * Arguments:
- * off The offset to map in. Must be i_pagesize aligned.
- * map 0 means use map_entry, 1 means use map_offset
- * Returns:
- * Returns 0 for success or an errno value on failure.
- * Preconditions:
- */
-int
-logfile_domap(cfsd_logfile_object_t *logfile_object_p, off_t off, int map)
-{
- int xx;
- int len;
- mmap_info_t *mmp;
-
- dbug_enter("logfile_domap");
- dbug_precond(logfile_object_p->i_fid >= 0);
-
- len = logfile_object_p->i_maplen;
- mmp = (map == 0) ?
- &logfile_object_p->i_map_entry :
- &logfile_object_p->i_map_offset;
-
- logfile_object_p->i_stat_mapmove++;
-
- /* destroy old mapping if it exists */
- if (mmp->i_pa) {
- /* determine how far we have to move the map */
- logfile_object_p->i_stat_mapdist += abs(mmp->i_paoff - off);
-
- /* remove the map */
- xx = munmap(mmp->i_pa, mmp->i_palen);
- if (xx == -1) {
- xx = errno;
- dbug_print(("error", "Could not unmap %s, %d, %p, %d",
- logfile_object_p->i_name, xx, mmp->i_pa,
- mmp->i_palen));
- }
- mmp->i_pa = NULL;
- mmp->i_palen = 0;
- mmp->i_paoff = 0;
- mmp->i_paend = 0;
- }
-
- /* do the mapping */
- mmp->i_pa = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
- logfile_object_p->i_fid, off);
- if (mmp->i_pa == MAP_FAILED) {
- xx = errno;
- dbug_print(("error",
- "Could not map %s, error %d, off %d, len %d",
- logfile_object_p->i_name, xx, off, len));
- mmp->i_pa = NULL;
- dbug_leave("logfile_domap");
- return (xx);
- }
-
- mmp->i_palen = len;
- mmp->i_paoff = off;
- mmp->i_paend = off + len - 1;
- dbug_leave("logfile_domap");
- return (0);
-}
-
-/*
- * logfile_getaddr
- *
- * Description:
- * Returns an address of a particular offset in the file.
- * The size of the item to map is i_maxmap
- * This routine assumes that if we have to remap that i_maxmap
- * will fit inside the default mapping size.
- * Arguments:
- * start offset in the file to map
- * map 0 means use map_entry, 1 means use map_offset
- * Returns:
- * Returns NULL for a failure with the mapping file.
- * Preconditions:
- */
-caddr_t
-logfile_getaddr(cfsd_logfile_object_t *logfile_object_p, off_t start, int map)
-{
- mmap_info_t *mmp;
- caddr_t pa;
- off_t end;
-
- dbug_enter("logfile_getaddr");
-
- mmp = (map == 0) ?
- &logfile_object_p->i_map_entry :
- &logfile_object_p->i_map_offset;
-
- /* determine the end of the item */
- end = start + logfile_object_p->i_maxmap - 1;
-
- /* map the entry in if necessary */
- if ((start < mmp->i_paoff) || (mmp->i_paend < end)) {
- if (logfile_domap(logfile_object_p,
- start & logfile_object_p->i_pagemask, map)) {
- dbug_leave("logfile_getaddr");
- return (NULL);
- }
- dbug_assert((mmp->i_paoff <= start) && (end <= mmp->i_paend));
- }
-
- /* make an address and return it */
- pa = mmp->i_pa + (start - mmp->i_paoff);
- dbug_leave("logfile_getaddr");
- return (pa);
-}
-
-/*
- * logfile_setup
- *
- * Description:
- * Sets up to use the specified file.
- * Call this routine before using any of the other routines.
- * Arguments:
- * filename file to use
- * maxmap max amount needed after a map
- * Returns:
- * Returns 0 for success or an errno value.
- * Preconditions:
- * precond(filename)
- */
-int
-logfile_setup(cfsd_logfile_object_t *logfile_object_p,
- const char *filename, int maxmap)
-{
- int xx;
- struct stat sinfo;
- long *versionp;
-
- dbug_enter("logfile_setup");
- dbug_precond(filename);
-
- /* clean up from a previous setup */
- logfile_teardown(logfile_object_p);
-
- strlcpy(logfile_object_p->i_name, filename,
- sizeof (logfile_object_p->i_name));
- dbug_print(("info", "filename %s", logfile_object_p->i_name));
- logfile_object_p->i_maxmap = maxmap;
-
- /* get the page info */
- logfile_object_p->i_pagesize = PAGESIZE;
- logfile_object_p->i_pagemask = PAGEMASK;
- logfile_object_p->i_maplen = logfile_object_p->i_pagesize * 100;
-
- /* open the file */
- logfile_object_p->i_fid = open(logfile_object_p->i_name,
- O_RDWR | O_NONBLOCK);
- if (logfile_object_p->i_fid == -1) {
- xx = errno;
- dbug_print(("error", "Could not open %s, %d",
- logfile_object_p->i_name, xx));
- dbug_leave("logfile_setup");
- return (xx);
- }
-
- /* get the size and type of file */
- xx = fstat(logfile_object_p->i_fid, &sinfo);
- if (xx) {
- xx = errno;
- if (xx == ENOENT) {
- dbug_print(("info", "No log file to roll"));
- } else {
- dbug_print(("error", "Could not stat %s, %d",
- logfile_object_p->i_name, xx));
- }
- dbug_leave("logfile_setup");
- return (xx);
- }
- logfile_object_p->i_size = sinfo.st_size;
-
- /* sanity check, better be a regular file */
- if (!S_ISREG(sinfo.st_mode)) {
- xx = ENOTSUP;
- dbug_print(("error", "%s Not a regular file.",
- logfile_object_p->i_name));
- dbug_leave("logfile_setup");
- return (xx);
- }
-
- /* better not be too small */
- if (logfile_object_p->i_size < LOGFILE_ENTRY_START) {
- dbug_print(("error", "File %s is too small %d.",
- logfile_object_p->i_name, logfile_object_p->i_size));
- dbug_leave("logfile_setup");
- return (EINVAL);
- }
-
- /* initialize statistic gathering */
- logfile_object_p->i_stat_mapmove = 0;
- logfile_object_p->i_stat_mapdist = 0;
-
- /* check the version number */
- versionp = (long *)logfile_getaddr(logfile_object_p, 0, 1);
- if (versionp == NULL) {
- dbug_leave("logfile_setup");
- return (EIO);
- }
- if (*versionp != CFS_DLOG_VERSION) {
- dbug_print(("error", "Log file version mismatch %d != %d",
- *versionp, CFS_DLOG_VERSION));
- dbug_leave("logfile_setup");
- return (EINVAL);
- }
-
- /* return success */
- dbug_leave("logfile_setup");
- return (0);
-}
-
-/*
- * logfile_teardown
- *
- * Description:
- * Uninitializes the object.
- * Call logfile_setup before using this object again.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-logfile_teardown(cfsd_logfile_object_t *logfile_object_p)
-{
- int xx;
-
- dbug_enter("logfile_teardown");
-
- if (logfile_object_p->i_map_entry.i_pa) {
- xx = munmap(logfile_object_p->i_map_entry.i_pa,
- logfile_object_p->i_map_entry.i_palen);
- if (xx == -1) {
- xx = errno;
- dbug_print(("error", "Could not unmap %s, %d, %p, %d",
- logfile_object_p->i_name, xx,
- logfile_object_p->i_map_entry.i_pa,
- logfile_object_p->i_map_entry.i_palen));
- }
- logfile_object_p->i_map_entry.i_pa = NULL;
- }
- logfile_object_p->i_map_entry.i_paoff = 0;
- logfile_object_p->i_map_entry.i_paend = 0;
- logfile_object_p->i_map_entry.i_palen = 0;
-
- if (logfile_object_p->i_map_offset.i_pa) {
- xx = munmap(logfile_object_p->i_map_offset.i_pa,
- logfile_object_p->i_map_offset.i_palen);
- if (xx == -1) {
- xx = errno;
- dbug_print(("error", "Could not unmap %s, %d, %p, %d",
- logfile_object_p->i_name, xx,
- logfile_object_p->i_map_offset.i_pa,
- logfile_object_p->i_map_offset.i_palen));
- }
- logfile_object_p->i_map_offset.i_pa = NULL;
- }
- logfile_object_p->i_map_offset.i_paoff = 0;
- logfile_object_p->i_map_offset.i_paend = 0;
- logfile_object_p->i_map_offset.i_palen = 0;
-
- if (logfile_object_p->i_fid != -1) {
- if (close(logfile_object_p->i_fid))
- dbug_print(("error", "Could not close %s, %d",
- logfile_object_p->i_name, errno));
- logfile_object_p->i_fid = -1;
- }
- logfile_object_p->i_cur_offset = 0;
- logfile_object_p->i_cur_entry = NULL;
- dbug_leave("logfile_teardown");
-}
-
-/*
- * logfile_entry
- *
- * Description:
- * Sets addrp to the address of the log entry at offset
- * The mapping remains in effect until:
- * a) this routine is called again
- * b) logfile_teardown is called
- * c) this object is destroyed
- * Arguments:
- * offset offset to start of entry
- * entpp place to store address
- * Returns:
- * Returns 0 for success, 1 for EOF, -1 if a fatal error occurs.
- * Preconditions:
- * precond(addrp)
- */
-int
-logfile_entry(cfsd_logfile_object_t *logfile_object_p,
- off_t offset,
- cfs_dlog_entry_t **entpp)
-{
- cfs_dlog_entry_t *entp;
-
- dbug_enter("logfile_entry");
- dbug_precond(entpp);
- dbug_precond(offset >= sizeof (long));
-
-
- logfile_object_p->i_stat_nextcnt++;
-
- /* check for eof */
- if (offset >= logfile_object_p->i_size) {
- dbug_leave("logfile_entry");
- return (1);
- }
- dbug_assert((offset & 3) == 0);
-
- /* get the address of the entry */
- entp = (cfs_dlog_entry_t *)logfile_getaddr(logfile_object_p, offset, 0);
- if (entp == NULL) {
- dbug_leave("logfile_entry");
- return (-1);
- }
- /* sanity check, record should be alligned */
- if (entp->dl_len & 3) {
- dbug_print(("error",
- "Record at offset %d length is not alligned %d",
- offset, entp->dl_len));
- dbug_leave("logfile_entry");
- return (-1);
- }
-
- /* sanity check record should a reasonable size */
- if ((entp->dl_len < CFS_DLOG_ENTRY_MINSIZE) ||
- (entp->dl_len > CFS_DLOG_ENTRY_MAXSIZE)) {
- dbug_print(("error",
- "Record at offset %d has an invalid size %d", offset,
- entp->dl_len));
- dbug_leave("logfile_entry");
- return (-1);
- }
-
- /* preserve offset and pointer */
- logfile_object_p->i_cur_offset = offset;
- logfile_object_p->i_cur_entry = entp;
-
- /* return success */
- *entpp = entp;
- dbug_leave("logfile_entry");
- return (0);
-}
-
-/*
- * logfile_offset
- *
- * Description:
- * Sets addrp to the address of the specified offset.
- * The mapping remains in effect until:
- * a) this routine is called again
- * b) logfile_teardown is called
- * c) this object is destroyed
- * Arguments:
- * offset offset into file, must be 0 <= offset < i_size
- * addrp returns mapped address
- * Returns:
- * Returns 0 for success, -1 if a fatal error occurs.
- * Preconditions:
- * precond(addrp)
- */
-int
-logfile_offset(cfsd_logfile_object_t *logfile_object_p,
- off_t offset,
- caddr_t *addrp)
-{
- caddr_t pa;
-
- dbug_enter("logfile_offset");
- dbug_precond(addrp);
- dbug_precond((0 <= offset) && (offset < logfile_object_p->i_size));
-
- logfile_object_p->i_stat_offcnt++;
-
- /* get the address for the offset */
- pa = logfile_getaddr(logfile_object_p, offset, 1);
- if (pa == NULL) {
- dbug_leave("logfile_offset");
- return (-1);
- }
- /* return success */
- *addrp = pa;
- dbug_leave("logfile_offset");
- return (0);
-}
-
-/*
- * logfile_sync
- *
- * Description:
- * Performs an fsync on the log file.
- * Arguments:
- * Returns:
- * Returns 0 for success or an errno value on failure.
- * Preconditions:
- */
-int
-logfile_sync(cfsd_logfile_object_t *logfile_object_p)
-{
- int xx;
-
- dbug_enter("logfile_sync");
-
- if (logfile_object_p->i_fid == -1) {
- dbug_leave("logfile_sync");
- return (0);
- }
- xx = fsync(logfile_object_p->i_fid);
- if (xx) {
- xx = errno;
- dbug_print(("error", "fsync failed %d", xx));
- }
- dbug_leave("logfile_sync");
- return (xx);
-}
-
-/*
- * logfile_dumpstats
- *
- * Description:
- * Prints out various stats about the hashing.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-logfile_dumpstats(cfsd_logfile_object_t *logfile_object_p)
-{
- int xx;
- double dd;
-
- dbug_enter("logfile_dumpstats");
-
- dbug_print(("dump", "Request - next %d",
- logfile_object_p->i_stat_nextcnt));
- dbug_print(("dump", "Request - offset %d",
- logfile_object_p->i_stat_offcnt));
- dbug_print(("dump", "Map Moves %d", logfile_object_p->i_stat_mapmove));
- dbug_print(("dump", "Mapping Size %d", logfile_object_p->i_maplen));
- dbug_print(("dump", "Item Size %d", logfile_object_p->i_maxmap));
- dbug_print(("dump", "File Size %d", logfile_object_p->i_size));
- if (logfile_object_p->i_stat_mapmove == 0) {
- dbug_leave("logfile_dumpstats");
- return;
- }
-
- dd = (double)logfile_object_p->i_stat_mapmove /
- (logfile_object_p->i_stat_nextcnt +
- logfile_object_p->i_stat_offcnt);
- dbug_print(("dump", "Mmap moves per Request %.2f", dd));
-
- xx = logfile_object_p->i_stat_mapdist /
- logfile_object_p->i_stat_mapmove;
- dbug_print(("dump", "Average distance per mmap moves %d", xx));
- dbug_leave("logfile_dumpstats");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.h
deleted file mode 100644
index 08bb94a0cc..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_logfile.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * cfsd_logfile.h
- *
- * Include file for the cfsd_logfile class.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#ifndef CFSD_LOGFILE
-#define CFSD_LOGFILE
-
-/* should come up with a standard dlog version size */
-/* XXX should move these to <sys/fs/cachefs_dlog.h> */
-#define LOGFILE_ENTRY_START sizeof (long)
-#define CFS_DLOG_ENTRY_MINSIZE sizeof (long)
-
-/* mmap info */
-typedef struct mmap_info {
- caddr_t i_pa; /* address of mmap section */
- size_t i_palen; /* length of mmap section */
- off_t i_paoff; /* offset of mmap section */
- off_t i_paend; /* end offset of mmap section */
-}mmap_info_t;
-
-typedef struct cfsd_logfile_object {
- char i_name[MAXPATHLEN * 3]; /* name of file */
- int i_fid; /* fid of file */
- off_t i_size; /* file size */
- int i_stat_nextcnt; /* number of next calls */
- int i_stat_offcnt; /* number of offset calls */
- int i_stat_mapmove; /* number of times map moved */
- long i_stat_mapdist; /* how far we move the map */
-
- mmap_info_t i_map_entry; /* mmap for log entries */
- mmap_info_t i_map_offset; /* mmap for arbitrary offsets */
-
- off_t i_cur_offset; /* offset to log entry */
- cfs_dlog_entry_t *i_cur_entry; /* ptr to log entry */
-
- long i_pagesize; /* size of a page */
- u_long i_pagemask; /* page alignment mask */
- long i_maplen; /* amount to map */
- int i_maxmap; /* max amount referenced */
-} cfsd_logfile_object_t;
-
-cfsd_logfile_object_t *cfsd_logfile_create(void);
-void cfsd_logfile_destroy(cfsd_logfile_object_t *cfsd_logfile_object_p);
-
-int logfile_domap(cfsd_logfile_object_t *logfile_object_p, off_t off, int map);
-caddr_t logfile_getaddr(cfsd_logfile_object_t *logfile_object_p,
- off_t start, int map);
-
-/* performs setup for the specified file */
-int logfile_setup(cfsd_logfile_object_t *logfile_object_p,
- const char *filename, int maxmap);
-void logfile_teardown(cfsd_logfile_object_t *logfile_object_p);
-
-/* returns ptr to a log file entry */
-int logfile_entry(cfsd_logfile_object_t *logfile_object_p, off_t offset,
- cfs_dlog_entry_t **entpp);
-
-/* returns ptr to arbitrary point in log */
-int logfile_offset(cfsd_logfile_object_t *logfile_object_p, off_t offset,
- caddr_t *addrp);
-
-/* syncs the logfile to disk */
-int logfile_sync(cfsd_logfile_object_t *logfile_object_p);
-
-/* prints out various stats how the log file is used */
-void logfile_dumpstats(cfsd_logfile_object_t *logfile_object_p);
-
-#endif /* CFSD_LOGFILE */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_main.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_main.c
deleted file mode 100644
index 4f1fdeb8d3..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_main.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * 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
- * 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 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Main routines for cachefs daemon.
- */
-
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h> /* for pmap_unset */
-#include <string.h> /* strcmp */
-#include <signal.h>
-#include <unistd.h> /* setsid */
-#include <sys/types.h>
-#include <memory.h>
-#include <stropts.h>
-#include <netconfig.h>
-#include <libintl.h>
-#include <locale.h>
-#include <thread.h>
-#include <sys/resource.h> /* rlimit */
-#include <synch.h>
-#include <mdbug/mdbug.h>
-#include <common/cachefsd.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_fscache.h"
-#include "cfsd_cache.h"
-#include "cfsd_all.h"
-#include "cfsd_subr.h"
-
-#define RPCGEN_ACTION(X) X
-#include "cachefsd_tbl.i"
-
-#ifndef SIG_PF
-#define SIG_PF void(*)(int)
-#endif
-
-typedef bool_t (* LOCAL)(void *, void *, struct svc_req *);
-
-/* global definitions */
-cfsd_all_object_t *all_object_p = NULL;
-
-/* forward references */
-void msgout(char *msgp);
-void cachefsdprog_1(struct svc_req *rqstp, register SVCXPRT *transp);
-void sigusr1_handler(int, siginfo_t *, void *);
-static int void_close(void *, int);
-
-/*
- * -----------------------------------------------------------------
- * main
- *
- * Description:
- * main routine for the chart daemon.
- * Arguments:
- * argc
- * argv
- * Returns:
- * Returns 0 for a normal exit, !0 if an error occurred.
- * Preconditions:
- * precond(argv)
- */
-
-int
-main(int argc, char **argv)
-{
- pid_t pid;
- int xx;
- char mname[FMNAMESZ + 1];
- int opt_fork = 0;
- int opt_mt = 0;
- char *opt_root = NULL;
- int c;
- char *msgp;
- int size;
- struct rlimit rl;
- struct sigaction nact;
- int ofd = -1;
- char *netid;
- struct netconfig *nconf = NULL;
- SVCXPRT *transp;
- cfsd_fscache_object_t *fscache_object_p;
- int mode;
- /* selectable maximum RPC request record size */
- int maxrecsz = RPC_MAXDATASIZE;
-
- dbug_enter("main");
- dbug_process("cfsadmin");
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /* verify root */
- if (getuid() != 0) {
- fprintf(stderr, gettext("%s: must be run by root\n"), argv[0]);
- dbug_leave("main");
- return (1);
- }
-
- /* Increase number of file descriptors to maximum allowable */
- xx = getrlimit(RLIMIT_NOFILE, &rl);
- if (xx < 0) {
- dbug_print(("error",
- "getrlimit/RLIMIT_NOFILE failed %d", errno));
- dbug_leave("main");
- return (1);
- }
- rl.rlim_cur = rl.rlim_max;
- xx = setrlimit(RLIMIT_NOFILE, &rl);
- if (xx < 0) {
- dbug_print(("error",
- "setrlimit/RLIMIT_NOFILE failed %d", errno));
- dbug_leave("main");
- return (1);
- }
- (void) enable_extended_FILE_stdio(-1, -1);
-
- while ((c = getopt(argc, argv, "fmr:#:")) != EOF) {
- switch (c) {
- case 'f':
- opt_fork = 1;
- break;
-
- case 'm':
- /*
- * XXX don't use this until race between mount
- * and umount is fixed.
- */
- opt_mt = 1;
- break;
-
- case 'r':
- opt_root = optarg;
- break;
-
- case '#': /* dbug args */
- msgp = dbug_push(optarg);
- if (msgp) {
- printf("dbug_push failed \"%s\"\n", msgp);
- dbug_leave("main");
- return (1);
- }
- ofd = db_getfd();
- break;
-
- default:
- printf(gettext("illegal switch\n"));
- dbug_leave("main");
- return (1);
- }
- }
-
- /* XXX need some way to prevent multiple daemons from running */
-
- dbug_print(("info", "cachefsd started..."));
-
- if (opt_mt) {
- dbug_print(("info", "MT_AUTO mode set"));
- mode = RPC_SVC_MT_AUTO;
- if (!rpc_control(RPC_SVC_MTMODE_SET, &mode)) {
- msgout(gettext("unable to set automatic MT mode."));
- dbug_leave("main");
- return (1);
- }
- }
-
- /*
- * Enable non-blocking mode and maximum record size checks for
- * connection oriented transports.
- */
- if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) {
- msgout(gettext("unable to set max RPC record size"));
- }
-
- /* ignore sigpipe */
- nact.sa_handler = SIG_IGN;
- nact.sa_sigaction = NULL;
- sigemptyset(&nact.sa_mask);
- nact.sa_flags = 0;
- xx = sigaction(SIGPIPE, &nact, NULL);
- if (xx) {
- dbug_print(("error", "sigaction/SIGPIPE failed %d", errno));
- }
-
- /* catch sigusr1 signals, used to wake up threads */
- nact.sa_handler = NULL;
- nact.sa_sigaction = sigusr1_handler;
- sigemptyset(&nact.sa_mask);
- nact.sa_flags = SA_SIGINFO;
- xx = sigaction(SIGUSR1, &nact, NULL);
- if (xx) {
- dbug_print(("error", "sigaction failed %d", errno));
- }
-
- /* do not set up rpc services if just taking care of root */
- if (opt_root) {
- dbug_print(("info", "handling just root"));
-
- /* make the fscache object */
- fscache_object_p =
- cfsd_fscache_create("rootcache", opt_root, 1);
-
- /* init the fscache object with mount information */
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- fscache_setup(fscache_object_p);
- fscache_object_p->i_mounted = 1;
- fscache_unlock(fscache_object_p);
-
- if (fscache_object_p->i_disconnectable &&
- fscache_object_p->i_mounted) {
- pid = fork();
- if (pid < 0) {
- perror(gettext("cannot fork"));
- cfsd_fscache_destroy(fscache_object_p);
- dbug_leave("main");
- return (1);
- }
- if (pid) {
- cfsd_fscache_destroy(fscache_object_p);
- dbug_leave("main");
- return (0);
- }
- (void) fdwalk(void_close, &ofd);
- xx = open("/dev/sysmsg", O_RDWR);
- (void) dup2(xx, 1);
- (void) dup2(xx, 2);
- setsid();
-
- fscache_process(fscache_object_p);
- } else {
- /* not disconnectable */
- cfsd_fscache_destroy(fscache_object_p);
- dbug_leave("main");
- return (1);
- }
- cfsd_fscache_destroy(fscache_object_p);
- dbug_leave("main");
- return (0);
- }
-
- /* if a inetd started us */
- else if (!ioctl(0, I_LOOK, mname) &&
- ((strcmp(mname, "sockmod") == 0) ||
- (strcmp(mname, "timod") == 0))) {
- dbug_print(("info", "started by inetd"));
-
- if (freopen("/dev/null", "w", stderr) == NULL)
- return (1);
-
- /* started from inetd */
- if ((netid = getenv("NLSPROVIDER")) == NULL)
- netid = "ticotsord";
- if ((nconf = getnetconfigent(netid)) == NULL)
- msgout(gettext("cannot get transport info"));
-
- if (strcmp(mname, "sockmod") == 0) {
- if (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, "timod")) {
- msgout(
- gettext("could not get the right module"));
- dbug_leave("main");
- return (1);
- }
- }
- if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
- msgout(gettext("cannot create server handle"));
- dbug_leave("main");
- return (1);
- }
- if (nconf)
- freenetconfigent(nconf);
- xx = svc_reg(transp, CACHEFSDPROG, CACHEFSDVERS,
- cachefsdprog_1, 0);
- if (!xx) {
- msgout(gettext(
- "unable to reg (CACHEFSDPROG, CACHEFSDVERS)."));
- dbug_leave("main");
- return (1);
- }
- }
-
- /* else if started by hand */
- else {
- /* if we should fork */
- if (opt_fork) {
- dbug_print(("info", "forking"));
- pid = fork();
- if (pid < 0) {
- perror(gettext("cannot fork"));
- dbug_leave("main");
- return (1);
- }
- if (pid) {
- dbug_leave("main");
- return (0);
- }
- (void) fdwalk(void_close, &ofd);
- xx = open("/dev/sysmsg", 2);
- (void) dup2(xx, 1);
- (void) dup2(xx, 2);
- setsid();
- }
-
- /* connect to *ANY* local loopback transport provider */
- xx = svc_create(cachefsdprog_1, CACHEFSDPROG, CACHEFSDVERS,
- "local");
- if (!xx) {
- msgout(gettext("unable to create (CACHEFSDPROG, "
- "CACHEFSDVERS) for netpath."));
- dbug_leave("main");
- return (1);
- }
- }
-
- /* find existing caches and mounted file systems */
- all_object_p = cfsd_all_create();
- subr_cache_setup(all_object_p);
-
- /* process requests */
- svc_run();
-
- msgout(gettext("svc_run returned"));
- cfsd_all_destroy(all_object_p);
- dbug_leave("main");
- return (1);
-}
-
-/*
- * Callback function for fdwalk() to close all files.
- */
-static int
-void_close(void *ofdp, int fd)
-{
- if (fd != *(int *)ofdp) {
- if (close(fd) != 0)
- dbug_print(("err",
- "cannot close fd %d, %d", fd, errno));
- }
- return (0);
-}
-
-/*
- * -----------------------------------------------------------------
- * msgout
- *
- * Description:
- * Outputs an error message to stderr.
- * Arguments:
- * msgp
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-
-void
-msgout(char *msgp)
-{
- dbug_enter("msgout");
- dbug_precond(msgp);
-
- (void) fprintf(stderr, "%s\n", msgp);
- dbug_leave("msgout");
-}
-
-
-/*
- * -----------------------------------------------------------------
- * cachefsdprog_1
- *
- * Description:
- * Arguments:
- * rqstp
- * transp
- * Returns:
- * Preconditions:
- * precond(rqstp)
- * precond(transp)
- */
-void
-cachefsdprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
-{
- int index;
- struct rpcgen_table *rtp;
- void *argumentp = NULL;
- void *resultp = NULL;
- LOCAL local;
- int xx;
-
- dbug_enter("cachefsdprog_1");
-
- dbug_precond(rqstp);
- dbug_precond(transp);
-
- /* make sure a valid command number */
- index = rqstp->rq_proc;
- if ((index < 0) || (cachefsdprog_1_nproc <= index)) {
- msgout(gettext("bad message"));
- svcerr_noproc(transp);
- dbug_leave("cachefsdprog_1");
- return;
- }
-
- /* get command information */
- rtp = &cachefsdprog_1_table[index];
-
- /* get memory for the arguments */
- if (rtp->len_arg != 0)
- argumentp = (void *)cfsd_calloc(rtp->len_arg);
-
- /* get memory for the results */
- if (rtp->len_res != 0)
- resultp = (void *)cfsd_calloc(rtp->len_res);
-
- /* get the arguments */
- if (rtp->xdr_arg && argumentp) {
- if (!svc_getargs(transp, rtp->xdr_arg, (caddr_t)argumentp)) {
- svcerr_decode(transp);
- cfsd_free(argumentp);
- cfsd_free(resultp);
- dbug_leave("cachefsdprog_1");
- return;
- }
- }
-
- /* call the routine to process the command */
- local = (LOCAL)rtp->proc;
- xx = (*local)(argumentp, resultp, rqstp);
-
- /* if the command could not be processed */
- if (xx == 0) {
- svcerr_systemerr(transp);
- }
-
- /* else send the results back to the caller */
- else {
- xx = svc_sendreply(transp, rtp->xdr_res, (caddr_t)resultp);
- if (!xx)
- svcerr_systemerr(transp);
-
- /* free the results */
- xx = cachefsdprog_1_freeresult(transp, rtp->xdr_res,
- (caddr_t)resultp);
- if (xx == 0)
- msgout(gettext("unable to free results"));
- }
-
- /* free the passed in arguments */
- if (!svc_freeargs(transp, rtp->xdr_arg, (caddr_t)argumentp)) {
- msgout(gettext("unable to free arguments"));
- abort();
- }
-
- if (argumentp)
- cfsd_free(argumentp);
- if (resultp)
- cfsd_free(resultp);
- dbug_leave("cachefsdprog_1");
-}
-
-/*
- * sigusr1_handler
- *
- * Description:
- * Catches sigusr1 signal so threads wake up.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-sigusr1_handler(int sig, siginfo_t *sp, void *vp)
-{
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.c
deleted file mode 100644
index b47398cc05..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * 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 1994-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Methods of the cfsd_maptbl classes.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <synch.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
-#include <sys/cred.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <mdbug/mdbug.h>
-#include "cfsd.h"
-#include "cfsd_maptbl.h"
-
-/*
- * cfsd_maptbl_create
- *
- * Description:
- * Constructor for the cfsd_maptbl class.
- * Just does some setup not much else.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-cfsd_maptbl_object_t *
-cfsd_maptbl_create(void)
-{
- cfsd_maptbl_object_t *maptbl_object_p;
-
- dbug_enter("cfsd_maptbl_create");
-
- maptbl_object_p = cfsd_calloc(sizeof (cfsd_maptbl_object_t));
-
- maptbl_object_p->i_fid = -1;
- maptbl_object_p->i_pa = NULL;
- maptbl_object_p->i_paoff = 0;
- maptbl_object_p->i_paend = 0;
- maptbl_object_p->i_palen = 0;
- dbug_leave("cfsd_maptbl_create");
- return (maptbl_object_p);
-}
-
-/*
- * cfsd_maptbl_destroy
- *
- * Description:
- * Destructor for the cfsd_maptbl class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-cfsd_maptbl_destroy(cfsd_maptbl_object_t *maptbl_object_p)
-{
- dbug_enter("cfsd_maptbl_destroy");
- dbug_precond(maptbl_object_p);
- maptbl_teardown(maptbl_object_p);
- cfsd_free(maptbl_object_p);
- dbug_leave("cfsd_maptbl_destroy");
-}
-
-/*
- * maptbl_domap
- *
- * Description:
- * Maps in the specified section of the file.
- * Arguments:
- * off The offset to map in. Must be i_pagesize aligned.
- * Returns:
- * Returns 0 for success or an errno value on failure.
- * Preconditions:
- */
-int
-maptbl_domap(cfsd_maptbl_object_t *maptbl_object_p, off_t off)
-{
- int xx;
- int len;
-
- dbug_enter("maptbl_domap");
- dbug_precond(maptbl_object_p);
- dbug_precond(maptbl_object_p->i_fid >= 0);
-
- len = maptbl_object_p->i_maplen;
-
- maptbl_object_p->i_stat_mapmove++;
-
- /* destroy old mapping if it exists */
- if (maptbl_object_p->i_pa) {
- /* determine how far we have to move the map */
- maptbl_object_p->i_stat_mapdist +=
- abs(maptbl_object_p->i_paoff - off);
-
- /* remove the map */
- xx = munmap(maptbl_object_p->i_pa, maptbl_object_p->i_palen);
- if (xx == -1) {
- xx = errno;
- dbug_print(("error", "Could not unmap %s, %d, %p, %d",
- maptbl_object_p->i_name, xx, maptbl_object_p->i_pa,
- maptbl_object_p->i_palen));
- }
- maptbl_object_p->i_pa = NULL;
- maptbl_object_p->i_palen = 0;
- maptbl_object_p->i_paoff = 0;
- maptbl_object_p->i_paend = 0;
- }
-
- /* do the mapping */
- maptbl_object_p->i_pa =
- mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
- maptbl_object_p->i_fid, off);
- if (maptbl_object_p->i_pa == MAP_FAILED) {
- xx = errno;
- dbug_print(("error",
- "Could not map %s, error %d, off %d, len %d",
- maptbl_object_p->i_name, xx, off, len));
- maptbl_object_p->i_pa = NULL;
- dbug_leave("maptbl_domap");
- return (xx);
- }
-
- maptbl_object_p->i_palen = len;
- maptbl_object_p->i_paoff = off;
- maptbl_object_p->i_paend = off + len - 1;
- dbug_leave("maptbl_domap");
- return (0);
-}
-
-/*
- * maptbl_getaddr
- *
- * Description:
- * Returns an address of a particular entry in the file.
- * Arguments:
- * index
- * Returns:
- * Returns NULL for a failure with the mapping file.
- * Preconditions:
- */
-caddr_t
-maptbl_getaddr(cfsd_maptbl_object_t *maptbl_object_p, int index)
-{
- off_t start;
- off_t end;
- caddr_t pa;
-
- dbug_enter("maptbl_getaddr");
- dbug_precond(maptbl_object_p);
- dbug_precond(index < maptbl_object_p->i_entries);
-
- /* find the boundaries of the entry */
- start = index * sizeof (struct cfs_dlog_mapping_space);
- end = start + sizeof (struct cfs_dlog_mapping_space) - 1;
-
- /* map the entry in if necessary */
- if ((start < maptbl_object_p->i_paoff) ||
- (maptbl_object_p->i_paend < end)) {
- if (maptbl_domap(maptbl_object_p,
- start & maptbl_object_p->i_pagemask)) {
- dbug_leave("maptbl_getaddr");
- return (NULL);
- }
- }
-
- /* make an address and return it */
- pa = maptbl_object_p->i_pa + (start - maptbl_object_p->i_paoff);
- dbug_leave("maptbl_getaddr");
- return (pa);
-}
-
-/*
- * maptbl_cidhashaddr
- *
- * Description:
- * Finds the address of the specified cid by hashing to
- * the appropriate entry. If the cid does not already
- * exist in the file, then the address of where it should
- * reside is returned.
- * Arguments:
- * cid
- * addrp
- * Returns:
- * Returns 0 for success, 1 if entry not found, -1 if an
- * error occurs in the mapping file.
- * Preconditions:
- */
-int
-maptbl_cidhashaddr(cfsd_maptbl_object_t *maptbl_object_p,
- cfs_cid_t cid,
- caddr_t *addrp)
-{
- ino64_t *pa;
- int index;
- ino64_t fileno;
- int start_index;
-
- dbug_enter("maptbl_cidhashaddr");
- dbug_precond(maptbl_object_p);
- dbug_precond(addrp);
-
- maptbl_object_p->i_stat_requests++;
-
- /* get the index from the first hash function */
- index = maptbl_hash1(maptbl_object_p, cid);
-
- maptbl_object_p->i_stat_probes++;
-
- /* get the address of the entry */
- pa = (ino64_t *)maptbl_getaddr(maptbl_object_p, index);
- if (pa == NULL) {
- dbug_leave("maptbl_cidhashaddr");
- return (-1);
- }
- fileno = *pa;
-
- /* check for match */
- if (fileno == cid.cid_fileno) {
- *addrp = (caddr_t)pa;
- dbug_leave("maptbl_cidhashaddr");
- return (0);
- }
-
- /* check for not found */
- if (fileno == 0) {
- *addrp = (caddr_t)pa;
- dbug_leave("maptbl_cidhashaddr");
- return (1);
- }
-
- /* get the index from the second hash function */
- index = maptbl_hash2(maptbl_object_p, cid, index);
-
- /* do a linear search for a match or empty entry */
- start_index = index;
- do {
- maptbl_object_p->i_stat_probes++;
-
- /* get the address of the entry */
- pa = (ino64_t *)maptbl_getaddr(maptbl_object_p, index);
- if (pa == NULL) {
- dbug_leave("maptbl_cidhashaddr");
- return (-1);
- }
- fileno = *pa;
-
- /* check for match */
- if (fileno == cid.cid_fileno) {
- *addrp = (caddr_t)pa;
- dbug_leave("maptbl_cidhashaddr");
- return (0);
- }
-
- /* check for not found */
- if (fileno == 0) {
- *addrp = (caddr_t)pa;
- dbug_leave("maptbl_cidhashaddr");
- return (1);
- }
-
- /* move to the next entry */
- index++;
- index = index % maptbl_object_p->i_entries;
- } while (start_index != index);
-
- /* table full, this is bad */
- dbug_print(("error", "Table is full"));
- dbug_leave("maptbl_cidhashaddr");
- return (-1);
-}
-
-/*
- * maptbl_hash1
- *
- * Description:
- * Hashes a cid into an index into the table.
- * Arguments:
- * cid
- * Returns:
- * Returns the index.
- * Preconditions:
- */
-int
-maptbl_hash1(cfsd_maptbl_object_t *maptbl_object_p, cfs_cid_t cid)
-{
- unsigned int xx;
- unsigned int a, b;
-
- dbug_precond(maptbl_object_p);
-#if 0
- xx = cid.cid_fileno % i_entries;
-#else
- a = cid.cid_fileno >> 16;
- b = a ^ cid.cid_fileno;
- xx = b % maptbl_object_p->i_entries;
-#endif
- return (xx);
-}
-
-/*
- * maptbl_hash2
- *
- * Description:
- * Hashes a cid into an index into the table.
- * Arguments:
- * cid
- * index
- * Returns:
- * Returns the index.
- * Preconditions:
- */
-int
-maptbl_hash2(cfsd_maptbl_object_t *maptbl_object_p, cfs_cid_t cid, int index)
-{
- unsigned int xx;
- unsigned int a, b, c, d;
-
- dbug_precond(maptbl_object_p);
-#if 0
- a = cid.cid_fileno & 0x0ff;
- b = (cid.cid_fileno >> 8) & 0x0ff;
- b = cid.cid_fileno ^ a ^ b;
- xx = b % maptbl_object_p->i_hash2mod;
-#else
- a = cid.cid_fileno & 0x0ff;
- b = (cid.cid_fileno >> 8) & 0x0ff;
- c = (cid.cid_fileno >> 16) & 0x0ff;
- d = (cid.cid_fileno >> 24) & 0x0ff;
- xx = cid.cid_fileno ^ (a << 8) ^ b ^ c ^ d;
- xx = xx % maptbl_object_p->i_hash2mod;
-#endif
- xx = (index + xx) % maptbl_object_p->i_entries;
- return (xx);
-}
-
-/*
- * maptbl_setup
- *
- * Description:
- * Performs setup for the cfsd_maptbl class.
- * This routine must be called before other routines are used.
- * Arguments:
- * filename
- * Returns:
- * Returns 0 for success or an errno value.
- * Preconditions:
- * precond(filename)
- */
-int
-maptbl_setup(cfsd_maptbl_object_t *maptbl_object_p, const char *filename)
-{
- int xx;
- struct stat sinfo;
- off_t offset;
- long *lp;
- size_t cnt;
- off_t size;
-
- dbug_enter("maptbl_setup");
- dbug_precond(maptbl_object_p);
- dbug_precond(filename);
-
- /* clean up from a previous setup */
- maptbl_teardown(maptbl_object_p);
-
- strlcpy(maptbl_object_p->i_name, filename,
- sizeof (maptbl_object_p->i_name));
- dbug_print(("info", "filename %s", maptbl_object_p->i_name));
-
- /* get the page info */
- maptbl_object_p->i_pagesize = PAGESIZE;
- maptbl_object_p->i_pagemask = PAGEMASK;
- maptbl_object_p->i_maplen = maptbl_object_p->i_pagesize * 100;
-
- /* open the file */
- maptbl_object_p->i_fid = open(maptbl_object_p->i_name,
- O_RDWR | O_NONBLOCK);
- if (maptbl_object_p->i_fid == -1) {
- xx = errno;
- dbug_print(("error",
- "Could not open %s, %d", maptbl_object_p->i_name, xx));
- dbug_leave("maptbl_setup");
- return (xx);
- }
-
- /* get the size and type of file */
- xx = fstat(maptbl_object_p->i_fid, &sinfo);
- if (xx) {
- xx = errno;
- dbug_print(("error",
- "Could not stat %s, %d", maptbl_object_p->i_name, xx));
- dbug_leave("maptbl_setup");
- return (xx);
- }
- maptbl_object_p->i_size = sinfo.st_size;
-
- /* sanity check, better be a regular file */
- if (!S_ISREG(sinfo.st_mode)) {
- xx = ENOTSUP;
- dbug_print(("error",
- "%s Not a regular file.", maptbl_object_p->i_name));
- dbug_leave("maptbl_setup");
- return (xx);
- }
-
- /* determine number of entries */
- maptbl_object_p->i_entries =
- maptbl_object_p->i_size / sizeof (struct cfs_dlog_mapping_space);
-
- /* set up modulo value for second hash function */
- maptbl_object_p->i_hash2mod = (maptbl_object_p->i_entries / 2) + 1;
-
- /* initialize statistic gathering */
- maptbl_object_p->i_stat_requests = 0;
- maptbl_object_p->i_stat_probes = 0;
- maptbl_object_p->i_stat_mapmove = 0;
- maptbl_object_p->i_stat_mapdist = 0;
- maptbl_object_p->i_stat_filled = 0;
-
- /* zero the file */
- for (offset = 0; offset < maptbl_object_p->i_size;
- offset += maptbl_object_p->i_maplen) {
- /* map in a section of the file */
- xx = maptbl_domap(maptbl_object_p, offset);
- if (xx) {
- dbug_leave("maptbl_setup");
- return (xx);
- }
- /* zero this section of the file */
- lp = (long *)maptbl_object_p->i_pa;
- size = maptbl_object_p->i_size - offset;
- if (size < maptbl_object_p->i_palen) {
- cnt = size / sizeof (long);
- } else {
- cnt = maptbl_object_p->i_palen / sizeof (long);
- dbug_assert((cnt * sizeof (long)) ==
- maptbl_object_p->i_palen);
- }
- memset(lp, 0, cnt * sizeof (*lp));
- }
-
- /* return success */
- dbug_leave("maptbl_setup");
- return (0);
-}
-
-/*
- * maptbl_teardown
- *
- * Description:
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-maptbl_teardown(cfsd_maptbl_object_t *maptbl_object_p)
-{
- int xx;
-
- dbug_enter("maptbl_teardown");
- dbug_precond(maptbl_object_p);
-
- if (maptbl_object_p->i_pa) {
- xx = munmap(maptbl_object_p->i_pa, maptbl_object_p->i_palen);
- if (xx == -1) {
- xx = errno;
- dbug_print(("error", "Could not unmap %s, %d, %p, %d",
- maptbl_object_p->i_name, xx, maptbl_object_p->i_pa,
- maptbl_object_p->i_palen));
- }
- maptbl_object_p->i_pa = NULL;
- }
- maptbl_object_p->i_paoff = 0;
- maptbl_object_p->i_paend = 0;
- maptbl_object_p->i_palen = 0;
-
- if (maptbl_object_p->i_fid != -1) {
- if (close(maptbl_object_p->i_fid))
- dbug_print(("err", "cannot close maptbl fd, error %d",
- errno));
- maptbl_object_p->i_fid = -1;
- }
- dbug_leave("maptbl_teardown");
-}
-
-/*
- * maptbl_get
- *
- * Description:
- * Gets the mapping info for the specified cid.
- * Arguments:
- * cid
- * valuep
- * Returns:
- * Returns 0 for success, 1 if entry not found, -1 if an
- * error occurs in the mapping file.
- * Preconditions:
- * precond(valuep)
- */
-int
-maptbl_get(cfsd_maptbl_object_t *maptbl_object_p,
- cfs_cid_t cid,
- struct cfs_dlog_mapping_space *valuep)
-{
- int xx;
- struct cfs_dlog_mapping_space *pa;
-
- dbug_enter("maptbl_get");
- dbug_precond(maptbl_object_p);
- dbug_precond(valuep);
-
- if (maptbl_object_p->i_entries == 0) {
- dbug_leave("maptbl_get");
- return (1);
- }
- xx = maptbl_cidhashaddr(maptbl_object_p, cid, (caddr_t *)&pa);
- if (xx == 0)
- *valuep = *pa;
- dbug_leave("maptbl_get");
- return (xx);
-}
-
-/*
- * maptbl_set
- *
- * Description:
- * Sets the mapping info for the cid.
- * If insert is 1 then if the entry is not found it is put in the
- * table.
- * Arguments:
- * valuep
- * insert
- * Returns:
- * Returns 0 if mapping info placed in the table, 1 if entry
- * is not found an insert is 0, -1 if an error occurs in the
- * mapping file.
- * Preconditions:
- * precond(valuep)
- */
-int
-maptbl_set(cfsd_maptbl_object_t *maptbl_object_p,
- struct cfs_dlog_mapping_space *valuep,
- int insert)
-{
- int xx;
- struct cfs_dlog_mapping_space *pa;
-
- dbug_enter("maptbl_set");
- dbug_precond(maptbl_object_p);
- dbug_precond(valuep);
-
- dbug_assert(maptbl_object_p->i_entries > 0);
-
- xx = maptbl_cidhashaddr(maptbl_object_p, valuep->ms_cid,
- (caddr_t *)&pa);
- if ((xx == 0) || ((xx == 1) && insert)) {
- *pa = *valuep;
- if (xx == 1)
- maptbl_object_p->i_stat_filled++;
- xx = 0;
- }
- dbug_leave("maptbl_set");
- return (xx);
-}
-
-/*
- * maptbl_dumpstats
- *
- * Description:
- * Prints out various stats about the hashing.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-maptbl_dumpstats(cfsd_maptbl_object_t *maptbl_object_p)
-{
- int xx;
- double dd;
-
- dbug_enter("maptbl_dumpstats");
- dbug_precond(maptbl_object_p);
-
- dbug_print(("dump", "Total Entries %d", maptbl_object_p->i_entries));
- dbug_print(("dump", "Filled Entries %d",
- maptbl_object_p->i_stat_filled));
- dbug_print(("dump", "Requests %d", maptbl_object_p->i_stat_requests));
- dbug_print(("dump", "Probes %d", maptbl_object_p->i_stat_probes));
- dbug_print(("dump", "Map Moves %d", maptbl_object_p->i_stat_mapmove));
- dbug_print(("dump", "Mapping Size %d", maptbl_object_p->i_maplen));
- dbug_print(("dump", "File Size %d", maptbl_object_p->i_size));
- if (maptbl_object_p->i_stat_requests == 0) {
- dbug_leave("maptbl_dumpstats");
- return;
- }
- dd = (double)maptbl_object_p->i_stat_probes /
- maptbl_object_p->i_stat_requests;
- dbug_print(("dump", "Probes per Request %.2f", dd));
-
- dd = (double)maptbl_object_p->i_stat_mapmove /
- maptbl_object_p->i_stat_requests;
- dbug_print(("dump", "Mmap moves per Request %.2f", dd));
-
- xx = maptbl_object_p->i_stat_mapdist / maptbl_object_p->i_stat_mapmove;
- dbug_print(("dump", "Average distance per mmap moves %d", xx));
-
- xx = ((100.0 * maptbl_object_p->i_stat_filled) /
- maptbl_object_p->i_entries) + .5;
- dbug_print(("dump", "Table filled %d%%", xx));
-
- dbug_leave("maptbl_dumpstats");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.h
deleted file mode 100644
index 18a0f7d669..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_maptbl.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * cfsd_maptbl.h
- *
- * Include file for the maptbl class.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#ifndef CFSD_MAPTBL
-#define CFSD_MAPTBL
-
-typedef struct cfsd_maptbl_object {
- char i_name[MAXPATHLEN * 3]; /* name of file */
- int i_fid; /* fid of file */
- off_t i_size; /* file size */
- int i_entries; /* number of entries */
- int i_hash2mod; /* second hash module value */
- int i_stat_filled; /* number of filled entries */
- int i_stat_requests; /* number of lookups done */
- int i_stat_probes; /* number of probes */
- int i_stat_mapmove; /* number of times map moved */
- long i_stat_mapdist; /* how far we move the map */
- caddr_t i_pa; /* address of mmap section */
- size_t i_palen; /* length of mmap section */
- off_t i_paoff; /* offset of mmap section */
- off_t i_paend; /* end offset of mmap section */
- long i_pagesize; /* size of a page */
- u_long i_pagemask; /* page alignment mask */
- long i_maplen; /* amount to map */
-} cfsd_maptbl_object_t;
-
-cfsd_maptbl_object_t *cfsd_maptbl_create(void);
-void cfsd_maptbl_destroy(cfsd_maptbl_object_t *maptbl_object_p);
-
-int maptbl_domap(cfsd_maptbl_object_t *maptbl_object_p, off_t off);
-caddr_t maptbl_getaddr(cfsd_maptbl_object_t *maptbl_object_p, int index);
-int maptbll_cidhashaddr(cfsd_maptbl_object_t *maptbl_object_p,
- cfs_cid_t cid, caddr_t *addrp);
-int maptbl_hash1(cfsd_maptbl_object_t *maptbl_object_p, cfs_cid_t cid);
-int maptbl_hash2(cfsd_maptbl_object_t *maptbl_object_p, cfs_cid_t cid,
- int index);
-
-/* performs setup for the specified file */
-int maptbl_setup(cfsd_maptbl_object_t *maptbl_object_p, const char *filename);
-void maptbl_teardown(cfsd_maptbl_object_t *maptbl_object_p);
-
-/* gets/sets cid mapping */
-int maptbl_get(cfsd_maptbl_object_t *maptbl_object_p, cfs_cid_t cid,
- struct cfs_dlog_mapping_space *valuep);
-int maptbl_set(cfsd_maptbl_object_t *maptbl_object_p,
- struct cfs_dlog_mapping_space *valuep, int insert);
-
-/* prints out various stats about the hashing */
-void maptbl_dumpstats(cfsd_maptbl_object_t *maptbl_object_p);
-
-#endif /* CFSD_MAPTBL */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.c
deleted file mode 100644
index 73f5bb0a5e..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Various support routines.
- */
-
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <dirent.h>
-#include <wait.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h> /* for pmap_unset */
-#include <string.h> /* strcmp */
-#include <signal.h>
-#include <unistd.h> /* setsid */
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/mnttab.h>
-#include <sys/vfstab.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <memory.h>
-#include <stropts.h>
-#include <netconfig.h>
-#include <sys/resource.h> /* rlimit */
-#include <thread.h>
-#include <synch.h>
-#include <mdbug/mdbug.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_fscache.h"
-#include "cfsd_cache.h"
-#include "cfsd_all.h"
-#include <common/cachefsd.h>
-#include <common/subr.h>
-
-/* forward references */
-void *subr_mount_thread(void *datap);
-int subr_fsck_cache(const char *cachedirp);
-void subr_doexec(const char *fstype, char *newargv[], const char *progp);
-
-/*
- * subr_add_mount
- *
- * Description:
- * Adds the specified file system to the data structures.
- * Arguments:
- * allp ptr to set of data structures
- * dirp ptr to name of cache directory
- * idp ptr to id of file system cache in dirp
- * Returns:
- * Preconditions:
- * precond(allp)
- * precond(dirp)
- * precond(idp)
- */
-void
-subr_add_mount(cfsd_all_object_t *all_object_p,
- const char *dirp,
- const char *idp)
-{
- int xx;
- thread_t new_thread;
- cfsd_cache_object_t *cache_object_p;
- cfsd_fscache_object_t *fscache_object_p;
-
- dbug_enter("subr_add_mount");
-
- dbug_precond(all_object_p);
- dbug_precond(dirp);
- dbug_precond(idp);
-
- dbug_print(("info", "cachedir %s, cacheid %s", dirp, idp));
-
- /* find or create the cache object */
- all_lock(all_object_p);
- cache_object_p = all_cachelist_find(all_object_p, dirp);
- if (cache_object_p == NULL) {
- /* make the cache object */
- cache_object_p = cfsd_cache_create();
- xx = all_object_p->i_nextcacheid;
- xx = cache_setup(cache_object_p, dirp, xx);
- if (xx == 0) {
- dbug_print(("error", "invalid cache %s", dirp));
- cfsd_cache_destroy(cache_object_p);
- all_unlock(all_object_p);
- dbug_leave("subr_add_mount");
- return;
- }
- all_cachelist_add(all_object_p, cache_object_p);
- all_cachefstab_update(all_object_p);
- }
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt++;
- cache_unlock(cache_object_p);
- all_unlock(all_object_p);
-
- /* find or create the fscache object */
- cache_lock(cache_object_p);
- fscache_object_p = cache_fscachelist_find(cache_object_p, idp);
- if (fscache_object_p == NULL) {
- /* make the fscache object and add it to the list */
- xx = cache_object_p->i_nextfscacheid;
- fscache_object_p = cfsd_fscache_create(idp, dirp, xx);
- cache_fscachelist_add(cache_object_p, fscache_object_p);
- } else {
- /* don't do any more if already mounted */
- fscache_lock(fscache_object_p);
- if (fscache_object_p->i_mounted) {
- cache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
- cache_unlock(cache_object_p);
- dbug_print(("info", "fscache already mounted"));
- dbug_leave("subr_add_mount");
- return;
- }
- fscache_unlock(fscache_object_p);
- }
-
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- fscache_unlock(fscache_object_p);
- cache_unlock(cache_object_p);
-
- /* init the fscache object with mount information */
- fscache_lock(fscache_object_p);
- fscache_setup(fscache_object_p);
-
- /* start the disconnect thread if necessary */
- if (fscache_object_p->i_disconnectable &&
- fscache_object_p->i_mounted &&
- (fscache_object_p->i_threaded == 0) &&
- (strcmp(fscache_object_p->i_name, "rootcache") != 0)) {
- fscache_object_p->i_refcnt++;
- fscache_object_p->i_threaded = 1;
- xx = thr_create(NULL, 0, subr_mount_thread, fscache_object_p,
- THR_DETACHED | THR_NEW_LWP, &new_thread);
- if (xx) {
- /* XXX cachefs kmod cannot allow transition */
- dbug_print(("error", "mount thr_create failed %d", xx));
- fscache_object_p->i_refcnt--;
- fscache_object_p->i_threaded = 0;
- }
- fscache_object_p->i_threadid = new_thread;
- }
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
-
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- dbug_leave("subr_add_mount");
-}
-
-/*
- * ------------------------------------------------------------
- * subr_mount_thread
- *
- * Description:
- * Called when a thread is created via thr_create to process
- * an fscache.
- * Arguments:
- * datap ptr to cfsd_fscache to process
- * Returns:
- * Returns NULL.
- * Preconditions:
- * precond(datap)
- */
-void *
-subr_mount_thread(void *datap)
-{
- cfsd_fscache_object_t *fscache_object_p;
-
- dbug_enter("subr_mount_thread");
- dbug_precond(datap);
-
- fscache_object_p = (cfsd_fscache_object_t *)datap;
-
- fscache_process(fscache_object_p);
-
- fscache_lock(fscache_object_p);
-
- /* close down the message file descriptor */
- if (fscache_object_p->i_ofd >= 0) {
- if (close(fscache_object_p->i_ofd))
- dbug_print(("error", "cannot close fscache fd error %d",
- errno));
- fscache_object_p->i_ofd = -1;
- }
-
- fscache_object_p->i_threaded = 0;
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
-
- dbug_leave("subr_mount_thread");
- return (NULL);
-}
-
-/*
- * ------------------------------------------------------------
- * subr_cache_setup
- *
- * Description:
- * Called once when the daemon starts up to get the current state
- * of caches reflected in the daemon.
- * Arguments:
- * allp
- * Returns:
- * Preconditions:
- * precond(allp)
- */
-void
-subr_cache_setup(cfsd_all_object_t *all_object_p)
-{
- cfsd_cache_object_t *cache_object_p;
- int fixcachefstab = 0;
- int xx;
- FILE *fin;
- char buf[MAXPATHLEN];
- struct mnttab minfo;
- struct mnttab mpref;
- char *cp;
- char *xcp;
- struct vfstab vinfo;
- struct vfstab vpref;
- size_t index;
- int lockfd;
- DIR *dirp;
- char pathname[MAXPATHLEN];
- int len;
- struct dirent64 *entp;
- struct stat64 sinfo;
-
- dbug_enter("subr_cache_setup");
- dbug_precond(all_object_p);
-
- all_lock(all_object_p);
-
- /* find all the caches indicated in the CACHEFSTAB file */
- fin = fopen(CACHEFSTAB, "r");
- if (fin == NULL) {
- dbug_print(("info", "%s does not exist", CACHEFSTAB));
- } else {
- while (fgets(buf, sizeof (buf), fin) != NULL) {
- if (strlen(buf) == 1)
- continue;
- /*
- * if the line did not fit in the buffer
- * it is invalid (i.e. no newline char)
- */
- dbug_precond(buf[(strlen(buf) - 1)] == '\n');
- if (buf[(strlen(buf) - 1)] != '\n') {
-#if 0
- /*
- * if the line is invalid read until
- * you get to the next line.
- * we only need to do this if we are
- * going to continue
- */
- do {
- cp = fgets(buf, sizeof (buf), fin);
- } while ((cp != NULL) &&
- (buf[(strlen(buf) - 1)] != '\n'));
-#endif
- break;
- }
- buf[strlen(buf) - 1] = '\0';
- dbug_print(("info", "cachefstab cache \"%s\"", buf));
- cache_object_p = all_cachelist_find(all_object_p, buf);
- if (cache_object_p == NULL) {
- /* make the cache object */
- cache_object_p = cfsd_cache_create();
- xx = all_object_p->i_nextcacheid;
- xx = cache_setup(cache_object_p, buf, xx);
- if (xx == 0) {
- cfsd_cache_destroy(cache_object_p);
- fixcachefstab++;
- } else {
- all_cachelist_add(all_object_p,
- cache_object_p);
- }
- } else {
- fixcachefstab++;
- }
- }
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- CACHEFSTAB, errno));
- }
-
- /* read the mnttab file looking for caches we may have missed */
- fin = fopen(MNTTAB, "r");
- if (fin == NULL) {
- dbug_print(("info", "%s does not exist", MNTTAB));
- } else {
- mpref.mnt_special = NULL;
- mpref.mnt_mountp = NULL;
- mpref.mnt_fstype = "cachefs";
- mpref.mnt_mntopts = NULL;
- mpref.mnt_time = NULL;
- while ((xx = getmntany(fin, &minfo, &mpref)) != -1) {
- if (xx != 0)
- continue;
- cp = hasmntopt(&minfo, "cachedir=");
- if (cp == NULL)
- cp = "/cache"; /* XXX define in mount.c */
- else {
- cp += 9;
- xcp = strchr(cp, ',');
- if (xcp)
- *xcp = '\0';
- }
- dbug_print(("info", "mnttab cache \"%s\"", cp));
- cache_object_p = all_cachelist_find(all_object_p, cp);
- if (cache_object_p == NULL) {
- /* make the cache object */
- cache_object_p = cfsd_cache_create();
- xx = all_object_p->i_nextcacheid;
- xx = cache_setup(cache_object_p, cp, xx);
- if (xx == 0) {
- cfsd_cache_destroy(cache_object_p);
- fixcachefstab++;
- } else {
- all_cachelist_add(all_object_p,
- cache_object_p);
- }
- } else {
- fixcachefstab++;
- }
- }
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- MNTTAB, errno));
- }
-
- /* read the vfstab file looking for caches we may have missed */
- fin = fopen(VFSTAB, "r");
- if (fin == NULL) {
- dbug_print(("info", "%s does not exist", VFSTAB));
- } else {
- vpref.vfs_special = NULL;
- vpref.vfs_fsckdev = NULL;
- vpref.vfs_mountp = NULL;
- vpref.vfs_fstype = "cachefs";
- vpref.vfs_fsckpass = NULL;
- vpref.vfs_automnt = NULL;
- vpref.vfs_mntopts = NULL;
- while ((xx = getvfsany(fin, &vinfo, &vpref)) != -1) {
- if (xx != 0)
- continue;
- cp = strstr(vinfo.vfs_mntopts, "cachedir=");
- if (cp == NULL)
- cp = "/cache"; /* XXX define in mount.c */
- else {
- cp += 9;
- xcp = strchr(cp, ',');
- if (xcp)
- *xcp = '\0';
- }
- dbug_print(("info", "vfstab cache \"%s\"", cp));
- cache_object_p = all_cachelist_find(all_object_p, cp);
- if (cache_object_p == NULL) {
- /* make the cache object */
- cache_object_p = cfsd_cache_create();
- xx = all_object_p->i_nextcacheid;
- xx = cache_setup(cache_object_p, cp, xx);
- if (xx == 0) {
- cfsd_cache_destroy(cache_object_p);
- } else {
- all_cachelist_add(all_object_p,
- cache_object_p);
- fixcachefstab++;
- }
- }
- }
- if (fclose(fin))
- dbug_print(("err", "cannot close %s, %d",
- VFSTAB, errno));
- }
-
- /* fix up the CACHEFSTAB file if it is out of date */
- if (fixcachefstab)
- all_cachefstab_update(all_object_p);
-
- /*
- * now for each cache we found,
- * find all the file systems in the cache
- */
- for (index = 0; index < all_object_p->i_cachecount; index++) {
- cache_object_p = all_cachelist_at(all_object_p, index);
- dbug_assert(cache_object_p);
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt++;
- cache_unlock(cache_object_p);
- all_unlock(all_object_p);
-
- /* fix up the cache if necessary */
- xx = subr_fsck_cache(cache_object_p->i_cachedir);
- if (xx != 0) {
- dbug_print(("error", "could not fix up cache %d",
- cache_object_p->i_cachedir));
- all_lock(all_object_p);
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- continue;
- }
-
- /* lock out activity on the cache */
- lockfd = cachefs_dir_lock(cache_object_p->i_cachedir, 0);
- if (lockfd < 0) {
- dbug_print(("error", "cannot aquire cache lock on %s",
- cache_object_p->i_cachedir));
- all_lock(all_object_p);
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- continue;
- }
-
- /* open the cache directory */
- dirp = opendir(cache_object_p->i_cachedir);
- if (dirp == NULL) {
- dbug_print(("error", "cannot open dir %s",
- cache_object_p->i_cachedir));
- cachefs_dir_unlock(lockfd);
- all_lock(all_object_p);
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- continue;
- }
-
- strlcpy(pathname, cache_object_p->i_cachedir,
- sizeof (pathname));
- strlcat(pathname, "/", sizeof (pathname));
- len = strlen(pathname);
-
- /* read the directory entries */
- while ((entp = readdir64(dirp)) != NULL) {
- /* skip . and .. */
- if ((strcmp(entp->d_name, ".") == 0) ||
- (strcmp(entp->d_name, "..") == 0))
- continue;
-
- pathname[len] = '\0';
- strlcat(pathname, entp->d_name, sizeof (pathname));
-
- /* get info on the file */
- xx = lstat64(pathname, &sinfo);
- if (xx != 0) {
- dbug_print(("error",
- "cannot stat %s %d", pathname, errno));
- continue;
- }
-
- /* skip unless a symbolic link */
- if (!S_ISLNK(sinfo.st_mode))
- continue;
-
- /* add this file system to the list */
- subr_add_mount(all_object_p, cache_object_p->i_cachedir,
- entp->d_name);
- }
- if (closedir(dirp))
- dbug_print(("err", "cannot close dir, %d", errno));
- cachefs_dir_unlock(lockfd);
- all_lock(all_object_p);
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- }
-
- all_unlock(all_object_p);
- dbug_leave("subr_cache_setup");
-}
-
-/*
- * ------------------------------------------------------------
- * subr_fsck_cache
- *
- * Description:
- * Fixes the cache if necessary.
- * Arguments:
- * cachedirp
- * Returns:
- * Returns 0 for success !0 if the cache is not fixed.
- * Preconditions:
- * precond(cachedirp)
- */
-int
-subr_fsck_cache(const char *cachedirp)
-{
- char *fsck_argv[4];
- int status = 0;
- pid_t pid;
-
- dbug_enter("subr_fsck_cache");
-
- dbug_precond(cachedirp);
-
- fsck_argv[1] = "fsck";
- fsck_argv[2] = (char *)cachedirp;
- fsck_argv[3] = NULL;
-
- dbug_print(("info", "about to fsck %s", cachedirp));
-
- /* fork */
- if ((pid = fork()) == -1) {
- dbug_print(("error", "could not fork fsck %d", errno));
- dbug_leave("subr_fsck_cache");
- return (1);
- }
-
- if (pid == 0) {
- /* do the fsck */
- subr_doexec("cachefs", fsck_argv, "fsck");
- } else {
- /* wait for the child to exit */
- if (waitpid(pid, &status, 0) == -1) {
- dbug_print(("error", "fsck wait failed %d", errno));
- dbug_leave("subr_fsck_cache");
- return (1);
- }
-
- if (!WIFEXITED(status)) {
- dbug_print(("error", "fsck did not exit"));
- dbug_leave("subr_fsck_cache");
- return (1);
- }
-
- if (WEXITSTATUS(status) != 0) {
- dbug_print(("error", "fsck failed"));
- dbug_leave("subr_fsck_cache");
- return (1);
- }
- }
- dbug_leave("subr_fsck_cache");
- return (0);
-}
-
-/*
- * ------------------------------------------------------------
- * subr_doexec
- *
- * Description:
- * Execs the specified program with the specified command line arguments.
- * This function never returns.
- * Arguments:
- * fstype type of file system
- * newargv command line arguments
- * progp name of program to exec
- * Returns:
- * Preconditions:
- * precond(fstype)
- * precond(newargv)
- * precond(progp)
- */
-void
-subr_doexec(const char *fstype, char *newargv[], const char *progp)
-{
-#define VFS_PATH "/usr/lib/fs"
-#define ALT_PATH "/etc/fs"
-
- char full_path[MAXPATHLEN];
- char alter_path[MAXPATHLEN];
- char *vfs_path = VFS_PATH;
- char *alt_path = ALT_PATH;
-
- dbug_enter("subr_doexec");
-
- dbug_precond(fstype);
- dbug_precond(newargv);
- dbug_precond(progp);
-
- /* build the full pathname of the fstype dependent command. */
- snprintf(full_path, sizeof (full_path), "%s/%s/%s", vfs_path,
- fstype, progp);
- snprintf(alter_path, sizeof (alter_path), "%s/%s/%s", alt_path,
- fstype, progp);
-
- /* if the program exists */
- if (access(full_path, X_OK) == 0) {
- /* invoke the program */
- execv(full_path, &newargv[1]);
-
- /* if wrong permissions */
- if (errno == EACCES) {
- dbug_print(("error", "cannot execute %s %s",
- full_path, strerror(errno)));
- }
-
-#ifdef OBSOLETE
- /* if it did not work and the shell might make it */
- if (errno == ENOEXEC) {
- newargv[0] = "sh";
- newargv[1] = full_path;
- execv("/sbin/sh", &newargv[0]);
- }
-#endif
- }
-
-#ifdef OBSOLETE
- /* try the alternate path */
- execv(alter_path, &newargv[1]);
-
- /* if wrong permissions */
- if (errno == EACCES) {
- dbug_print(("error", "cannot execute %s %s",
- alter_path, strerror(errno)));
- }
-
- /* if it did not work and the shell might make it */
- if (errno == ENOEXEC) {
- newargv[0] = "sh";
- newargv[1] = alter_path;
- execv("/sbin/sh", &newargv[0]);
- }
-
- dbug_print(("error", "operation not applicable to FSType %s", fstype));
-#endif
- dbug_leave("subr_doexec");
- _exit(1);
-}
-
-/*
- * ------------------------------------------------------------
- * pr_err
- *
- * Description:
- * Arguments:
- * fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, "cachefsd -F cachefs: ");
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
-
-
-/*
- * subr_strdup
- *
- * Description:
- * Returns the string dupped. Returns NULL if passed NULL.
- * Calls new to allocate memory.
- * Arguments:
- * strp
- * Returns:
- * Preconditions:
- */
-char *
-subr_strdup(const char *strp)
-{
- char *retp = NULL;
- int len;
-
- if (strp) {
- len = strlen(strp) + 1;
- retp = cfsd_calloc(len);
- if (retp)
- strlcpy(retp, strp, len);
- }
- return (retp);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_calloc
- *
- * Description:
- * allocates memory of a given size, will retry if error
- * Arguments:
- * size
- * Returns:
- * pointer to memory
- * Preconditions:
- * precond(size)
- */
-
-void *
-cfsd_calloc(int size)
-{
- void *alloc_ptr;
-
- dbug_enter("cfsd_calloc");
- dbug_precond(size);
-
- /* allocate memory, if calloc fails sleep and retry */
- while ((alloc_ptr = calloc(size, 1)) == NULL) {
- cfsd_sleep(5);
- }
-
- dbug_leave("cfsd_calloc");
- return (alloc_ptr);
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_free
- *
- * Description:
- * frees memory allocated from cfsd_calloc
- * Arguments:
- * pointer to memeory
- * Returns:
- * none
- * Preconditions:
- * precond(size)
- */
-
-void
-cfsd_free(void *free_ptr)
-{
- dbug_enter("cfsd_free");
- dbug_precond(free_ptr);
-
- /* free memory */
- if (free_ptr)
- free(free_ptr);
-
- dbug_leave("cfsd_free");
-}
-/*
- * -----------------------------------------------------------------
- * cfsd_sleep
- *
- * Description:
- * A reimplemenation of the sleep(3c) function call using
- * cond_timedwait.
- * Problem withe sleep(3c) hanging. May return early.
- * Arguments:
- * sec number of seconds to sleep for
- * Returns:
- * Preconditions:
- */
-
-void
-cfsd_sleep(int sec)
-{
- cond_t cv;
- mutex_t mt;
- timestruc_t reltime;
-
- dbug_enter("cfsd_sleep");
-
- if (sec > 0) {
- mutex_init(&mt, USYNC_THREAD, NULL);
- cond_init(&cv, USYNC_THREAD, 0);
-
- reltime.tv_sec = sec;
- reltime.tv_nsec = 0;
-
- mutex_lock(&mt);
- cond_reltimedwait(&cv, &mt, &reltime);
- mutex_unlock(&mt);
-
- cond_destroy(&cv);
- mutex_destroy(&mt);
- }
- dbug_leave("cfsd_sleep");
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.h b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.h
deleted file mode 100644
index 9cbb4a665f..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_subr.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * cfsd_subr.h
- *
- * Include file for the various common routines.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#ifndef CFSD_SUBR
-#define CFSD_SUBR
-
-void subr_add_mount(cfsd_all_object_t *all_object_p, const char *dirp,
- const char *idp);
-void *subr_mount_thread(void *datap);
-void subr_cache_setup(cfsd_all_object_t *all_object_p);
-int subr_fsck_cache(const char *cachedirp);
-void subr_doexec(const char *fstype, char *newargv[], const char *progp);
-void pr_err(char *fmt, ...);
-char *subr_strdup(const char *strp);
-
-#endif /* CFSD_SUBR */
diff --git a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_svc.c b/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_svc.c
deleted file mode 100644
index d7f6a7e220..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsd/cfsd_svc.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * 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 1994-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * RPC service routines.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h> /* for pmap_unset */
-#include <string.h> /* strcmp */
-#include <signal.h>
-#include <unistd.h> /* setsid */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <memory.h>
-#include <stropts.h>
-#include <netconfig.h>
-#include <sys/resource.h> /* rlimit */
-#include <thread.h>
-#include <synch.h>
-#include <mdbug/mdbug.h>
-#include <common/cachefsd.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include "cfsd.h"
-#include "cfsd_kmod.h"
-#include "cfsd_maptbl.h"
-#include "cfsd_logfile.h"
-#include "cfsd_fscache.h"
-#include "cfsd_cache.h"
-#include "cfsd_all.h"
-#include "cfsd_subr.h"
-
-/* declared in cfsd_main.c */
-extern cfsd_all_object_t *all_object_p;
-
-/*
- * cachefsd_null_1_svc
- *
- * Description:
- * Routine to process NULLPROC command, see /usr/include/rpc/clnt.h.
- * Arguments:
- * inp should be NULL
- * outp should be NULL
- * reqp svc_req info
- * Returns:
- * Always returns 1, e.g. returns success result.
- * Preconditions:
- * precond(reqp)
- */
-bool_t
-cachefsd_null_1_svc(void *inp, void *outp, struct svc_req *reqp)
-{
- dbug_enter("cachefsd_null_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp == NULL);
- dbug_assert(outp == NULL);
-
- dbug_leave("cachefsd_null_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_caches_1_svc
- *
- * Description:
- * Returns list of caches on the system.
- * Arguments:
- * inp should be NULL
- * outp should point to return object
- * reqp svc_req info
- * Returns:
- * Returns 1 for success 0 if an error occurs.
- * Preconditions:
- * precond(reqp)
- */
-bool_t
-cachefsd_caches_1_svc(void *inp,
- cachefsd_caches_return *outp,
- struct svc_req *reqp)
-{
- size_t cnt;
- size_t index;
- cfsd_cache_object_t *cache_object_p;
- cachefsd_caches_id *headp, *idp;
-
- dbug_enter("cachefsd_caches_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp == NULL);
- dbug_assert(outp);
-
- if (inp || (outp == NULL)) {
- dbug_leave("cachefsd_caches_1_svc");
- return (0);
- }
- all_lock(all_object_p);
- headp = NULL;
-
- /* if there are any caches */
- cnt = all_object_p->i_cachecount;
- if (cnt) {
- /* allocate space for each cache information */
- headp = idp = cfsd_calloc(sizeof (cachefsd_caches_id) * cnt);
-
- /* for each cache */
- for (index = 0; index < cnt; index++, idp++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index);
- dbug_assert(cache_object_p);
-
- /* get the cache id and name */
- idp->cci_cacheid = cache_object_p->i_cacheid;
- idp->cci_name = subr_strdup(cache_object_p->i_cachedir);
- }
- }
-
- /* fill in the return object */
- outp->ccr_modify = all_object_p->i_modify;
- outp->ccr_ids.ccr_ids_len = cnt;
- outp->ccr_ids.ccr_ids_val = headp;
-
- all_unlock(all_object_p);
-
- dbug_leave("cachefsd_caches_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_cache_status_1_svc
- *
- * Description:
- * Returns status about a particular cache.
- * Arguments:
- * inp should be ptr to cache id
- * outp should be ptr to place to put cache status
- * reqp svc_req info
- * Returns:
- * Returns 1 for success 0 if an error occurs.
- * Preconditions:
- * precond(reqp)
- */
-bool_t
-cachefsd_cache_status_1_svc(int *inp, struct cachefsd_cache_status *outp,
- struct svc_req *reqp)
-{
- cfsd_fscache_object_t *fscache_object_p = NULL;
- size_t cnt, index;
- cfsd_cache_object_t *cache_object_p;
- cfsd_kmod_object_t *kmod_object_p;
- cachefsio_getstats_t gs;
- int xx;
-
- dbug_enter("cachefsd_cache_status_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp);
- dbug_assert(outp);
-
- if ((inp == NULL) || (outp == NULL)) {
- dbug_leave("cachefsd_cache_status_1_svc");
- return (0);
- }
- memset(outp, 0, sizeof (*outp));
-
- /* find the requested cache */
- all_lock(all_object_p);
- cnt = all_object_p->i_cachecount;
- for (index = 0; index < cnt; index++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index);
- dbug_assert(cache_object_p);
-
- /* if a match */
- if (cache_object_p->i_cacheid == *inp) {
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt++;
- cache_unlock(cache_object_p);
- break;
- }
- }
- all_unlock(all_object_p);
-
- /* if no match */
- if (index >= cnt) {
- dbug_leave("cachefsd_cache_status_1_svc");
- return (1);
- }
- /* find a mounted file system in the cache */
- cache_lock(cache_object_p);
- cnt = cache_object_p->i_fscachecount;
- for (index = 0; index < cnt; index++) {
- /* get the fscache */
- fscache_object_p = cache_fscachelist_at(cache_object_p, index);
- dbug_assert(fscache_object_p);
-
- /* mounted */
- if (fscache_object_p->i_mounted) {
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- fscache_unlock(fscache_object_p);
- break;
- }
- fscache_object_p = NULL;
- }
- cache_unlock(cache_object_p);
-
- outp->ccs_size = 0;
- outp->ccs_lrusize = 0;
- outp->ccs_packsize = 0;
- outp->ccs_freesize = 0;
- outp->ccs_lrutime = 0;
-
- kmod_object_p = cfsd_kmod_create();
- if (fscache_object_p) {
- xx = kmod_setup(kmod_object_p, fscache_object_p->i_mntpt);
- if (xx != 0) {
- dbug_print(("err",
- "setup of kmod interface failed %d", xx));
- } else if ((xx = kmod_getstats(kmod_object_p, &gs)) != 0) {
- dbug_print(("err", "getstat failed %d", xx));
- } else {
- outp->ccs_size = gs.gs_total;
- outp->ccs_lrusize = gs.gs_gc + gs.gs_active;
- outp->ccs_packsize = gs.gs_packed;
- outp->ccs_freesize = gs.gs_free;
- outp->ccs_lrutime = gs.gs_gctime;
-
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
- }
- }
- cfsd_kmod_destroy(kmod_object_p);
-
- outp->ccs_id = cache_object_p->i_cacheid;
- outp->ccs_name = subr_strdup(cache_object_p->i_cachedir);
- outp->ccs_modify = cache_object_p->i_modify;
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
-
- dbug_leave("cachefsd_cache_status_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_mounts_1_svc
- *
- * Description:
- * Returns the list of file systems that are in the cache.
- * Arguments:
- * inp should be ptr to cache id
- * outp should be ptr to place to put mounts
- * reqp svc_req info
- * Returns:
- * Returns 1 for success 0 if an internal error occurs.
- * Preconditions:
- * precond(reqp)
- */
-bool_t
-cachefsd_mounts_1_svc(int *inp, struct cachefsd_mount_returns *outp,
- struct svc_req *reqp)
-{
- size_t cnt, index;
- cfsd_cache_object_t *cache_object_p;
- cfsd_fscache_object_t *fscache_object_p;
- struct cachefsd_mount *headp, *idp;
-
- dbug_enter("cachefsd_mounts_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp);
- dbug_assert(outp);
- if ((inp == NULL) || (outp == NULL)) {
- dbug_leave("cachefsd_mounts_1_svc");
- return (0);
- }
- memset(outp, 0, sizeof (*outp));
-
- /* find the requested cache */
- all_lock(all_object_p);
- cnt = all_object_p->i_cachecount;
- for (index = 0; index < cnt; index++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index);
- dbug_assert(cache_object_p);
-
- /* if a match */
- if (cache_object_p->i_cacheid == *inp) {
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt++;
- cache_unlock(cache_object_p);
- break;
- }
- }
- all_unlock(all_object_p);
-
- /* if no match was found */
- if (index >= cnt) {
- outp->cmr_error = ENOENT;
- dbug_leave("cachefsd_mounts_1_svc");
- return (1);
- }
-
- cache_lock(cache_object_p);
- headp = NULL;
-
- /* if there are any fscaches */
- cnt = cache_object_p->i_fscachecount;
- if (cnt) {
- /* allocate space for each fscache information */
- headp = idp = cfsd_calloc(sizeof (cachefsd_mount) * cnt);
- /* for each fscache */
- for (index = 0; index < cnt; index++, idp++) {
- /* get the fscache */
- fscache_object_p =
- cache_fscachelist_at(cache_object_p, index);
- dbug_assert(fscache_object_p);
-
- /* get the fscache id and name */
- idp->cm_fsid = fscache_object_p->i_fscacheid;
- idp->cm_name = subr_strdup(fscache_object_p->i_name);
- }
- }
-
- /* fill in the return object */
- outp->cmr_modify = cache_object_p->i_modify;
- outp->cmr_error = 0;
- outp->cmr_names.cmr_names_len = cnt;
- outp->cmr_names.cmr_names_val = headp;
-
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
-
- dbug_leave("cachefsd_mounts_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_mount_stat_1_svc
- *
- * Description:
- * Returns status information about a single file system
- * in the cache.
- * Arguments:
- * inp should be which file system to get info for
- * outp should be place to put mount info
- * reqp svc_req info
- * Returns:
- * Returns 1 for success 0 if an error occurs.
- * Preconditions:
- * precond(reqp)
- */
-bool_t
-cachefsd_mount_stat_1_svc(struct cachefsd_mount_stat_args *inp,
- struct cachefsd_mount_stat *outp, struct svc_req *reqp)
-{
- size_t cnt, index;
- cfsd_cache_object_t *cache_object_p;
- cfsd_fscache_object_t *fscache_object_p;
- char namebuf[MAXPATHLEN];
- struct stat sinfo;
-
- dbug_enter("cachefsd_mount_stat_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp);
- dbug_assert(outp);
- if ((inp == NULL) || (outp == NULL)) {
- dbug_leave("cachefsd_mount_stat_1_svc");
- return (0);
- }
- memset(outp, 0, sizeof (*outp));
-
- /* find the requested cache */
- all_lock(all_object_p);
- cnt = all_object_p->i_cachecount;
- for (index = 0; index < cnt; index++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index);
- dbug_assert(cache_object_p);
-
- /* if a match */
- if (cache_object_p->i_cacheid == inp->cma_cacheid) {
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt++;
- cache_unlock(cache_object_p);
- break;
- }
- }
- all_unlock(all_object_p);
-
- /* if no match was found */
- if (index >= cnt) {
- dbug_leave("cachefsd_mount_stat_1_svc");
- return (1);
- }
-
- /* find the requested fscache */
- cache_lock(cache_object_p);
- cnt = cache_object_p->i_fscachecount;
- for (index = 0; index < cnt; index++) {
- /* get the fscache */
- fscache_object_p = cache_fscachelist_at(cache_object_p, index);
- dbug_assert(fscache_object_p);
-
- /* if a match */
- if (fscache_object_p->i_fscacheid == inp->cma_fsid) {
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- fscache_unlock(fscache_object_p);
- break;
- }
- }
- cache_unlock(cache_object_p);
-
- /* if no match was found */
- if (index >= cnt) {
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
- dbug_leave("cachefsd_mount_stat_1_svc");
- return (1);
- }
-
- fscache_lock(fscache_object_p);
-
- /* see if there are changes to roll to the server */
- if ((fscache_object_p->i_connected == 0) &&
- (fscache_object_p->i_changes == 0)) {
- snprintf(namebuf, sizeof (namebuf), "%s/%s/%s",
- cache_object_p->i_cachedir, fscache_object_p->i_name,
- CACHEFS_DLOG_FILE);
- if (stat(namebuf, &sinfo) == 0) {
- fscache_changes(fscache_object_p, 1);
- }
- }
-
- /* fill in the return object */
- outp->cms_cacheid = cache_object_p->i_cacheid;
- outp->cms_fsid = fscache_object_p->i_fscacheid;
- outp->cms_name = subr_strdup(fscache_object_p->i_name);
- outp->cms_backfs = subr_strdup(fscache_object_p->i_backfs);
- outp->cms_mountpt = subr_strdup(fscache_object_p->i_mntpt);
- outp->cms_backfstype = subr_strdup(fscache_object_p->i_backfstype);
- outp->cms_writemode = NULL;
- outp->cms_options = subr_strdup(fscache_object_p->i_cfsopt);
- outp->cms_mounted = fscache_object_p->i_mounted;
- outp->cms_connected = fscache_object_p->i_connected;
- outp->cms_reconcile = fscache_object_p->i_reconcile;
- outp->cms_changes = fscache_object_p->i_changes;
- outp->cms_time_state = fscache_object_p->i_time_state;
- outp->cms_mnttime = fscache_object_p->i_time_mnt;
- outp->cms_modify = fscache_object_p->i_modify;
-
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
-
- cache_lock(cache_object_p);
- cache_object_p->i_refcnt--;
- cache_unlock(cache_object_p);
-
- dbug_leave("cachefsd_mount_stat_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_fs_mounted_1_svc
- *
- * Description:
- * Sent by the mount command to indicate a new file system
- * has been mounted
- * Arguments:
- * inp ptr to mount information
- * outp should be null
- * reqp svc_req info
- * Returns:
- * Returns 1 for success 0 if an internal error occurs.
- * Preconditions:
- * precond(inp)
- */
-bool_t
-cachefsd_fs_mounted_1_svc(struct cachefsd_fs_mounted *inp, void *outp,
- struct svc_req *reqp)
-{
- int error = 0;
-
- dbug_enter("cachefsd_fs_mounted_1_svc");
- dbug_precond(reqp);
-
- dbug_assert(inp);
- dbug_assert(outp == NULL);
- if ((inp == NULL) || outp) {
- dbug_leave("cachefsd_fs_mounted_1_svc");
- return (0);
- }
-
- if (inp->mt_cachedir == NULL) {
- dbug_print(("error", "cachedir is null"));
- error = 1;
- }
- if (inp->mt_cacheid == NULL) {
- dbug_print(("error", "cacheid is null"));
- error = 1;
- }
-
- if (error == 0) {
- dbug_print(("info", "Mounted in %s file system %s",
- inp->mt_cachedir, inp->mt_cacheid));
- subr_add_mount(all_object_p, inp->mt_cachedir, inp->mt_cacheid);
- }
-
- dbug_leave("cachefsd_fs_mounted_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_fs_unmounted_1_svc
- *
- * Description:
- * Arguments:
- * inp
- * outp
- * reqp
- * Returns:
- * Returns 1 for success 0 if an internal error occurs.
- * Preconditions:
- * precond(inp)
- * precond(outp == NULL)
- * precond(reqp)
- */
-bool_t
-cachefsd_fs_unmounted_1_svc(struct cachefsd_fs_unmounted *inp, int *outp,
- struct svc_req *reqp)
-{
- size_t cnt1, cnt2, index1, index2;
- cfsd_cache_object_t *cache_object_p;
- cfsd_fscache_object_t *fscache_object_p = NULL;
- int found = 0;
- int flag = 0;
-
- dbug_enter("cachefsd_fs_unmounted_1_svc");
-
- dbug_precond(inp);
- dbug_precond(outp);
- dbug_precond(reqp);
-
- if ((inp == NULL) || (outp == NULL)) {
- dbug_leave("cachefsd_fs_unmounted_1_svc");
- return (0);
- }
- memset(outp, 0, sizeof (*outp));
-
- if (inp->mntpt == NULL) {
- dbug_print(("error", "mntpt is null"));
- *outp = EIO;
- dbug_leave("cachefsd_fs_unmounted_1_svc");
- return (1);
- }
-
- /* for each cache */
- all_lock(all_object_p);
- cnt1 = all_object_p->i_cachecount;
- for (index1 = 0; index1 < cnt1; index1++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index1);
- dbug_assert(cache_object_p);
-
- /* for each file system in this cache */
- cache_lock(cache_object_p);
- cnt2 = cache_object_p->i_fscachecount;
- for (index2 = 0; index2 < cnt2; index2++) {
- /* get the fscache */
- fscache_object_p =
- cache_fscachelist_at(cache_object_p, index2);
- dbug_assert(fscache_object_p);
-
- /* skip if not mounted */
- if (fscache_object_p->i_mounted == 0)
- continue;
-
- /* if a match */
- if (strcmp(fscache_object_p->i_mntpt,
- inp->mntpt) == 0) {
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- flag = inp->flag;
- fscache_unlock(fscache_object_p);
- found = 1;
- break;
- }
- }
- cache_unlock(cache_object_p);
- if (found)
- break;
- fscache_object_p = NULL;
- }
- all_unlock(all_object_p);
-
- /* if no match */
- if (fscache_object_p == NULL) {
- *outp = EIO;
- } else {
- *outp = fscache_unmount(fscache_object_p, flag);
-
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
- }
- dbug_leave("cachefsd_fs_unmounted_1_svc");
- return (1);
-}
-
-/*
- * cachefsd_disconnection_1_svc
- *
- * Description:
- * Arguments:
- * inp
- * outp
- * reqp
- * Returns:
- * Returns 1 for success 0 if an internal error occurs.
- * Preconditions:
- * precond(inp)
- * precond(outp)
- * precond(reqp)
- */
-bool_t
-cachefsd_disconnection_1_svc(struct cachefsd_disconnection_args *inp, int *outp,
- struct svc_req *reqp)
-{
- size_t cnt1, cnt2, index1, index2;
- cfsd_cache_object_t *cache_object_p;
- cfsd_fscache_object_t *fscache_object_p = NULL;
- int found = 0;
-
- dbug_enter("cachefsd_disconnection_1_svc");
-
- dbug_precond(inp);
- dbug_precond(outp);
- dbug_precond(reqp);
-
- if ((inp == NULL) || (outp == NULL)) {
- dbug_leave("cachefsd_disconnection_1_svc");
- return (0);
- }
- memset(outp, 0, sizeof (*outp));
-
- /* for each cache */
- all_lock(all_object_p);
- cnt1 = all_object_p->i_cachecount;
- for (index1 = 0; index1 < cnt1; index1++) {
- /* get the cache */
- cache_object_p = all_cachelist_at(all_object_p, index1);
- dbug_assert(cache_object_p);
-
- /* for each file system in this cache */
- cache_lock(cache_object_p);
- cnt2 = cache_object_p->i_fscachecount;
- for (index2 = 0; index2 < cnt2; index2++) {
- /* get the fscache */
- fscache_object_p =
- cache_fscachelist_at(cache_object_p, index2);
- dbug_assert(fscache_object_p);
-
- /* if a match */
- if (strcmp(fscache_object_p->i_mntpt, inp->cda_mntpt)
- == 0) {
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt++;
- fscache_unlock(fscache_object_p);
- found = 1;
- break;
- }
- }
- cache_unlock(cache_object_p);
- if (found)
- break;
- fscache_object_p = NULL;
- }
- all_unlock(all_object_p);
-
- /* if no match */
- if (fscache_object_p == NULL) {
- *outp = 3;
- } else {
- *outp = fscache_simdisconnect(fscache_object_p,
- inp->cda_disconnect);
-
- fscache_lock(fscache_object_p);
- fscache_object_p->i_refcnt--;
- fscache_unlock(fscache_object_p);
- }
- dbug_leave("cachefsd_disconnection_1_svc");
- return (1);
-}
-
-/*
- * cachefsdprog_1_freeresult
- *
- * Description:
- * Arguments:
- * transp
- * xdr_result
- * resultp
- * Returns:
- * Returns ...
- * Preconditions:
- * precond(transp)
- */
-int
-cachefsdprog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result,
- caddr_t resultp)
-{
- dbug_enter("cachefsdprog_1_freeresult");
-
- dbug_precond(transp);
-
- (void) xdr_free(xdr_result, resultp);
- dbug_leave("cachefsdprog_1_freeresult");
- return (1);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfsfstype/Makefile b/usr/src/cmd/fs.d/cachefs/cfsfstype/Makefile
deleted file mode 100644
index e65e5069cf..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsfstype/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989,1996 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-
-FSTYPE= cachefs
-LIBPROG= cfsfstype
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cfsfstype.o
-
-include ../Makefile.cachefs
-
-CPPFLAGS += -D_LARGEFILE64_SOURCE
diff --git a/usr/src/cmd/fs.d/cachefs/cfsfstype/cfsfstype.c b/usr/src/cmd/fs.d/cachefs/cfsfstype/cfsfstype.c
deleted file mode 100644
index cb56090afe..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfsfstype/cfsfstype.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * cfsfstype.c
- *
- * Cache FS admin utility. Used to glean information out of the
- * rootfs, frontfs, and backfs variables in the kernel.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <dirent.h>
-#include <ftw.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/filio.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dir.h>
-
-
-static void pr_err(char *fmt, ...);
-static void usage(char *);
-
-/*
- *
- * main
- *
- * Description:
- * Main routine for the cfsfstype program.
- * Arguments:
- * argc number of command line arguments
- * argv command line arguments
- * Returns:
- * Returns 0 for failure, > 0 for an error.
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- int c;
- int nflag = 0;
- struct statvfs64 svb;
- int fd;
-
- /* verify root running command */
- if (getuid() != 0) {
- pr_err(gettext("must be run by root"));
- return (1);
- }
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /* parse the command line arguments */
- while ((c = getopt(argc, argv, "n")) != EOF) {
- switch (c) {
-
- case 'n':
- nflag = 1;
- break;
-
- default:
- usage(gettext("illegal option"));
- return (1);
- }
- }
- argc -= optind;
- argv += optind;
- if (argc > 1) {
- usage(gettext("too many file names specified"));
- return (1);
- }
-
- /* if just path is specified, just statvfs it */
- if (!nflag) {
- if (argc != 1) {
- usage(gettext("no file name"));
- return (1);
- }
- if (statvfs64(*argv, &svb) < 0) {
- pr_err(gettext("Cannot open %s: %s"), *argv,
- strerror(errno));
- return (1);
- }
- (void) printf("%s\n", svb.f_basetype);
- return (0);
- }
-
- fd = open("/", O_RDONLY);
- if (fd < 0) {
- perror(gettext("Open of root directory"));
- return (1);
- }
-
- if (argc == 1) {
- close(fd);
- fd = open(*argv, O_RDONLY);
- if (fd < 0) {
- perror(gettext("open of specified directory"));
- return (1);
- }
- }
-
- if (ioctl(fd, _FIOSTOPCACHE)) {
- perror(gettext("Convert ioctl fault"));
- return (1);
- }
- return (0);
-}
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a usage message for this utility.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-
-static void
-usage(char *msgp)
-{
- fprintf(stderr, gettext("cfsfstype: %s\n"), msgp);
- fprintf(stderr, gettext("usage: cfsfstype file\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-static void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cfsfstype: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/cfstagchk/Makefile b/usr/src/cmd/fs.d/cachefs/cfstagchk/Makefile
deleted file mode 100644
index 762aaf4b25..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfstagchk/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989 by Sun Microsystems, Inc.
-#
-
-FSTYPE= cachefs
-LIBPROG= cfstagchk
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= cfstagchk.o
-
-include ../Makefile.cachefs
-
-LDLIBS += -ladm
diff --git a/usr/src/cmd/fs.d/cachefs/cfstagchk/cfstagchk.c b/usr/src/cmd/fs.d/cachefs/cfstagchk/cfstagchk.c
deleted file mode 100644
index 31d02bee6f..0000000000
--- a/usr/src/cmd/fs.d/cachefs/cfstagchk/cfstagchk.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * -----------------------------------------------------------------
- *
- * cfstagchk.c
- *
- * Cache FS admin utility. Used to read and/or write a
- * cache tag from/to the specified partition.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/vtoc.h>
-
-void pr_err(char *fmt, ...);
-void usage(char *);
-
-/*
- * -----------------------------------------------------------------
- *
- * main
- *
- * Description:
- * Main routine for the cfstagchk program
- * Arguments:
- * argc number of command line arguments
- * argv command line arguments
- * Returns:
- * Returns 0 for failure, > 0 for an error.
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- int c;
- int which;
-
- char *path;
-
- int wflag;
- int fd, err, slice;
- struct vtoc vtoc;
- struct partition *p;
-
- /* verify root running command */
- if (getuid() != 0) {
- pr_err(gettext("must be run by root"));
- return (1);
- }
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /* set defaults for command line options */
- wflag = 0;
-
- /* parse the command line arguments */
- while ((c = getopt(argc, argv, "w")) != EOF) {
- switch (c) {
-
- case 'w': /* write */
- wflag = 1;
- break;
-
- default:
- usage(gettext("illegal option"));
- return (1);
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 1) {
- usage(gettext("must specify a single device"));
- return (1);
- }
-
- fd = open(*argv, O_RDWR);
- if (fd < 0) {
- pr_err("can't open %s", *argv);
- return (1);
- }
-
- slice = read_vtoc(fd, &vtoc);
- if (slice < 0) {
- pr_err(gettext("can't read vtoc"));
- return (1);
- }
- p = &vtoc.v_part[slice];
- if (!wflag) {
- err = 0;
- if (p->p_tag != V_CACHE)
- err++;
- } else {
- p->p_tag = V_CACHE;
- err = write_vtoc(fd, &vtoc);
- if (err < 0)
- pr_err(gettext("write_vtoc failure"));
- }
- return (err);
-}
-
-/*
- * -----------------------------------------------------------------
- *
- * usage
- *
- * Description:
- * Prints a usage message for this utility.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-
-void
-usage(char *msgp)
-{
- fprintf(stderr, gettext("cfstagchk: %s\n"), msgp);
- fprintf(stderr, gettext("usage: cfstagchk [-w] device\n"));
-}
-
-/*
- * -----------------------------------------------------------------
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("cfstagchk: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/Makefile b/usr/src/cmd/fs.d/cachefs/common/Makefile
deleted file mode 100644
index 2fa44d06dd..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# 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 1989,1996-2003 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/fs.d/cachefs/common
-#
-
-FSTYPE= cachefs
-
-include ../../Makefile.fstype
-
-PROGOBJS= objs/subr.o objs/stats_create.o objs/stats_stats.o \
- objs/stats_log.o objs/stats_dbm.o objs/cachefsd_clnt.o \
- objs/cachefsd_xdr.o
-
-PROGOBJSMT= objsmt/subr.o objsmt/stats_create.o objsmt/stats_stats.o \
- objsmt/stats_log.o objsmt/stats_dbm.o objsmt/cachefsd_clnt.o \
- objsmt/cachefsd_xdr.o
-
-include ../Makefile.cachefs
-
-ARFLAGS= rc
-CLEANFILES += cachefsd_clnt.c cachefsd_xdr.c $(PROGOBJS) $(PROGOBJSMT)
-CLOBBERFILES += $(LIBRARY) $(LIBRARYMT) cachefsd.h
-RPCGENFLAGS= -M -C -T
-CPPFLAGS += -D_LARGEFILE64_SOURCE
-CPPFLAGSMT += ${CPPFLAGS} -D_REENTRANT
-
-all: $(LIBRARY) $(LIBRARYMT)
-
-
- objs objsmt:
- -@mkdir -p $@
-
- objs/%.o : %.c
- $(CC) ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
-
- objsmt/%.o : %.c
- $(CC) ${CFLAGS} ${CPPFLAGSMT} -c -o $@ $<
-
-
-$(LIBRARY): objs cachefsd.h $(PROGOBJS)
- -$(RM) $(LIBRARY)
- $(AR) $(ARFLAGS) $(LIBRARY) $(PROGOBJS)
-
-$(LIBRARYMT): objsmt cachefsd.h $(PROGOBJSMT)
- -$(RM) $(LIBRARYMT)
- $(AR) $(ARFLAGS) $(LIBRARYMT) $(PROGOBJSMT)
-
-cachefsd_clnt.c : cachefsd.x
- $(RPCGEN) $(RPCGENFLAGS) -l -o cachefsd_clnt.c cachefsd.x
-
-cachefsd_xdr.c : cachefsd.x
- $(RPCGEN) $(RPCGENFLAGS) -c -o cachefsd_xdr.c cachefsd.x
-
-cachefsd.h : cachefsd.x
- $(RPCGEN) $(RPCGENFLAGS) -h -o cachefsd.h cachefsd.x
-
diff --git a/usr/src/cmd/fs.d/cachefs/common/cachefsd.x b/usr/src/cmd/fs.d/cachefs/common/cachefsd.x
deleted file mode 100644
index 747e743d91..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/cachefsd.x
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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 1996, 2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* -----------------------------------------------------------------
- *
- * cachefsd.x
- *
- * Rpcgen file for generating cachefsd interface.
- */
-
-/* #ident "%Z%%M% %I% %E% SMI" */
-
-
-/*
- * List of caches.
- */
-struct cachefsd_caches_id {
- int cci_cacheid; /* id of cache */
- string cci_name<>; /* pathname of cache */
-};
-struct cachefsd_caches_return {
- u_int ccr_modify; /* changes when modified */
- cachefsd_caches_id ccr_ids<>; /* list of caches */
-};
-
-/*
- * Stats about a single cache.
- * All sizes are in 1K blocks.
- */
-struct cachefsd_cache_status {
- int ccs_id; /* id of cache */
- string ccs_name<>; /* name of cache */
- longlong_t ccs_size; /* size of cache */
- longlong_t ccs_lrusize; /* size of lru files */
- longlong_t ccs_packsize; /* size of packed files */
- longlong_t ccs_freesize; /* size of free space */
- u_int ccs_lrutime; /* time of oldest item on lru */
- u_int ccs_modify; /* changes when modified */
-};
-
-/*
- * List of file systems in a cache.
- */
-struct cachefsd_mount {
- int cm_fsid; /* id of file system */
- string cm_name<>; /* name of file system */
-};
-struct cachefsd_mount_returns {
- cachefsd_mount cmr_names<>; /* list of file systems */
- u_int cmr_modify; /* changes when modified */
- int cmr_error; /* 0 if no error */
-};
-
-/*
- * Stats about a single file system in a cache.
- */
-struct cachefsd_mount_stat_args {
- int cma_cacheid; /* id of cache */
- int cma_fsid; /* id of file system */
-};
-struct cachefsd_mount_stat {
- int cms_cacheid; /* id of cache */
- int cms_fsid; /* id of file system */
- string cms_name<>; /* name of file system */
- string cms_backfs<>; /* back file system */
- string cms_mountpt<>; /* most recent mount point */
- string cms_backfstype<>; /* type of back file system */
- string cms_writemode<>; /* write mode */
- string cms_options<>; /* remaining options */
- int cms_mounted; /* 1 if mounted */
- int cms_connected; /* 1 if connected */
- int cms_reconcile; /* 1 if reconcile in progress */
- int cms_changes; /* 1 if changes to push back */
- u_int cms_time_state; /* time of state change */
- u_int cms_mnttime; /* time of last mount/umount */
- u_int cms_modify; /* changes when modified */
-};
-
-/*
- * Sent by mount command to indicate a new mounted file system.
- */
-struct cachefsd_fs_mounted {
- string mt_cachedir<>; /* cache directory path */
- string mt_cacheid<>; /* cache id */
-};
-
-/*
- * Sent by umount command to unmount file system.
- * cachefsd may get the request to force unmount
- * the cachefs front file system, thus flag is
- * necessary to indicate forced unmount.
- * Hopefully, someday forced unmount is supported
- * for cachefs !!
- */
-struct cachefsd_fs_unmounted {
- string mntpt<>; /* Mount point */
- int flag; /* MS_FORCE flag */
-};
-
-/*
- * Sets file system to simulate disconnection.
- */
-struct cachefsd_disconnection_args {
- string cda_mntpt<>; /* mntpt of file system */
- int cda_disconnect; /* 1 disconnect, 0 connect */
-};
-
-/*
- * -----------------------------------------------------------------
- * This is the definition of the routines supported by the service.
- */
-program CACHEFSDPROG {
- version CACHEFSDVERS {
- void CACHEFSD_NULL(void) = 0;
- cachefsd_caches_return CACHEFSD_CACHES(void) = 1;
- cachefsd_cache_status CACHEFSD_CACHE_STATUS(int id) = 2;
- cachefsd_mount_returns CACHEFSD_MOUNTS(int id) = 3;
- cachefsd_mount_stat CACHEFSD_MOUNT_STAT(
- struct cachefsd_mount_stat_args) = 4;
- void CACHEFSD_FS_MOUNTED(struct cachefsd_fs_mounted) = 5;
- int CACHEFSD_FS_UNMOUNTED(struct cachefsd_fs_unmounted) = 6;
- int CACHEFSD_DISCONNECTION(struct cachefsd_disconnection_args)
- = 7;
- } = 1;
-} = 100235;
-
-#ifdef RPC_HDR
-%
-#endif /* RPC_HDR */
diff --git a/usr/src/cmd/fs.d/cachefs/common/stats.h b/usr/src/cmd/fs.d/cachefs/common/stats.h
deleted file mode 100644
index f8823fcd70..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/stats.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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 1996-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _CACHEFS_LIB_STATS_H
-#define _CACHEFS_LIB_STATS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-#include <kstat.h>
-#include <ndbm.h>
-
-#ifndef DEBUG
-#define NDEBUG
-#endif /* DEBUG */
-
-#define STATS_MAGIC 54545
-
-typedef struct stats_cookie {
- int st_magic;
-
- char *st_progname;
-
- uint_t st_flags; /* misc. flags */
- int st_fsid; /* id # for kstat `cachefs.#.stat' */
-
- FILE *st_logstream; /* stream for logfile */
- XDR st_logxdr;
- struct cachefs_log_logfile_header st_loghead;
- char st_asciirec[BUFSIZ];
-
- DBM *st_dbm;
- char st_dbm_name[MAXPATHLEN];
-
- int st_ws_init;
- u_offset_t st_ws_current;
- u_offset_t st_ws_high;
- int st_ws_expensive;
-
- char st_errorstr[BUFSIZ];
- int st_errno;
-
- kstat_ctl_t *st_kstat_cookie;
-} stats_cookie_t;
-
-/*
- * error types for the API (given by stats_errno())
- */
-
-enum stats_error {
- SE_NOERROR, /* placeholder so no errors == 0 */
- SE_INVAL, /* invalid use of the API */
- SE_NOMEM, /* ran out of memory */
- SE_FILE, /* trouble with file i/o */
- SE_CORRUPT, /* trouble with a corrupt file */
- SE_KERNEL /* trouble coming from communication with the kernel */
-};
-
-/*
- * flags in cookie->st_flags
- */
-
-#define ST_VALID 0x0001 /* initialized completely */
-#define ST_BOUND 0x0002 /* bound to a particular filesystem or cache */
-#define ST_ERROR 0x0004 /* an error has occured */
-#define ST_LFOPEN 0x0008 /* logstream is open */
-#define ST_DBMOPEN 0x0010 /* dbm descriptor is open */
-#define ST_WSCOMP 0x0020 /* working set size computed */
-
-/*
- * flags for logfile-to-workingset
- */
-
-#define GRI_ADD 0x01 /* we may have added to the alloc map */
-#define GRI_TRUNC 0x02 /* we may have truncated the alloc map */
-#define GRI_MODIFY 0x04 /* we modified this file */
-#define GRI_METADATA 0x08 /* we created metadata */
-#define GRI_EXPENSIVE 0x10 /* record indicates `expensive' logging */
-
-/*
- * structures for logfile-to-workingset
- */
-
-#define FI_METADATA 0x01 /* this file has metadata */
-
-/*
- * len and offset are now u_offset_t in sync with struct cachefs_allocmap in
- * file cachefs_fs.h
- */
-typedef struct fid_info {
- int fi_magic;
-
- uint_t fi_flags;
-
- caddr_t fi_vfsp;
-
- uint_t fi_ent_n;
- struct fid_info_allocent {
- u_offset_t offset;
- u_offset_t len;
- } fi_ent[C_MAX_ALLOCINFO_SLOTS];
-
- u_offset_t fi_total;
-} fid_info;
-
-#define FI_MAGIC (3748321)
-
-typedef struct mount_info {
- int mi_magic;
-
- uint_t mi_mounted:1;
- uint_t mi_used:1;
-
- u_offset_t mi_current;
- u_offset_t mi_high;
-
- uint_t mi_flags;
- uint_t mi_filegrp_size;
- char mi_path[2];
-} mount_info;
-
-#define MI_MAGIC (837492)
-
-/*
- * Define the maximum size of char mi_path[]
- *
- * The maximum size of mi_path is a path (MAXPATHLEN) and a cacheid
- * (C_MAX_MOUNT_FSCDIRNAME) plus terminating nulls (2).
- *
- * Additional space is allocated to mi_path at runtime using malloc().
- */
-
-#define MI_MAX_MI_PATH (MAXPATHLEN + C_MAX_MOUNT_FSCDIRNAME + 2)
-
-typedef struct filegrp_info {
- int fg_magic;
-
- uint_t fg_count; /* high-water known # of attrcache entries */
- uint_t fg_bcount; /* # of bits set in fg_bits */
- uchar_t fg_bits[DEF_FILEGRP_SIZE / NBBY];
-
- size_t fg_size; /* high-water attrcache size (MAXBSIZE ceiling) */
-} fg_info;
-
-#define FG_MAGIC (673492)
-
-/*
- * the cachefs stats (stats_*) API.
- */
-
-/* stats_create.c */
-stats_cookie_t *stats_create_mountpath(char *, char *);
-stats_cookie_t *stats_create_unbound(char *);
-cachefs_kstat_key_t *stats_next(stats_cookie_t *);
-cachefs_kstat_key_t *stats_getkey(stats_cookie_t *);
-void stats_destroy(stats_cookie_t *);
-int stats_good(stats_cookie_t *);
-char *stats_errorstr(stats_cookie_t *);
-int stats_errno(stats_cookie_t *);
-int stats_inerror(stats_cookie_t *);
-void stats_perror(stats_cookie_t *, int, char *, ...);
-
-/* stats_log.c */
-int stats_log_kernel_setname(stats_cookie_t *, char *);
-int stats_log_which(stats_cookie_t *, int, int);
-char *stats_log_kernel_getname(stats_cookie_t *);
-int stats_log_logfile_open(stats_cookie_t *, char *);
-void *stats_log_logfile_read(stats_cookie_t *, int *);
-char *stats_log_record_toascii(stats_cookie_t *, void *);
-uint_t stats_log_get_record_info(stats_cookie_t *,
- void *, caddr_t *, cfs_fid_t **, ino64_t *, u_offset_t *, u_offset_t *);
-void stats_log_fi_add(stats_cookie_t *, fid_info *, u_offset_t, u_offset_t);
-void stats_log_fi_trunc(stats_cookie_t *, fid_info *, u_offset_t, u_offset_t);
-struct cachefs_log_logfile_header *stats_log_getheader(stats_cookie_t *);
-void stats_log_compute_wssize(stats_cookie_t *);
-int stats_log_wssize_init(stats_cookie_t *);
-u_offset_t stats_log_wssize_current(stats_cookie_t *);
-u_offset_t stats_log_wssize_high(stats_cookie_t *);
-int stats_log_wssize_expensive(stats_cookie_t *);
-
-/* stats_stats.c */
-uint_t stats_hits(stats_cookie_t *);
-uint_t stats_misses(stats_cookie_t *);
-uint_t stats_passes(stats_cookie_t *);
-uint_t stats_fails(stats_cookie_t *);
-uint_t stats_modifies(stats_cookie_t *);
-uint_t stats_gc_count(stats_cookie_t *);
-time_t stats_gc_time(stats_cookie_t *);
-time_t stats_gc_before(stats_cookie_t *);
-time_t stats_gc_after(stats_cookie_t *);
-int stats_zero_stats(stats_cookie_t *);
-
-/* stats_dbm.c */
-void stats_dbm_open(stats_cookie_t *);
-void stats_dbm_rm(stats_cookie_t *);
-void stats_dbm_close(stats_cookie_t *);
-fid_info *stats_dbm_fetch_byfid(stats_cookie_t *, cfs_fid_t *);
-void stats_dbm_store_byfid(stats_cookie_t *, cfs_fid_t *, fid_info *);
-mount_info *stats_dbm_fetch_byvfsp(stats_cookie_t *, caddr_t);
-void stats_dbm_store_byvfsp(stats_cookie_t *, caddr_t, mount_info *);
-void stats_dbm_delete_byvfsp(stats_cookie_t *, caddr_t);
-size_t stats_dbm_attrcache_addsize(stats_cookie_t *, mount_info *,
- ino64_t, uint_t);
-datum stats_dbm_firstkey(stats_cookie_t *);
-datum stats_dbm_nextkey(stats_cookie_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CACHEFS_LIB_STATS_H */
diff --git a/usr/src/cmd/fs.d/cachefs/common/stats_create.c b/usr/src/cmd/fs.d/cachefs/common/stats_create.c
deleted file mode 100644
index f3f4c549f3..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/stats_create.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * stats_create.c
- *
- * Routines for the `clean interface' to cachefs statistics.
- */
-
-#include <stdarg.h>
-#include <libintl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <sys/fs/cachefs_fs.h>
-#include <string.h>
-#include "stats.h"
-
-void *malloc(), *calloc();
-
-/* forward declarations of statics */
-static stats_cookie_t *stats_create(char *);
-
-static stats_cookie_t *
-stats_create(char *progname)
-{
- stats_cookie_t *rc;
-
- if ((rc = (stats_cookie_t *)calloc(1, sizeof (*rc))) == NULL)
- goto out;
-
- rc->st_magic = STATS_MAGIC;
- if (rc->st_progname = strrchr(progname, '/'))
- rc->st_progname++;
- else
- rc->st_progname = progname;
-
- if ((rc->st_kstat_cookie = kstat_open()) == NULL) {
- stats_perror(rc, SE_KERNEL,
- gettext("Cannot initialize kstats"));
- goto out;
- }
-
-out:
- return (rc);
-}
-
-stats_cookie_t *
-stats_create_unbound(char *progname)
-{
- stats_cookie_t *st;
-
- if ((st = stats_create(progname)) == NULL)
- goto out;
-
- st->st_flags |= ST_VALID;
-
-out:
- return (st);
-}
-
-stats_cookie_t *
-stats_create_mountpath(char *mountpath, char *progname)
-{
- stats_cookie_t *st;
- kstat_t *key;
- cachefs_kstat_key_t *k;
- dev_t dev;
- ino64_t ino;
- struct stat64 s;
- int i, n;
-
- if ((st = stats_create(progname)) == NULL)
- goto out;
-
- if ((key = kstat_lookup(st->st_kstat_cookie, "cachefs", 0, "key"))
- == NULL) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot lookup cachefs key kstat"));
- goto out;
- }
- if (kstat_read(st->st_kstat_cookie, key, NULL) < 0) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read cachefs key kstat"));
- goto out;
- }
- k = (cachefs_kstat_key_t *)key->ks_data;
- n = key->ks_ndata;
-
- if (stat64(mountpath, &s) != 0) {
- stats_perror(st, SE_FILE,
- gettext("Cannot stat %s"), mountpath);
- goto out;
- }
- ino = s.st_ino;
- dev = s.st_dev;
-
- for (i = 0; i < n; i++) {
- k[i].ks_mountpoint += (uintptr_t)k;
- k[i].ks_backfs += (uintptr_t)k;
- k[i].ks_cachedir += (uintptr_t)k;
- k[i].ks_cacheid += (uintptr_t)k;
-
- if (! k[i].ks_mounted)
- continue;
-
- if ((stat64((char *)(uintptr_t)k[i].ks_mountpoint, &s) == 0) &&
- (s.st_dev == dev) &&
- (s.st_ino == ino))
- break;
- }
-
- if (i >= n) {
- stats_perror(st, SE_FILE,
- gettext("%s: not a cachefs mountpoint"), mountpath);
- goto out;
- }
-
- st->st_fsid = k[i].ks_id;
-
- st->st_flags |= ST_VALID | ST_BOUND;
-
-out:
- return (st);
-}
-
-/*
- * stats_next - bind the cookie to the next valid cachefs mount.
- *
- * returns cachefs_kstat_key_t *, which gives all the info you need.
- * returns NULL if we're out of mounts, or if an error occured.
- * returns malloc()ed data, which the client has to free() itself.
- */
-
-cachefs_kstat_key_t *
-stats_next(stats_cookie_t *st)
-{
- kstat_t *key;
- cachefs_kstat_key_t *k, *prc = NULL, *rc = NULL;
- int i, n;
-
- assert(stats_good(st));
-
- if (((key = kstat_lookup(st->st_kstat_cookie, "cachefs", 0,
- "key")) == NULL) ||
- (kstat_read(st->st_kstat_cookie, key, NULL) < 0)) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot get cachefs key kstat"));
- goto out;
- }
- k = (cachefs_kstat_key_t *)key->ks_data;
- n = key->ks_ndata;
-
- if (st->st_flags & ST_BOUND) {
- for (i = 0; i < n; i++)
- if (st->st_fsid == k[i].ks_id)
- break;
- ++i;
- if (i < n) {
- prc = k + i;
- st->st_fsid = k[i].ks_id;
- } else
- st->st_flags &= ~ST_BOUND;
- } else if (n > 0) {
- st->st_fsid = k[0].ks_id;
- st->st_flags |= ST_BOUND;
- prc = k;
- }
-
-out:
- if (prc != NULL) {
- char *s;
- int size;
-
- prc->ks_mountpoint += (uintptr_t)k;
- prc->ks_backfs += (uintptr_t)k;
- prc->ks_cachedir += (uintptr_t)k;
- prc->ks_cacheid += (uintptr_t)k;
-
- size = sizeof (*rc);
- size += strlen((char *)(uintptr_t)prc->ks_mountpoint) + 1;
- size += strlen((char *)(uintptr_t)prc->ks_backfs) + 1;
- size += strlen((char *)(uintptr_t)prc->ks_cachedir) + 1;
- size += strlen((char *)(uintptr_t)prc->ks_cacheid) + 1;
-
- if ((rc = (cachefs_kstat_key_t *)
- malloc(size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc return code"));
- } else {
- memcpy(rc, prc, sizeof (*rc));
- s = (char *)((uintptr_t)rc + sizeof (*rc));
-
- (void) strcpy(s, (char *)(uintptr_t)prc->ks_mountpoint);
- rc->ks_mountpoint = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)prc->ks_backfs);
- rc->ks_backfs = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)prc->ks_cachedir);
- rc->ks_cachedir = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)prc->ks_cacheid);
- rc->ks_cacheid = (uintptr_t)s;
- }
- }
-
- return (rc);
-}
-
-cachefs_kstat_key_t *
-stats_getkey(stats_cookie_t *st)
-{
- kstat_t *ksp;
- cachefs_kstat_key_t *k, *key, *rc = NULL;
- int size;
- char *s;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_BOUND);
-
- if (((ksp = kstat_lookup(st->st_kstat_cookie, "cachefs", 0,
- "key")) == NULL) ||
- (kstat_read(st->st_kstat_cookie, ksp, NULL) < 0)) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot get cachefs key kstat"));
- goto out;
- }
- key = (cachefs_kstat_key_t *)ksp->ks_data;
- k = key + st->st_fsid - 1;
- k->ks_mountpoint += (uintptr_t)key;
- k->ks_backfs += (uintptr_t)key;
- k->ks_cachedir += (uintptr_t)key;
- k->ks_cacheid += (uintptr_t)key;
- size = sizeof (*rc);
- size += strlen((char *)(uintptr_t)k->ks_mountpoint) + 1;
- size += strlen((char *)(uintptr_t)k->ks_backfs) + 1;
- size += strlen((char *)(uintptr_t)k->ks_cachedir) + 1;
- size += strlen((char *)(uintptr_t)k->ks_cacheid) + 1;
-
- if ((rc = (cachefs_kstat_key_t *)malloc(size)) == NULL)
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc return code"));
- else {
- memcpy(rc, k, sizeof (*rc));
- s = (char *)((uintptr_t)rc + sizeof (*rc));
-
- (void) strcpy(s, (char *)(uintptr_t)k->ks_mountpoint);
- rc->ks_mountpoint = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_backfs);
- rc->ks_backfs = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_cachedir);
- rc->ks_cachedir = (uintptr_t)s;
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_cacheid);
- rc->ks_cacheid = (uintptr_t)s;
- s += strlen(s) + 1;
- }
-
- assert(rc->ks_id == st->st_fsid);
-
-out:
- return (rc);
-}
-
-void
-stats_destroy(stats_cookie_t *st)
-{
- void free();
-
- if (st == NULL)
- return;
-
- if (st->st_kstat_cookie != NULL)
- kstat_close(st->st_kstat_cookie);
- if (st->st_logxdr.x_ops != NULL)
- xdr_destroy(&st->st_logxdr);
- if ((st->st_logstream != NULL) && (st->st_flags & ST_LFOPEN))
- (void) fclose(st->st_logstream);
-
- /*
- * we don't want to depend on dbm (or stats_dbm), so we don't
- * do a stats_dbm_close. we do try to require the client to
- * have done it, via an assert(), however.
- */
-
- assert(! (st->st_flags & ST_DBMOPEN));
-
- st->st_magic++;
-
- free(st);
-}
-
-int
-stats_good(stats_cookie_t *st)
-{
- if (st == NULL)
- return (0);
- if (st->st_magic != STATS_MAGIC)
- return (0);
- if (! (st->st_flags & ST_VALID))
- return (0);
-
- return (1);
-}
-
-void
-/*PRINTFLIKE3*/
-stats_perror(stats_cookie_t *st, int Errno, char *fmt, ...)
-{
-
- va_list ap;
-
- assert(st != NULL);
- assert(st->st_magic == STATS_MAGIC);
-
- va_start(ap, fmt);
- (void) vsnprintf(st->st_errorstr, sizeof (st->st_errorstr), fmt, ap);
- va_end(ap);
-
- st->st_errno = Errno;
-
- st->st_flags |= ST_ERROR;
-}
-
-char *
-stats_errorstr(stats_cookie_t *st)
-{
- assert(st != NULL);
- assert(st->st_magic == STATS_MAGIC);
-
- return (st->st_errorstr);
-}
-
-int
-stats_errno(stats_cookie_t *st)
-{
- assert(st != NULL);
- assert(st->st_magic == STATS_MAGIC);
-
- return (st->st_errno);
-}
-
-int
-stats_inerror(stats_cookie_t *st)
-{
- assert(st != NULL);
- assert(st->st_magic == STATS_MAGIC);
-
- return (st->st_flags & ST_ERROR);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/stats_dbm.c b/usr/src/cmd/fs.d/cachefs/common/stats_dbm.c
deleted file mode 100644
index 26f0ad9400..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/stats_dbm.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * 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 (c) 1996-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * stats_dbm.c
- *
- * Routines for dbm access.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <time.h>
-#include <string.h>
-#include <sys/fs/cachefs_fs.h>
-#include "stats.h"
-#include <assert.h>
-#include <ndbm.h>
-
-void
-stats_dbm_open(stats_cookie_t *st)
-{
- char *tmpdir;
- pid_t getpid();
-
- assert(stats_good(st));
- assert(! (st->st_flags & ST_DBMOPEN));
-
- if ((tmpdir = getenv("TMPDIR")) == NULL)
- tmpdir = "/tmp";
-
- (void) snprintf(st->st_dbm_name, sizeof (st->st_dbm_name), "%s/%s-%d",
- tmpdir, st->st_progname, getpid());
- st->st_dbm = dbm_open(st->st_dbm_name, O_RDWR | O_CREAT, 0666);
- if (st->st_dbm == NULL) {
- stats_perror(st, SE_FILE,
- gettext("Cannot open dbm file %s"), st->st_dbm_name);
- return;
- }
-
- st->st_flags |= ST_DBMOPEN;
-}
-
-void
-stats_dbm_rm(stats_cookie_t *st)
-{
- char buffy[MAXPATHLEN], *eobase;
- int unlink(), buflen, eobaselen;
-
- assert(stats_good(st));
-
- if (! (st->st_flags & ST_DBMOPEN))
- return;
-
- if (strlcpy(buffy, st->st_dbm_name, sizeof (buffy)) >
- ((sizeof (buffy)) - (sizeof (".xxx"))))
- return; /* No space for the file extensions */
- buflen = strlen(buffy);
- eobase = buffy + buflen;
- eobaselen = (sizeof (buffy)) - buflen;
-
- (void) strlcpy(eobase, ".dir", eobaselen);
- (void) unlink(buffy);
-
- (void) strlcpy(eobase, ".pag", eobaselen);
- (void) unlink(buffy);
-}
-
-void
-stats_dbm_close(stats_cookie_t *st)
-{
- assert(stats_good(st));
-
- if (! (st->st_flags & ST_DBMOPEN))
- return;
-
- st->st_flags &= ~ST_DBMOPEN;
-
- if (st->st_dbm == NULL)
- return;
-
- dbm_close(st->st_dbm);
-}
-
-fid_info *
-stats_dbm_fetch_byfid(stats_cookie_t *st, cfs_fid_t *fidp)
-{
- datum key, value;
- fid_info *rc;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- key.dptr = (char *)fidp;
- key.dsize = sizeof (*fidp);
- value = dbm_fetch(st->st_dbm, key);
-
- assert((value.dptr == NULL) || (value.dsize == sizeof (fid_info)));
- if (value.dptr == NULL)
- return (NULL);
-
- if ((rc = malloc(sizeof (*rc))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc memory for fid_info record"));
- return (NULL);
- }
-
- memcpy(rc, value.dptr, sizeof (*rc));
- if (rc->fi_magic != FI_MAGIC) {
- free(rc);
- return (NULL);
- }
-
- return (rc);
-}
-
-void
-stats_dbm_store_byfid(stats_cookie_t *st, cfs_fid_t *fidp, fid_info *fi)
-{
- datum key, value;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- fi->fi_magic = FI_MAGIC;
-
- key.dptr = (char *)fidp;
- key.dsize = sizeof (*fidp);
-
- value.dptr = (char *)fi;
- value.dsize = sizeof (*fi);
-
- if (dbm_store(st->st_dbm, key, value, DBM_REPLACE) != 0) {
- stats_perror(st, SE_FILE,
- gettext("Cannot store fid info"));
- return;
- }
-}
-
-mount_info *
-stats_dbm_fetch_byvfsp(stats_cookie_t *st, caddr_t vfsp)
-{
- mount_info *rc, *mi;
- int len1, len2, size;
-
- datum key, value;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- key.dptr = (char *)&vfsp;
- key.dsize = sizeof (vfsp);
- value = dbm_fetch(st->st_dbm, key);
-
- if (value.dptr == NULL)
- return (NULL);
-
- mi = (mount_info *)value.dptr;
-
- len1 = strlen(mi->mi_path);
- len2 = strlen(mi->mi_path + len1 + 1);
- size = sizeof (*rc) + len1 + len2 - CLPAD(mount_info, mi_path);
-
- if ((rc = malloc(size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc memory for mountinfo"));
- return (NULL);
- }
- memcpy(rc, mi, size);
-
- if (rc->mi_magic != MI_MAGIC) {
- free(rc);
- return (NULL);
- }
-
- return (rc);
-}
-
-void
-stats_dbm_store_byvfsp(stats_cookie_t *st, caddr_t vfsp, mount_info *mi)
-{
- datum key, value;
- int len1, len2;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- mi->mi_magic = MI_MAGIC;
-
- key.dptr = (char *)&vfsp;
- key.dsize = sizeof (vfsp);
-
- len1 = strlen(mi->mi_path);
- len2 = strlen(mi->mi_path + len1 + 1);
- value.dptr = (char *)mi;
- value.dsize = sizeof (*mi) +
- len1 + len2 -
- CLPAD(mount_info, mi_path);
-
- if (dbm_store(st->st_dbm, key, value, DBM_REPLACE) != 0) {
- stats_perror(st, SE_FILE,
- gettext("Cannot store mount info"));
- return;
- }
-}
-
-void
-stats_dbm_delete_byvfsp(stats_cookie_t *st, caddr_t vfsp)
-{
- datum key;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- key.dptr = (caddr_t)&vfsp;
- key.dsize = sizeof (vfsp);
-
- (void) dbm_delete(st->st_dbm, key);
-}
-
-datum
-stats_dbm_firstkey(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- return (dbm_firstkey(st->st_dbm));
-}
-
-datum
-stats_dbm_nextkey(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- return (dbm_nextkey(st->st_dbm));
-}
-
-/*
- * count var will be non-zero only for the record type CACHEFS_LOG_MDCREATE
- * and count can't be >2GB because it refers to the number of entries in
- * the attribute cache file.
- */
-size_t
-stats_dbm_attrcache_addsize(stats_cookie_t *st, mount_info *mi,
- ino64_t fileno, uint_t count)
-{
- char keystring[BUFSIZ];
- datum key, value;
- char *cacheid;
- fg_info fg, *fgp = NULL;
- size_t size = 0, overhead = 0;
- uchar_t tbits;
- int i;
- uint_t gfileno;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
-
- /* look up any known data about this filegrp */
- cacheid = mi->mi_path + strlen(mi->mi_path) + 1;
- (void) snprintf(keystring, sizeof (keystring), "%s.%lld", cacheid,
- fileno / (ino64_t)mi->mi_filegrp_size);
- gfileno = (uint_t)(fileno % (ino64_t)mi->mi_filegrp_size);
- key.dsize = strlen(keystring); /* no need to null terminate */
- key.dptr = keystring;
- value = dbm_fetch(st->st_dbm, key);
-
- size = sizeof (struct attrcache_header);
- size += mi->mi_filegrp_size * sizeof (struct attrcache_index);
- size += mi->mi_filegrp_size / NBBY;
-
- if ((value.dptr != NULL) && (value.dsize == sizeof (fg))) {
- /* align the structure */
- memcpy((char *)&fg, value.dptr, sizeof (fg));
- fgp = &fg;
- if (fgp->fg_magic != FG_MAGIC)
- fgp = NULL; /* oops -- key collision! */
- }
-
- /* if we haven't seen this filegrp yet */
- if (fgp == NULL) {
- memset((char *)&fg, '\0', sizeof (fg));
- fgp = &fg;
- fgp->fg_magic = FG_MAGIC;
-
- /* filegrp frontfile directory */
- overhead += st->st_loghead.lh_maxbsize;
- }
-
- /* high-water the given count (if any) with our known count */
- if (count > fgp->fg_count)
- fgp->fg_count = count;
-
- /* set a bit for this file */
- if ((gfileno / NBBY) < sizeof (fgp->fg_bits)) {
- tbits = 1 << (gfileno % NBBY);
- if (! (fgp->fg_bits[gfileno / NBBY] & tbits))
- fgp->fg_bcount++;
- fgp->fg_bits[gfileno / NBBY] |= tbits;
- }
-
- /* high-water our derived count with our known count */
- if (fgp->fg_bcount > fgp->fg_count)
- fgp->fg_count = fgp->fg_bcount;
-
- /* account for the size of all known attrcache entries */
- size += fgp->fg_count * sizeof (struct cachefs_metadata);
-
- /* round to the ceiling block boundary */
- size += st->st_loghead.lh_maxbsize - 1;
- size &= ~ (st->st_loghead.lh_maxbsize - 1);
-
- /* sneaky :-) -- high-water fg_size, and make size the delta */
- size -= fgp->fg_size;
- fgp->fg_size += size;
-
- value.dptr = (char *)fgp;
- value.dsize = sizeof (*fgp);
- if (dbm_store(st->st_dbm, key, value, DBM_REPLACE) != 0)
- stats_perror(st, SE_FILE,
- gettext("Cannot store attrcache info"));
-
- return (size + overhead);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/stats_log.c b/usr/src/cmd/fs.d/cachefs/common/stats_log.c
deleted file mode 100644
index 09b06392dd..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/stats_log.c
+++ /dev/null
@@ -1,1898 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Routines for cachefs logging.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <libintl.h>
-#include <time.h>
-#include <string.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-#include <malloc.h>
-#include <limits.h>
-#include "stats.h"
-#include <assert.h>
-
-/* forward declarations of statics */
-static kstat_t *stats_log_kstat_read(stats_cookie_t *);
-static char *stats_log_fmtfid(cfs_fid_t *);
-static bool_t stats_xdr_loghead(XDR *, struct cachefs_log_logfile_header *);
-static int stats_log_fi_comp(const void *a, const void *b);
-
-int
-stats_log_kernel_setname(stats_cookie_t *st, char *path)
-{
- int error = 0;
- kstat_t *log;
- cachefs_log_control_t *lc;
- int exists = 0;
-
- assert(stats_good(st));
-
- if ((log = stats_log_kstat_read(st)) == NULL) {
- error = stats_errno(st);
- goto out;
- }
-
- lc = (cachefs_log_control_t *)log->ks_data;
-
- /*
- * the stats_ API allows a NULL or an empty path to turn off
- * logging, but the kstat interface has the string buffered,
- * so we need to make an empty string.
- */
-
- if (path == NULL)
- path = "";
- if ((lc->lc_path[0] == 0) && (path[0] == 0))
- goto out;
-
- (void) strlcpy(lc->lc_path, path, sizeof (lc->lc_path));
-
- if (path[0] != '\0') {
- struct stat64 s;
- int f;
-
- exists = access(path, F_OK);
- /* logfile will be <2GB */
- f = open(path, O_WRONLY | O_CREAT, 0666);
- if (f < 0) {
- stats_perror(st, error = SE_FILE,
- gettext("Cannot open/create logfile: %s"),
- strerror(errno));
- goto out;
- }
-
- if (fstat64(f, &s) < 0) {
- stats_perror(st, error = SE_FILE,
- gettext("Cannot stat logfile: %s"),
- strerror(errno));
- (void) close(f);
- goto out;
- }
-
- /*
- * the kernel will accept an empty file as a logfile. we must
- * make sure that we created this empty file, i.e. that it's
- * not an already existing file that happened to be empty.
- *
- * if we hand the kernel a nonempty file, it will check the
- * magic number. thus, if they hand it something like
- * /etc/passwd, the kernel should reject it. we just have to
- * catch the cases of empty files we don't want to be
- * logfiles.
- */
-
- if ((exists == 0) && (s.st_size == 0LL)) {
- stats_perror(st, error = SE_INVAL,
- gettext(
- "Cannot use existing empty file as a logfile"));
- (void) close(f);
- goto out;
- }
-
- (void) close(f);
- }
-
- if (kstat_write(st->st_kstat_cookie, log, NULL) < 0) {
- stats_perror(st, error = SE_KERNEL,
- gettext("Cannot set logfile path for this filesystem"));
- goto out;
- }
-
-out:
- if ((error != 0) && (path[0] != '\0') && (exists != 0))
- (void) unlink(path);
-
- return (error);
-}
-
-int
-stats_log_which(stats_cookie_t *st, int which, int onoff)
-{
- int error = 0;
- kstat_t *log;
- cachefs_log_control_t *lc;
-
- assert(stats_good(st));
-
- if ((log = stats_log_kstat_read(st)) == NULL) {
- error = stats_errno(st);
- goto out;
- }
-
- lc = (cachefs_log_control_t *)log->ks_data;
-
- if (onoff)
- CACHEFS_LOG_SET(lc, which);
- else
- CACHEFS_LOG_CLEAR(lc, which);
-
- if (kstat_write(st->st_kstat_cookie, log, NULL) < 0) {
- stats_perror(st, error = SE_KERNEL,
- gettext("Cannot set log bitmap for this filesystem"));
- goto out;
- }
-
-out:
- return (error);
-}
-
-char *
-stats_log_kernel_getname(stats_cookie_t *st)
-{
- char *rc = NULL;
- kstat_t *log;
- cachefs_log_control_t *lc;
-
- assert(stats_good(st));
-
- if ((log = stats_log_kstat_read(st)) == NULL)
- goto out;
-
- lc = (cachefs_log_control_t *)log->ks_data;
-
- rc = lc->lc_path; /* rc[0] will be '\0' if we're not logging */
-
-out:
- return (rc);
-}
-
-static kstat_t *
-stats_log_kstat_read(stats_cookie_t *st)
-{
- kstat_t *rc;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_BOUND);
-
- if ((rc = kstat_lookup(st->st_kstat_cookie,
- "cachefs", st->st_fsid, "log")) == NULL) {
- /*
- * XXX if st was created for a particular cachedir, we
- * should scan for another st->st_fsid that'll get us
- * the same cache.
- */
- stats_perror(st, SE_KERNEL,
- gettext("Cannot lookup kstats for this filesystem"));
- goto out;
- }
- if (kstat_read(st->st_kstat_cookie, rc, NULL) < 0) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read kstats for this filesystem"));
- rc = NULL;
- goto out;
- }
-
-out:
- return (rc);
-}
-
-int
-stats_log_logfile_open(stats_cookie_t *st, char *fname)
-{
- int rc = 0;
-
- assert(stats_good(st));
-
- if ((fname == NULL) || (fname[0] == '\0')) {
- kstat_t *log;
- cachefs_log_control_t *lc;
-
- if ((log = stats_log_kstat_read(st)) == NULL) {
- rc = -1;
- goto out;
- }
- lc = (cachefs_log_control_t *)log->ks_data;
- fname = lc->lc_path;
- }
-
- /* logfile will be <2GB */
- if ((st->st_logstream = fopen(fname, "r")) == NULL) {
- stats_perror(st, SE_FILE,
- gettext("Cannot open logfile %s"), fname);
- rc = -1;
- goto out;
- }
- xdrstdio_create(&st->st_logxdr, st->st_logstream, XDR_DECODE);
-
- if (! stats_xdr_loghead(&st->st_logxdr, &st->st_loghead)) {
- stats_perror(st, SE_CORRUPT,
- gettext("Cannot read header from logfile %s"), fname);
- rc = -1;
- goto out;
- }
- if (st->st_loghead.lh_magic != CACHEFS_LOG_MAGIC) {
- stats_perror(st, SE_CORRUPT,
- gettext("%s: Invalid log file header"), fname);
- rc = -1;
- goto out;
- }
- if (st->st_loghead.lh_revision > CACHEFS_LOG_FILE_REV) {
- stats_perror(st, SE_CORRUPT,
- gettext("%s: Revision too high"), fname);
- rc = -1;
- goto out;
- }
-
- st->st_flags |= ST_LFOPEN;
-
-out:
- if (rc != 0) {
- if (st->st_logstream != NULL) {
- (void) fclose(st->st_logstream);
- st->st_logstream = NULL;
- }
- if (st->st_logxdr.x_ops != NULL) {
- xdr_destroy(&st->st_logxdr);
- st->st_logxdr.x_ops = NULL;
- }
- }
- return (rc);
-}
-
-static bool_t
-stats_xdr_loghead(XDR *xdrs, struct cachefs_log_logfile_header *lh)
-{
- if ((! xdr_u_int(xdrs, &lh->lh_magic)) ||
- (! xdr_u_int(xdrs, &lh->lh_revision)) ||
- (! xdr_int(xdrs, &lh->lh_errno)) ||
- (! xdr_u_int(xdrs, &lh->lh_blocks)) ||
- (! xdr_u_int(xdrs, &lh->lh_files)) ||
- (! xdr_u_int(xdrs, &lh->lh_maxbsize)) ||
- (! xdr_u_int(xdrs, &lh->lh_pagesize)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void *
-stats_log_logfile_read(stats_cookie_t *st, int *type)
-{
- void *rc = NULL;
- size_t size;
- int ttype;
- XDR *xdrs;
- char *string1, *string2;
-
- assert(stats_good(st));
-
- xdrs = &st->st_logxdr;
-
- if (! (st->st_flags & ST_LFOPEN)) {
- stats_perror(st, SE_INVAL,
- gettext("Logfile was not open"));
- goto out;
- }
-
- if (type == NULL)
- type = &ttype;
-
- if (! xdr_int(xdrs, type))
- goto out;
-
- switch (*type) {
- struct cachefs_log_mount_record mount, *mountp;
- struct cachefs_log_umount_record umount;
- struct cachefs_log_getpage_record getpage;
- struct cachefs_log_readdir_record readdir;
- struct cachefs_log_readlink_record readlink;
- struct cachefs_log_remove_record remove;
- struct cachefs_log_rmdir_record rmdir;
- struct cachefs_log_truncate_record truncate;
- struct cachefs_log_putpage_record putpage;
- struct cachefs_log_create_record create;
- struct cachefs_log_mkdir_record mkdir;
- struct cachefs_log_rename_record rename;
- struct cachefs_log_symlink_record symlink;
- struct cachefs_log_populate_record populate;
- struct cachefs_log_csymlink_record csymlink;
- struct cachefs_log_filldir_record filldir;
- struct cachefs_log_mdcreate_record mdcreate;
- struct cachefs_log_gpfront_record gpfront;
- struct cachefs_log_rfdir_record rfdir;
- struct cachefs_log_ualloc_record ualloc;
- struct cachefs_log_calloc_record challoc;
- struct cachefs_log_nocache_record nocache;
-
- case CACHEFS_LOG_MOUNT:
- if ((! xdr_int(xdrs, &mount.error)) ||
- (! xdr_int(xdrs, (int *)&mount.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&mount.vfsp,
- sizeof (mount.vfsp))) ||
- (! xdr_u_int(xdrs, &mount.flags)) ||
- (! xdr_u_int(xdrs, &mount.popsize)) ||
- (! xdr_u_int(xdrs, &mount.fgsize)) ||
- (! xdr_u_short(xdrs, &mount.pathlen)) ||
- (! xdr_u_short(xdrs, &mount.cacheidlen))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated mount record"));
- goto out;
- }
- mount.type = *type;
- size = sizeof (mount) + mount.pathlen + mount.cacheidlen -
- CLPAD(cachefs_log_mount_record, path);
- if ((rc = mountp =
- (struct cachefs_log_mount_record *)
- calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &mount, size);
- string1 = mountp->path;
- string2 = mountp->path + mount.pathlen + 1;
- (void) xdr_wrapstring(xdrs, &string1);
- (void) xdr_wrapstring(xdrs, &string2);
- break;
-
- case CACHEFS_LOG_UMOUNT:
- if ((! xdr_int(xdrs, &umount.error)) ||
- (! xdr_int(xdrs, (int *)&umount.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&umount.vfsp,
- sizeof (umount.vfsp)))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated umount record"));
- goto out;
- }
- umount.type = *type;
- size = sizeof (umount);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &umount, size);
- break;
-
- case CACHEFS_LOG_GETPAGE:
- if ((! xdr_int(xdrs, &getpage.error)) ||
- (! xdr_int(xdrs, (int *)&getpage.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&getpage.vfsp,
- sizeof (getpage.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&getpage.fid,
- sizeof (getpage.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&getpage.fileno)) ||
- (! xdr_int(xdrs, (int *)&getpage.uid)) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&getpage.offset)) ||
- (! xdr_u_int(xdrs, &getpage.len))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated getpage record"));
- goto out;
- }
- getpage.type = *type;
- size = sizeof (getpage);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &getpage, size);
- break;
-
- case CACHEFS_LOG_READDIR:
- if ((! xdr_int(xdrs, &readdir.error)) ||
- (! xdr_int(xdrs, (int *)&readdir.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&readdir.vfsp,
- sizeof (readdir.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&readdir.fid,
- sizeof (readdir.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&readdir.fileno)) ||
- (! xdr_int(xdrs, (int *)&readdir.uid)) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&readdir.offset)) ||
- (! xdr_int(xdrs, &readdir.eof))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated readdir record"));
- goto out;
- }
- readdir.type = *type;
- size = sizeof (readdir);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &readdir, size);
- break;
-
- case CACHEFS_LOG_READLINK:
- if ((! xdr_int(xdrs, &readlink.error)) ||
- (! xdr_int(xdrs, (int *)&readlink.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&readlink.vfsp,
- sizeof (readlink.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&readlink.fid,
- sizeof (readlink.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&readlink.fileno)) ||
- (! xdr_int(xdrs, (int *)&readlink.uid)) ||
- (! xdr_u_int(xdrs,
- &readlink.length))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated readlink record"));
- goto out;
- }
- readlink.type = *type;
- size = sizeof (readlink);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &readlink, size);
- break;
-
- case CACHEFS_LOG_REMOVE:
- if ((! xdr_int(xdrs, &remove.error)) ||
- (! xdr_int(xdrs, (int *)&remove.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&remove.vfsp,
- sizeof (remove.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&remove.fid,
- sizeof (remove.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&remove.fileno)) ||
- (! xdr_int(xdrs, (int *)&remove.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated remove record"));
- goto out;
- }
- remove.type = *type;
- size = sizeof (remove);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &remove, size);
- break;
-
- case CACHEFS_LOG_RMDIR:
- if ((! xdr_int(xdrs, &rmdir.error)) ||
- (! xdr_int(xdrs, (int *)&rmdir.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rmdir.vfsp,
- sizeof (rmdir.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rmdir.fid,
- sizeof (rmdir.fid))) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rmdir.fileno)) ||
- (! xdr_int(xdrs, (int *)&rmdir.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated rmdir record"));
- goto out;
- }
- rmdir.type = *type;
- size = sizeof (rmdir);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &rmdir, size);
- break;
-
- case CACHEFS_LOG_TRUNCATE:
- if ((! xdr_int(xdrs, &truncate.error)) ||
- (! xdr_int(xdrs, (int *)&truncate.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&truncate.vfsp,
- sizeof (truncate.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&truncate.fid,
- sizeof (truncate.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&truncate.fileno)) ||
- (! xdr_int(xdrs, (int *)&truncate.uid)) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&truncate.size))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated truncate record"));
- goto out;
- }
- truncate.type = *type;
- size = sizeof (truncate);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &truncate, size);
- break;
-
- case CACHEFS_LOG_PUTPAGE:
- if ((! xdr_int(xdrs, &putpage.error)) ||
- (! xdr_int(xdrs, (int *)&putpage.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&putpage.vfsp,
- sizeof (putpage.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&putpage.fid,
- sizeof (putpage.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&putpage.fileno)) ||
- (! xdr_int(xdrs, (int *)&putpage.uid)) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&putpage.offset)) ||
- (! xdr_u_int(xdrs, &putpage.len))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated putpage record"));
- goto out;
- }
- putpage.type = *type;
- size = sizeof (putpage);
- if ((rc = (caddr_t)calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &putpage, size);
- break;
-
- case CACHEFS_LOG_CREATE:
- if ((! xdr_int(xdrs, &create.error)) ||
- (! xdr_int(xdrs, (int *)&create.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&create.vfsp,
- sizeof (create.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&create.fid,
- sizeof (create.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&create.fileno)) ||
- (! xdr_int(xdrs, (int *)&create.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated create record"));
- goto out;
- }
- create.type = *type;
- size = sizeof (create);
- if ((rc = (struct cachefs_log_create_record *)
- calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &create, size);
- break;
-
- case CACHEFS_LOG_MKDIR:
- if ((! xdr_int(xdrs, &mkdir.error)) ||
- (! xdr_int(xdrs, (int *)&mkdir.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&mkdir.vfsp,
- sizeof (mkdir.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&mkdir.fid,
- sizeof (mkdir.fid))) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&mkdir.fileno)) ||
- (! xdr_int(xdrs, (int *)&mkdir.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated mkdir record"));
- goto out;
- }
- mkdir.type = *type;
- size = sizeof (mkdir);
- if ((rc = (struct cachefs_log_mkdir_record *)
- calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &mkdir, size);
- break;
-
- case CACHEFS_LOG_RENAME:
- if ((! xdr_int(xdrs, &rename.error)) ||
- (! xdr_int(xdrs, (int *)&rename.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rename.vfsp,
- sizeof (rename.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rename.gone,
- sizeof (rename.gone))) ||
- (! xdr_int(xdrs, &rename.removed)) ||
- (! xdr_int(xdrs, (int *)&rename.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated rename record"));
- goto out;
- }
- rename.type = *type;
- size = sizeof (rename);
- if ((rc = (struct cachefs_log_rename_record *)
- calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &rename, size);
- break;
-
- case CACHEFS_LOG_SYMLINK:
- if ((! xdr_int(xdrs, &symlink.error)) ||
- (! xdr_int(xdrs, (int *)&symlink.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&symlink.vfsp,
- sizeof (symlink.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&symlink.fid,
- sizeof (symlink.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&symlink.fileno)) ||
- (! xdr_int(xdrs, (int *)&symlink.uid)) ||
- (! xdr_u_int(xdrs, &symlink.size))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated symlink record"));
- goto out;
- }
- symlink.type = *type;
- size = sizeof (symlink);
- if ((rc = (struct cachefs_log_symlink_record *)
- calloc(1, size)) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &symlink, size);
- break;
-
- case CACHEFS_LOG_POPULATE:
- if ((! xdr_int(xdrs, &populate.error)) ||
- (! xdr_int(xdrs, (int *)&populate.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&populate.vfsp,
- sizeof (populate.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&populate.fid,
- sizeof (populate.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&populate.fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&populate.off)) ||
- (! xdr_u_int(xdrs, &populate.size))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated populate record"));
- goto out;
- }
- populate.type = *type;
- if ((rc = (struct cachefs_log_populate_record *)
- calloc(1, sizeof (populate))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &populate, sizeof (populate));
- break;
-
- case CACHEFS_LOG_CSYMLINK:
- if ((! xdr_int(xdrs, &csymlink.error)) ||
- (! xdr_int(xdrs, (int *)&csymlink.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&csymlink.vfsp,
- sizeof (csymlink.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&csymlink.fid,
- sizeof (csymlink.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&csymlink.fileno)) ||
- (! xdr_int(xdrs, &csymlink.size))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated csymlink record"));
- goto out;
- }
- csymlink.type = *type;
- if ((rc = (struct cachefs_log_csymlink_record *)
- calloc(1, sizeof (csymlink))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &csymlink, sizeof (csymlink));
- break;
-
- case CACHEFS_LOG_FILLDIR:
- if ((! xdr_int(xdrs, &filldir.error)) ||
- (! xdr_int(xdrs, (int *)&filldir.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&filldir.vfsp,
- sizeof (filldir.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&filldir.fid,
- sizeof (filldir.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&filldir.fileno)) ||
- (! xdr_int(xdrs, &filldir.size))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated filldir record"));
- goto out;
- }
- filldir.type = *type;
- if ((rc = (struct cachefs_log_filldir_record *)
- calloc(1, sizeof (filldir))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &filldir, sizeof (filldir));
- break;
-
- case CACHEFS_LOG_MDCREATE:
- if ((! xdr_int(xdrs, &mdcreate.error)) ||
- (! xdr_int(xdrs, (int *)&mdcreate.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&mdcreate.vfsp,
- sizeof (mdcreate.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&mdcreate.fid,
- sizeof (mdcreate.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&mdcreate.fileno)) ||
- (! xdr_u_int(xdrs, &mdcreate.count))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated mdcreate record"));
- goto out;
- }
- mdcreate.type = *type;
- if ((rc = (struct cachefs_log_mdcreate_record *)
- calloc(1, sizeof (mdcreate))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &mdcreate, sizeof (mdcreate));
- break;
-
- case CACHEFS_LOG_GPFRONT:
- if ((! xdr_int(xdrs, &gpfront.error)) ||
- (! xdr_int(xdrs, (int *)&gpfront.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&gpfront.vfsp,
- sizeof (gpfront.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&gpfront.fid,
- sizeof (gpfront.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&gpfront.fileno)) ||
- (! xdr_int(xdrs, (int *)&gpfront.uid)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&gpfront.off)) ||
- (! xdr_u_int(xdrs, &gpfront.len))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated gpfront record"));
- goto out;
- }
- gpfront.type = *type;
- if ((rc = (struct cachefs_log_gpfront_record *)
- calloc(1, sizeof (gpfront))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &gpfront, sizeof (gpfront));
- break;
-
- case CACHEFS_LOG_RFDIR:
- if ((! xdr_int(xdrs, &rfdir.error)) ||
- (! xdr_int(xdrs, (int *)&rfdir.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rfdir.vfsp,
- sizeof (rfdir.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rfdir.fid,
- sizeof (rfdir.fid))) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rfdir.fileno)) ||
- (! xdr_int(xdrs, (int *)&rfdir.uid))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated rfdir record"));
- goto out;
- }
- rfdir.type = *type;
- if ((rc = (struct cachefs_log_rfdir_record *)
- calloc(1, sizeof (rfdir))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &rfdir, sizeof (rfdir));
- break;
-
- case CACHEFS_LOG_UALLOC:
- if ((! xdr_int(xdrs, &ualloc.error)) ||
- (! xdr_int(xdrs, (int *)&ualloc.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&ualloc.vfsp,
- sizeof (ualloc.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&ualloc.fid,
- sizeof (ualloc.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&ualloc.fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&ualloc.off)) ||
- (! xdr_u_int(xdrs, &ualloc.len))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated ualloc record"));
- goto out;
- }
- ualloc.type = *type;
- if ((rc = (struct cachefs_log_ualloc_record *)
- calloc(1, sizeof (ualloc))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &ualloc, sizeof (ualloc));
- break;
-
- case CACHEFS_LOG_CALLOC:
- if ((! xdr_int(xdrs, &challoc.error)) ||
- (! xdr_int(xdrs, (int *)&challoc.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&challoc.vfsp,
- sizeof (challoc.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&challoc.fid,
- sizeof (challoc.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&challoc.fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&challoc.off)) ||
- (! xdr_u_int(xdrs, &challoc.len))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated calloc record"));
- goto out;
- }
- challoc.type = *type;
- if ((rc = (struct cachefs_log_calloc_record *)
- calloc(1, sizeof (challoc))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &challoc, sizeof (challoc));
- break;
-
- case CACHEFS_LOG_NOCACHE:
- if ((! xdr_int(xdrs, &nocache.error)) ||
- (! xdr_int(xdrs, (int *)&nocache.time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&nocache.vfsp,
- sizeof (nocache.vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&nocache.fid,
- sizeof (nocache.fid))) ||
- (! xdr_u_longlong_t(xdrs,
- (u_longlong_t *)&nocache.fileno))) {
- stats_perror(st, SE_CORRUPT,
- gettext("Truncated nocache record"));
- goto out;
- }
- nocache.type = *type;
- if ((rc = (struct cachefs_log_nocache_record *)
- calloc(1, sizeof (nocache))) == NULL) {
- stats_perror(st, SE_NOMEM,
- gettext("Cannot malloc record"));
- goto out;
- }
- memcpy(rc, &nocache, sizeof (nocache));
- break;
-
- default:
- stats_perror(st, SE_CORRUPT,
- gettext("Corrupt logfile (position %x)"),
- ftell(st->st_logstream));
- break;
- }
-
-out:
- return (rc);
-}
-
-/*
- * convert a logfile record (read by stats_log_logfile_read()) to
- * ascii. probably not for end-user consumption, but this should be
- * the official way to do it.
- */
-
-char *
-stats_log_record_toascii(stats_cookie_t *st, void *recp)
-{
- int rectype = *((int *)recp);
- int recerror = *((int *)recp + 1);
- time_t tt = *((time_t *)((int *)recp + 2));
- struct tm *tm = localtime(&tt);
- char buffy[BUFSIZ], *fidstr, *fidstr2, *fidstr3;
-
- struct cachefs_log_mount_record *mountp;
- struct cachefs_log_umount_record *umountp;
- struct cachefs_log_getpage_record *getpagep;
- struct cachefs_log_readdir_record *readdirp;
- struct cachefs_log_readlink_record *readlinkp;
- struct cachefs_log_remove_record *removep;
- struct cachefs_log_rmdir_record *rmdirp;
- struct cachefs_log_truncate_record *truncatep;
- struct cachefs_log_putpage_record *putpagep;
- struct cachefs_log_create_record *createp;
- struct cachefs_log_mkdir_record *mkdirp;
- struct cachefs_log_rename_record *renamep;
- struct cachefs_log_symlink_record *symlinkp;
- struct cachefs_log_populate_record *populatep;
- struct cachefs_log_csymlink_record *csymlinkp;
- struct cachefs_log_filldir_record *filldirp;
- struct cachefs_log_mdcreate_record *mdcreatep;
- struct cachefs_log_gpfront_record *gpfrontp;
- struct cachefs_log_rfdir_record *rfdirp;
- struct cachefs_log_ualloc_record *uallocp;
- struct cachefs_log_calloc_record *callocp;
- struct cachefs_log_nocache_record *nocachep;
-
- assert(stats_good(st));
-
- (void) sprintf(st->st_asciirec, "%2d/%-2d %2d:%.2d %2d",
- tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
- recerror);
-
- switch (rectype) {
- case CACHEFS_LOG_MOUNT:
- mountp = (struct cachefs_log_mount_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %8x %d %d %s (%s)", "Mount", mountp->vfsp,
- mountp->flags, mountp->popsize,
- mountp->fgsize, mountp->path,
- mountp->path + mountp->pathlen + 1);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- break;
-
- case CACHEFS_LOG_UMOUNT:
- umountp = (struct cachefs_log_umount_record *)recp;
- (void) snprintf(buffy, sizeof (buffy), " %-8s %llx",
- "Umount", umountp->vfsp);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- break;
-
- case CACHEFS_LOG_GETPAGE:
- getpagep = (struct cachefs_log_getpage_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %ld %llu %u",
- "Getpage",
- getpagep->vfsp, fidstr = stats_log_fmtfid(&getpagep->fid),
- getpagep->fileno,
- getpagep->uid, getpagep->offset, getpagep->len);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_READDIR:
- readdirp = (struct cachefs_log_readdir_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %llx %d", "Readdir",
- readdirp->vfsp, fidstr = stats_log_fmtfid(&readdirp->fid),
- readdirp->fileno,
- readdirp->uid, readdirp->offset, readdirp->eof);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_READLINK:
- readlinkp = (struct cachefs_log_readlink_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %u", "Readlink",
- readlinkp->vfsp,
- fidstr = stats_log_fmtfid(&readlinkp->fid),
- readlinkp->fileno,
- readlinkp->uid, readlinkp->length);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_REMOVE:
- removep = (struct cachefs_log_remove_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Remove",
- removep->vfsp, fidstr = stats_log_fmtfid(&removep->fid),
- removep->fileno,
- removep->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_RMDIR:
- rmdirp = (struct cachefs_log_rmdir_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Rmdir",
- rmdirp->vfsp, fidstr = stats_log_fmtfid(&rmdirp->fid),
- rmdirp->fileno,
- rmdirp->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_TRUNCATE:
- truncatep = (struct cachefs_log_truncate_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %llu", "Truncate",
- truncatep->vfsp,
- fidstr = stats_log_fmtfid(&truncatep->fid),
- truncatep->fileno,
- truncatep->uid, truncatep->size);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_PUTPAGE:
- putpagep = (struct cachefs_log_putpage_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %llu %u", "Putpage",
- putpagep->vfsp, fidstr = stats_log_fmtfid(&putpagep->fid),
- putpagep->fileno,
- putpagep->uid, putpagep->offset, putpagep->len);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_CREATE:
- createp = (struct cachefs_log_create_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Create",
- createp->vfsp,
- fidstr = stats_log_fmtfid(&createp->fid),
- createp->fileno,
- createp->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_MKDIR:
- mkdirp = (struct cachefs_log_mkdir_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Mkdir",
- mkdirp->vfsp,
- fidstr = stats_log_fmtfid(&mkdirp->fid),
- mkdirp->fileno,
- mkdirp->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_RENAME:
- renamep = (struct cachefs_log_rename_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %d", "Rename",
- renamep->vfsp,
- fidstr = stats_log_fmtfid(&renamep->gone),
- renamep->fileno,
- renamep->removed, renamep->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_SYMLINK:
- symlinkp = (struct cachefs_log_symlink_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %u", "Symlink",
- symlinkp->vfsp,
- fidstr = stats_log_fmtfid(&symlinkp->fid),
- symlinkp->fileno,
- symlinkp->uid, symlinkp->size);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_POPULATE:
- populatep = (struct cachefs_log_populate_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %llu %d", "Populate",
- populatep->vfsp,
- fidstr = stats_log_fmtfid(&populatep->fid),
- populatep->fileno,
- populatep->off, populatep->size);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_CSYMLINK:
- csymlinkp = (struct cachefs_log_csymlink_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Csymlink",
- csymlinkp->vfsp,
- fidstr = stats_log_fmtfid(&csymlinkp->fid),
- csymlinkp->fileno,
- csymlinkp->size);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_FILLDIR:
- filldirp = (struct cachefs_log_filldir_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Filldir",
- filldirp->vfsp,
- fidstr = stats_log_fmtfid(&filldirp->fid),
- filldirp->fileno,
- filldirp->size);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_MDCREATE:
- mdcreatep = (struct cachefs_log_mdcreate_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %u", "Mdcreate",
- mdcreatep->vfsp,
- fidstr = stats_log_fmtfid(&mdcreatep->fid),
- mdcreatep->fileno, mdcreatep->count);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_GPFRONT:
- gpfrontp = (struct cachefs_log_gpfront_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d %llu %u", "Gpfront",
- gpfrontp->vfsp,
- fidstr = stats_log_fmtfid(&gpfrontp->fid),
- gpfrontp->fileno,
- gpfrontp->uid, gpfrontp->off, gpfrontp->len);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_RFDIR:
- rfdirp = (struct cachefs_log_rfdir_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %d", "Rfdir",
- rfdirp->vfsp,
- fidstr = stats_log_fmtfid(&rfdirp->fid),
- rfdirp->fileno,
- rfdirp->uid);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_UALLOC:
- uallocp = (struct cachefs_log_ualloc_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %llu %u", "Ualloc",
- uallocp->vfsp,
- fidstr = stats_log_fmtfid(&uallocp->fid),
- uallocp->fileno,
- uallocp->off, uallocp->len);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_CALLOC:
- callocp = (struct cachefs_log_calloc_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu %llu %u", "Calloc",
- callocp->vfsp,
- fidstr = stats_log_fmtfid(&callocp->fid),
- callocp->fileno, callocp->off, callocp->len);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- case CACHEFS_LOG_NOCACHE:
- nocachep = (struct cachefs_log_nocache_record *)recp;
- (void) snprintf(buffy, sizeof (buffy),
- " %-8s %llx %s %llu", "Nocache",
- nocachep->vfsp,
- fidstr = stats_log_fmtfid(&nocachep->fid),
- nocachep->fileno);
- (void) strlcat(st->st_asciirec, buffy,
- sizeof (st->st_asciirec));
- free(fidstr);
- break;
-
- default:
- stats_perror(st, SE_CORRUPT,
- gettext(
- "Attempt to format invalid log type=%d (position %x)"),
- rectype, ftell(st->st_logstream));
- return (NULL);
- }
-
- return (st->st_asciirec);
-}
-
-uint_t
-stats_log_get_record_info(stats_cookie_t *sc,
- void *recp, caddr_t *vfsp, cfs_fid_t **fidp, ino64_t *filenop,
- u_offset_t *offp, u_offset_t *lenp)
-{
- int type = ((int *)recp)[0];
- int error = ((int *)recp)[1];
- uint_t rc = 0;
-
- struct cachefs_log_getpage_record *getpagep;
- struct cachefs_log_readdir_record *readdirp;
- struct cachefs_log_readlink_record *readlinkp;
- struct cachefs_log_remove_record *removep;
- struct cachefs_log_rmdir_record *rmdirp;
- struct cachefs_log_truncate_record *truncatep;
- struct cachefs_log_putpage_record *putpagep;
- struct cachefs_log_create_record *createp;
- struct cachefs_log_mkdir_record *mkdirp;
- struct cachefs_log_rename_record *renamep;
- struct cachefs_log_symlink_record *symlinkp;
- struct cachefs_log_populate_record *populatep;
- struct cachefs_log_csymlink_record *csymlinkp;
- struct cachefs_log_filldir_record *filldirp;
- struct cachefs_log_mdcreate_record *mdcreatep;
- struct cachefs_log_gpfront_record *gpfrontp;
- struct cachefs_log_rfdir_record *rfdirp;
- struct cachefs_log_ualloc_record *uallocp;
- struct cachefs_log_calloc_record *callocp;
- struct cachefs_log_nocache_record *nocachep;
-
- switch (type) {
- case CACHEFS_LOG_RFDIR:
- if ((error == EINVAL) || (error == ENOENT))
- error = 0;
- break;
- }
-
- if (error != 0)
- return (0);
-
- switch (type) {
- case CACHEFS_LOG_GETPAGE:
- getpagep = (struct cachefs_log_getpage_record *)recp;
- *fidp = &getpagep->fid;
- *filenop = getpagep->fileno;
- *vfsp = (caddr_t)(uintptr_t)getpagep->vfsp;
- *offp = getpagep->offset;
- *lenp = (u_offset_t)getpagep->len;
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_READDIR:
- readdirp = (struct cachefs_log_readdir_record *)recp;
- *fidp = &readdirp->fid;
- *filenop = readdirp->fileno;
- *vfsp = (caddr_t)(uintptr_t)readdirp->vfsp;
- *offp = readdirp->offset;
- *lenp = (u_offset_t)sc->st_loghead.lh_maxbsize;
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_READLINK:
- readlinkp = (struct cachefs_log_readlink_record *)recp;
- *fidp = &readlinkp->fid;
- *filenop = readlinkp->fileno;
- *vfsp = (caddr_t)(uintptr_t)readlinkp->vfsp;
- *offp = 0LL;
- *lenp = (u_offset_t)((readlinkp->length > C_FSL_SIZE) ?
- readlinkp->length : 0);
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_REMOVE:
- removep = (struct cachefs_log_remove_record *)recp;
- *fidp = &removep->fid;
- *filenop = removep->fileno;
- *vfsp = (caddr_t)(uintptr_t)removep->vfsp;
- *offp = *lenp = 0LL;
- rc = (GRI_TRUNC | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_RMDIR:
- rmdirp = (struct cachefs_log_rmdir_record *)recp;
- *fidp = &rmdirp->fid;
- *filenop = rmdirp->fileno;
- *vfsp = (caddr_t)(uintptr_t)rmdirp->vfsp;
- *offp = *lenp = 0LL;
- rc = (GRI_TRUNC | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_TRUNCATE:
- truncatep = (struct cachefs_log_truncate_record *)recp;
- *fidp = &truncatep->fid;
- *filenop = truncatep->fileno;
- *vfsp = (caddr_t)(uintptr_t)truncatep->vfsp;
- *offp = 0LL;
- *lenp = truncatep->size;
- rc = (GRI_TRUNC | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_PUTPAGE:
- putpagep = (struct cachefs_log_putpage_record *)recp;
- *fidp = &putpagep->fid;
- *filenop = putpagep->fileno;
- *vfsp = (caddr_t)(uintptr_t)putpagep->vfsp;
- *offp = putpagep->offset;
- *lenp = (u_offset_t)putpagep->len;
- rc = (GRI_ADD | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_CREATE:
- createp = (struct cachefs_log_create_record *)recp;
- *fidp = &createp->fid;
- *filenop = createp->fileno;
- *vfsp = (caddr_t)(uintptr_t)createp->vfsp;
- *offp = *lenp = 0LL;
- rc = (GRI_ADD | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_MKDIR:
- mkdirp = (struct cachefs_log_mkdir_record *)recp;
- *fidp = &mkdirp->fid;
- *filenop = mkdirp->fileno;
- *vfsp = (caddr_t)(uintptr_t)mkdirp->vfsp;
- *offp = *lenp = 0LL;
- rc = (GRI_ADD | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_RENAME:
- renamep = (struct cachefs_log_rename_record *)recp;
- *fidp = &renamep->gone;
- *filenop = renamep->fileno;
- *vfsp = (caddr_t)(uintptr_t)renamep->vfsp;
- *offp = *lenp = 0LL;
- rc = GRI_MODIFY;
- if (renamep->removed)
- rc |= GRI_TRUNC;
- break;
-
- case CACHEFS_LOG_SYMLINK:
- symlinkp = (struct cachefs_log_symlink_record *)recp;
- *fidp = &symlinkp->fid;
- *filenop = symlinkp->fileno;
- *vfsp = (caddr_t)(uintptr_t)symlinkp->vfsp;
- *offp = 0LL;
- *lenp = (u_offset_t)((symlinkp->size > C_FSL_SIZE) ?
- symlinkp->size : 0);
- rc = (GRI_ADD | GRI_MODIFY);
- break;
-
- case CACHEFS_LOG_POPULATE:
- populatep = (struct cachefs_log_populate_record *)recp;
- *fidp = &populatep->fid;
- *filenop = populatep->fileno;
- *vfsp = (caddr_t)(uintptr_t)populatep->vfsp;
- *offp = populatep->off;
- *lenp = (u_offset_t)populatep->size;
- rc = GRI_ADD;
- break;
-
- case CACHEFS_LOG_CSYMLINK:
- csymlinkp = (struct cachefs_log_csymlink_record *)recp;
- *fidp = &csymlinkp->fid;
- *filenop = csymlinkp->fileno;
- *vfsp = (caddr_t)(uintptr_t)csymlinkp->vfsp;
- *offp = 0LL;
- *lenp = (u_offset_t)((csymlinkp->size > C_FSL_SIZE) ?
- csymlinkp->size : 0);
- rc = GRI_ADD;
- break;
-
- case CACHEFS_LOG_FILLDIR:
- filldirp = (struct cachefs_log_filldir_record *)recp;
- *fidp = &filldirp->fid;
- *filenop = filldirp->fileno;
- *vfsp = (caddr_t)(uintptr_t)filldirp->vfsp;
- *offp = 0LL;
- *lenp = (u_offset_t)(filldirp->size);
- rc = GRI_ADD;
- break;
-
- case CACHEFS_LOG_MDCREATE:
- mdcreatep = (struct cachefs_log_mdcreate_record *)recp;
- *fidp = &mdcreatep->fid;
- *filenop = mdcreatep->fileno;
- *vfsp = (caddr_t)(uintptr_t)mdcreatep->vfsp;
- *lenp = (u_offset_t)mdcreatep->count;
- rc = GRI_METADATA;
- break;
-
- case CACHEFS_LOG_GPFRONT:
- gpfrontp = (struct cachefs_log_gpfront_record *)recp;
- *fidp = &gpfrontp->fid;
- *filenop = gpfrontp->fileno;
- *vfsp = (caddr_t)(uintptr_t)gpfrontp->vfsp;
- *offp = gpfrontp->off;
- *lenp = (u_offset_t)sc->st_loghead.lh_pagesize;
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_RFDIR:
- rfdirp = (struct cachefs_log_rfdir_record *)recp;
- rfdirp->error = 0;
- *fidp = &rfdirp->fid;
- *filenop = rfdirp->fileno;
- *vfsp = (caddr_t)(uintptr_t)rfdirp->vfsp;
- *offp = 0LL;
- *lenp = (u_offset_t)sc->st_loghead.lh_maxbsize;
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_UALLOC:
- uallocp = (struct cachefs_log_ualloc_record *)recp;
- *fidp = &uallocp->fid;
- *filenop = uallocp->fileno;
- *vfsp = (caddr_t)(uintptr_t)uallocp->vfsp;
- *offp = uallocp->off;
- *lenp = (u_offset_t)uallocp->len;
- rc = (GRI_ADD);
- break;
-
- case CACHEFS_LOG_CALLOC:
- callocp = (struct cachefs_log_calloc_record *)recp;
- *fidp = &callocp->fid;
- *filenop = callocp->fileno;
- *vfsp = (caddr_t)(uintptr_t)callocp->vfsp;
- *offp = callocp->off;
- *lenp = (u_offset_t)callocp->len;
- rc = (GRI_ADD | GRI_EXPENSIVE);
- break;
-
- case CACHEFS_LOG_NOCACHE:
- nocachep = (struct cachefs_log_nocache_record *)recp;
- *fidp = &nocachep->fid;
- *filenop = nocachep->fileno;
- *vfsp = (caddr_t)(uintptr_t)nocachep->vfsp;
- *offp = *lenp = 0LL;
- rc = (GRI_TRUNC);
- break;
- }
-
- return (rc);
-}
-
-/*
- * ascii formatter for fids. returns a malloc()ed string -- it's up to
- * the caller to free it.
- */
-
-static char *
-stats_log_fmtfid(cfs_fid_t *fidp)
-{
- char buffy[BUFSIZ], *rc;
-
-(void) strcpy(buffy, "<fid>");
-
- rc = strdup(buffy);
- if (rc == NULL)
- rc = "out of memory";
-
- return (rc);
-}
-
-void
-stats_log_fi_add(stats_cookie_t *st, fid_info *fip, u_offset_t off,
-u_offset_t len)
-{
- int i, j;
- u_offset_t iend, jend, tmp;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_DBMOPEN);
- assert(st->st_flags & ST_LFOPEN);
-
- /* shortcut if we had some sort of zero-length thing */
-
- if (len == 0LL)
- return;
-
- /* `smear' the offset and length to block boundaries */
-
- /*
- * pre-largefiles: iend = off & ~(st->st_loghead.lh_maxbsize - 1);
- * largefiles: make sure that we ~ all bits in the 64 bit
- * version of (st->st_loghead.lh_maxbsize - 1)
- */
- tmp = (u_offset_t)(st->st_loghead.lh_maxbsize - 1);
- iend = off & ~tmp;
-
- jend = off + len;
- jend += (u_offset_t)(st->st_loghead.lh_maxbsize - 1);
- /*
- * pre-largefiles: jend &= ~(st->st_loghead.lh_maxbsize - 1);
- * largefiles: make sure that we ~ all bits in the 64 bit
- * version of (st->st_loghead.lh_maxbsize - 1)
- */
- jend &= ~tmp;
-
- off = iend;
- len = jend - off;
-
- /* see if our offset falls within an existing chunk */
- for (i = 0; i < fip->fi_ent_n; i++) {
- iend = fip->fi_ent[i].offset + fip->fi_ent[i].len;
- if ((fip->fi_ent[i].offset <= off) && (iend >= off))
- break;
- }
-
- /* update the chunk, or make a new one */
- if (i < fip->fi_ent_n) {
- if ((off + len) > iend)
- fip->fi_ent[i].len = off + len - fip->fi_ent[i].offset;
- } else if (i < C_MAX_ALLOCINFO_SLOTS) {
- fip->fi_ent_n = i + 1;
- fip->fi_ent[i].offset = off;
- fip->fi_ent[i].len = len;
- } else {
- /* cachefs does a nocache, so we'll immitate */
-
- /*
- * XXX we're free to grow again. assume we got
- * inactivated right away -- the worst case!
- */
-
- fip->fi_ent_n = 0;
- fip->fi_total = 0LL;
- }
-
- /* quit for the trivial (hopefully the usual) case... */
- if (fip->fi_ent_n <= 1) {
- if (fip->fi_ent_n == 0)
- fip->fi_total = 0LL;
- else
- fip->fi_total = fip->fi_ent[0].len;
- return;
- }
-
- /*
- * we have to see if we can consolidate any chunks. the
- * chunks aren't guaranteed to be in any kind of order, so we
- * do a qsort. otherwise, the consolidation would be N^2 (but
- * we're probably close here).
- */
-
- qsort(fip->fi_ent, fip->fi_ent_n, sizeof (fip->fi_ent[0]),
- stats_log_fi_comp);
-
- /* tag non-essential entries with offset == -1, and consolidate */
- for (i = 0; i < fip->fi_ent_n - 1; i++) {
- if ((offset_t)fip->fi_ent[i].offset < 0)
- continue;
- iend = fip->fi_ent[i].offset + fip->fi_ent[i].len;
-
- for (j = i + 1; j < fip->fi_ent_n; j++) {
- if (iend < fip->fi_ent[j].offset)
- break;
- jend = fip->fi_ent[j].offset + fip->fi_ent[j].len;
- if (jend >= iend)
- fip->fi_ent[i].len =
- jend - fip->fi_ent[i].offset;
- fip->fi_ent[j].offset = (u_offset_t)-1;
- }
- }
-
- /* get rid of non-essential entries (without preserving order) */
- for (i = 0; i < fip->fi_ent_n; i++)
- if ((offset_t)fip->fi_ent[i].offset < 0)
- fip->fi_ent[i--] = fip->fi_ent[--(fip->fi_ent_n)];
-
- /* add up the new total size */
- for (i = fip->fi_total = 0LL; i < fip->fi_ent_n; i++)
- fip->fi_total += fip->fi_ent[i].len;
-}
-
-static int
-stats_log_fi_comp(const void *a, const void *b)
-{
- struct fid_info_allocent *fa = (struct fid_info_allocent *)a;
- struct fid_info_allocent *fb = (struct fid_info_allocent *)b;
-
- if ((offset_t)(fa->offset - fb->offset) > 0)
- return (1);
- if ((offset_t)(fa->offset - fb->offset) < 0)
- return (-1);
- return (0);
-}
-
-void
-stats_log_fi_trunc(stats_cookie_t *st, fid_info *fip, u_offset_t off,
-u_offset_t len)
-{
- fip->fi_ent_n = 1;
- fip->fi_ent[0].offset = off;
- fip->fi_ent[0].len = len;
- fip->fi_total = len;
-}
-
-struct cachefs_log_logfile_header *
-stats_log_getheader(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_LFOPEN);
-
- return (&st->st_loghead);
-}
-
-void
-stats_log_compute_wssize(stats_cookie_t *st)
-{
- void *record;
- int type;
- struct cachefs_log_mount_record *mountp;
- struct cachefs_log_umount_record *umountp;
- datum key;
- caddr_t vfsp;
- mount_info *mi = NULL, *mip;
- size_t len1, len2, maxlen;
- char *string1, *string2;
- uint_t rflags;
- fid_info fi, *fip;
- cfs_fid_t *fidp;
- ino64_t fileno;
- u_offset_t off;
- u_offset_t len;
- struct cachefs_log_logfile_header *lh = &st->st_loghead;
- size_t delta;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_LFOPEN);
- assert(st->st_flags & ST_DBMOPEN);
-
- /*
- * The maximum size of a mount_info structure is the size of
- * the structure less the space already defined for char mi_path[]
- * plus the maximum size of mi_path.
- *
- * Additional space is allocated to mi_path at runtime using
- * malloc(). The size needs to be calculated in-situ as ANSI C
- * will only allow 'sizeof expression' or 'sizeof (type)'.
- */
-
- mi = malloc(sizeof (*mi) - sizeof (mi->mi_path) + MI_MAX_MI_PATH);
- if (mi == NULL) {
- stats_perror(st, SE_NOMEM, gettext("Out of memory"));
- goto out;
- }
-
- st->st_ws_init = st->st_loghead.lh_blocks;
-
- while (record = stats_log_logfile_read(st, &type)) {
- switch (type) {
- case CACHEFS_LOG_MOUNT:
- mountp = (struct cachefs_log_mount_record *)record;
- if (mountp->error != 0)
- break;
- for (key = stats_dbm_firstkey(st);
- key.dptr != NULL;
- key = stats_dbm_nextkey(st)) {
- if (key.dsize != sizeof (vfsp))
- continue;
-
- memcpy((caddr_t)&vfsp, key.dptr,
- sizeof (vfsp));
- mip = stats_dbm_fetch_byvfsp(st, vfsp);
- if (mip == NULL)
- continue;
-
- len1 = strlen(mip->mi_path);
- len2 = strlen(mip->mi_path + len1 + 1);
- memcpy((caddr_t)mi, mip, sizeof (*mi) +
- len1 + len2 - CLPAD(mount_info, mi_path));
- free(mip);
-
- string1 = mi->mi_path + len1 + 1;
- string2 = mountp->path + mountp->pathlen + 1;
- if (strcmp(string1, string2) == 0) {
- stats_dbm_delete_byvfsp(st, vfsp);
- break;
- }
- }
- if (key.dptr == NULL) {
- /* non-idempotent setup stuff */
- memset(mi, '\0', sizeof (*mi));
- mi->mi_flags = mountp->flags;
- mi->mi_filegrp_size = mountp->fgsize;
- }
-
- /*
- * idempotent setup stuff
- *
- * Careful string handling around mi_path
- * is required as it contains two NULL
- * terminated strings.
- */
-
- mi->mi_mounted = 1;
- maxlen = MI_MAX_MI_PATH - 1;
- len1 = strlcpy(mi->mi_path, mountp->path, maxlen);
- if (len1 >= maxlen) {
- stats_perror(st, SE_CORRUPT,
- gettext("Path too long in log file"));
- break;
- }
-
- len1 = strlen(mi->mi_path);
- maxlen = MI_MAX_MI_PATH - (len1 + 1);
- len2 = strlcpy(mi->mi_path + len1 + 1,
- mountp->path + mountp->pathlen + 1, maxlen);
- if (len2 >= maxlen) {
- stats_perror(st, SE_CORRUPT,
- gettext("CacheID too long in log file"));
- break;
- }
-
- stats_dbm_store_byvfsp(st,
- (caddr_t)(uintptr_t)mountp->vfsp, mi);
- break;
-
- case CACHEFS_LOG_UMOUNT:
- umountp = (struct cachefs_log_umount_record *)record;
- if (umountp->error != 0)
- break;
- mip = stats_dbm_fetch_byvfsp(st,
- (caddr_t)(uintptr_t)umountp->vfsp);
- if (mip == NULL)
- break;
- mip->mi_mounted = 0;
- stats_dbm_store_byvfsp(st,
- (caddr_t)(uintptr_t)umountp->vfsp, mip);
- free(mip);
- break;
-
- default:
- rflags = stats_log_get_record_info(st, record,
- &vfsp, &fidp, &fileno, &off, &len);
- if (rflags == 0) /* shortcut */
- break;
-
- mip = stats_dbm_fetch_byvfsp(st, vfsp);
- if (mip == NULL) /* hopefully very rare */
- break;
-
- fip = stats_dbm_fetch_byfid(st, fidp);
- if (fip == NULL) {
- fip = &fi;
- memset(&fi, '\0', sizeof (fi));
- fi.fi_vfsp = vfsp;
- }
-
- /* account for the creation of the fscache */
- if (! mip->mi_used) {
- mip->mi_used = 1;
-
- /* account for the .cfs_option file */
- mip->mi_current += (u_offset_t)lh->lh_maxbsize;
- st->st_ws_current +=
- (u_offset_t)lh->lh_maxbsize;
- }
-
- /*
- * Add in the size-growth of the attrcache.
- * len will be non-zero only for the record type
- * CACHEFS_LOG_MDCREATE, and len can't be > 2GB because
- * it refers to the number of entries in
- * the attribute cache file.
- */
- assert(len <= UINT_MAX);
- delta = stats_dbm_attrcache_addsize(st, mip, fileno,
- (type == CACHEFS_LOG_MDCREATE) ? (uint_t)len : 0);
- st->st_ws_current += (u_offset_t)delta;
- mip->mi_current += (u_offset_t)delta;
-
- /* see if this is an `expensive' logfile */
- if ((! st->st_ws_expensive) && (rflags & GRI_EXPENSIVE))
- st->st_ws_expensive = 1;
-
- /* subtract current frontfile size ... */
- st->st_ws_current -= fip->fi_total;
- mip->mi_current -= fip->fi_total;
-
- /* compute new frontfile size */
- if ((mip->mi_flags & CFS_WRITE_AROUND) &&
- (rflags & GRI_MODIFY)) {
- fip->fi_total = 0LL;
- fip->fi_ent_n = 0;
- } else if (rflags & GRI_ADD) {
- stats_log_fi_add(st, fip, off, len);
- } else if (rflags & GRI_TRUNC) {
- stats_log_fi_trunc(st, fip, off, len);
- }
- if (rflags & GRI_METADATA)
- fip->fi_flags |= FI_METADATA;
-
- /* add back in new frontfile size */
- mip->mi_current += fip->fi_total;
- if (mip->mi_current > mip->mi_high)
- mip->mi_high = mip->mi_current;
- stats_dbm_store_byvfsp(st, vfsp, mip);
- free(mip);
- st->st_ws_current += fip->fi_total;
- if (st->st_ws_current > st->st_ws_high)
- st->st_ws_high = st->st_ws_current;
-
- stats_dbm_store_byfid(st, fidp, fip);
- if (fip != &fi)
- free(fip);
- break;
- }
-
- free(record);
-
- if (stats_inerror(st))
- break;
- }
-
-out:
- if (mi != NULL)
- free(mi);
- if (! stats_inerror(st))
- st->st_flags |= ST_WSCOMP;
-}
-
-int
-stats_log_wssize_init(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_WSCOMP);
-
- return (st->st_ws_init);
-}
-
-u_offset_t
-stats_log_wssize_current(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_WSCOMP);
-
- return (st->st_ws_current);
-}
-
-u_offset_t
-stats_log_wssize_high(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_WSCOMP);
-
- return (st->st_ws_high);
-}
-
-
-int
-stats_log_wssize_expensive(stats_cookie_t *st)
-{
- assert(stats_good(st));
- assert(st->st_flags & ST_WSCOMP);
-
- return (st->st_ws_expensive);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/stats_stats.c b/usr/src/cmd/fs.d/cachefs/common/stats_stats.c
deleted file mode 100644
index c1b3fe4cdf..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/stats_stats.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * 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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * stats_stats.c
- *
- * Routines for the `clean interface' to cachefs statistics.
- */
-
-#include <libintl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <sys/fs/cachefs_fs.h>
-#include "stats.h"
-
-static kstat_t *
-stats_read_stat(stats_cookie_t *st)
-{
- kstat_t *stat;
-
- assert(stats_good(st));
- assert(st->st_flags & ST_BOUND);
-
- if (((stat = kstat_lookup(st->st_kstat_cookie,
- "cachefs", st->st_fsid, "stats")) == NULL) ||
- (kstat_read(st->st_kstat_cookie, stat, NULL) < 0)) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot lookup statistics"),
- st->st_fsid);
- goto out;
- }
-out:
- return (stat);
-}
-
-u_int
-stats_hits(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_hits;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-u_int
-stats_misses(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_misses;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-u_int
-stats_passes(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_passes;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-u_int
-stats_fails(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_fails;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-u_int
-stats_modifies(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_modifies;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-u_int
-stats_gc_count(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- u_int rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_gc_count;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-time_t
-stats_gc_time(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- time_t rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_gc_time;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-time_t
-stats_gc_before(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- time_t rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_gc_before_atime;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-time_t
-stats_gc_after(stats_cookie_t *st)
-{
- kstat_t *ks;
- cachefs_stats_t *stats;
- time_t rc = 0;
-
- if ((ks = stats_read_stat(st)) != NULL) {
- stats = (cachefs_stats_t *) ks->ks_data;
- rc = stats->st_gc_after_atime;
- } else {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot read statistics"));
- }
-
- return (rc);
-}
-
-int
-stats_zero_stats(stats_cookie_t *st)
-{
- cachefs_stats_t stats;
- kstat_t *ks;
- int rc = 0;
- void *memset();
-
- assert(stats_good(st));
- assert(st->st_flags & ST_BOUND);
-
- if ((ks = stats_read_stat(st)) == NULL) {
- rc = -1;
- goto out;
- }
-
- memset(&stats, '\0', sizeof (stats));
- ks->ks_data = &stats;
-
- if (kstat_write(st->st_kstat_cookie, ks, NULL) < 0) {
- stats_perror(st, SE_KERNEL,
- gettext("Cannot zero statistics"));
- rc = -1;
- goto out;
- }
-
-out:
- return (rc);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/subr.c b/usr/src/cmd/fs.d/cachefs/common/subr.c
deleted file mode 100644
index 887379c987..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/subr.c
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Common subroutines used by the programs in these subdirectories.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <wait.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <ftw.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <utmpx.h>
-#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/mman.h>
-#include <sys/fs/cachefs_fs.h>
-#include "subr.h"
-
-/*
- *
- * cachefs_dir_lock
- *
- * Description:
- * Gets a lock on the cache directory.
- * To release the lock, call cachefs_dir_unlock
- * with the returned value.
- * Arguments:
- * cachedirp name of the cache directory
- * shared 1 if shared, 0 if not
- * Returns:
- * Returns -1 if the lock cannot be obtained immediatly.
- * If the lock is obtained, returns a value >= 0.
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cachefs_dir_lock(const char *cachedirp, int shared)
-{
- int fd;
- int xx;
- int len;
- char buf[MAXPATHLEN];
- struct flock fl;
- char *strp;
- struct stat statb;
-
- /* make a path prefix to the cache directory lock file */
- strp = CACHEFS_ROOTRUN;
- xx = stat(strp, &statb);
- if ((xx < 0) || ((statb.st_mode & S_IFMT) != S_IFDIR))
- strp = "/tmp";
-
- /* won't overflow */
- len = snprintf(buf, sizeof (buf), "%s/%s", strp, CACHEFS_LOCKDIR_PRE);
-
- if (strlcat(buf, cachedirp, sizeof (buf)) >= sizeof (buf)) {
- pr_err(gettext("Cache directory name %s is too long"),
- cachedirp);
- return (-1);
- }
-
- strp = &buf[len];
-
- while (strp = strchr(strp, '/')) { /* convert path to a file */
- *strp = '_';
- }
-
- /*
- * Create and open the cache directory lock file.
- * This file will be <2G.
- */
- fd = open(buf, O_RDWR | O_CREAT, 0700);
- if (fd == -1) {
- pr_err(gettext("Cannot open lock file %s"), buf);
- return (-1);
- }
-
- /* try to set the lock */
- fl.l_type = (shared == 1) ? F_RDLCK : F_WRLCK;
- fl.l_whence = 0;
- fl.l_start = 1024;
- fl.l_len = 1024;
- fl.l_sysid = 0;
- fl.l_pid = 0;
- /* CACHEFS_LOCK_FILE will be <2GB */
- xx = fcntl(fd, F_SETLKW, &fl);
- if (xx == -1) {
- if (errno == EAGAIN) {
- pr_err(gettext("Cannot gain access to the "
- "cache directory %s."), cachedirp);
- } else {
- pr_err(gettext("Unexpected failure on lock file %s %s"),
- buf, strerror(errno));
- }
- close(fd);
- return (-1);
- }
-
- /* return the file descriptor which can be used to release the lock */
- return (fd);
-}
-
-/*
- *
- * cachefs_dir_unlock
- *
- * Description:
- * Releases an advisory lock on the cache directory.
- * Arguments:
- * fd cookie returned by cachefs_dir_lock
- * Returns:
- * Returns -1 if the lock cannot be released or 0 for success.
- * Preconditions:
- */
-
-int
-cachefs_dir_unlock(int fd)
-{
- struct flock fl;
- int error = 0;
- int xx;
-
- /* release the lock */
- fl.l_type = F_UNLCK;
- fl.l_whence = 0;
- fl.l_start = 1024;
- fl.l_len = 1024;
- fl.l_sysid = 0;
- fl.l_pid = 0;
- /* fd will be <2GB */
- xx = fcntl(fd, F_SETLK, &fl);
- if (xx == -1) {
- pr_err(gettext("Unexpected failure releasing lock file %s"),
- strerror(errno));
- error = -1;
- }
-
- /* close the lock file */
- close(fd);
-
- return (error);
-}
-
-/*
- *
- * cachefs_label_file_get
- *
- * Description:
- * Gets the contents of a cache label file.
- * Performs error checking on the file.
- * Arguments:
- * filep name of the cache label file
- * clabelp where to put the file contents
- * Returns:
- * Returns 0 for success or -1 if an error occurs.
- * Preconditions:
- * precond(filep)
- * precond(clabelp)
- */
-
-int
-cachefs_label_file_get(const char *filep, struct cache_label *clabelp)
-{
- int xx;
- int fd;
- struct stat64 statinfo;
-
- /* get info on the file */
- xx = lstat64(filep, &statinfo);
- if (xx == -1) {
- if (errno != ENOENT) {
- pr_err(gettext("Cannot stat file %s: %s"),
- filep, strerror(errno));
- } else {
- pr_err(gettext("File %s does not exist."), filep);
- }
-
- return (-1);
- }
-
- /* if the file is the wrong type */
- if (!S_ISREG(statinfo.st_mode)) {
- pr_err(gettext("Cache label file %s corrupted"), filep);
- return (-1);
- }
-
- /* if the file is the wrong size; it will be <2GB */
- if (statinfo.st_size != (offset_t)sizeof (struct cache_label)) {
- pr_err(gettext("Cache label file %s wrong size"), filep);
- return (-1);
- }
-
- /* open the cache label file */
- fd = open(filep, O_RDONLY);
- if (fd == -1) {
- pr_err(gettext("Error opening %s: %s"), filep,
- strerror(errno));
- return (-1);
- }
-
- /* read the current set of parameters */
- xx = read(fd, clabelp, sizeof (struct cache_label));
- if (xx != sizeof (struct cache_label)) {
- pr_err(gettext("Reading %s failed: %s\n"), filep,
- strerror(errno));
- close(fd);
- return (-1);
- }
- close(fd);
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_label_file_put
- *
- * Description:
- * Outputs the contents of a cache label object to a file.
- * Arguments:
- * filep name of the cache label file
- * clabelp where to get the file contents
- * Returns:
- * Returns 0 for success or -1 if an error occurs.
- * Preconditions:
- * precond(filep)
- * precond(clabelp)
- */
-
-int
-cachefs_label_file_put(const char *filep, struct cache_label *clabelp)
-{
- int xx;
- int fd;
-
- /* get rid of the file if it already exists */
- xx = unlink(filep);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("Could not remove %s: %s"), filep,
- strerror(errno));
- return (-1);
- }
-
- /* open the cache label file; this file will be <2GB */
- fd = open(filep, O_CREAT | O_RDWR, 0600);
- if (fd == -1) {
- pr_err(gettext("Error creating %s: %s"), filep,
- strerror(errno));
- return (-1);
- }
-
- /* write out the cache label object */
- xx = write(fd, clabelp, sizeof (struct cache_label));
- if (xx != sizeof (struct cache_label)) {
- pr_err(gettext("Writing %s failed: %s"), filep,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- /* make sure the contents get to disk */
- if (fsync(fd) != 0) {
- pr_err(gettext("Writing %s failed on sync: %s"), filep,
- strerror(errno));
- close(fd);
- return (-1);
- }
-
- close(fd);
-
- /* return success */
- return (0);
-}
-
-int
-cachefs_label_file_vcheck(char *filep, struct cache_label *clabelp)
-{
- /* check for an invalid version number */
- if (clabelp->cl_cfsversion != CFSVERSION) {
- pr_err(gettext("Cache label file %s corrupted"), filep);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- *
- * cachefs_inuse
- *
- * Description:
- * Tests whether or not the cache directory is in use by
- * the cache file system.
- * Arguments:
- * cachedirp name of the file system cache directory
- * Returns:
- * Returns 1 if the cache is in use or an error, 0 if not.
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cachefs_inuse(const char *cachedirp)
-{
- int fd;
- int xx;
- char buf[MAXPATHLEN];
- char *lockp = CACHEFS_LOCK_FILE;
- struct flock fl;
-
- /* see if path name is too long */
- xx = strlen(cachedirp) + strlen(lockp) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Cache directory name %s is too long"),
- cachedirp);
- return (1);
- }
-
- /* make a path to the cache directory lock file */
- snprintf(buf, sizeof (buf), "%s/%s", cachedirp, lockp);
-
- /* Open the kernel in use lock file. This file will be <2GB. */
- fd = open(buf, O_RDWR, 0700);
- if (fd == -1) {
- pr_err(gettext("Cannot open lock file %s"), buf);
- return (1);
- }
-
- /* test the lock status */
- fl.l_type = F_WRLCK;
- fl.l_whence = 0;
- fl.l_start = 0;
- fl.l_len = 1024;
- fl.l_sysid = 0;
- fl.l_pid = 0;
- xx = fcntl(fd, F_GETLK, &fl);
- if (xx == -1) {
- pr_err(gettext("Unexpected failure on lock file %s %s"),
- buf, strerror(errno));
- close(fd);
- return (1);
- }
- close(fd);
-
- if (fl.l_type == F_UNLCK)
- xx = 0;
- else
- xx = 1;
-
- /* return whether or not the cache is in use */
- return (xx);
-}
-
-/*
- *
- * cachefs_resouce_size
- *
- * Description:
- * Returns information about a resource file.
- * Arguments:
- * maxinodes number of inodes to be managed by the resource file
- * rinfop set to info about the resource file
- * Returns:
- * Preconditions:
- * precond(rinfop)
- */
-
-void
-cachefs_resource_size(int maxinodes, struct cachefs_rinfo *rinfop)
-{
- int fsize;
-
- fsize = MAXBSIZE;
-
- rinfop->r_ptroffset = fsize;
-
- fsize += MAXBSIZE * (maxinodes / CACHEFS_RLPMBS);
- if ((maxinodes % CACHEFS_RLPMBS) != 0)
- fsize += MAXBSIZE;
-
- rinfop->r_fsize = fsize;
-}
-
-/*
- *
- * cachefs_create_cache
- *
- * Description:
- * Creates the specified cache directory and populates it as
- * needed by CFS.
- * Arguments:
- * dirp the name of the cache directory
- * uv user values (may be NULL)
- * clabel label file contents, or placeholder for this
- * Returns:
- * Returns 0 for success or:
- * -1 for an error
- * -2 for an error and cache directory partially created
- * Preconditions:
- * precond(dirp)
- */
-
-int
-cachefs_create_cache(char *dirp, struct cachefs_user_values *uv,
- struct cache_label *clabel)
-{
- int xx;
- char path[CACHEFS_XMAXPATH];
- int fd;
- void *bufp;
- int cnt;
- struct cache_usage cu;
- FILE *fp;
- char *parent;
- struct statvfs64 svfs;
-
- cu.cu_blksused = 0;
- cu.cu_filesused = 0;
- cu.cu_flags = 0;
-
- /* make sure cache dir name is not too long */
- if (strlen(dirp) > (size_t)PATH_MAX) {
- pr_err(gettext("path name %s is too long."), dirp);
- return (-1);
- }
-
- /* ensure the path isn't in cachefs */
- parent = cachefs_file_to_dir(dirp);
- if (parent == NULL) {
- pr_err(gettext("Out of memory"));
- return (-1);
- }
- if (statvfs64(parent, &svfs) != 0) {
- pr_err(gettext("%s: %s"), parent, strerror(errno));
- free(parent);
- return (-1);
- }
- if (strcmp(svfs.f_basetype, CACHEFS_BASETYPE) == 0) {
- pr_err(gettext("Cannot create cache in cachefs filesystem"));
- free(parent);
- return (-1);
- }
- free(parent);
-
- /* make the directory */
- if (mkdir(dirp, 0) == -1) {
- switch (errno) {
- case EEXIST:
- pr_err(gettext("%s already exists."), dirp);
- break;
-
- default:
- pr_err(gettext("mkdir %s failed: %s"),
- dirp, strerror(errno));
- }
- return (-1);
- }
- cu.cu_filesused += 1;
- cu.cu_blksused += 1;
-
- /* convert user values to a cache_label */
- if (uv != NULL) {
- xx = cachefs_convert_uv2cl(uv, clabel, dirp);
- if (xx)
- return (-2);
- }
-
- /*
- * Create the cache directory lock file.
- * Used by the kernel module to indicate the cache is in use.
- * This file will be <2G.
- */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_LOCK_FILE);
- fd = open(path, O_RDWR | O_CREAT, 0700);
- if (fd == -1) {
- pr_err(gettext("Cannot create lock file %s"), path);
- return (-1);
- }
- close(fd);
-
- /* make the directory for the back file system mount points */
- /* note: we do not count this directory in the resources */
- snprintf(path, sizeof (path), "%s/%s", dirp, BACKMNT_NAME);
- if (mkdir(path, 0700) == -1) {
- pr_err(gettext("mkdir %s failed: %s"), path,
- strerror(errno));
- return (-2);
- }
-
- /* make the directory for lost+found */
- /* note: we do not count this directory in the resources */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_LOSTFOUND_NAME);
- if (mkdir(path, 0700) == -1) {
- pr_err(gettext("mkdir %s failed: %s"), path,
- strerror(errno));
- return (-2);
- }
-
- /* make the networker "don't back up" file; this file is <2GB */
- xx = 0;
- snprintf(path, sizeof (path), "%s/%s", dirp, NOBACKUP_NAME);
- if ((fp = fopen(path, "w")) != NULL) {
- if (realpath(dirp, path) != NULL) {
- fprintf(fp, "<< ./ >>\n");
- fprintf(fp, "+skip: .?* *\n");
- if (fclose(fp) == 0)
- xx = 1;
- }
- }
- if (xx == 0) {
- snprintf(path, sizeof (path), "%s/%s", dirp, NOBACKUP_NAME);
- pr_err(gettext("can't create %s"), path);
- (void) unlink(path);
- } else {
- cu.cu_filesused += 1;
- cu.cu_blksused += 1;
- }
-
- /* create the unmount file */
- xx = 0;
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_UNMNT_FILE);
- if ((fp = fopen(path, "w")) != NULL) {
- time32_t btime;
-
- btime = get_boottime();
- fwrite((void *)&btime, sizeof (btime), 1, fp);
- if (fclose(fp) == 0)
- xx = 1;
- }
- if (xx == 0)
- pr_err(gettext("can't create .cfs_unmnt file"));
-
- /* create the cache label file */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHELABEL_NAME);
- xx = cachefs_label_file_put(path, clabel);
- if (xx == -1) {
- pr_err(gettext("creating %s failed."), path);
- return (-2);
- }
- cu.cu_filesused += 1;
- cu.cu_blksused += 1;
-
- /* create the cache label duplicate file */
- snprintf(path, sizeof (path), "%s/%s.dup", dirp, CACHELABEL_NAME);
- xx = cachefs_label_file_put(path, clabel);
- if (xx == -1) {
- pr_err(gettext("creating %s failed."), path);
- return (-2);
- }
- cu.cu_filesused += 1;
- cu.cu_blksused += 1;
-
- /* create the resouce file; this file will be <2GB */
- snprintf(path, sizeof (path), "%s/%s", dirp, RESOURCE_NAME);
- fd = open(path, O_CREAT | O_RDWR, 0600);
- if (fd == -1) {
- pr_err(gettext("create %s failed: %s"), path,
- strerror(errno));
- return (-2);
- }
- cu.cu_filesused += 1;
-
- /* allocate a zeroed buffer for filling the resouce file */
- bufp = calloc(1, MAXBSIZE);
- if (bufp == NULL) {
- pr_err(gettext("out of space %d."), MAXBSIZE);
- close(fd);
- return (-2);
- }
-
- /* determine number of MAXBSIZE chunks to make the file */
- cnt = 1; /* for the header */
- cnt += clabel->cl_maxinodes / CACHEFS_RLPMBS;
- if ((clabel->cl_maxinodes % CACHEFS_RLPMBS) != 0)
- ++cnt;
-
- /* fill up the file with zeros */
- for (xx = 0; xx < cnt; xx++) {
- if (write(fd, bufp, MAXBSIZE) != MAXBSIZE) {
- pr_err(gettext("write %s failed: %s"), path,
- strerror(errno));
- close(fd);
- free(bufp);
- return (-2);
- }
- }
- free(bufp);
- cu.cu_blksused += cnt;
-
- /* position to the begining of the file */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- pr_err(gettext("lseek %s failed: %s"), path,
- strerror(errno));
- close(fd);
- return (-2);
- }
-
- /* write the cache usage structure */
- xx = sizeof (struct cache_usage);
- if (write(fd, &cu, xx) != xx) {
- pr_err(gettext("cu write %s failed: %s"), path,
- strerror(errno));
- close(fd);
- return (-2);
- }
-
- /* make sure the contents get to disk */
- if (fsync(fd) != 0) {
- pr_err(gettext("fsync %s failed: %s"), path,
- strerror(errno));
- close(fd);
- return (-2);
- }
- close(fd);
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_delete_all_cache
- *
- * Description:
- * Delete all caches in cache directory.
- * Arguments:
- * dirp the pathname of of the cache directory to delete
- * Returns:
- * Returns 0 for success or -1 for an error.
- * Preconditions:
- * precond(dirp)
- */
-
-int
-cachefs_delete_all_cache(char *dirp)
-{
- DIR *dp;
- struct dirent64 *dep;
- int xx;
- char path[CACHEFS_XMAXPATH];
- struct stat64 statinfo;
-
- /* make sure cache dir name is not too long */
- if (strlen(dirp) > (size_t)PATH_MAX) {
- pr_err(gettext("path name %s is too long."),
- dirp);
- return (-1);
- }
-
- /* check that dirp is probably a cachefs directory */
- snprintf(path, sizeof (path), "%s/%s", dirp, BACKMNT_NAME);
- xx = access(path, R_OK | W_OK | X_OK);
-
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHELABEL_NAME);
- xx |= access(path, R_OK | W_OK);
-
- if (xx) {
- pr_err(gettext("%s does not appear to be a "
- "cachefs cache directory."), dirp);
- return (-1);
- }
-
- /* remove the lost+found directory if it exists and is empty */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_LOSTFOUND_NAME);
- xx = rmdir(path);
- if (xx == -1) {
- if (errno == EEXIST) {
- pr_err(gettext("Cannot delete cache '%s'. "
- "First move files in '%s' to a safe location."),
- dirp, path);
- return (-1);
- } else if (errno != ENOENT) {
- pr_err(gettext("rmdir %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
- }
-
- /* delete the back FS mount point directory if it exists */
- snprintf(path, sizeof (path), "%s/%s", dirp, BACKMNT_NAME);
- xx = lstat64(path, &statinfo);
- if (xx == -1) {
- if (errno != ENOENT) {
- pr_err(gettext("lstat %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
- } else {
- xx = nftw64(path, cachefs_delete_file, 16,
- FTW_PHYS | FTW_DEPTH | FTW_MOUNT);
- if (xx == -1) {
- pr_err(gettext("unable to delete %s"), path);
- return (-1);
- }
- }
-
- /* open the cache directory specified */
- if ((dp = opendir(dirp)) == NULL) {
- pr_err(gettext("cannot open cache directory %s: %s"),
- dirp, strerror(errno));
- return (-1);
- }
-
- /* read the file names in the cache directory */
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if (strcmp(dep->d_name, ".") == 0 ||
- strcmp(dep->d_name, "..") == 0)
- continue;
-
- /* stat the file */
- snprintf(path, sizeof (path), "%s/%s", dirp, dep->d_name);
- xx = lstat64(path, &statinfo);
- if (xx == -1) {
- if (errno == ENOENT) {
- /* delete_cache may have nuked a directory */
- continue;
- }
-
- pr_err(gettext("lstat %s failed: %s"),
- path, strerror(errno));
- closedir(dp);
- return (-1);
- }
-
- /* ignore anything that is not a link */
- if (!S_ISLNK(statinfo.st_mode))
- continue;
-
- /* delete the file system cache directory */
- xx = cachefs_delete_cache(dirp, dep->d_name);
- if (xx) {
- closedir(dp);
- return (-1);
- }
- }
- closedir(dp);
-
- /* remove the cache dir unmount file */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_UNMNT_FILE);
- xx = unlink(path);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* remove the cache label file */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHELABEL_NAME);
- xx = unlink(path);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* remove the cache label duplicate file */
- snprintf(path, sizeof (path), "%s/%s.dup", dirp, CACHELABEL_NAME);
- xx = unlink(path);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* remove the resource file */
- snprintf(path, sizeof (path), "%s/%s", dirp, RESOURCE_NAME);
- xx = unlink(path);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* remove the cachefslog file if it exists */
- snprintf(path, sizeof (path), "%s/%s", dirp, LOG_STATUS_NAME);
- (void) unlink(path);
-
- /* remove the networker "don't back up" file if it exists */
- snprintf(path, sizeof (path), "%s/%s", dirp, NOBACKUP_NAME);
- (void) unlink(path);
-
- /* remove the lock file */
- snprintf(path, sizeof (path), "%s/%s", dirp, CACHEFS_LOCK_FILE);
- xx = unlink(path);
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* remove the directory */
- xx = rmdir(dirp);
- if (xx == -1) {
- pr_err(gettext("rmdir %s failed: %s"), dirp,
- strerror(errno));
- return (-1);
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_delete_cache
- *
- * Description:
- * Deletes the specified file system cache.
- * Arguments:
- * dirp cache directory name
- * namep file system cache directory to delete
- * Returns:
- * Returns 0 for success, -1 for failure.
- * Preconditions:
- * precond(dirp)
- * precond(namep)
- */
-
-int
-cachefs_delete_cache(char *dirp, char *namep)
-{
- char path[CACHEFS_XMAXPATH];
- char buf[CACHEFS_XMAXPATH];
- int xx;
- struct stat64 statinfo;
-
- /* make sure cache dir name is not too long */
- if (strlen(dirp) > (size_t)PATH_MAX) {
- pr_err(gettext("path name %s is too long."),
- dirp);
- return (-1);
- }
-
- /* construct the path name of the file system cache directory */
- snprintf(path, sizeof (path), "%s/%s", dirp, namep);
-
- /* stat the specified file */
- xx = lstat64(path, &statinfo);
- if (xx == -1) {
- pr_err(gettext("lstat %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* make sure name is a symbolic link */
- if (!S_ISLNK(statinfo.st_mode)) {
- pr_err(gettext("\"%s\" is not a valid cache id."), namep);
- return (-1);
- }
-
- /* read the contents of the symbolic link */
- xx = readlink(path, buf, sizeof (buf));
- if (xx == -1) {
- pr_err(gettext("Readlink of %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
- buf[xx] = '\0';
-
- /* remove the directory */
- snprintf(path, sizeof (path), "%s/%s", dirp, buf);
- xx = nftw64(path, cachefs_delete_file, 16,
- FTW_PHYS | FTW_DEPTH | FTW_MOUNT);
- if (xx == -1) {
- pr_err(gettext("directory walk of %s failed."), dirp);
- return (-1);
- }
-
- /* delete the link */
- snprintf(path, sizeof (path), "%s/%s", dirp, namep);
- if (unlink(path) == -1) {
- pr_err(gettext("unlink %s failed: %s"), path,
- strerror(errno));
- return (-1);
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_delete_file
- *
- * Description:
- * Remove a file or directory; called by nftw64().
- * Arguments:
- * namep pathname of the file
- * statp stat info about the file
- * flg info about file
- * ftwp depth information
- * Returns:
- * Returns 0 for success, -1 for failure.
- * Preconditions:
- * precond(namep)
- */
-
-int
-cachefs_delete_file(const char *namep, const struct stat64 *statp, int flg,
- struct FTW *ftwp)
-{
- /* ignore . and .. */
- if (strcmp(namep, ".") == 0 || strcmp(namep, "..") == 0)
- return (0);
-
- switch (flg) {
- case FTW_F: /* files */
- case FTW_SL:
- if (unlink(namep) == -1) {
- pr_err(gettext("unlink %s failed: %s"),
- namep, strerror(errno));
- return (-1);
- }
- break;
-
- case FTW_DP: /* directories that have their children processed */
- if (rmdir(namep) == -1) {
- pr_err(gettext("rmdir %s failed: %s"),
- namep, strerror(errno));
- return (-1);
- }
- break;
-
- case FTW_D: /* ignore directories if children not processed */
- break;
-
- default:
- pr_err(gettext("failure on file %s, flg %d."),
- namep, flg);
- return (-1);
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_convert_uv2cl
- *
- * Description:
- * Copies the contents of a cachefs_user_values object into a
- * cache_label object, performing the necessary conversions.
- * Arguments:
- * uvp cachefs_user_values to copy from
- * clp cache_label to copy into
- * dirp cache directory
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(uvp)
- * precond(clp)
- * precond(dirp)
- */
-
-int
-cachefs_convert_uv2cl(const struct cachefs_user_values *uvp,
- struct cache_label *clp, const char *dirp)
-{
- struct statvfs64 fs;
- int xx;
- double ftmp;
- double temp;
-
- /* get file system information */
- xx = statvfs64(dirp, &fs);
- if (xx == -1) {
- pr_err(gettext("statvfs %s failed: %s"), dirp,
- strerror(errno));
- return (-1);
- }
-
- ftmp = (double)fs.f_frsize / (double)MAXBSIZE;
-
- /* front fs is less than 1 terabyte */
- temp = (double)uvp->uv_maxblocks / 100.0 *
- (double)fs.f_blocks * ftmp + .5;
- clp->cl_maxblks = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- temp = (double)uvp->uv_minblocks / 100.0 *
- (double)fs.f_blocks * ftmp + .5;
- clp->cl_blockmin = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- temp = (double)uvp->uv_threshblocks / 100.0 *
- (double)fs.f_blocks * ftmp + .5;
- clp->cl_blocktresh = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- temp = (double)uvp->uv_maxfiles / 100.0 * (double)fs.f_files + .5;
- clp->cl_maxinodes = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- temp = (double)uvp->uv_minfiles / 100.0 * (double)fs.f_files + .5;
- clp->cl_filemin = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- temp = (double)uvp->uv_threshfiles / 100.0 * (double)fs.f_files +.5;
- clp->cl_filetresh = temp < (double)INT_MAX ? (int)temp : INT_MAX;
-
- ftmp = (double)(1024 * 1024) / (double)MAXBSIZE;
- clp->cl_maxfiles = uvp->uv_maxfilesize * ftmp + .5;
-
- clp->cl_blkhiwat = uvp->uv_hiblocks / 100.0 * clp->cl_maxblks + .5;
- clp->cl_blklowat = uvp->uv_lowblocks / 100.0 * clp->cl_maxblks + .5;
-
- clp->cl_filehiwat = uvp->uv_hifiles / 100.0 * clp->cl_maxinodes + .5;
- clp->cl_filelowat = uvp->uv_lowfiles / 100.0 * clp->cl_maxinodes + .5;
-
- clp->cl_cfsversion = CFSVERSION;
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cachefs_convert_cl2uv
- *
- * Description:
- * Copies the contents of a cache_label object into a
- * cachefs_user_values object, performing the necessary conversions.
- * Arguments:
- * clp cache_label to copy from
- * uvp cachefs_user_values to copy into
- * dirp cache directory
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(clp)
- * precond(uvp)
- * precond(dirp)
- */
-
-int
-cachefs_convert_cl2uv(const struct cache_label *clp,
- struct cachefs_user_values *uvp, const char *dirp)
-{
- struct statvfs64 fs;
- int xx;
- double temp;
- double ftmp;
- long long ltmp;
-
- /* get file system information */
- xx = statvfs64(dirp, &fs);
- if (xx == -1) {
- pr_err(gettext("statvfs %s failed: %s"), dirp,
- strerror(errno));
- return (-1);
- }
-
-#define BOUND(yy) \
- yy = (yy < 0) ? 0 : yy; \
- yy = (yy > 100) ? 100 : yy;
-
- ftmp = (double)MAXBSIZE / (double)fs.f_frsize;
-
- temp = (double)clp->cl_maxblks * ftmp /
- (double)fs.f_blocks * 100. + .5;
- BOUND(temp);
- uvp->uv_maxblocks = (int)temp;
-
- temp = (double)clp->cl_blockmin * ftmp /
- (double)fs.f_blocks * 100. + .5;
- BOUND(temp);
- uvp->uv_minblocks = (int)temp;
-
- temp = (double)clp->cl_blocktresh * ftmp /
- (double)fs.f_blocks * 100. + .5;
- BOUND(temp);
- uvp->uv_threshblocks = (int)temp;
-
- temp = ((double)clp->cl_maxinodes / fs.f_files) * 100. + .5;
- BOUND(temp);
- uvp->uv_maxfiles = (int)temp;
-
- temp = ((double)clp->cl_filemin / fs.f_files) * 100. + .5;
- BOUND(temp);
- uvp->uv_minfiles = (int)temp;
-
- temp = ((double)clp->cl_filetresh / fs.f_files) * 100. + .5;
- BOUND(temp);
- uvp->uv_threshfiles = (int)temp;
-
- ltmp = ((long long)clp->cl_maxfiles * MAXBSIZE);
- uvp->uv_maxfilesize = (ltmp + (MAXBSIZE / 2)) / (1024 * 1024);
-
- xx = ((double)clp->cl_blkhiwat / clp->cl_maxblks) * 100. + .5;
- BOUND(xx);
- uvp->uv_hiblocks = xx;
-
- xx = ((double)clp->cl_blklowat / clp->cl_maxblks) * 100. + .5;
- BOUND(xx);
- uvp->uv_lowblocks = xx;
-
- xx = ((double)clp->cl_filehiwat / clp->cl_maxinodes) * 100. + .5;
- BOUND(xx);
- uvp->uv_hifiles = xx;
-
- xx = ((double)clp->cl_filelowat / clp->cl_maxinodes) * 100. + .5;
- BOUND(xx);
- uvp->uv_lowfiles = xx;
-
- /* return success */
- return (0);
-}
-
-/*
- * cachefs_file_to_dir
- *
- * takes in a path, and returns the parent directory of that path.
- *
- * it's the caller's responsibility to free the pointer returned by
- * this function.
- */
-
-char *
-cachefs_file_to_dir(const char *path)
-{
- char *rc, *cp;
-
- if (path == NULL)
- return (NULL);
-
- rc = strdup(path);
- if (rc == NULL)
- return (NULL);
-
- if ((cp = strrchr(rc, '/')) == NULL) {
-
- /*
- * if no slashes at all, return "." (current directory).
- */
-
- (void) free(rc);
- rc = strdup(".");
-
- } else if (cp == rc) {
-
- /*
- * else, if the last '/' is the first character, chop
- * off from there (i.e. return "/").
- */
-
- rc[1] = '\0';
-
- } else {
-
- /*
- * else, we have a path like /foo/bar or foo/bar.
- * chop off from the last '/'.
- */
-
- *cp = '\0';
-
- }
-
- return (rc);
-}
-
-/*
- * cachefs_clean_flag_test
- *
- * Description:
- * Tests whether or not the clean flag on the file system
- * is set.
- * Arguments:
- * cachedirp name of the the file system cache directory
- * Returns:
- * Returns 1 if the cache was shut down cleanly, 0 if not.
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cachefs_clean_flag_test(const char *cachedirp)
-{
- char *namep;
- int xx;
- char buf[MAXPATHLEN];
- int fd;
- struct cache_usage cu;
-
- /* construct the path name of the resource file */
- namep = RESOURCE_NAME;
- xx = strlen(cachedirp) + strlen(namep) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Path name too long %s/%s"),
- cachedirp, namep);
- return (39);
- }
- snprintf(buf, sizeof (buf), "%s/%s", cachedirp, namep);
-
- /* open the file; it will be <2GB */
- fd = open(buf, O_RDONLY);
- if (fd == -1) {
- pr_err(gettext("Cannot open %s: %s"), buf, strerror(errno));
- return (0);
- }
-
- /* read the cache_usage structure */
- xx = read(fd, &cu, sizeof (cu));
- if (xx != sizeof (cu)) {
- pr_err(gettext("Error reading %s: %d %s"), buf,
- xx, strerror(errno));
- close(fd);
- return (0);
- }
- close(fd);
-
- /* return state of the cache */
- return ((cu.cu_flags & CUSAGE_ACTIVE) == 0);
-}
-
-time32_t
-get_boottime()
-{
- struct utmpx id, *putmp;
-
- id.ut_type = BOOT_TIME;
- setutxent();
- if ((putmp = getutxid(&id)) != NULL)
- return ((time32_t)putmp->ut_tv.tv_sec);
- return (-1);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/common/subr.h b/usr/src/cmd/fs.d/cachefs/common/subr.h
deleted file mode 100644
index 622c35e85b..0000000000
--- a/usr/src/cmd/fs.d/cachefs/common/subr.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 (c) 1996-1998, by Sun Microsystems, Inc.
- * All Rights Reserved.
- */
-
-#ifndef _SUBR_H
-#define _SUBR_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * subr.h
- *
- * Function prototypes for subr.c
- */
-
-#include <ftw.h>
-
-/* size to make a buffer for holding a pathname */
-#define CACHEFS_XMAXPATH (PATH_MAX + MAXNAMELEN + 2)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* resource file info */
-struct cachefs_rinfo {
- int r_fsize; /* total file size */
- int r_ptroffset; /* offset to pointers area */
- int r_ptrsize; /* size of pointers area */
- int r_identoffset; /* offset to idents area */
- int r_identsize; /* size of idents area */
-};
-
-struct cachefs_user_values {
- int uv_maxblocks;
- int uv_minblocks;
- int uv_threshblocks;
- int uv_maxfiles;
- int uv_minfiles;
- int uv_threshfiles;
- int uv_maxfilesize;
- int uv_hiblocks;
- int uv_lowblocks;
- int uv_hifiles;
- int uv_lowfiles;
-};
-
-int cachefs_dir_lock(const char *cachedirp, int shared);
-int cachefs_dir_unlock(int fd);
-int cachefs_label_file_get(const char *filep, struct cache_label *clabelp);
-int cachefs_label_file_put(const char *filep, struct cache_label *clabelp);
-int cachefs_inuse(const char *cachedirp);
-int cachefs_label_file_vcheck(char *filep, struct cache_label *clabelp);
-void cachefs_resource_size(int maxinodes, struct cachefs_rinfo *rinfop);
-int cachefs_create_cache(char *dirp, struct cachefs_user_values *,
- struct cache_label *);
-int cachefs_delete_all_cache(char *dirp);
-int cachefs_delete_cache(char *dirp, char *namep);
-int cachefs_delete_file(const char *namep, const struct stat64 *statp, int flg,
- struct FTW *ftwp);
-int cachefs_convert_uv2cl(const struct cachefs_user_values *uvp,
- struct cache_label *clp, const char *dirp);
-int cachefs_convert_cl2uv(const struct cache_label *clp,
- struct cachefs_user_values *uvp, const char *dirp);
-char *cachefs_file_to_dir(const char *);
-int cachefs_clean_flag_test(const char *cachedirp);
-void pr_err(char *fmt, ...);
-time32_t get_boottime(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SUBR_H */
diff --git a/usr/src/cmd/fs.d/cachefs/dfshares/Makefile b/usr/src/cmd/fs.d/cachefs/dfshares/Makefile
deleted file mode 100644
index 798c74c750..0000000000
--- a/usr/src/cmd/fs.d/cachefs/dfshares/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# 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 (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-FSTYPE= cachefs
-LIBPROG= dfshares
-SRCS= dfshares.sh
-
-include ../../Makefile.fstype
-
-all: $(LIBPROG)
-
-install: all
-
-clean:
- $(RM) $(LIBPROG)
diff --git a/usr/src/cmd/fs.d/cachefs/dfshares/dfshares.sh b/usr/src/cmd/fs.d/cachefs/dfshares/dfshares.sh
deleted file mode 100644
index 3e56241a89..0000000000
--- a/usr/src/cmd/fs.d/cachefs/dfshares/dfshares.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/sh
-#
-# 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 (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-# dfshares is a server utility but cachefs is a client
-# filesystem, so dfshares for cachefs will do nothing.
-# This utility is needed because cachefs is included in
-# /etc/dfs/fstypes.
-
-exit 0
diff --git a/usr/src/cmd/fs.d/cachefs/fsck/Makefile b/usr/src/cmd/fs.d/cachefs/fsck/Makefile
deleted file mode 100644
index cae2746b40..0000000000
--- a/usr/src/cmd/fs.d/cachefs/fsck/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989, 1996 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# cmd/fs.d/cachefs/fsck
-#
-
-FSTYPE= cachefs
-LIBPROG= fsck
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= fsck.o res.o dlog_ck.o
-
-include ../Makefile.cachefs
-CPPFLAGS += -D_LARGEFILE64_SOURCE
-
-$(LIBPROG) : $(CFSLIB)
-
-$(PROGOBJS) : $(CACHEFSDIR)/subr.h $(CACHEFSDIR)/cachefsd.h
diff --git a/usr/src/cmd/fs.d/cachefs/fsck/dlog_ck.c b/usr/src/cmd/fs.d/cachefs/fsck/dlog_ck.c
deleted file mode 100644
index f728b59ca4..0000000000
--- a/usr/src/cmd/fs.d/cachefs/fsck/dlog_ck.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * 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 1996-2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-
-/* forward references */
-static int create_mapfile(char *fname, int size);
-
-int
-dlog_ck(char *dir_path, ino64_t *maxlocalfilenop)
-{
- int err;
- int n;
- char dlog_path[MAXPATHLEN];
- char dmap_path[MAXPATHLEN];
- struct stat64 statinfo;
- int fd;
- int dlog_version;
- off_t offset;
- struct cfs_dlog_entry buf;
- int max_seq_num;
- int ent_count = 0;
- ino64_t fileno, maxlocalfileno;
-
- if (maxlocalfilenop)
- *maxlocalfilenop = 0LL;
-
- n = strlen(dir_path) + strlen(CACHEFS_DLOG_FILE) + 2;
- if (n > MAXPATHLEN) {
- pr_err(gettext("%s/%s: path too long"),
- dir_path, CACHEFS_DLOG_FILE);
- return (-1);
- }
- sprintf(dlog_path, "%s/%s", dir_path, CACHEFS_DLOG_FILE);
-
- n = strlen(dir_path) + strlen(CACHEFS_DMAP_FILE) + 2;
- if (n > MAXPATHLEN) {
- pr_err(gettext("%s/%s: path too long"),
- dir_path, CACHEFS_DMAP_FILE);
- return (-1);
- }
- sprintf(dmap_path, "%s/%s", dir_path, CACHEFS_DMAP_FILE);
-
- err = lstat64(dlog_path, &statinfo);
- if (err < 0) {
- if (errno == ENOENT)
- (void) unlink(dmap_path);
- /*
- * No disconnect log(dlog) file exists to check
- */
- return (0);
- }
-
- /* this file will be <2GB */
- fd = open(dlog_path, O_RDWR);
- if (fd < 0) {
- pr_err(gettext("can't open %s"), dlog_path);
- return (-2);
- }
- err = read(fd, &dlog_version, sizeof (dlog_version));
- if (err != sizeof (dlog_version)) {
- pr_err(gettext("can't read %s"), dlog_path);
- (void) close(fd);
- return (-3);
- }
- if (dlog_version != CFS_DLOG_VERSION) {
- pr_err(gettext(
- "unknown version number in %s"), dlog_path);
- (void) close(fd);
- return (-4);
- }
-
- offset = sizeof (dlog_version);
- max_seq_num = 0;
- maxlocalfileno = 0LL;
- while (offset < (off_t)statinfo.st_size) {
- err = (int) lseek(fd, offset, SEEK_SET);
- if (err == -1) {
- pr_err(gettext("can't lseek %s"), dlog_path);
- (void) close(fd);
- return (-5);
- }
-
- err = read(fd, &buf, sizeof (buf));
- if (err < 0) {
- pr_err(gettext("can't read %s"), dlog_path);
- (void) close(fd);
- return (-6);
- }
- ++ent_count;
- if (buf.dl_op == CFS_DLOG_TRAILER) {
- goto out;
- }
- if ((buf.dl_len & 3) == 0) {
- /*
- * Record length must be on a word boundary and
- * fit into the correct size range.
- */
- if ((buf.dl_len < sizeof (int)) ||
- (buf.dl_len > CFS_DLOG_ENTRY_MAXSIZE)) {
- goto out;
- }
- /*
- * Make sure length does not point beyond end of
- * file
- */
- if ((offset + (off_t)buf.dl_len) >
- (off_t)statinfo.st_size) {
- goto out;
- }
- } else {
- goto out;
- }
-
- /* make sure the valid field is reasonable */
- switch (buf.dl_valid) {
- case CFS_DLOG_VAL_CRASH:
- case CFS_DLOG_VAL_COMMITTED:
- case CFS_DLOG_VAL_ERROR:
- case CFS_DLOG_VAL_PROCESSED:
- break;
- default:
- goto out;
- }
-
- /* make sure the operation field is reasonable */
- fileno = 0LL;
- switch (buf.dl_op) {
- case CFS_DLOG_CREATE:
- fileno = buf.dl_u.dl_create.dl_new_cid.cid_fileno;
- break;
- case CFS_DLOG_REMOVE:
- break;
- case CFS_DLOG_LINK:
- break;
- case CFS_DLOG_RENAME:
- break;
- case CFS_DLOG_MKDIR:
- fileno = buf.dl_u.dl_mkdir.dl_child_cid.cid_fileno;
- break;
- case CFS_DLOG_RMDIR:
- break;
- case CFS_DLOG_SYMLINK:
- fileno = buf.dl_u.dl_symlink.dl_child_cid.cid_fileno;
- break;
- case CFS_DLOG_SETATTR:
- break;
- case CFS_DLOG_SETSECATTR:
- break;
- case CFS_DLOG_MODIFIED:
- break;
- case CFS_DLOG_MAPFID:
- break;
- default:
- goto out;
- }
-
- /* track the largest local fileno used */
- if (maxlocalfileno < fileno)
- maxlocalfileno = fileno;
-
- /* track the largest sequence number used */
- if (max_seq_num < buf.dl_seq) {
- max_seq_num = buf.dl_seq;
- }
-
- offset += buf.dl_len;
- }
-
-out:
- if ((buf.dl_op != CFS_DLOG_TRAILER) ||
- (buf.dl_len != sizeof (struct cfs_dlog_trailer)) ||
- (buf.dl_valid != CFS_DLOG_VAL_COMMITTED) ||
- ((offset + (off_t)buf.dl_len) != (off_t)statinfo.st_size)) {
- ftruncate(fd, offset);
- buf.dl_len = sizeof (struct cfs_dlog_trailer);
- buf.dl_op = CFS_DLOG_TRAILER;
- buf.dl_valid = CFS_DLOG_VAL_COMMITTED;
- buf.dl_seq = max_seq_num + 1;
- if (wrdlog(fd, &buf, buf.dl_len, offset) != 0) {
- (void) close(fd);
- return (-7);
- }
- }
-
- if (fsync(fd) == -1) {
- pr_err(gettext("Cannot sync %s"), dlog_path);
- (void) close(fd);
- return (-8);
- }
- (void) close(fd); /* ignore return since fsync() successful */
-
- /* check to see that mapfile exists; if not, create it. */
- if (access(dmap_path, F_OK) != 0) {
- /* XXX ent_count is a very high upper bound */
- if (create_mapfile(dmap_path,
- ent_count * sizeof (struct cfs_dlog_mapping_space)) != 0) {
- return (-9);
- }
- }
-
- if (maxlocalfilenop)
- *maxlocalfilenop = maxlocalfileno;
- return (0);
-}
-
-int
-wrdlog(int fd, char * buf, int len, off_t offset)
-{
- int err;
-
- err = lseek(fd, offset, SEEK_SET);
- if (err < 0) {
- return (-1);
- }
-
- err = write(fd, buf, len);
- if (err != len) {
- return (-2);
- }
-
- return (0);
-}
-
-static int
-create_mapfile(char *fname, int size)
-{
- char buffy[BUFSIZ];
- int fd, rc, wsize;
-
- /* this file will be <2GB */
- fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
- if (fd < 0)
- return (errno);
-
- memset(buffy, '\0', sizeof (buffy));
- while (size > 0) {
- wsize = (size > sizeof (buffy)) ? sizeof (buffy) : size;
- if (write(fd, buffy, wsize) != wsize) {
- rc = errno;
- (void) close(fd);
- (void) unlink(fname);
- return (rc);
- }
- size -= wsize;
- }
-
- if (fsync(fd) != 0) {
- rc = errno;
- (void) close(fd);
- (void) unlink(fname);
- return (rc);
- }
- (void) close(fd);
-
- return (0);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/fsck/fsck.c b/usr/src/cmd/fs.d/cachefs/fsck/fsck.c
deleted file mode 100644
index 1f934ca9d5..0000000000
--- a/usr/src/cmd/fs.d/cachefs/fsck/fsck.c
+++ /dev/null
@@ -1,1879 +0,0 @@
-/*
- * 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.
- */
-
-/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * Portions of this source code were derived from Berkeley 4.3 BSD
- * under license from the Regents of the University of California.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * fsck.c
- *
- * Cachefs fsck program.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <wait.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <ftw.h>
-#include <dirent.h>
-#include <search.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/mman.h>
-#include <sys/fs/cachefs_fs.h>
-#include <syslog.h>
-#include "../common/subr.h"
-#include "res.h"
-
-char *cfs_opts[] = {
-#define CFSOPT_PREEN 0
- "preen",
-#define CFSOPT_NOCLEAN 1
- "noclean",
-#define CFSOPT_VERBOSE 2
- "verbose",
-#define CFSOPT_NONOCLEAN 3
- "nonoclean",
-
- NULL
-};
-
-extern int dlog_ck(char *dir_path, ino64_t *maxlocalfilenop);
-
-/* forward references */
-void usage(char *msgp);
-void pr_err(char *fmt, ...);
-int cfs_check(char *cachedirp, int noclean, int mflag, int verbose,
- int nonoclean);
-int cache_label_file(char *cachedirp, struct cache_label *clabelp);
-int cache_permissions(char *cachedirp);
-int cache_check_dir(char *cachedirp, char *namep);
-int process_fsdir(char *cachedirp, char *namep, res *resp, int verbose);
-int process_fsinfo(char *namep, ino64_t maxlocalfileno,
- cachefs_fsinfo_t *fsinfop, int verbose);
-int process_fsgroup(char *dirp, char *namep, res *resp, ino64_t base,
- int fgsize, ino64_t fsid, int local, int verbose);
-int tree_remove(const char *namep, const struct stat64 *statp, int type,
- struct FTW *ftwp);
-int cache_upgrade(char *cachedirp, int lockid);
-int file_remove(const char *namep, const struct stat64 *statp, int verbose);
-void cache_backmnt_cleanup(char *cachedirp, char *backmnt_namep);
-
-#define FLAGS_FTW (FTW_PHYS | FTW_MOUNT | FTW_DEPTH)
-
-static int S_verbose = 0;
-static char S_lostfound[MAXPATHLEN];
-static int S_move_lostfound = 0;
-
-/*
- *
- * main
- *
- * Description:
- * Main routine for the cachefs fsck program.
- * Arguments:
- * argc number of command line arguments
- * argv list of command line arguments
- * Returns:
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking (fsck
- * -m only)
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * 40 for root mounted fs, same as 0
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- int xx;
- int c;
- char *optionp;
- char *valuep;
- int mflag;
- int noclean;
- char *cachedirp;
- int lockid;
- int verbose;
- int nonoclean;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /* verify root running command */
- if (getuid() != 0) {
- fprintf(stderr, gettext(
- "fsck -F cachefs: must be run by root\n"));
- return (1);
- }
-
- /* process command line options */
- optionp = NULL;
- mflag = 0;
- noclean = 0;
- verbose = 0;
- nonoclean = 0;
- while ((c = getopt(argc, argv, "mnNo:yY")) != EOF) {
- switch (c) {
- case 'm': /* check but do not repair */
- mflag = 1;
- break;
-
- case 'n': /* answer no to questions */
- case 'N':
- /* ignored */
- break;
-
- case 'o':
- optionp = optarg;
- while (*optionp) {
- xx = getsubopt(&optionp, cfs_opts, &valuep);
- switch (xx) {
- case CFSOPT_PREEN:
- /* preen is the default mode */
- break;
- case CFSOPT_NOCLEAN:
- noclean = 1;
- break;
- case CFSOPT_VERBOSE:
- verbose++;
- S_verbose++;
- break;
- case CFSOPT_NONOCLEAN:
- nonoclean = 1;
- break;
- default:
- case -1:
- pr_err(gettext("unknown option %s"),
- valuep);
- return (1);
- }
- }
- break;
-
- case 'y': /* answer yes to questions */
- case 'Y':
- /* ignored, this is the default */
- break;
-
- default:
- usage("invalid option");
- return (1);
- }
- }
-
- /* verify fsck device is specified */
- if (argc - optind < 1) {
- usage(gettext("must specify cache directory"));
- return (1);
- }
-
- /* save cache directory */
- cachedirp = argv[argc - 1];
-
- /* ensure cache directory exists */
- if (access(cachedirp, F_OK) != 0) {
- pr_err(gettext("Cache directory %s does not exist."),
- cachedirp);
- return (39);
- }
-
- /* lock the cache directory non-shared */
- lockid = cachefs_dir_lock(cachedirp, 0);
- if (lockid == -1) {
- /* exit if could not get the lock */
- return (1);
- }
-
- /* is the cache directory in use */
- if (cachefs_inuse(cachedirp)) {
- if (noclean) {
- pr_err(gettext("Cache directory %s is in use."),
- cachedirp);
- xx = 33;
- } else {
- /* assume if in use that it is clean */
- xx = 0;
- }
- cachefs_dir_unlock(lockid);
- return (xx);
- }
-
- xx = cache_upgrade(cachedirp, lockid);
- if (xx != 0) {
- /* check the file system */
- xx = cfs_check(cachedirp, noclean, mflag, verbose, nonoclean);
- }
-
- /* unlock the cache directory */
- cachefs_dir_unlock(lockid);
-
- /* inform if files moved to lost+found */
- if (S_move_lostfound) {
- pr_err(gettext("Files recovered to %s"), S_lostfound);
- }
-
- /* return the status of the file system checking */
- return (xx);
-}
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a short usage message.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp) {
- pr_err("%s", msgp);
- }
-
- (void) fprintf(stderr,
- gettext("Usage: fsck -F cachefs [ -o specific_options ] [ -m ] "
- "cachedir\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("fsck -F cachefs: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
-
-/*
- *
- * cache_upgrade
- *
- * Description:
- *
- * See if the current cache is out of date. If it is, do
- * whatever magic is necessary to upgrade it. All such magic
- * should be encapsulated here!
- *
- * Arguments:
- *
- * cachedirp name of the cache directory to check
- *
- * Returns:
- * Returns:
- * 0 cache was upgraded and shouldn't be checked
- * 1 problem unrelated to the file system
- * 36 uncorrectable errors detected - terminate normally
- * 39 uncorrectable errors detected - terminate immediately
- * 50 cache was already up-to-date (maybe we should fsck it)
- * 51 cache was upgraded (but you should do fsck)
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cache_upgrade(char *cachedirp, int lockid)
-{
-#ifdef CFSRLDEBUG
- static int canupgrade[] = {1, 2, 3, 103, 104, 105, 106, 107,
- 4, 5, 108, 6, 7, 8, 0};
-#else /* CFSRLDEBUG */
- static int canupgrade[] = {1, 2, 3, 103, 104, 105, 106, 107,
- 4, 108, 5, 109, 110, 6, 111, 0};
-#endif /* CFSRLDEBUG */
- char labelpath[MAXPATHLEN];
- struct cache_label clabel;
- int i;
-
- if (((int)strlen(cachedirp) + (int)strlen(CACHELABEL_NAME) + 2)
- >= MAXPATHLEN)
- return (1);
-
- (void) sprintf(labelpath, "%s/%s", cachedirp, CACHELABEL_NAME);
-
- if (cachefs_label_file_get(labelpath, &clabel) != 0)
- return (1);
-
- /* nothing to do if we're current */
- if (clabel.cl_cfsversion == CFSVERSION)
- return (50);
-
- /* see if it's an old version that we know how to upgrade */
- for (i = 0; canupgrade[i] != 0; i++)
- if (clabel.cl_cfsversion == canupgrade[i])
- break;
- if (canupgrade[i] == 0)
- return (36);
-
- syslog(LOG_USER | LOG_INFO,
- gettext("fsck -F cachefs: Recreating cache %s"), cachedirp);
-
- /* currently, to `upgrade' we delete the old cache */
- if (cachefs_delete_all_cache(cachedirp) != 0)
- return (36);
-
- /* do any magic necessary to convert the old label to the new one */
- clabel.cl_cfsversion = CFSVERSION;
-
- /* create the new cache! */
- if (cachefs_create_cache(cachedirp, NULL, &clabel) != 0)
- return (36);
-
- return (0);
-}
-
-/*
- *
- * cfs_check
- *
- * Description:
- * This routine performs the actual checking of the cache
- * file system.
- * The file system must be inactive when this routine is called.
- * Arguments:
- * cachedirp name of the cache directory to check
- * noclean 1 means ignore clean flag
- * mflag 1 means no fixes, only check if mountable
- * verbose indicate level of verbosity for diagnostics
- * nonoclean 1 means honor clean flag; don't by default
- * Returns:
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * 40 for root mounted fs, same as 0, XXX
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cfs_check(char *cachedirp, int noclean, int mflag, int verbose, int nonoclean)
-{
- DIR *dp;
- struct dirent64 *dep;
- char buf[MAXPATHLEN];
- struct stat64 statinfo;
- int xx;
- char *namep;
- res *resp;
- struct cache_label clabel;
-
- /* if checking the clean flag is sufficient */
- if ((noclean == 0) && (nonoclean || mflag)) {
- /* if the clean flag is set */
- if (cachefs_clean_flag_test(cachedirp)) {
- if (verbose) {
- pr_err(gettext("Cache %s is clean"), cachedirp);
- }
- return (0);
- }
- }
-
- /* if mflag specified then go no farther */
- if (mflag)
- return (32);
-
- /* check the cache label file for correctness */
- xx = cache_label_file(cachedirp, &clabel);
- if (xx)
- return (xx);
-
- /* make sure the kernel lock file exists */
- sprintf(buf, "%s/%s", cachedirp, CACHEFS_LOCK_FILE);
- xx = open(buf, O_RDWR | O_CREAT, 0700);
- if (xx == -1) {
- pr_err(gettext("Cannot create lock file %s"), buf);
- return (39);
- }
- close(xx);
-
- /* fix permissions on the cache directory */
- xx = cache_permissions(cachedirp);
- if (xx)
- return (xx);
-
- /* make the back file system mount directory if necessary */
- xx = cache_check_dir(cachedirp, BACKMNT_NAME);
- if (xx)
- return (xx);
-
- /* clean out junk in the back file system mount directory */
- cache_backmnt_cleanup(cachedirp, BACKMNT_NAME);
-
- /* make the lost+found directory if necessary */
- xx = cache_check_dir(cachedirp, CACHEFS_LOSTFOUND_NAME);
- if (xx)
- return (xx);
-
- /* construct the path to the lost and found directory for file_remove */
- sprintf(S_lostfound, "%s/%s", cachedirp, CACHEFS_LOSTFOUND_NAME);
-
- /* construct the path name of the resource file */
- namep = RESOURCE_NAME;
- xx = strlen(cachedirp) + strlen(namep) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Path name too long %s/%s"),
- cachedirp, namep);
- return (39);
- }
- sprintf(buf, "%s/%s", cachedirp, namep);
-
- /* make a res object to operate on the resource file */
- resp = res_create(buf, clabel.cl_maxinodes, verbose);
- if (resp == NULL) {
- pr_err(gettext("Could not process resource file %s: %s"),
- buf, strerror(errno));
- return (39);
- }
-
- /* open the cache directory */
- if ((dp = opendir(cachedirp)) == NULL) {
- pr_err(gettext("Cannot open directory %s: %s"), cachedirp,
- strerror(errno));
- res_destroy(resp);
- return (39);
- }
-
- /* mark all directories */
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* check path length */
- xx = strlen(cachedirp) + strlen(dep->d_name) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Path name too long %s/%s"),
- cachedirp, dep->d_name);
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
-
- /* stat the file */
- sprintf(buf, "%s/%s", cachedirp, dep->d_name);
- xx = lstat64(buf, &statinfo);
- if (xx == -1) {
- if (errno != ENOENT) {
- pr_err(gettext("Cannot stat %s: %s"), cachedirp,
- strerror(errno));
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
- continue;
- }
-
- /* if a directory */
- if (S_ISDIR(statinfo.st_mode)) {
- xx = chmod(buf, 0700);
- if (xx == -1) {
- pr_err(gettext("Cannot chmod %s: %s"), buf,
- strerror(errno));
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
- }
- }
-
- /* process files in the cache directory */
- rewinddir(dp);
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* stat the file */
- sprintf(buf, "%s/%s", cachedirp, dep->d_name);
- xx = lstat64(buf, &statinfo);
- if (xx == -1) {
- if (errno != ENOENT) {
- pr_err(gettext("Cannot stat %s: %s"), cachedirp,
- strerror(errno));
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
- continue;
- }
-
- /* ignore directories */
- if (S_ISDIR(statinfo.st_mode))
- continue;
-
- /* if not a link */
- if (!S_ISLNK(statinfo.st_mode)) {
- /*
- * XXX make sure a valid file
- * Update file and block counts for this file.
- * This file will be <2GB.
- */
- res_addfile(resp, (long)statinfo.st_size);
- continue;
- }
-
- /* process the file system cache directory */
- xx = process_fsdir(cachedirp, dep->d_name, resp, verbose);
- if (xx) {
- closedir(dp);
- res_destroy(resp);
- return (xx);
- }
- }
-
- /* look for directories that do not belong */
- rewinddir(dp);
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* stat the file */
- sprintf(buf, "%s/%s", cachedirp, dep->d_name);
- xx = lstat64(buf, &statinfo);
- if (xx == -1) {
- if (errno != ENOENT) {
- pr_err(gettext("Cannot stat %s: %s"), cachedirp,
- strerror(errno));
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
- continue;
- }
-
- /* XXX should we unlink extraneous regular files? */
-
- /* ignore all but directories */
- if (!S_ISDIR(statinfo.st_mode))
- continue;
-
- /* ignore directories we have checked */
- if ((statinfo.st_mode & S_IAMB) != 0700)
- continue;
-
- /* ignore the mount directory */
- if (strcmp(dep->d_name, BACKMNT_NAME) == 0)
- continue;
-
- /* ignore the lost+found directory */
- if (strcmp(dep->d_name, CACHEFS_LOSTFOUND_NAME) == 0)
- continue;
-
- /* remove the directory */
- xx = nftw64(buf, tree_remove, 3, FLAGS_FTW);
- if (xx != 0) {
- pr_err(gettext("Error walking tree %s."), namep);
- closedir(dp);
- res_destroy(resp);
- return (39);
- }
-
- if (verbose)
- pr_err(gettext("Directory removed: %s"), buf);
- }
-
- /* close the directory */
- closedir(dp);
-
- /* add one file and one block for the cache directory itself */
- res_addfile(resp, 1);
-
- /* finish off the resource file processing */
- xx = res_done(resp);
- if (xx == -1) {
- pr_err(gettext("Could not finish resource file %s: %s"),
- buf, strerror(errno));
- return (39);
- }
- res_destroy(resp);
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cache_label_file
- *
- * Description:
- * This routine performs the checking and fixing up of the
- * cache label file.
- * Arguments:
- * cachedirp name of the cache directory to check
- * clabelp cache label contents put here if not NULL
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cache_label_file(char *cachedirp, struct cache_label *clabelp)
-{
- int xx;
- char buf1[MAXPATHLEN];
- char buf2[MAXPATHLEN];
- char *namep;
- struct cache_label clabel1, clabel2;
-
- namep = CACHELABEL_NAME;
-
- /* see if path name is too long */
- xx = strlen(cachedirp) + strlen(namep) + 10;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Cache directory name %s is too long"),
- cachedirp);
- return (39);
- }
-
- /* make a path to the cache label file and its backup copy */
- sprintf(buf1, "%s/%s", cachedirp, namep);
- sprintf(buf2, "%s/%s.dup", cachedirp, namep);
-
- /* get the contents of the cache label file */
- xx = cachefs_label_file_get(buf1, &clabel1);
- if (xx == -1) {
- /* get the backup cache label file contents */
- xx = cachefs_label_file_get(buf2, &clabel2);
- if (xx == -1) {
- pr_err(gettext("Run `cfsadmin -d all %s'\n"
- "and then run\n"
- "`cfsadmin -c %s'\n"), cachedirp, cachedirp);
- return (39);
- }
-
- /* write the cache label file */
- xx = cachefs_label_file_put(buf1, &clabel2);
- if (xx == -1) {
- pr_err(gettext("Run `cfsadmin -d all %s'\n"
- "and then run\n"
- "`cfsadmin -c %s'\n"), cachedirp, cachedirp);
- return (39);
- }
- pr_err(gettext("Cache label file %s repaired."), buf1);
-
- /* copy out the contents to the caller */
- if (clabelp)
- *clabelp = clabel2;
-
- /* return success */
- return (0);
- }
-
- /* get the contents of the backup cache label file */
- xx = cachefs_label_file_get(buf2, &clabel2);
- if (xx == -1) {
- /* write the backup cache label file */
- xx = cachefs_label_file_put(buf2, &clabel1);
- if (xx == -1) {
- return (39);
- }
- pr_err(gettext("Cache label file %s repaired."), buf2);
- }
-
- /* copy out the contents to the caller */
- if (clabelp)
- *clabelp = clabel1;
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cache_permissions
- *
- * Description:
- * Checks the permissions on the cache directory and fixes
- * them if necessary.
- * Arguments:
- * cachedirp name of the cache directory to check
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * Preconditions:
- * precond(cachedirp)
- */
-
-int
-cache_permissions(char *cachedirp)
-{
- int xx;
- struct stat64 statinfo;
-
- /* get info about the cache directory */
- xx = lstat64(cachedirp, &statinfo);
- if (xx == -1) {
- pr_err(gettext("Could not stat %s: %s"), cachedirp,
- strerror(errno));
- return (34);
- }
-
- /* check the mode bits */
- if ((statinfo.st_mode & S_IAMB) != 0) {
-
- /* fix the mode bits */
- xx = chmod(cachedirp, 0);
- if (xx == -1) {
- pr_err(gettext("Could not set modes bits on "
- "cache directory %s: %s"),
- cachedirp, strerror(errno));
- return (36);
- }
- pr_err(gettext("Mode bits reset on cache directory %s"),
- cachedirp);
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * cache_check_dir
- *
- * Description:
- * Checks for the existance of the directory
- * and creates it if necessary.
- * Arguments:
- * cachedirp name of the cache directory containing the dir
- * namep name of dir
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * Preconditions:
- * precond(cachedirp)
- * precond(dirp)
- */
-
-int
-cache_check_dir(char *cachedirp, char *namep)
-{
- int xx;
- char buf[MAXPATHLEN];
- struct stat64 statinfo;
-
- /* see if path name is too long */
- xx = strlen(cachedirp) + strlen(namep) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Cache directory name %s is too long"),
- cachedirp);
- return (39);
- }
-
- /* make the pathname of the directory */
- sprintf(buf, "%s/%s", cachedirp, namep);
-
- /* get info on the directory */
- xx = lstat64(buf, &statinfo);
- if (xx == -1) {
- /* if an error other than it does not exist */
- if (errno != ENOENT) {
- pr_err(gettext("Error on lstat(2) of %s: %s"),
- buf, strerror(errno));
- return (39);
- }
-
- /* make the directory */
- xx = mkdir(buf, 0);
- if (xx == -1) {
- pr_err(gettext("Could not create directory %s"),
- buf);
- return (39);
- }
- pr_err(gettext("Created directory %s"), buf);
- }
-
- /* else see if really a directory */
- else if (!S_ISDIR(statinfo.st_mode)) {
- /* get rid of the file */
- xx = unlink(buf);
- if (xx == -1) {
- pr_err(gettext("Cannot remove %s: %s"), buf,
- strerror(errno));
- return (39);
- }
-
- /* make the directory */
- xx = mkdir(buf, 0);
- if (xx == -1) {
- pr_err(gettext("Could not create directory %s"),
- buf);
- return (39);
- }
- pr_err(gettext("Created directory %s"), buf);
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * process_fsdir
- *
- * Description:
- * Performs the necessary checking and repair on the
- * specified file system cache directory.
- * Calls res_addfile and res_addident as appropriate.
- * Arguments:
- * cachedirp name of cache directory
- * namep name of link file for the file system cache
- * resp res object for res_addfile and res_addident calls
- * verbose indicate level of verbosity for diagnostics
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * Preconditions:
- * precond(cachedirp)
- * precond(namep && is a sym link)
- * precond(resp)
- */
-
-int
-process_fsdir(char *cachedirp, char *namep, res *resp, int verbose)
-{
- DIR *dp;
- struct dirent64 *dep;
- char linkpath[MAXPATHLEN];
- char dirpath[MAXPATHLEN];
- char attrpath[MAXPATHLEN];
- char buf[MAXPATHLEN];
- int xx;
- struct stat64 statinfo;
- char *atp = ATTRCACHE_NAME;
- int fd;
- ino64_t base;
- int local;
- char *strp;
- ino64_t fsid;
- int error = 0;
- int hashsize = 0;
- ENTRY hitem;
- ino64_t maxlocalfileno;
- cachefs_fsinfo_t fsinfo;
- time32_t btime;
-
- /* construct the path to the sym link */
- xx = strlen(cachedirp) + strlen(namep) + 3;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Pathname too long %s/%s"), cachedirp, namep);
- error = 39;
- goto out;
- }
- sprintf(linkpath, "%s/%s", cachedirp, namep);
-
- /* read the contents of the link */
- xx = readlink(linkpath, buf, sizeof (buf));
- if (xx == -1) {
- pr_err(gettext("Unable to read link %s: %s"), linkpath,
- strerror(errno));
- error = 39;
- goto out;
- }
- buf[xx] = '\0';
-
- /* do a one time check on lengths of files */
- xx = strlen(cachedirp) + strlen(buf) + 20 + 20;
- if (xx >= MAXPATHLEN) {
- pr_err(gettext("Pathname too long %s/%s"), cachedirp, buf);
- error = 39;
- goto out;
- }
-
- /* construct the path to the directory */
- sprintf(dirpath, "%s/%s", cachedirp, buf);
-
- /* stat the directory */
- xx = lstat64(dirpath, &statinfo);
- if ((xx == -1) || (strtoull(buf, NULL, 16) != statinfo.st_ino)) {
- if ((xx == -1) && (errno != ENOENT)) {
- pr_err(gettext("Could not stat %s: %s"), dirpath,
- strerror(errno));
- error = 39;
- } else
- error = -1;
- goto out;
- }
- fsid = statinfo.st_ino;
-
- /*
- * Check for a disconnect log(dlog) file and verify it.
- */
- xx = dlog_ck(dirpath, &maxlocalfileno);
- if (xx) {
- error = -1;
- goto out;
- }
-
- /* process the fsinfo file */
- sprintf(buf, "%s/%s", dirpath, CACHEFS_FSINFO);
- xx = process_fsinfo(buf, maxlocalfileno, &fsinfo, verbose);
- if (xx) {
- error = -1;
- pr_err(gettext("Cannot update fsinfo file %s"), buf);
- goto out;
- }
-
- /* create the unmount file in the cachedir */
- sprintf(buf, "%s/%s", dirpath, CACHEFS_UNMNT_FILE);
- /* this file will be < 2GB */
- fd = open(buf, O_CREAT | O_RDWR, 0666);
- if (fd == -1) {
- pr_err(gettext("Cannot create unmnt file %s: %s"), buf,
- strerror(errno));
- error = -1;
- goto out;
- }
- btime = get_boottime();
- if (write(fd, &btime, sizeof (btime)) == -1) {
- pr_err(gettext("Cannot write cachedir unmnt file %s: %s"), buf,
- strerror(errno));
- error = -1;
- goto out;
- }
- close(fd);
-
- /* create the unmount file */
- sprintf(buf, "%s/%s", dirpath, CACHEFS_UNMNT_FILE);
- /* this file will be < 2GB */
- fd = open(buf, O_CREAT | O_RDWR, 0666);
- if (fd == -1) {
- pr_err(gettext("Cannot create unmnt file %s: %s"), buf,
- strerror(errno));
- error = -1;
- goto out;
- }
- close(fd);
-
- /* construct the name to the attrcache directory */
- sprintf(attrpath, "%s/%s", dirpath, atp);
-
- /* open the attrcache directory */
- if ((dp = opendir(attrpath)) == NULL) {
- pr_err(gettext("Cannot open directory %s: %s"), attrpath,
- strerror(errno));
- error = -1;
- goto out;
- }
-
- /* make one pass, counting how big to make the hash table */
- while (readdir64(dp) != NULL)
- ++hashsize;
- if (hcreate(hashsize + 1000) == 0) {
- pr_err(gettext("Cannot allocate heap space."));
- (void) closedir(dp);
- hashsize = 0;
- error = 39;
- goto out;
- }
- rewinddir(dp);
-
- /* loop reading the contents of the directory */
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* check for a reasonable name */
- xx = strlen(dep->d_name);
- if ((xx != 16) && (xx != 17)) {
- /* bad file */
- pr_err(gettext("Unknown file %s/%s"),
- attrpath, dep->d_name);
- closedir(dp);
- error = 39;
- goto out;
- }
-
- /* derive the base number from the file name */
- if (*(dep->d_name) == 'L') {
- local = 1;
- base = strtoull(dep->d_name + 1, &strp, 16);
- } else {
- local = 0;
- base = strtoull(dep->d_name, &strp, 16);
- }
- if (*strp != '\0') {
- /* bad file */
- pr_err(gettext("Unknown file %s/%s"),
- attrpath, dep->d_name);
- closedir(dp);
- error = 39;
- goto out;
- }
-
- /* process the file group */
- error = process_fsgroup(dirpath, dep->d_name, resp,
- base, fsinfo.fi_fgsize, fsid, local, verbose);
- if (error) {
- closedir(dp);
- goto out;
- }
- }
- closedir(dp);
-
- /* open the fscache directory */
- if ((dp = opendir(dirpath)) == NULL) {
- pr_err(gettext("Cannot open directory %s: %s"), dirpath,
- strerror(errno));
- error = 39;
- goto out;
- }
-
- /* loop reading the contents of the directory */
- while ((dep = readdir64(dp)) != NULL) {
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- /* ignore cachefs special files */
- xx = strncmp(dep->d_name, CACHEFS_PREFIX, CACHEFS_PREFIX_LEN);
- if (xx == 0)
- continue;
-
- hitem.key = dep->d_name;
- hitem.data = NULL;
- if (hsearch(hitem, FIND) == NULL) {
- sprintf(buf, "%s/%s", dirpath, dep->d_name);
- if (verbose) {
- printf("Unreferenced dir %s\n", buf);
- }
- xx = nftw64(buf, tree_remove, 3, FLAGS_FTW);
- if (xx != 0) {
- pr_err(gettext("Could not remove %s"), buf);
- error = 39;
- closedir(dp);
- goto out;
- }
- }
- }
- closedir(dp);
-
- /* add the info file to the resource */
- res_addfile(resp, 1);
-
- /* add the directory to the resources */
- res_addfile(resp, 1);
-
- /* add the sym link to the resources */
- res_addfile(resp, 1);
-
- /* change the mode on the directory to indicate we visited it */
- xx = chmod(dirpath, 0777);
- if (xx == -1) {
- pr_err(gettext("Cannot chmod %s: %s"), dirpath,
- strerror(errno));
- error = 39;
- goto out;
- }
-
-out:
- /* free up the heap allocated by the hash functions */
- if (hashsize != 0)
- hdestroy();
-
- if (error == -1) {
- /* remove the sym link */
- xx = unlink(linkpath);
- if (xx == -1) {
- pr_err(gettext("Unable to remove %s: %s"), linkpath,
- strerror(errno));
- error = 39;
- } else {
- error = 0;
- }
- }
-
- return (error);
-}
-
-/*
- * Processes and fixes up the fsinfo file.
- */
-int
-process_fsinfo(char *namep, ino64_t maxlocalfileno, cachefs_fsinfo_t *fsinfop,
- int verbose)
-{
- int fd;
- int error;
- cachefs_fsinfo_t fsinfo;
- int xx;
-
- /* open the info file; this file will be <2GB */
- fd = open(namep, O_RDWR);
- if (fd == -1) {
- error = errno;
- if (verbose)
- pr_err(gettext("Could not open %s: %s"),
- namep, strerror(errno));
- if (error != ENOENT)
- return (-1);
-
- /* try to create the info file */
- fd = open(namep, O_RDWR | O_CREAT, 0666);
- if (fd == -1) {
- if (verbose)
- pr_err(gettext("Could not create %s: %s"),
- namep, strerror(errno));
- return (-1);
- }
-
- }
-
- /* read the contents of the info file */
- xx = read(fd, &fsinfo, sizeof (fsinfo));
- if (xx != sizeof (fsinfo)) {
- memset(&fsinfo, 0, sizeof (fsinfo));
- }
-
- /* fix up the fields as necessary */
- if (fsinfo.fi_popsize < DEF_POP_SIZE)
- fsinfo.fi_popsize = DEF_POP_SIZE;
- if (fsinfo.fi_fgsize < DEF_FILEGRP_SIZE)
- fsinfo.fi_fgsize = DEF_FILEGRP_SIZE;
- if (fsinfo.fi_localfileno < maxlocalfileno)
- fsinfo.fi_localfileno = maxlocalfileno;
-
- /* write back the info to the file */
- if (lseek(fd, 0, SEEK_SET) == -1) {
- if (verbose)
- pr_err(gettext("Could not lseek %s: %s"),
- namep, strerror(errno));
- close(fd);
- return (-1);
- }
- xx = write(fd, &fsinfo, sizeof (fsinfo));
- if (xx != sizeof (fsinfo)) {
- if (verbose)
- pr_err(gettext("Could not write %s: %s"),
- namep, strerror(errno));
- close(fd);
- return (-1);
- }
-
- if (fsync(fd) == -1) {
- pr_err(gettext("Could not sync %s: %s"),
- namep, strerror(errno));
- (void) close(fd);
- return (-1);
- }
- (void) close(fd);
- *fsinfop = fsinfo;
- return (0);
-}
-
-/*
- *
- * process_fsgroup
- *
- * Description:
- * Performs the necessary checking and repair on the
- * specified file group directory.
- * Calls res_addfile and res_addident as appropriate.
- * Arguments:
- * dirpath pathname to fscache directory
- * namep name of fsgroup
- * resp res object for res_addfile and res_addident calls
- * base base offset for file numbers in this directory
- * fgsize size of the file groups
- * fsid file system id
- * local 1 if fsgroup dir is a local dir
- * verbose indicate level of verbosity for diagnostics
- * Returns:
- * 0 file system is okay and does not need checking
- * 1 problem unrelated to the file system
- * 32 file system is unmounted and needs checking
- * 33 file system is already mounted
- * 34 cannot stat device
- * 36 uncorrectable errors detected - terminate normally
- * 37 a signal was caught during processing
- * 39 uncorrectable errors detected - terminate immediately
- * Preconditions:
- * precond(dirp)
- * precond(namep)
- * precond(resp)
- * precond(fgsize > 0)
- */
-
-int
-process_fsgroup(char *dirp, char *namep, res *resp, ino64_t base, int fgsize,
- ino64_t fsid, int local, int verbose)
-{
- DIR *dp;
- struct dirent64 *dep;
- char buf[MAXPATHLEN];
- char attrfile[MAXPATHLEN];
- char attrdir[MAXPATHLEN];
- int xx;
- struct stat64 statinfo;
- char *atp = ATTRCACHE_NAME;
- void *addrp = MAP_FAILED;
- struct attrcache_header *ahp;
- struct attrcache_index *startp = NULL;
- struct attrcache_index *aip;
- uchar_t *bitp;
- int offlen;
- int bitlen;
- int fd;
- int offentry;
- int size;
- struct cachefs_metadata *metap;
- int index;
- char *strp;
- uint_t offset;
- int error = 0;
- ENTRY hitem;
- int nffs;
- int rlno;
- rl_entry_t ent;
- enum cachefs_rl_type which;
-
- /* construct the name to the attribute file and front file dir */
- sprintf(attrfile, "%s/%s/%s", dirp, atp, namep);
- sprintf(attrdir, "%s/%s", dirp, namep);
-
- /* get the size of the attribute file */
- xx = lstat64(attrfile, &statinfo);
- if (xx == -1) {
- pr_err(gettext("Could not stat %s: %s"), attrfile,
- strerror(errno));
- error = 39;
- goto out;
- }
-
- offlen = sizeof (struct attrcache_index) * fgsize;
- bitlen = (sizeof (uchar_t) * fgsize + 7) / 8;
- /* attrfile will be <2GB */
- size = (int)statinfo.st_size;
- offentry = sizeof (struct attrcache_header) + offlen + bitlen;
-
- /* if the attribute file is the wrong size */
- if (size < offentry) {
- error = -1;
- goto out;
- }
-
- /* open the attribute file */
- fd = open(attrfile, O_RDWR);
- if (fd == -1) {
- pr_err(gettext("Could not open %s: %s"),
- attrfile, strerror(errno));
- error = 39;
- goto out;
- }
-
- /* mmap the file into our address space */
- addrp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (addrp == MAP_FAILED) {
- pr_err(gettext("Could not map %s: %s"),
- attrfile, strerror(errno));
- close(fd);
- error = 39;
- goto out;
- }
- close(fd);
-
- /* set up pointers into mapped file */
- ahp = (struct attrcache_header *)addrp;
- startp = (struct attrcache_index *)(ahp + 1);
- bitp = (uchar_t *)((char *)startp + offlen);
-
- /* clear the bitmap */
- memset(bitp, 0, bitlen);
-
- /* fix number of allocated blocks value if necessary */
- xx = (size + MAXBSIZE - 1) / MAXBSIZE;
- if (xx != ahp->ach_nblks) {
- if (verbose) {
- pr_err(gettext("File %s size wrong, old %d new %d:"
- "corrected."),
- attrfile, ahp->ach_nblks, xx);
- }
- ahp->ach_nblks = xx;
- }
- ahp->ach_nffs = 0;
- nffs = 0;
-
- /* verify sanity of attribute file */
- ahp->ach_count = 0;
- for (index = 0; index < fgsize; index++) {
-
- /* get next entry to work on */
- aip = startp + index;
-
- /* save offset to data */
- offset = aip->ach_offset;
- aip->ach_offset = 0;
-
- /* if entry not in use */
- if (aip->ach_written == 0)
- continue;
- aip->ach_written = 0;
-
- /* if offset is out of range or invalid */
- if ((offset < offentry) ||
- ((size - sizeof (struct cachefs_metadata)) < offset) ||
- (offset & 3)) {
- if (verbose)
- pr_err(gettext("Offset %d invalid - index %d"),
- offset, index);
- continue;
- }
-
- /* get pointer to meta data */
- metap = (struct cachefs_metadata *)((char *)addrp + offset);
-
- /* sanity check the meta data */
- if ((metap->md_vattr.va_nodeid != (base + (ino64_t)index)) ||
- ((metap->md_flags & (MD_FILE | MD_POPULATED)) ==
- MD_POPULATED) ||
- ((metap->md_flags & MD_FILE) && (metap->md_rlno == 0)) ||
- (metap->md_rltype < CACHEFS_RL_START) ||
- (metap->md_rltype > CACHEFS_RL_END)) {
- if (verbose) {
- pr_err(gettext("Metadata corrupted %d"), index);
- }
- continue;
- }
-
- /* if there is a front file */
- if (metap->md_flags & MD_FILE) {
- /* make sure front file is still there */
- if (local)
- sprintf(buf, "%s/L%016llx", attrdir,
- base + (ino64_t)index);
- else
- sprintf(buf, "%s/%016llx", attrdir,
- base + (ino64_t)index);
- if (access(buf, F_OK)) {
- if (verbose) {
- pr_err(gettext("File error %s %s"),
- buf, strerror(errno));
- }
- continue;
- }
- nffs++;
-
- /* make sure default ACL directory holder is there */
- if (metap->md_flags & MD_ACLDIR) {
- sprintf(buf, (local) ?
- "%s/L%016llx.d" : "%s/%016llx.d",
- attrdir, base + (ino64_t)index);
- if (access(buf, F_OK)) {
- if (verbose) {
- pr_err(gettext(
- "File error %s %s"),
- buf, strerror(errno));
- }
- continue;
- }
- }
- }
-
- /* if using a rl slot */
- if (metap->md_rlno) {
- /* make sure not on an unusable list */
- if ((metap->md_rltype == CACHEFS_RL_NONE) ||
- (metap->md_rltype == CACHEFS_RL_FREE)) {
- if (verbose) {
- pr_err(gettext("Bad list %d, %d"),
- metap->md_rltype, index);
- }
- continue;
- }
-
- /* move from the active to the gc list */
- if (metap->md_rltype == CACHEFS_RL_ACTIVE)
- metap->md_rltype = CACHEFS_RL_GC;
-
- /* move from the mf to the modified list */
- if (metap->md_rltype == CACHEFS_RL_MF)
- metap->md_rltype = CACHEFS_RL_MODIFIED;
-
- /* add to the resource file */
- ent.rl_attrc = 0;
- ent.rl_local = local;
- ent.rl_fsid = fsid;
- ent.rl_fileno = base + (ino64_t)index;
- ent.rl_current = metap->md_rltype;
- xx = res_addident(resp, metap->md_rlno, &ent,
- metap->md_frontblks * MAXBSIZE,
- (metap->md_flags & MD_FILE) ? 1 : 0);
- if (xx == -1) {
- if (verbose) {
- pr_err(gettext(
- "File %s, bad rlno"), attrfile);
- }
- continue;
- }
- ahp->ach_nffs++;
- }
-
- /* mark entry as valid */
- aip->ach_written = 1;
- aip->ach_offset = offset;
-
- /* set bitmap for this entry */
- xx = (offset - offentry) / sizeof (struct cachefs_metadata);
- bitp[xx/8] |= 1 << (xx % 8);
-
- /* bump number of active entries */
- ahp->ach_count += 1;
- }
-
- /* loop reading the contents of the front file directory */
- dp = opendir(attrdir);
- while (dp && ((dep = readdir64(dp)) != NULL)) {
- int acldir;
-
- /* ignore . and .. */
- if ((strcmp(dep->d_name, ".") == 0) ||
- (strcmp(dep->d_name, "..") == 0))
- continue;
-
- acldir = 0;
- xx = strlen(dep->d_name);
- /* check for valid ACL directory */
- if ((xx > 2) && (strcmp(dep->d_name + xx - 2, ".d") == 0)) {
- acldir = 1;
- } else if ((xx != 16) && (xx != 17)) {
- /*
- * Bad file.
- * Front file dir name is based on 64 bit inode number.
- */
- pr_err(gettext("Unknown file %s/%s"),
- attrdir, dep->d_name);
- closedir(dp);
- error = 39;
- goto out;
- }
-
- sprintf(buf, "%s/%s", attrdir, dep->d_name);
-
- /* determine index into file group */
- if (*(dep->d_name) == 'L') {
- index = (int)(strtoull(dep->d_name + 1, &strp,
- 16) - base);
- } else {
- index = (int)(strtoull(dep->d_name, &strp, 16) - base);
- }
-
- /* verify a valid file */
- if (((! acldir) && (*strp != '\0')) ||
- ((acldir) && (strcmp(strp, ".d") != 0)) ||
- (index < 0) || (fgsize <= index) ||
- (startp[index].ach_written == 0)) {
- /* remove the file */
- xx = file_remove(buf, NULL, verbose);
- if (xx == -1) {
- error = 39;
- goto out;
- }
- continue;
- }
-
- /* verify file should be there */
- aip = startp + index;
- offset = aip->ach_offset;
- metap = (struct cachefs_metadata *)((char *)addrp + offset);
- if (((metap->md_flags & MD_FILE) == 0) ||
- ((acldir) && ((metap->md_flags & MD_ACLDIR) == 0))) {
- /* remove the file */
- if (acldir)
- xx = rmdir(buf);
- else
- xx = file_remove(buf, NULL, verbose);
- if (xx == -1) {
- error = 39;
- goto out;
- }
- continue;
- }
- if (! acldir)
- nffs--;
- }
-
- /* close the directory */
- if (dp)
- closedir(dp);
-
- /* if we did not find the correct number of front files in the dir */
- rlno = ahp->ach_rlno;
- if (nffs != 0) {
- if (verbose) {
- pr_err(gettext("Front file mismatch %d in %s"),
- nffs, attrdir);
- }
- error = -1;
- goto out;
- }
-
- /* add the attrcache file to the resouce file */
- which = (ahp->ach_nffs == 0) ? CACHEFS_RL_GC : CACHEFS_RL_ATTRFILE;
- ahp->ach_rl_current = which;
- ent.rl_attrc = 1;
- ent.rl_local = local;
- ent.rl_fsid = fsid;
- ent.rl_fileno = base;
- ent.rl_current = which;
- error = res_addident(resp, rlno, &ent, size, 1);
- if (error == -1) {
- if (verbose) {
- pr_err(gettext("%s bad rlno %d\n"), attrfile, rlno);
- }
- goto out;
- } else if (ahp->ach_nffs > 0) {
- /* add the directory to the resources */
- res_addfile(resp, 1);
-
- /* indicate that the file group directory is okay */
- hitem.key = strdup(namep);
- hitem.data = NULL;
- if (hsearch(hitem, ENTER) == NULL) {
- pr_err(gettext("Hash table full"));
- error = 39;
- goto out;
- }
- }
-
-out:
- if (error == -1) {
- if (startp) {
- /* clear idents we created for this attrcache file */
- for (index = 0; index < fgsize; index++) {
- aip = startp + index;
- if (aip->ach_written == 0)
- continue;
- metap = (struct cachefs_metadata *)((char *)
- addrp + aip->ach_offset);
- if (metap->md_rlno != 0) {
- /* clear the resource file idents */
- res_clearident(resp, metap->md_rlno,
- (metap->md_frontblks * MAXBSIZE),
- (metap->md_flags & MD_FILE) ? 1:0);
- if (verbose) {
- pr_err(gettext("Removed %d"),
- metap->md_rlno);
- }
- }
- }
- }
-
- /* nuke the attrcache file */
- xx = unlink(attrfile);
- if (xx == -1) {
- pr_err(gettext("Unable to remove %s"), attrfile);
- error = 39;
- } else {
- error = 0;
- if (verbose) {
- pr_err(gettext("Removed attrcache %s"),
- attrfile);
- }
- }
- }
-
- if (msync(addrp, size, MS_SYNC) == -1) {
- pr_err(gettext("Unable to sync %s"), attrfile);
- error = 39;
- }
-
- /* unmap the attribute file */
- if (addrp != MAP_FAILED)
- munmap(addrp, size);
-
- return (error);
-}
-
-/*
- *
- * tree_remove
- *
- * Description:
- * Called via the nftw64(3c) routine, this routine removes
- * the specified file.
- * Arguments:
- * namep pathname to the file
- * statp stat info on the file
- * type ftw type information
- * ftwp pointer to additional ftw information
- * Returns:
- * Returns 0 for success or -1 if an error occurs.
- * Preconditions:
- * precond(namep)
- * precond(statp)
- * precond(ftwp)
- */
-
-int
-tree_remove(const char *namep, const struct stat64 *statp, int type,
- struct FTW *ftwp)
-{
- int xx;
-
- switch (type) {
- case FTW_D:
- case FTW_DP:
- case FTW_DNR:
- xx = rmdir(namep);
- if (xx != 0) {
- pr_err(gettext("Could not remove directory %s: %s"),
- namep, strerror(errno));
- return (-1);
- }
-#if 0
- pr_err(gettext("Directory %s removed."), namep);
-#endif
- break;
-
- default:
- xx = file_remove(namep, statp, S_verbose);
-#if 0
- pr_err(gettext("File %s removed."), namep);
-#endif
- break;
- }
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * file_remove
- *
- * Description:
- * Removes the specified file.
- * If the file is a local file or has been modified locally
- * then it is moved to lost+found.
- * Should only be called for non-directory files.
- * Arguments:
- * namep pathname to the file
- * statp stat info on the file or NULL
- * verbose 1 means be verbose about what is being removed
- * Returns:
- * Returns 0 for success or -1 if an error occurs.
- * Preconditions:
- * precond(namep)
- */
-
-int
-file_remove(const char *namep, const struct stat64 *statp, int verbose)
-{
- int xx;
- int ii;
- struct stat64 statinfo;
- int dolf = 0;
- char newname[MAXPATHLEN * 2];
- char *strp;
-
- /* get stat info on the file if we were not passed it */
- if (statp == NULL) {
- xx = stat64(namep, &statinfo);
- if (xx) {
- if (verbose) {
- pr_err(gettext("stat failed %s %d"),
- namep, errno);
- }
- return (-1);
- }
- statp = &statinfo;
- }
-
- /* ignore directories */
- if (S_ISDIR(statp->st_mode)) {
- errno = EINVAL;
- return (-1);
- }
-
- /* if a local file then move to lost+found */
- strp = strrchr(namep, '/');
- if (strp == NULL) {
- errno = EINVAL;
- return (-1);
- }
- strp++;
- if (*strp == 'L')
- dolf = 1;
-
- /* if a modified file then move to lost+found */
- if ((statp->st_mode & S_IAMB) == 0766)
- dolf = 1;
-
- /* if moving to lost+found */
- if (dolf) {
- sprintf(newname, "%s/%s", S_lostfound, strp);
- xx = stat64(newname, &statinfo);
- for (ii = 1; ((ii < 1000) && (xx == 0)); ii++) {
- sprintf(newname, "%s/%s_%d", S_lostfound, strp, ii);
- xx = stat64(newname, &statinfo);
- }
- xx = rename(namep, newname);
- if (xx) {
- pr_err(gettext("Could not move file %s to %s: %s"),
- namep, newname, strerror(errno));
- exit(-1);
- }
- S_move_lostfound = 1;
- return (0);
- }
-
- /* remove the file */
- xx = unlink(namep);
- if (xx == -1) {
- pr_err(gettext("Could not remove file %s: %s"),
- namep, strerror(errno));
- } else if (verbose) {
- pr_err(gettext("Removed %s"), namep);
- }
-
- return (0);
-}
-
-void
-cache_backmnt_cleanup(char *cachedirp, char *backmnt_namep)
-{
- DIR *dirp;
- struct dirent *entp;
- char dirname[MAXPATHLEN * 2];
-
- /* open the directory */
- sprintf(dirname, "%s/%s", cachedirp, backmnt_namep);
- dirp = opendir(dirname);
- if (dirp == NULL)
- return;
-
- /*
- * Try to remove everything in the directory with rmdir.
- * Should only be empty directories in here at this point.
- * If not, do not worry about it.
- */
- for (;;) {
- /* get the next dir entry */
- entp = readdir(dirp);
- if (entp == NULL)
- break;
-
- /*
- * Try and remove the directory.
- * This will fail if there is anything in the dir,
- * like a mounted file system.
- */
- rmdir(entp->d_name);
- }
- closedir(dirp);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/fsck/res.c b/usr/src/cmd/fs.d/cachefs/fsck/res.c
deleted file mode 100644
index 6331f213ab..0000000000
--- a/usr/src/cmd/fs.d/cachefs/fsck/res.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- *
- * res.c
- *
- * Implements routines to create a cache resource file.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/fcntl.h>
-#include <sys/mman.h>
-#include <sys/fs/cachefs_fs.h>
-#include "res.h"
-
-struct res {
- int p_magic; /* magic number */
- int p_done:1; /* 1 if res_done called */
- int p_verbose:1; /* 1 means print errors */
- void *p_addrp; /* address of mapped file */
- long p_size; /* size of mapped file */
- struct cache_usage *p_cusagep; /* ptr to cache_usage */
- struct cachefs_rl_info *p_linfop; /* ptr to rl_info */
- rl_entry_t *p_rlentp; /* ptr to first rl_entry */
- int p_totentries; /* max number of rl entries */
- char p_name[MAXPATHLEN]; /* name of resource file */
-};
-
-#define MAGIC 8272
-#define precond(A) assert(A)
-#define MININDEX 1
-
-#define RL_HEAD(resp, type) \
- (&(resp->p_linfop->rl_items[CACHEFS_RL_INDEX(type)]))
-#define CVBLKS(nbytes) ((nbytes + MAXBSIZE - 1) / MAXBSIZE)
-
-/* forward references */
-void res_rlent_moveto(res *resp, enum cachefs_rl_type type, uint_t entno,
- long blks);
-void res_reset(res *resp);
-void res_clear(res *resp);
-int res_listcheck(res *, enum cachefs_rl_type);
-
-/*
- *
- * res_create
- *
- * Description:
- * Creates a res object and returns a pointer to it.
- * The specified file is used to store resource file data.
- * Arguments:
- * namep name of the resource file
- * entries max number of rl entries in the file
- * verbose 1 means print out error messages
- * Returns:
- * Returns a pointer to the object or NULL if an error occurred.
- * Preconditions:
- * precond(namep)
- * precond(entries > 3)
- * precond(strlen(namep) < MAXPATHLEN)
- */
-
-res *
-res_create(char *namep, int entries, int verbose)
-{
- int xx;
- long size;
- int fd;
- char buf[1024];
- long cnt;
- unsigned int amt;
- ssize_t result;
- void *addrp;
- res *resp;
- struct stat64 statinfo;
-
- precond(namep);
- precond(entries > MININDEX);
-
- /* determine the size needed for the resource file */
- size = MAXBSIZE;
- size += MAXBSIZE * (entries / CACHEFS_RLPMBS);
- if ((entries % CACHEFS_RLPMBS) != 0)
- size += MAXBSIZE;
-
- /* if the file does not exist or is the wrong size/type */
- xx = lstat64(namep, &statinfo);
- /* resource file will be <2GB */
- if ((xx == -1) || (statinfo.st_size != (offset_t)size) ||
- !(S_ISREG(statinfo.st_mode))) {
-
- /* remove the resource file */
- xx = unlink(namep);
- if ((xx == -1) && (errno != ENOENT))
- return (NULL);
-
- /* create and open the file */
- fd = open(namep, O_CREAT | O_RDWR, 0600);
- if (fd == -1)
- return (NULL);
-
- /* fill the file with zeros */
- memset(buf, 0, sizeof (buf));
- for (cnt = size; cnt > 0; cnt -= result) {
- amt = sizeof (buf);
- if (amt > cnt)
- amt = cnt;
- result = write(fd, buf, amt);
- if (result == -1) {
- close(fd);
- return (NULL);
- }
- }
- }
-
- /* else open the file */
- else {
- fd = open(namep, O_RDWR);
- if (fd == -1)
- return (NULL);
- }
-
- /* mmap the file into our address space */
- addrp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (addrp == (void *)-1) {
- close(fd);
- return (NULL);
- }
-
- /* close the file descriptor, we do not need it anymore */
- close(fd);
-
- /* allocate memory for the res object */
- resp = malloc(sizeof (res));
- if (resp == NULL) {
- munmap(addrp, size);
- return (NULL);
- }
-
- /* initialize the object */
- resp->p_magic = MAGIC;
- resp->p_done = 0;
- resp->p_addrp = addrp;
- resp->p_size = size;
- resp->p_verbose = verbose;
- resp->p_cusagep = (struct cache_usage *)addrp;
- resp->p_linfop = (struct cachefs_rl_info *)((char *)addrp +
- sizeof (struct cache_usage));
- resp->p_rlentp = (rl_entry_t *)((char *)addrp + MAXBSIZE);
- resp->p_totentries = entries;
- strcpy(resp->p_name, namep);
-
- /* reset the resource file in preperation to rebuild it */
- res_reset(resp);
-
- /* return the object */
- return (resp);
-}
-
-/*
- *
- * res_destroy
- *
- * Description:
- * Destroys the specifed res object.
- * If res_done has not been called on the object or if res_done
- * failed, then the resource file will be deleted.
- * Arguments:
- * resp object to destroy
- * Returns:
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-void
-res_destroy(res *resp)
-{
- precond(resp);
- precond(resp->p_magic == MAGIC);
-
- /* unmap the file */
- munmap(resp->p_addrp, resp->p_size);
-
- /* if res_done not performed */
- if (resp->p_done == 0) {
- /* remove the resource file */
- unlink(resp->p_name);
- }
-
- /* destroy the object */
- resp->p_magic = -MAGIC;
- free(resp);
-}
-
-rl_entry_t *
-res_rlent_get(res *resp, uint_t entno)
-{
- rl_entry_t *rlentp, *window;
- uint_t whichwindow, winoffset;
-
- precond((entno >= MININDEX) && (entno < resp->p_totentries));
-
- whichwindow = entno / CACHEFS_RLPMBS;
- winoffset = entno % CACHEFS_RLPMBS;
-
- window = (rl_entry_t *)
- (((caddr_t)resp->p_rlentp) + (MAXBSIZE * whichwindow));
- rlentp = window + winoffset;
-
- return (rlentp);
-}
-
-/*
- *
- * res_reset
- *
- * Description:
- * Resets the resource file in preparation to rebuild it.
- * Arguments:
- * resp res object
- * Returns:
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-void
-res_reset(res *resp)
-{
- int index;
- rl_entry_t *rlentp;
- int ret;
- cachefs_rl_listhead_t *lhp;
-
- precond(resp);
- precond(resp->p_magic == MAGIC);
-
- resp->p_cusagep->cu_blksused = 0;
- resp->p_cusagep->cu_filesused = 0;
- resp->p_cusagep->cu_flags = CUSAGE_ACTIVE; /* dirty cache */
-
- /* clear out the non-pointer info */
- for (index = MININDEX; index < resp->p_totentries; index++) {
- rlentp = res_rlent_get(resp, index);
-
- rlentp->rl_attrc = 0;
- rlentp->rl_fsck = 0;
- rlentp->rl_local = 0;
- rlentp->rl_fsid = 0LL;
- rlentp->rl_fileno = 0;
- }
-
- /* verify validity of the various lists */
- ret = res_listcheck(resp, CACHEFS_RL_GC);
- if (ret == 1) {
- ret = res_listcheck(resp, CACHEFS_RL_ATTRFILE);
- if (ret == 1) {
- ret = res_listcheck(resp, CACHEFS_RL_MODIFIED);
- if (ret == 1) {
- ret = res_listcheck(resp, CACHEFS_RL_PACKED);
- if (ret == 1) {
- ret = res_listcheck(resp,
- CACHEFS_RL_PACKED_PENDING);
- }
- }
- }
- }
-
- /* if an error occurred on one of the lists */
- if (ret == 0) {
- res_clear(resp);
- return;
- }
-
- /* zero out total sizes, they get fixed up as we add items */
- RL_HEAD(resp, CACHEFS_RL_GC)->rli_blkcnt = 0;
- RL_HEAD(resp, CACHEFS_RL_ATTRFILE)->rli_blkcnt = 0;
- RL_HEAD(resp, CACHEFS_RL_MODIFIED)->rli_blkcnt = 0;
- RL_HEAD(resp, CACHEFS_RL_PACKED)->rli_blkcnt = 0;
- RL_HEAD(resp, CACHEFS_RL_PACKED_PENDING)->rli_blkcnt = 0;
-
- /* null out the heads of the lists we do not want to preserve */
- lhp = RL_HEAD(resp, CACHEFS_RL_FREE);
- memset(lhp, 0, sizeof (cachefs_rl_listhead_t));
- lhp = RL_HEAD(resp, CACHEFS_RL_NONE);
- memset(lhp, 0, sizeof (cachefs_rl_listhead_t));
- lhp = RL_HEAD(resp, CACHEFS_RL_MF);
- memset(lhp, 0, sizeof (cachefs_rl_listhead_t));
- lhp = RL_HEAD(resp, CACHEFS_RL_ACTIVE);
- memset(lhp, 0, sizeof (cachefs_rl_listhead_t));
-}
-
-/*
- *
- * res_listcheck
- *
- * Description:
- * Checks the specified list.
- * Arguments:
- * resp res object
- * type list to check
- * Returns:
- * Returns 1 if the list is ok, 0 if there is a problem.
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-int
-res_listcheck(res *resp, enum cachefs_rl_type type)
-{
- rl_entry_t *rlentp;
- int previndex, index;
- cachefs_rl_listhead_t *lhp;
- int itemcnt = 0;
-
- lhp = RL_HEAD(resp, type);
- index = lhp->rli_front;
- previndex = 0;
-
- /* walk the list */
- while (index != 0) {
- itemcnt++;
-
- /* make sure offset is in bounds */
- if ((index < MININDEX) || (index >= resp->p_totentries)) {
- if (resp->p_verbose)
- pr_err("index out of bounds %d", index);
- return (0);
- }
-
- /* get pointer to rl_entry object */
- rlentp = res_rlent_get(resp, index);
-
- /* check forward pointer */
- if (rlentp->rl_fwd_idx != previndex) {
- /* bad back pointer in rl list */
- if (resp->p_verbose)
- pr_err(gettext("bad forward pointer %d %d"),
- rlentp->rl_fwd_idx, previndex);
- return (0);
- }
-
- /* check for cycle */
- if (rlentp->rl_fsck) {
- /* cycle found in list */
- if (resp->p_verbose)
- pr_err(gettext("cycle found in list %d"),
- index);
- return (0);
- }
-
- /* check type */
- if (rlentp->rl_current != type) {
- /* entry doesn't belong here */
- if (resp->p_verbose)
- pr_err(gettext(
- "bad entry %d type %d in list type %d"),
- index, (int)rlentp->rl_current, (int)type);
- return (0);
- }
-
- /* indicate we have seen this pointer */
- rlentp->rl_fsck = 1;
- previndex = index;
- index = rlentp->rl_bkwd_idx;
- }
-
- /* verify number of items match */
- if (itemcnt != lhp->rli_itemcnt) {
- if (resp->p_verbose)
- pr_err(gettext("itemcnt wrong old %d new %d"),
- lhp->rli_itemcnt, itemcnt);
- return (0);
- }
-
- return (1);
-}
-
-/*
- *
- * res_clear
- *
- * Description:
- * Deletes all information from the resource file.
- * Arguments:
- * resp res object
- * Returns:
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-void
-res_clear(res *resp)
-{
- memset(resp->p_addrp, 0, resp->p_size);
-}
-
-
-/*
- *
- * res_done
- *
- * Description:
- * Called when through performing res_addfile and res_addident
- * to complete the resource file and flush the contents to
- * the disk file.
- * Arguments:
- * resp res object
- * Returns:
- * Returns 0 for success, -1 for an error with errno set
- * appropriatly.
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-int
-res_done(res *resp)
-{
- rl_entry_t *rlentp;
- int index;
- int xx;
- int ret;
-
- precond(resp);
- precond(resp->p_magic == MAGIC);
-
- /* scan the ident list to find the max allocated entry */
- resp->p_linfop->rl_entries = 0;
- for (index = MININDEX; index < resp->p_totentries; index++) {
- rlentp = res_rlent_get(resp, index);
- if (rlentp->rl_fsid && (ino64_t)rlentp->rl_fsck) {
- resp->p_linfop->rl_entries = index;
- }
- }
-
- /* scan the ident list to fix up the free list */
- for (index = MININDEX; index < resp->p_totentries; index++) {
- rlentp = res_rlent_get(resp, index);
-
- /* if entry is not valid */
- if ((rlentp->rl_fsid == 0LL) || (rlentp->rl_fsck == 0)) {
- /* if entry should appear on the free list */
- if (index <= resp->p_linfop->rl_entries) {
- res_rlent_moveto(resp,
- CACHEFS_RL_FREE, index, 0);
- }
- }
- rlentp->rl_fsck = 0; /* prepare to re-check */
- }
-
- /*
- * Sanity check that we do not have an internal error in
- * fsck. Eventually turn this stuff off.
- */
-#if 1
- ret = res_listcheck(resp, CACHEFS_RL_GC);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_ATTRFILE);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_MODIFIED);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_PACKED);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_PACKED_PENDING);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_FREE);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_NONE);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_MF);
- assert(ret == 1);
- ret = res_listcheck(resp, CACHEFS_RL_ACTIVE);
- assert(ret == 1);
-#endif
-
- /* indicate the cache is clean */
- resp->p_cusagep->cu_flags &= ~CUSAGE_ACTIVE;
-
- /* sync the data to the file */
- xx = msync(resp->p_addrp, resp->p_size, MS_SYNC);
- if (xx == -1)
- return (-1);
-
- resp->p_done = 1;
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * res_addfile
- *
- * Description:
- * Increments the number of files and blocks resource counts.
- * Arguments:
- * resp res object
- * nbytes number of bytes in the file
- * Returns:
- * Preconditions:
- * precond(resp is a valid res object)
- */
-
-void
-res_addfile(res *resp, long nbytes)
-{
- precond(resp);
- precond(resp->p_magic == MAGIC);
-
- /* update resource counts */
- resp->p_cusagep->cu_blksused += CVBLKS(nbytes);
- resp->p_cusagep->cu_filesused += 1;
-}
-
-/*
- *
- * res_addident
- *
- * Description:
- * Adds the specified file to the ident list.
- * Updates resource counts.
- * Arguments:
- * resp res object
- * index index into idents/pointers tables
- * dp ident information
- * nbytes number of bytes of item
- * file number of files of item
- * Returns:
- * Returns 0 for success or -1 if the index is already in use
- * or is not valid.
- * Preconditions:
- * precond(resp is a valid res object)
- * precond(dp)
- */
-
-int
-res_addident(res *resp, int index, rl_entry_t *dp, long nbytes, int file)
-{
- rl_entry_t *rlentp;
-
- precond(resp);
- precond(resp->p_magic == MAGIC);
- precond(dp);
-
- /* check index for sanity */
- if ((index < MININDEX) || (index >= resp->p_totentries)) {
- return (-1);
- }
-
- /* get pointer to ident */
- rlentp = res_rlent_get(resp, index);
-
- /* if something already there */
- if (rlentp->rl_fsid != 0LL) {
- return (-1);
- }
-
- /* if not on the right list, move it there */
- if ((rlentp->rl_fsck == 0) || (rlentp->rl_current != dp->rl_current))
- res_rlent_moveto(resp, dp->rl_current, index, CVBLKS(nbytes));
-
- rlentp->rl_fsck = 1;
- rlentp->rl_local = dp->rl_local;
- rlentp->rl_attrc = dp->rl_attrc;
- rlentp->rl_fsid = dp->rl_fsid;
- rlentp->rl_fileno = dp->rl_fileno;
-
- /* update resource counts */
- resp->p_cusagep->cu_blksused += CVBLKS(nbytes);
- resp->p_cusagep->cu_filesused += file;
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * res_clearident
- *
- * Description:
- * Removes the specified file from the ident list.
- * Updates resource counts.
- * Arguments:
- * resp res object
- * index index into idents/pointers tables
- * nbytes number of bytes in the file
- * file number of files
- * Returns:
- * Returns 0.
- * Preconditions:
- * precond(resp is a valid res object)
- * precond(index is valid)
- * precond(ident is in use)
- */
-
-void
-res_clearident(res *resp, int index, int nbytes, int file)
-{
- rl_entry_t *rlentp;
-
- precond(resp);
- precond(resp->p_magic == MAGIC);
- precond((index >= MININDEX) && (index < resp->p_totentries));
-
- /* get pointer to ident */
- rlentp = res_rlent_get(resp, index);
- precond(rlentp->rl_fsid != 0LL);
-
- /* clear the ident */
- rlentp->rl_fsid = 0LL;
- rlentp->rl_fileno = 0;
- rlentp->rl_attrc = 0;
- rlentp->rl_local = 0;
-
- /* update resource counts */
- resp->p_cusagep->cu_blksused -= CVBLKS(nbytes);
- resp->p_cusagep->cu_filesused -= file;
- assert(resp->p_cusagep->cu_blksused >= 0);
-}
-
-/*
- * This function moves an RL entry from whereever it currently is to
- * the requested list.
- */
-
-void
-res_rlent_moveto(res *resp, enum cachefs_rl_type type, uint_t entno, long blks)
-{
- rl_entry_t *rl_ent;
- uint_t prev, next;
- cachefs_rl_listhead_t *lhp;
- enum cachefs_rl_type otype;
-
- precond((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
- precond((entno >= MININDEX) && (entno < resp->p_totentries));
-
- rl_ent = res_rlent_get(resp, entno);
- if (rl_ent->rl_fsck) {
- /* remove entry from its previous list */
-
- next = rl_ent->rl_fwd_idx;
- prev = rl_ent->rl_bkwd_idx;
- otype = rl_ent->rl_current;
- assert((CACHEFS_RL_START <= otype) &&
- (otype <= CACHEFS_RL_END));
-
- lhp = RL_HEAD(resp, otype);
- if ((lhp->rli_back == 0) || (lhp->rli_front == 0))
- assert((lhp->rli_back == 0) && (lhp->rli_front == 0));
-
- if (lhp->rli_back == entno)
- lhp->rli_back = next;
- if (lhp->rli_front == entno)
- lhp->rli_front = prev;
- if (prev != 0) {
- rl_ent = res_rlent_get(resp, prev);
- rl_ent->rl_fwd_idx = next;
- }
- if (next != 0) {
- rl_ent = res_rlent_get(resp, next);
- rl_ent->rl_bkwd_idx = prev;
- }
- lhp->rli_blkcnt -= blks;
- lhp->rli_itemcnt--;
- }
-
- /* add entry to its new list */
-
- lhp = RL_HEAD(resp, type);
- rl_ent = res_rlent_get(resp, entno);
- rl_ent->rl_current = type;
- rl_ent->rl_bkwd_idx = 0;
- rl_ent->rl_fwd_idx = lhp->rli_back;
-
- if (lhp->rli_back != 0) {
- assert(lhp->rli_front != 0);
- rl_ent = res_rlent_get(resp, lhp->rli_back);
- rl_ent->rl_bkwd_idx = entno;
- } else {
- assert(lhp->rli_front == 0);
- lhp->rli_front = entno;
- }
- lhp->rli_back = entno;
- lhp->rli_blkcnt += blks;
- lhp->rli_itemcnt++;
-
- rl_ent = res_rlent_get(resp, entno);
- rl_ent->rl_current = type;
- rl_ent->rl_fsck = 1;
-}
diff --git a/usr/src/cmd/fs.d/cachefs/fsck/res.h b/usr/src/cmd/fs.d/cachefs/fsck/res.h
deleted file mode 100644
index 57f4fa15e0..0000000000
--- a/usr/src/cmd/fs.d/cachefs/fsck/res.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- *
- * res.h
- *
- * Defines routines to operate on the resource file.
- */
-
-#ifndef _RES_H
-#define _RES_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifndef cfs_fsck_res_h
-#define cfs_fsck_res_h
-
-typedef struct res res;
-
-res *res_create(char *namep, int entries, int verbose);
-void res_destroy(res *resp);
-int res_done(res *resp);
-void res_addfile(res *resp, long nbytes);
-int res_addident(res *resp, int index, rl_entry_t *dp, long nbytes, int file);
-void res_clearident(res *resp, int index, int nbytes, int file);
-
-#endif /* cfs_fsck_res_h */
-
-#endif /* _RES_H */
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/Makefile b/usr/src/cmd/fs.d/cachefs/mdbug/Makefile
deleted file mode 100644
index 4cf5b5f507..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# 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 1994-2003 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/fs.d/cachefs/mdbug
-#
-
-FSTYPE= cachefs
-
-include ../../Makefile.fstype
-
-PROGOBJS = flist.o dbug.o
-
-include ../Makefile.cachefs
-
-OBJS = $(PROGOBJS)
-ARFLAGS= rc
-CLOBBERFILES += $(LIB)
-CPPFLAGS += -DDBUG_UNIX=1 -D_REENTRANT
-CFLAGS += -g
-LIB = libdbug.a
-
-all : $(LIB)
-
-$(LIB) : $(OBJS)
- $(RM) -f $(LIB)
- $(AR) $(ARFLAGS) $(LIB) $(OBJS)
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/dbug.c b/usr/src/cmd/fs.d/cachefs/mdbug/dbug.c
deleted file mode 100644
index 175a7247da..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/dbug.c
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- *
- * dbug.c
- *
- * Purpose:
- * Implements the dbug_routine class.
- * This code is derived from the public domain DBUG
- * package written by Fred Fish.
- *
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifndef DBUG_OFF
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <string.h>
-#include <time.h>
-#include <thread.h>
-#include <sys/types.h>
-#include <signal.h>
-#include "flist.h"
-#include "mdbug.h"
-#include "priv.h"
-
-/* forward references */
-static int listparse(register char *ctlp, flist_object_t *head);
-static boolean inlist(flist_object_t *flist_object_p, const char *cp);
-static boolean dotrace(dbug_state_object_t *dbug_state_object_p,
- const char *func, const char *process);
-static void indent(register dbug_state_object_t *dbug_state_object_p,
- int indent);
-static void doprefix(dbug_state_object_t *dbug_state_object_p, int line,
- long lineno, const char *file, const char *process);
-static FILE *openfile(char *name);
-static boolean writable(char *pathname);
-static void changeowner(char *pathname);
-static int delayarg(int value);
-static void delay(uint_t xx);
-static ulong_t getclock();
-static char *mystrtok(char *s1, char *s2);
-void doabort();
-
-/* initialize static members of class */
-int sd_on = 0;
-char sd_process[128];
-long sd_lineno = 0;
-dbug_state_object_t *sd_push = NULL;
-
-/* this structure defines thread specific data */
-typedef struct thread_data {
-#ifdef STACKINIT
- unsigned long td_stackinit; /* Begining of stack. */
-#endif
- int td_line; /* Current line number. */
- char td_keyword[64]; /* Current keyword. */
- dbug_object_t *td_first; /* Current routine. */
-} thread_data_t;
-#ifdef _REENTRANT
-mutex_t mdt_lock;
-int mdt_once = 0;
-thread_key_t mdt_key;
-#else
-thread_data_t mdt_data;
-#endif
-/*
- * format of control string
- * command[:command:...]
- *
- * commands
- * debugging on 'd' d[,<keyword>[,...]]
- * delay value 'D' D[,<delay value>]
- * function list 'f' f[,<function name>[,...]]
- * print filename 'F' F
- * print pid 'i' i
- * print line number 'L' L
- * print call depth 'n' n
- * number each line 'N' N
- * output file 'o' o[,<filename>
- * process name list 'p' p[,<process name>[,...]]
- * print proc name 'P' P
- * reset indentation 'r' r
- * print runtime 'R' R
- * print thread info 'T' T
- * print trace 't' t
- * print stack depth 's' s
- */
-
-/*
- *
- * dbug_object_create
- *
- * Description:
- * Constructor for the dbug_routine class.
- * Arguments:
- * line - line number where object was created.
- * file - file name object was created in.
- * function- routine name object was created in.
- * Returns:
- * Errors:
- * Preconditions:
- */
-void
-dbug_object_create(int line, const char *file, const char *function)
-{
- dbug_object_t *dbug_object_p;
- dbug_state_object_t *dbug_state_object_p;
- ulong_t stacksize;
- int created = 0;
- char *cptr;
-
- thread_data_t *tdp = NULL;
-#ifdef _REENTRANT
- LOCK_THREAD_DATA();
- if (!mdt_once) {
- if (thr_keycreate(&mdt_key, dbug_thread_exit) != 0)
- doabort();
- mdt_once++;
- }
- GET_THREAD_DATA_PTR(&tdp);
- if (tdp == NULL) {
- tdp = (thread_data_t *)calloc(sizeof (*tdp), 1);
- if (tdp == NULL)
- doabort();
- thr_setspecific(mdt_key, tdp);
- created = 1;
- tdp->td_keyword[0] = '\0';
- tdp->td_first = NULL;
- }
-#else
- GET_THREAD_DATA_PTR(&tdp);
-#endif
-
- dbug_object_p = (dbug_object_t *)calloc(sizeof (dbug_object_t), 1);
-
- if (dbug_object_p == NULL)
- doabort();
-
- /* save the function name */
- if (function)
- strcpy(dbug_object_p->d_func, function);
- else
- strcpy(dbug_object_p->d_func, "unknown");
-
- /* save the base of the file name */
- if (file) {
- cptr = strrchr(file, '/');
- if (cptr == NULL)
- strcpy(dbug_object_p->d_file, file);
- else
- strcpy(dbug_object_p->d_file, cptr++);
- } else
- strcpy(dbug_object_p->d_file, "unknown");
-
- /* Chain this onto our list of them */
- dbug_object_p->d_prev = tdp->td_first;
- tdp->td_first = dbug_object_p;
-
- /* set the default routine exit point line number to zero */
- dbug_object_p->d_leaveline = 0;
-
- /* If debugging is off, then all done */
- if (NOT db_debugon())
- goto out;
-
- /* if the active state is null initialize it */
- if (sd_push == NULL)
- db_push("d,:f,:F:i:L:n:N:o,cfsd_debug.out:p,:P:r:R:T:t:s");
-
- /* get a pointer to the active state */
- dbug_state_object_p = sd_push;
-
-#ifdef STACKINIT
- /*
- * Get the new stack depth.
- * There a two problems associated with this.
- * One is because c++ allows declarations anywhere inside of
- * a routine. So it is difficult to position the dbug_enter()
- * macro after all declarations and still be useful.
- * Two is that the dbug_enter() macro should be before all
- * other automatic objects so that its destructor gets called
- * last as the routine is returning.
- * The solution is to advise placing the dbug_enter() macro at
- * the start of the routine and specifying that that stack
- * values apply upto but not including the current routine.
- */
- stacksize = (ulong_t)this;
- if (GROWDOWN)
- stacksize = tdp->td_stackinit - stacksize;
- else
- stacksize = stacksize - tdp->td_stackinit;
-#endif
-
- /* record the new nesting level */
- dbug_state_object_p->s_level++;
-
- /* if producing a trace of function calls */
- if (dotrace(dbug_state_object_p, dbug_object_p->d_func, sd_process)) {
- doprefix(dbug_state_object_p, line, sd_lineno++,
- dbug_object_p->d_file, sd_process);
- indent(dbug_state_object_p, dbug_state_object_p->s_level);
- if (dbug_state_object_p->sf_stack)
- fprintf(dbug_state_object_p->s_out_file, ">%s %ld\n",
- dbug_object_p->d_func, stacksize);
- else
- fprintf(dbug_state_object_p->s_out_file, ">%s\n",
- dbug_object_p->d_func);
- fflush(dbug_state_object_p->s_out_file);
- delay(dbug_state_object_p->s_delay);
- }
-
- /* if a new thread */
- if (created && dbug_state_object_p->sf_thread) {
- doprefix(dbug_state_object_p, line, sd_lineno++,
- dbug_object_p->d_file, sd_process);
- indent(dbug_state_object_p, dbug_state_object_p->s_level);
- fprintf(dbug_state_object_p->s_out_file, "thread created\n");
- fflush(dbug_state_object_p->s_out_file);
- delay(dbug_state_object_p->s_delay);
- }
-
-out:;
- UNLOCK_THREAD_DATA();
-}
-
-/*
- *
- * dbug_object_destroy
- *
- * Description:
- * Destructor for the dbug_routine class.
- * Unchains this object from the list.
- * Arguments:
- * Returns:
- * Errors:
- * Preconditions:
- */
-void
-dbug_object_destroy(char *function_name, int line)
-{
- dbug_object_t *dbug_object_p;
- dbug_state_object_t *dbug_state_object_p;
- thread_data_t *tdp;
-
- LOCK_THREAD_DATA();
- GET_THREAD_DATA_PTR(&tdp);
-
- /* unchain from the list of objects */
- dbug_object_p = tdp->td_first;
- tdp->td_first = dbug_object_p->d_prev;
-
- /* If debugging is off, then nothing else to do */
- if (NOT db_debugon())
- goto out;
-
- dbug_object_p->d_leaveline = line;
-
- /* get a pointer to the active state */
- dbug_state_object_p = sd_push;
-
- /*
- * Make sure the last one created is being deleted.
- * This will not be the case if there are multiple dbug_routine
- * objects per routine or if one is created outside of a routine.
- */
- if (strcmp(function_name, dbug_object_p->d_func)) {
- doprefix(dbug_state_object_p, dbug_object_p->d_leaveline,
- sd_lineno++, dbug_object_p->d_file, sd_process);
- indent(dbug_state_object_p, dbug_state_object_p->s_level);
- fprintf(dbug_state_object_p->s_out_file,
- "<expected %s, actual %s, ERROR: "
- "dbug_enter/dbug_leave out of sequence.\n",
- dbug_object_p->d_func, function_name);
- fflush(dbug_state_object_p->s_out_file);
- /* delay(dbug_state_object_p->s_delay); */
- }
-
- /* if producing a trace of function calls */
- if (dotrace(dbug_state_object_p, dbug_object_p->d_func, sd_process)) {
- doprefix(dbug_state_object_p, dbug_object_p->d_leaveline,
- sd_lineno++, dbug_object_p->d_file, sd_process);
- indent(dbug_state_object_p, dbug_state_object_p->s_level);
- fprintf(dbug_state_object_p->s_out_file, "<%s\n",
- dbug_object_p->d_func);
- fflush(dbug_state_object_p->s_out_file);
-#if 0
- delay(dbug_state_object_p->s_delay);
-#endif
- }
-
-
- /* record the new nesting level */
- dbug_state_object_p->s_level--;
-
-out:;
- free(dbug_object_p);
- UNLOCK_THREAD_DATA();
-}
-
-/*
- *
- * db_keyword
- *
- * Description:
- * Test a keyword to determine if it is in the currently active
- * keyword list. As with the function list, a keyword is accepted
- * if the list is null, otherwise it must match one of the list
- * members. When debugging is not on, no keywords are accepted.
- * After the maximum trace level is exceeded, no keywords are
- * accepted (this behavior subject to change). Additionally,
- * the current function and process must be accepted based on
- * their respective lists.
- * Arguments:
- * keyword - the keyword to test
- * Returns:
- * Returns 1 if keyword accepted, 0 otherwise.
- * Errors:
- * Preconditions:
- * precond(keyword)
- */
-int
-db_keyword(dbug_object_t *dbug_object_p, const char *keyword)
-{
- dbug_state_object_t *dbug_state_object_p;
- int ret = 0;
-
- /* return FALSE if not debugging */
- if (NOT db_debugon())
- return (0);
-
- LOCK_THREAD_DATA();
-
- /* return FALSE if not debugging */
- if (NOT db_debugon())
- goto out;
-
- /* get a pointer to the active state */
- dbug_state_object_p = sd_push;
-
- if (dbug_state_object_p->sf_debug) { /* is this test necessary ? */
- if (inlist(dbug_state_object_p->s_functions,
- dbug_object_p->d_func)) {
- if (inlist(dbug_state_object_p->s_processes,
- sd_process)) {
- if (inlist(dbug_state_object_p->s_keywords,
- keyword)) {
- ret = 1;
- goto out;
- }
- }
- }
- }
-
-out:
- UNLOCK_THREAD_DATA();
- return (ret);
-}
-
-/*
- *
- * db_pargs
- *
- * Description:
- * Saves arguments for subsequent usage by db_printf.
- * Arguments:
- * line - the line number the db_print occurs on
- * keyword - determines whether or not to really print anything
- * Returns:
- * Errors:
- * Preconditions:
- * precond(keyword)
- */
-void
-db_pargs(dbug_object_t *dbug_object_p, int line, char *keyword)
-{
- thread_data_t *tdp;
-
- /* return if no debugging yet */
- if (NOT db_debugon())
- return;
-
- GET_THREAD_DATA_PTR(&tdp);
-
- tdp->td_line = line;
- if (keyword)
- strcpy(tdp->td_keyword, keyword);
- else
- tdp->td_keyword[0] = '\0';
-}
-
-int
-db_getfd()
-{
- return (fileno(sd_push->s_out_file));
-}
-
-/*
- *
- * db_printf
- *
- * Description:
- * Outputs the specified message if the keyword specified
- * by db_pargs() has been selected. The line number specified
- * by db_pargs() is also used as the line number the db_printf()
- * occurs on. The format string should NOT include a terminating
- * newline as one is supplied automatically.
- * Arguments:
- * format - printf style printing control string
- * ... - additional arguments required by the control string
- * Returns:
- * Errors:
- * Preconditions:
- * precond(format)
- */
-void
-db_printf(char *keyword, char *format, ...)
-{
- dbug_object_t *dbug_object_p;
- thread_data_t *tdp;
- dbug_state_object_t *dbug_state_object_p = sd_push;
- va_list args;
-
- dbug_object_p = db_get_dbug_object_p();
- /* return if no debugging yet */
- if (NOT db_debugon())
- return;
-
- GET_THREAD_DATA_PTR(&tdp);
-
- /* return if keyword not selected */
- if (NOT db_keyword(dbug_object_p, tdp->td_keyword))
- return;
-
- LOCK_THREAD_DATA();
-
- /* get a pointer to the active state */
-
- va_start(args, format);
-
- doprefix(dbug_state_object_p, tdp->td_line, sd_lineno++,
- dbug_object_p->d_file, sd_process);
- if (dbug_state_object_p->sf_trace)
- indent(dbug_state_object_p, dbug_state_object_p->s_level +1);
- else
- fprintf(dbug_state_object_p->s_out_file, "%s: ",
- dbug_object_p->d_func);
- if (tdp->td_keyword[0])
- fprintf(dbug_state_object_p->s_out_file, "%s: ",
- tdp->td_keyword);
- vfprintf(dbug_state_object_p->s_out_file, format, args);
- fprintf(dbug_state_object_p->s_out_file, "\n");
- fflush(dbug_state_object_p->s_out_file);
- delay(dbug_state_object_p->s_delay);
-
- va_end(args);
-
- UNLOCK_THREAD_DATA();
-}
-
-/*
- *
- * db_traceprint
- *
- * Description:
- * Prints out a trace of the call stack.
- * Arguments:
- * line - the line number where this call was made
- * keyword - keyword to test against
- * Returns:
- * Errors:
- * Preconditions:
- */
-void
-db_traceprint(int line, const char *keyword)
-{
- dbug_object_t *dbug_object_p;
- dbug_object_t *pdr;
- /* return if no debugging yet */
- if (NOT db_debugon())
- return;
-
- if ((dbug_object_p = db_get_dbug_object_p()) == NULL)
- doabort();
-
- /* If the specified keyword is enabled */
- if (db_keyword(dbug_object_p, keyword)) {
- /* perform setup for using db_printf */
- db_pargs(dbug_object_p, line, NULL);
-
- /* Output a header message */
- db_printf(NULL, "Stack Trace");
-
- /* walk the stack of dbug_routine objects */
- for (pdr = dbug_object_p; pdr != NULL; pdr = pdr->d_prev) {
- /* output the routine name */
- db_printf(NULL, " %s() (%s)", pdr->d_func,
- pdr->d_file);
- }
- }
-}
-
-/*
- *
- * db_assert
- *
- * Description:
- * Called when an assert fails.
- * Prints out a stack trace and aborts.
- * Arguments:
- * line line number assert occurred at
- * msgp string form of assert code that failed
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-void
-db_assert(dbug_object_t *dbug_object_p, int line, const char *msgp)
-{
- if (NOT db_debugon())
- db_push("-#:d");
- db_pargs(dbug_object_p, line, NULL);
- db_printf(NULL, "Assertion Failed %s:%s():%d \"%s\"",
- dbug_object_p->d_file, dbug_object_p->d_func, line, msgp);
- db_traceprint(line, NULL);
- doabort();
-}
-
-/*
- *
- * db_precond
- *
- * Description:
- * Called when an precond fails.
- * Prints out a stack trace and aborts.
- * Arguments:
- * line line number precond occurred at
- * msgp string form of precond code that failed
- * Returns:
- * Preconditions:
- * precond(msgp)
- */
-void
-db_precond(dbug_object_t *dbug_object_p, int line, const char *msgp)
-{
- if (NOT db_debugon())
- db_push("-#:d");
- db_pargs(dbug_object_p, line, NULL);
- db_printf(NULL, "Precondition Failed %s:%s():%d \"%s\"",
- dbug_object_p->d_file, dbug_object_p->d_func, line, msgp);
- db_traceprint(line, NULL);
- doabort();
-}
-
-/*
- *
- * db_push
- *
- * Description:
- * Push current debugger state and set up a new one.
- * Returns NULL if no errors, an error string if there
- * is an error.
- *
- * format of control string
- * command[:command:...]
- *
- * commands
- * debugging on 'd' d[,<keyword>[,...]]
- * delay value 'D' D[,<delay value>]
- * function list 'f' f[,<function name>[,...]]
- * print filename 'F' F
- * print pid 'i' i
- * print line number 'L' L
- * print call depth 'n' n
- * number each line 'N' N
- * output file 'o' o[,<filename>
- * process name list 'p' p[,<process name>[,...]]
- * print proc name 'P' P
- * reset indentation 'r' r
- * print runtime 'R' R
- * print thread info 'T' T
- * print trace 't' t
- * print stack depth 's' s
- */
-char *
-db_push(const char *control)
-{
- char *dupcontrol = NULL;
- dbug_state_object_t *dbug_state_object_p;
- flist_object_t *flist_object_p;
- register char *scan;
- int retval;
- char res[100];
- int level;
-
- LOCK_THREAD_DATA();
-
- /* error if the control string is NULL */
- if (control == NULL) {
- strcpy(res, "mdbug: control string is NULL");
- goto out;
- }
-
- /* turn debugging flag off */
- sd_on = FALSE;
-
- /* get the level from the old state if it exists */
- if (sd_push == NULL)
- level = 0;
- else
- level = sd_push->s_level;
-
- /* Create a new state */
- dbug_state_object_p = dbug_state_create(level);
- if (dbug_state_object_p == NULL) {
- strcpy(res, "mdbug: out of memory, dbug_state_create");
- goto out;
- }
-
- /* add it to our list of states and make it the current one */
- dbug_state_object_p->s_next = sd_push;
- sd_push = dbug_state_object_p;
-
- /* Strip off -# if in the control string */
- if ((*control == '-') && (*(control+1) == '#'))
- control += 2;
-
- /* make a copy of the control string so we can modify it with strtok */
- dupcontrol = strdup(control);
- if (dupcontrol == NULL) {
- strcpy(res, "mdbug: out of memory, strdup");
- goto out;
- }
-
- /* parse the control string */
- for (scan = mystrtok(dupcontrol, ":");
- scan != NULL;
- scan = mystrtok(NULL, ":")) {
- switch (*scan++) {
- case 'd': /* debugging on */
- sd_on = TRUE;
- dbug_state_object_p->sf_debug = TRUE;
- if (*scan++ == ',') {
- retval = listparse(scan,
- dbug_state_object_p->s_keywords);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -d too many keywords");
- goto out;
- }
- }
- break;
-
- case 'D': /* specify delay value */
- dbug_state_object_p->s_delay = 0;
- if (*scan++ == ',') {
- flist_object_p = flist_create();
- retval = listparse(scan, flist_object_p);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -D too many delays");
- goto out;
- }
- if (flist_object_p->f_count > 0) {
- dbug_state_object_p->s_delay =
- delayarg(atoi(
- (char *)fl_top(flist_object_p)));
- }
- flist_destroy(flist_object_p);
- }
- break;
-
- case 'f': /* list of functions to watch */
- if (*scan++ == ',') {
- retval = listparse(scan,
- dbug_state_object_p->s_functions);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -f too many functions");
- goto out;
- }
- }
- break;
-
- case 'F': /* print file name with dbug output */
- dbug_state_object_p->sf_file = TRUE;
- break;
-
- case 'i': /* print pid with dbug output */
- dbug_state_object_p->sf_pid = TRUE;
- break;
-
- case 'L': /* print line nums with dbug output */
- dbug_state_object_p->sf_line = TRUE;
- break;
-
- case 'n': /* print function call depth */
- dbug_state_object_p->sf_depth = TRUE;
- break;
-
- case 'N': /* number each line of dbug output */
- dbug_state_object_p->sf_number = TRUE;
- break;
-
- case 'o': /* specifies output file for dbug */
- if (*scan++ == ',') {
- flist_object_p = flist_create();
- retval = listparse(scan, flist_object_p);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -o too many output files");
- goto out;
- }
-
- if (flist_object_p->f_count > 0) {
- dbug_state_object_p->s_out_file =
- openfile((char *)
- fl_top(flist_object_p));
- if (dbug_state_object_p->s_out_file !=
- NULL)
- dbug_state_object_p->sf_didopen
- = 1;
- } else
- dbug_state_object_p->s_out_file =
- openfile(NULL);
- flist_destroy(flist_object_p);
- } else
- dbug_state_object_p->s_out_file =
- openfile(NULL);
- if (dbug_state_object_p->s_out_file == NULL) {
- strcpy(res,
- "mdbug: -o cannot open output file");
- goto out;
- }
- break;
-
- case 'p': /* debug specified processes */
- if (*scan++ == ',') {
- retval = listparse(scan,
- dbug_state_object_p->s_processes);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -p too many processes");
- goto out;
- }
- }
- break;
-
- case 'P': /* print process name on dbug output */
- dbug_state_object_p->sf_process = TRUE;
- break;
-
- case 'r': /* reset indentation to zero */
- dbug_state_object_p->s_level = 0;
- break;
-
- case 's': /* print stack depth on enter */
- dbug_state_object_p->sf_stack = TRUE;
- break;
-
- case 'R': /* print time prog has been running */
- dbug_state_object_p->sf_time = TRUE;
- time(&dbug_state_object_p->s_starttime);
- break;
-
- case 'T': /* print thread information */
- dbug_state_object_p->sf_thread = TRUE;
- break;
-
- case 't': /* print trace of functions called */
- dbug_state_object_p->sf_trace = TRUE;
- dbug_state_object_p->s_maxdepth = MAXDEPTH;
- if (*scan++ == ',') {
- flist_object_p = flist_create();
- retval = listparse(scan, flist_object_p);
- if (retval < 0) {
- strcpy(res,
- "mdbug: -t too many traces");
- goto out;
- }
- if (flist_object_p->f_count > 0) {
- dbug_state_object_p->s_maxdepth =
- atoi((char *)
- fl_top(flist_object_p));
- }
- flist_destroy(flist_object_p);
- }
- break;
- }
- }
-
-out:
- /* free up the dupped control string */
- free(dupcontrol);
-
- UNLOCK_THREAD_DATA();
-
- /* return result */
- return (NULL);
-}
-
-/*
- *
- * db_pop
- *
- * Description:
- * Pop the debug stack.
- */
-void
-db_pop()
-{
- dbug_state_object_t *dbug_state_object_p;
-
- LOCK_THREAD_DATA();
-
- /* return if no debugging yet */
- if (sd_push == NULL)
- goto out;
-
- /* get and remove the top item from the list */
- dbug_state_object_p = sd_push;
- sd_push = dbug_state_object_p->s_next;
-
- /* Delete the item. */
- dbug_state_destroy(dbug_state_object_p);
-
- /* get the current top of the stack */
- dbug_state_object_p = sd_push;
- if (dbug_state_object_p) {
- /* See if debugging is turned on */
- if (dbug_state_object_p->sf_debug)
- sd_on = TRUE;
- else
- sd_on = FALSE;
- }
-
-out:;
- UNLOCK_THREAD_DATA();
-}
-
-/*
- *
- * db_process
- *
- * Description:
- * Specifies the name of the process.
- * Only the pointer is saved, the string is not copied.
- * Arguments:
- * namep
- * Returns:
- * Preconditions:
- */
-void
-db_process(const char *namep)
-{
- thread_data_t *tdp;
-
- strcpy(sd_process, namep);
-
-#ifdef STACKINIT
- GET_THREAD_DATA_PTR(&tdp);
- tdp->td_stackinit = (ulong_t)this;
-#endif
-}
-
-/*
- *
- * listparse
- *
- * Description:
- * parse list of modifiers in debug control string
- *
- * Given pointer to a comma separated list of strings in "cltp",
- * parses the list, building a list and returning a pointer to it.
- * The original comma separated list is destroyed in the process of
- * building the linked list, thus it had better be a duplicate
- * if it is important.
- *
- * This routine is only called from db_push.
- * Returns 0 for success, -1 for failure.
- */
-static int
-listparse(register char *ctlp, flist_object_t *head)
-{
- char *start;
- char *item;
-
- /* scan the string until end */
- while (*ctlp != '\0') {
- /* See if no more room on the list */
- if (fl_space(head) == 0)
- return (-1);
-
- /* save the begining of this section */
- start = ctlp;
-
- /* loop until the end of the token is found */
- while ((*ctlp != '\0') && (*ctlp != ','))
- ctlp++;
-
- /* add a string terminator if necessary, for strdup */
- if (*ctlp == ',')
- *ctlp++ = '\0';
-
- /* make a copy of the string */
- item = strdup(start);
- if (item == NULL)
- return (-1);
-
- /* add it to the list */
- fl_push(head, item);
- }
-
- return (0);
-}
-
-/*
- *
- * inlist
- *
- * Description:
- * Tests the string pointed to by "cp" to determine if it is in
- * the list pointed to by "flist_object_p". Linkp points to the first
- * link in the list. If flist_object_p is empty then the string is treated
- * as if it is in the list (I.E all strings are in the null list).
- * This may seem rather strange at first but leads to the desired
- * operation if no list is given. The net effect is that all
- * strings will be accepted when there is no list, and when there
- * is a list, only those strings in the list will be accepted.
- */
-static boolean
-inlist(flist_object_t *flist_object_p, const char *cp)
-{
- register boolean accept;
- register char *item;
-
- if ((flist_object_p == NULL) || (flist_object_p->f_count == 0) ||
- (cp == NULL))
- accept = TRUE;
- else {
- accept = FALSE;
-
- /* walk the list of items */
- for (item = (char *)fl_top(flist_object_p);
- item != NULL;
- item = (char *)fl_next(flist_object_p)) {
- /* see if a match */
- if (strcmp(item, cp) == 0) {
- accept = TRUE;
- break;
- }
- }
- }
-
- return (accept);
-}
-
-/*
- *
- * dotrace
- *
- * Description:
- * Checks to see if tracing is enabled based on whether the
- * user has specified tracing, the maximum trace depth has
- * not yet been reached, the current function is selected,
- * and the current process is selected. Returns TRUE if
- * tracing is enabled, FALSE otherwise.
- */
-static boolean
-dotrace(dbug_state_object_t *dbug_state_object_p, const char *func,
- const char *process)
-{
- boolean trace;
-
- trace = FALSE;
- if (dbug_state_object_p->sf_trace) {
- if (dbug_state_object_p->s_level <=
- dbug_state_object_p->s_maxdepth) {
- if (inlist(dbug_state_object_p->s_functions, func)) {
- if (inlist(dbug_state_object_p->s_processes,
- process)) {
- trace = TRUE;
- }
- }
- }
- }
-
- return (trace);
-}
-
-/*
- *
- * indent
- *
- * Description:
- * Indent a line to the given level. Note that this is
- * a simple minded but portable implementation.
- * There are better ways.
- *
- * Also, the indent must be scaled by the compile time option
- * of character positions per nesting level.
- */
-static void
-indent(register dbug_state_object_t *dbug_state_object_p, int indent)
-{
- register int count;
- char buffer[PRINTBUF];
-
- indent *= INDENT;
- for (count = 0;
- (count < (indent - INDENT)) && (count < (PRINTBUF - 1));
- count++) {
- if ((count % INDENT) == 0)
- buffer[count] = '|';
- else
- buffer[count] = ' ';
- }
-
- buffer[count] = '\0';
- fprintf(dbug_state_object_p->s_out_file, buffer);
- fflush(dbug_state_object_p->s_out_file);
-}
-
-/*
- *
- * doprefix
- *
- * Description:
- * Print prefix common to all debugger output lines, prior to
- * doing indentation if necessary. Print such information as
- * current process name, current source file name and line number,
- * and current function nesting depth.
- */
-static void
-doprefix(dbug_state_object_t *dbug_state_object_p, int line, long lineno,
- const char *file, const char *process)
-{
-#if DBUG_UNIX
- if (dbug_state_object_p->sf_pid)
- fprintf(dbug_state_object_p->s_out_file, "%5d: ",
- (int)getpid());
-#endif
-
- if (dbug_state_object_p->sf_thread)
- fprintf(dbug_state_object_p->s_out_file, "%5ld: ",
- (long)thr_self());
-
- if (dbug_state_object_p->sf_number)
- fprintf(dbug_state_object_p->s_out_file, "%5ld: ", lineno);
-
- if (dbug_state_object_p->sf_process && process)
- fprintf(dbug_state_object_p->s_out_file, "%s: ", process);
-
- if (dbug_state_object_p->sf_file)
- fprintf(dbug_state_object_p->s_out_file, "%14s: ", file);
-
- if (dbug_state_object_p->sf_line)
- fprintf(dbug_state_object_p->s_out_file, "%5d: ", line);
-
- if (dbug_state_object_p->sf_depth)
- fprintf(dbug_state_object_p->s_out_file, "%4d: ",
- dbug_state_object_p->s_level);
-
- fflush(dbug_state_object_p->s_out_file);
-}
-
-/*
- *
- * openfile
- *
- * Description:
- * Given name of a new file (or NULL for stdout) opens the file
- * and sets the output stream to the new file.
- */
-static FILE *
-openfile(char *name)
-{
- FILE *fp;
- boolean newfile;
-
- if (name == NULL)
- return (stdout);
-
- if (NOT writable(name))
- return (NULL);
-
- /* see if the file already exists */
- if (file_exists(name))
- newfile = FALSE;
- else
- newfile = TRUE;
-
- /* open the file */
- fp = fopen(name, "a+");
- if (fp == NULL)
- return (NULL);
-
- /*
- * If the file is newly created, give it away to the user
- * that started the program.
- */
- if (newfile) {
- changeowner(name);
- }
- return (fp);
-}
-
-/*
- *
- * writable
- *
- * Description:
- * Because the debugger might be linked in with a program that
- * runs with the set-uid-bit (suid) set, we have to be careful
- * about opening a user named file for debug output. This consists
- * of checking the file for write access with the real user id,
- * or checking the directory where the file will be created.
- *
- * Returns TRUE if the user would normally be allowed write or
- * create access to the named file. Returns FALSE otherwise.
- */
-static boolean
-writable(char *pathname)
-{
-#if DBUG_UNIX
-
- char *lastslash;
-
- boolean granted = FALSE;
- if (file_exists(pathname)) {
- if (file_writable(pathname)) {
- granted = TRUE;
- }
- } else {
- lastslash = strrchr(pathname, '/');
- if (lastslash != NULL) {
- *lastslash = '\0';
- } else {
- pathname = ".";
- }
- if (file_writable(pathname)) {
- granted = TRUE;
- }
- if (lastslash != NULL) {
- *lastslash = '/';
- }
- }
- return (granted);
-#else
- return (TRUE);
-#endif
-}
-
-/*
- *
- * changeowner
- *
- * Description:
- * For unix systems, change the owner of the newly created debug
- * file to the real owner. This is strictly for the benefit of
- * programs that are running with the set-user-id bit set.
- *
- * Note that at this point, the fact that pathname represents
- * a newly created file has already been established. If the
- * program that the debugger is linked to is not running with
- * the suid bit set, then this operation is redundant (but
- * harmless).
- */
-static void
-changeowner(char *pathname)
-{
-#if DBUG_UNIX
- chown(pathname, getuid(), getgid());
-#endif
-}
-
-/*
- *
- * delayarg
- *
- * Description:
- * Converts delay argument, given in tenths of a second, to the
- * appropriate numerical argument used by the system to delay
- * that that many tenths of a second. For example, on the
- * amiga, there is a system call "Delay()" which takes an
- * argument in ticks (50 per second). On unix, the sleep
- * command takes seconds. Thus a value of "10", for one
- * second of delay, gets converted to 50 on the amiga, and 1
- * on unix. Other systems will need to use a timing loop.
- */
-static int
-delayarg(int value)
-{
- unsigned int delayarg = 0;
-
-#if (unix || xenix)
- delayarg = value / 10; /* Delay is in seconds for sleep () */
-#endif
- return (delayarg);
-}
-
-/*
- *
- * delay
- *
- * Description:
- * Implements the delay function.
- *
- * A dummy delay stub for systems that do not support delays.
- * With a little work, this can be turned into a timing loop.
- */
-
-static void
-delay(uint_t xx)
-{
-#if (unix || xenix)
- sleep(xx);
-#endif
-#if amiga
- Delay(xx);
-#endif
-#ifdef __ZTC__
- msleep((ulong_t)xx);
-#endif
-}
-
-/*
- *
- * getclock
- *
- * Description:
- * Returns the time in milliseconds used by this process
- * so far.
- */
-#if (unix || xenix)
-
-#include <sys/param.h>
-#if BSD4_3 || sun
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-static ulong_t
-getclock()
-{
-#if 0
- struct rusage ru;
-
- getrusage(RUSAGE_SELF, &ru);
- return ((ru.ru_utime.tv_sec * 1000) + (ru.ru_utime.tv_usec / 1000));
-#else
- return (0);
-#endif
-}
-
-#else
-
-static ulong_t
-getclock()
-{
- return (0);
-}
-
-#endif
-#endif /* unix */
-
-#ifdef MSDOS
-static ulong_t
-getclock()
-{
- return (clock() * 10);
-}
-#endif
-
-/*
- *
- * mystrtok
- *
- * Description:
- * A version of strtok for those systems without it
- */
-static char *
-mystrtok(char *s1, char *s2)
-{
- static char *end = NULL;
- register char *rtnval;
-
- rtnval = NULL;
- if (s2 != NULL) {
- if (s1 != NULL) {
- end = s1;
- rtnval = mystrtok((char *)NULL, s2);
- } else if (end != NULL) {
- if (*end != '\0') {
- rtnval = end;
- while ((*end != *s2) && (*end != '\0')) {
- end++;
- }
- if (*end != '\0') {
- *end++ = '\0';
- }
- }
- }
- }
-
- return (rtnval);
-}
-
-/*
- *
- * dbug_thread_exit
- *
- * Description:
- * Called when a thread exits.
- * Arguments:
- * data pointer to thread specific data
- * Returns:
- * Preconditions:
- */
-void
-dbug_thread_exit(void *data)
-{
- dbug_state_object_t *dbug_state_object_p;
-
- LOCK_THREAD_DATA();
-
- /* If debugging is off, then nothing else to do */
- if (NOT db_debugon())
- goto out;
-
- /* get a pointer to the active state */
- dbug_state_object_p = sd_push;
-
- if (dbug_state_object_p->sf_thread) {
- doprefix(dbug_state_object_p, 0, sd_lineno++, "unknown",
- sd_process);
- indent(dbug_state_object_p, dbug_state_object_p->s_level);
- fprintf(dbug_state_object_p->s_out_file, "thread destroyed\n");
- fflush(dbug_state_object_p->s_out_file);
- delay(dbug_state_object_p->s_delay);
- }
-
-out:;
- FREE_THREAD_DATA(data);
- UNLOCK_THREAD_DATA();
-}
-
-/*
- *
- * doabort
- *
- * Description:
- * Causes the process to exit immediatly with a core dump.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-doabort()
-{
- dbug_state_object_t *dbug_state_object_p = sd_push;
- fflush(dbug_state_object_p->s_out_file);
- for (;;) {
- kill(getpid(), SIGABRT);
- (void) signal(SIGABRT, SIG_DFL);
- (void) sigrelse(SIGABRT);
- }
-}
-
-/*
- *
- * dbug_state_create
- *
- * Description:
- * Constructor for the dbug_state class.
- * Arguments:
- * The current level in the call stack.
- * Returns:
- * Preconditions:
- */
-dbug_state_object_t *
-dbug_state_create(int level)
-{
- dbug_state_object_t *dbug_state_object_p;
-
- dbug_state_object_p =
- (dbug_state_object_t *)calloc(sizeof (dbug_state_object_t), 1);
-
- if (dbug_state_object_p == NULL)
- doabort();
-
- dbug_state_object_p->sf_trace = 0;
- dbug_state_object_p->sf_debug = 0;
- dbug_state_object_p->sf_file = 0;
- dbug_state_object_p->sf_line = 0;
- dbug_state_object_p->sf_depth = 0;
- dbug_state_object_p->sf_process = 0;
- dbug_state_object_p->sf_number = 0;
- dbug_state_object_p->sf_pid = 0;
- dbug_state_object_p->sf_stack = 0;
- dbug_state_object_p->sf_time = 0;
- dbug_state_object_p->sf_didopen = 0;
- dbug_state_object_p->sf_thread = 0;
- dbug_state_object_p->s_maxdepth = MAXDEPTH;
- dbug_state_object_p->s_delay = 0;
- dbug_state_object_p->s_level = level;
- dbug_state_object_p->s_starttime = 0;
- dbug_state_object_p->s_out_file = stderr;
- dbug_state_object_p->s_next = NULL;
- return (dbug_state_object_p);
-}
-
-/*
- *
- * dbug_state_destroy
- *
- * Description:
- * Destructor for the dbug_state class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-dbug_state_destroy(dbug_state_object_t *dbug_state_object_p)
-{
- if (dbug_state_object_p->sf_didopen)
- fclose(dbug_state_object_p->s_out_file);
- free(dbug_state_object_p);
-}
-
-/*
- *
- * db_debugon
- *
- * Description:
- * Returns 1 if debugging is currently enabled, 0 otherwise.
- * Arguments:
- * Returns:
- * Errors:
- * Preconditions:
- */
-
-int
-db_debugon(dbug_object_p)
-dbug_object_t *dbug_object_p;
-{
- return (sd_on);
-}
-boolean
-file_exists(const char *pathname)
-{
- return (access(pathname, F_OK) == 0);
-}
-boolean
-file_writable(const char *pathname)
-{
- return (access(pathname, W_OK) == 0);
-}
-dbug_object_t *
-db_get_dbug_object_p()
-{
- thread_data_t *tdp;
-
- GET_THREAD_DATA_PTR(&tdp);
- return (tdp->td_first);
-}
-#endif /* DBUG_OFF */
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/flist.c b/usr/src/cmd/fs.d/cachefs/mdbug/flist.c
deleted file mode 100644
index 7a14876bac..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/flist.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * flist.c
- *
- * Defines the flist class.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "flist.h"
-#include "mdbug.h"
-
-/*
- *
- * flist_create
- *
- * Description:
- * Constructor for the flist class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-flist_object_t *
-flist_create()
-{
- flist_object_t *flist_object_p;
-
- flist_object_p = (flist_object_t *)calloc(sizeof (flist_object_t), 1);
-
- if (flist_object_p == NULL)
- doabort();
-
- flist_object_p->f_count = 0;
- flist_object_p->f_index = 0;
- return (flist_object_p);
-}
-
-/*
- *
- * flist_destroy
- *
- * Description:
- * Destructor for the flist class.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-flist_destroy(flist_object_t *flist_object_p)
-{
- free(flist_object_p);
-}
-/*
- *
- * fl_push
- *
- * Description:
- * Adds the specified pointer to the top of the list
- * if there is room. If there is no more room then
- * nothing happens.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fl_push(flist_object_t *flist_object_p, void *ptr)
-{
- if (flist_object_p->f_count < FLIST_SIZE) {
- flist_object_p->f_items[flist_object_p->f_count] = (char *)ptr;
- flist_object_p->f_count++;
- }
-}
-
-/*
- *
- * fl_pop
- *
- * Description:
- * Removes the top item from the list.
- * No action is taken if the list is empty.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fl_pop(flist_object_t *flist_object_p)
-{
- if (flist_object_p->f_count > 0)
- flist_object_p->f_count--;
-}
-
-/*
- *
- * fl_top
- *
- * Description:
- * Returns the top item on the list.
- * Sets the internal state so that a following call to
- * next() will return the second item on the list.
- * Returns NULL if the list is empty.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void *
-fl_top(flist_object_t *flist_object_p)
-{
- flist_object_p->f_index = flist_object_p->f_count;
- return (fl_next(flist_object_p));
-}
-
-/*
- *
- * fl_next
- *
- * Description:
- * Returns the next item on the list. NULL if there
- * is no next item.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void *
-fl_next(flist_object_t *flist_object_p)
-{
- if (flist_object_p->f_index > 0) {
- flist_object_p->f_index--;
- return (flist_object_p->f_items[ flist_object_p->f_index ]);
- } else {
- return (NULL);
- }
-}
-
-/*
- *
- * fl_clear
- *
- * Description:
- * Removes all items from the list and frees them.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-void
-fl_clear(flist_object_t *flist_object_p)
-{
- void *p1;
- while ((p1 = fl_top(flist_object_p)) != NULL) {
- free(p1);
- fl_pop(flist_object_p);
- }
-}
-/*
- *
- * fl_space
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns the number of free slots on the list.
- * Errors:
- * Preconditions:
- */
-int
-fl_space(flist_object_t *flist_object_p)
-{
- return (FLIST_SIZE - flist_object_p->f_count);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/flist.h b/usr/src/cmd/fs.d/cachefs/mdbug/flist.h
deleted file mode 100644
index e27803c0ae..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/flist.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * flist.h
- *
- * Defines a simple fixed size stack oriented list class
- *
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-/*
- * .LIBRARY Base
- * .FILE flist.cxx
- * .FILE flist.h
- * .NAME flist - simple list manager class
- *
- * .DESCRIPTION
- * The flist class is a simple list manager class designed specifically
- * for use by the mdbug package.
- * There is no destuctor for the class, so when an flist object is
- * deleted any objects still on the list are forgotten.
- */
-
-#ifndef FLIST_H
-#define FLIST_H
-
-#define FLIST_SIZE 10 /* The number of items that will fit on list. */
-
-typedef struct flist_object {
- char *f_items[FLIST_SIZE]; /* Pointers to the items. */
- int f_index; /* Index of item returned by next(). */
- int f_count; /* Number of items on list. */
-
-} flist_object_t;
-
-flist_object_t *flist_create();
-void flist_destroy(flist_object_t *flist_object_p);
-void fl_push(flist_object_t *flist_object_p, void *);
-void fl_pop(flist_object_t *flist_object_p);
-void *fl_top(flist_object_t *flist_object_p);
-void *fl_next(flist_object_t *flist_object_p);
-void fl_clear(flist_object_t *flist_object_p);
-int fl_space(flist_object_t *flist_object_p);
-#endif /* FLIST_H */
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/mdbug.h b/usr/src/cmd/fs.d/cachefs/mdbug/mdbug.h
deleted file mode 100644
index 83b1e05876..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/mdbug.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * mdbug.h
- *
- * Include file for the mdbug class.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-/*
- * .LIBRARY base
- * .NAME mdbug - macros for debugging C++ programs.
- * .FILE dbug.cc
- * .FILE mdbug.h
- */
-
-/*
- * .SECTION Description
- * The mdbug package provides a set of macros for debugging C++ programs.
- * Features include tracing function entry and exit points, printing
- * of debug messages, and heap corruption detection. All features can
- * be selectively enabled at run time using command line options. Also
- * defining the macro DBUG_OFF removes all mdbug code from the compilation.
- */
-
-#ifndef MDBUG_H
-#define MDBUG_H
-
-#define DBUG_STMT(A) do { A } while (0)
-
-#ifndef DBUG_OFF
-#define DBUG_LENGTH 64
-typedef struct dbug_object {
- char d_func[DBUG_LENGTH]; /* Name of current function. */
- char d_file[DBUG_LENGTH]; /* Name of current file. */
- struct dbug_object *d_prev; /* dbug_routine object */
- int d_leaveline; /* Exit line from routine. */
-} dbug_object_t;
-
-void dbug_object_create();
-void dbug_object_destroy(char *function_name, int line);
-int db_keyword(dbug_object_t *dbug_object_p, const char *keyword);
-void db_pargs(dbug_object_t *dbug_object_p, int line, char *keyword);
-void db_printf(char *keyword, char *format, ...);
-void db_traceprint(int line, const char *keyword);
-void db_assert(dbug_object_t *dbug_object_p, int line, const char *msgp);
-void db_precond(dbug_object_t *dbug_object_p, int line, const char *msgp);
-char *db_push(const char *control);
-void db_pop();
-void db_process(const char *namep);
-void dbug_thread_exit(void *data);
-dbug_object_t *db_get_dbug_object_p();
-void doabort();
-
-
-#define dbug_enter(A) dbug_object_create(__LINE__, __FILE__, A)
-#define dbug_leave(A) dbug_object_destroy(A, __LINE__)
-#define dbug_traceprint(KEY) db_traceprint(__LINE__, KEY)
-#define dbug_push(A) db_push(A)
-void dbug_pop();
-#define dbug_process(A) db_process(A)
-void dbug_assert();
-#define dbug_assert(A)\
- if (!(A)) { db_assert(db_get_dbug_object_p(), __LINE__, ""); }
-#define dbug_precond(A)\
- if (!(A)) { db_precond(db_get_dbug_object_p(), __LINE__, ""); }
-void dbug_execute();
-#define dbug_print(A) db_printf A
-int db_debugon();
-
-#else /* if DBUG_OFF */
-
-#define dbug_enter(A) 0
-#define dbug_leave(A) 0
-#define dbug_traceprint(KEY) 0
-#define dbug_push(A) 0
-#define dbug_pop() 0
-#define dbug_process(A) 0
-#define dbug_execute(KEY, CODE) 0
-#define dbug_print(A)
-#define dbug_assert(A) 0
-#define dbug_precond(A) 0
-#define db_debugon() 0
-
-#endif /* DBUG_OFF */
-#endif /* MDBUG_H */
diff --git a/usr/src/cmd/fs.d/cachefs/mdbug/priv.h b/usr/src/cmd/fs.d/cachefs/mdbug/priv.h
deleted file mode 100644
index 1fb3b87f72..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mdbug/priv.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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
- */
-/*
- *
- * priv.h
- *
- * Internal header file for the mdbug package.
- *
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-/* Copyright (c) 1994 by Sun Microsystems, Inc. */
-
-/*
- * .LIBRARY base
- * .NAME dbug_state - used by dbug_routine to maintain state
- *
- * .SECTION Description
- * The dbug_state class is used by the dbug_routine class to maintain
- * state established by the dbug_push() macro.
- * The priv.h include file is also used to store constructs used internally
- * by the mdbug package.
- */
-
-#ifndef PRIV_H
-#define PRIV_H
-
-/* DBUG_DOS or DBUG_UNIX should be defined in the makefile to 1 */
-
-/* Define various shorthand notations. */
-#define boolean int
-#define TRUE 1
-#define FALSE 0
-#define NOT !
-#define XOR ^
-#define MAX(x, y) (((x) > (y)) ? (x) : (y))
-#define MIN(x, y) (((x) > (y)) ? (y) : (x))
-
-/* Determine which way the stack grows */
-#if DBUG_DOS || DBUG_UNIX
-const int GROWDOWN = TRUE;
-#else
-const int GROWDOWN = FALSE;
-#endif
-
-/* Manifest constants which may be "tuned" if desired. */
-#define PRINTBUF 1024 /* Print buffer size */
-#define INDENT 4 /* Indentation per trace level */
-#define MAXDEPTH 200 /* Maximum trace depth default */
-
-boolean file_exists(const char *pathname);
-boolean file_writable(const char *pathname);
-
-/*
- * This class is used to maintain the state established by the
- * push call.
- */
-typedef struct dbug_state_object {
-
- boolean sf_trace:1; /* TRUE if tracing is on */
- boolean sf_debug:1; /* TRUE if debugging is on */
- boolean sf_file:1; /* TRUE if file name print enabled */
- boolean sf_line:1; /* TRUE if line number print enabled */
- boolean sf_depth:1; /* TRUE if function nest level print enabled */
- boolean sf_process:1; /* TRUE if process name print enabled */
- boolean sf_number:1; /* TRUE if number each line */
- boolean sf_pid:1; /* TRUE if identify each line with pid */
- boolean sf_stack:1; /* TRUE if should print stack depth */
- boolean sf_time:1; /* TRUE if should print time information */
- boolean sf_didopen:1; /* TRUE if opened the log file */
- boolean sf_thread:1; /* TRUE if should print thread information */
- int s_maxdepth; /* Current maximum trace depth */
- int s_delay; /* Delay amount after each output line */
- u_int s_level; /* Current function nesting level */
- time_t s_starttime; /* Time push was done */
- FILE *s_out_file; /* Current output stream */
- flist_object_t *s_functions; /* List of functions */
- flist_object_t *s_pfunctions; /* List of profiled functions */
- flist_object_t *s_keywords; /* List of debug keywords */
- flist_object_t *s_processes; /* List of process names */
-
- struct dbug_state_object *s_next; /* pointer to next pushed state */
-}dbug_state_object_t;
-
-dbug_state_object_t *dbug_state_create(int);
-void dbug_state_destroy(dbug_state_object_t *);
-
-#ifdef _REENTRANT
-#define LOCK_THREAD_DATA() mutex_lock(&mdt_lock)
-#define ALLOC_THREAD_DATA_PTR(TDP) db_alloc_thread_data(TDP)
-#define GET_THREAD_DATA_PTR(TDP) thr_getspecific(mdt_key, (void **)TDP)
-#define UNLOCK_THREAD_DATA() mutex_unlock(&mdt_lock)
-#define FREE_THREAD_DATA(PTR) free(PTR)
-#else
-#define LOCK_THREAD_DATA()
-#define ALLOC_THREAD_DATA_PTR(TDP) *TDP = &mdt_data
-#define GET_THREAD_DATA_PTR(TDP) *TDP = &mdt_data
-#define UNLOCK_THREAD_DATA()
-#define FREE_THREAD_DATA(PTR)
-#endif
-#endif /* PRIV_H */
diff --git a/usr/src/cmd/fs.d/cachefs/mount/Makefile b/usr/src/cmd/fs.d/cachefs/mount/Makefile
deleted file mode 100644
index 46d3689be1..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mount/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/fs.d/cachefs/mount
-#
-
-FSTYPE= cachefs
-LIBPROG= mount
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= mount.o $(FSLIB)
-
-include ../Makefile.cachefs
-
-CPPFLAGS += -D_LARGEFILE64_SOURCE -I../..
-LDLIBS += -lnsl -lkstat
-
-#
-# uncomment to use cachefs pass through with NFSv3 (for debugging)
-#
-#CFLAGS += -DCFS_NFSV3_PASSTHROUGH
-
-$(LIBPROG) : $(CFSLIB)
-
-$(PROGOBJS) : $(CACHEFSDIR)/subr.h $(CACHEFSDIR)/cachefsd.h
diff --git a/usr/src/cmd/fs.d/cachefs/mount/mount.c b/usr/src/cmd/fs.d/cachefs/mount/mount.c
deleted file mode 100644
index e495babca3..0000000000
--- a/usr/src/cmd/fs.d/cachefs/mount/mount.c
+++ /dev/null
@@ -1,1675 +0,0 @@
-/*
- * 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 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * Portions of this source code were derived from Berkeley 4.3 BSD
- * under license from the Regents of the University of California.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- *
- * mount.c
- *
- * Cachefs mount program.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <wait.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <fslib.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/mntio.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/utsname.h>
-#include <rpc/rpc.h>
-#include <kstat.h>
-#undef MAX
-#include <nfs/nfs.h>
-#include <nfs/nfs_clnt.h>
-#include <sys/mkdev.h>
-#include "../common/subr.h"
-#include "../common/cachefsd.h"
-
-char *cfs_opts[] = {
-#define CFSOPT_BACKFSTYPE 0
- "backfstype",
-#define CFSOPT_CACHEDIR 1
- "cachedir",
-#define CFSOPT_CACHEID 2
- "cacheid",
-#define CFSOPT_BACKPATH 3
- "backpath",
-
-#define CFSOPT_WRITEAROUND 4
- "write-around",
-#define CFSOPT_NONSHARED 5
- "non-shared",
-
-#define CFSOPT_DISCONNECTABLE 6
- "disconnectable",
-#define CFSOPT_SOFT 7
- "soft",
-
-#define CFSOPT_NOCONST 8
- "noconst",
-#define CFSOPT_CODCONST 9
- "demandconst",
-
-#define CFSOPT_LOCALACCESS 10
- "local-access",
-#define CFSOPT_LAZYMOUNT 11
- "lazy-mount",
-
-#define CFSOPT_RW 12
- "rw",
-#define CFSOPT_RO 13
- "ro",
-#define CFSOPT_SUID 14
- "suid",
-#define CFSOPT_NOSUID 15
- "nosuid",
-#define CFSOPT_REMOUNT 16
- "remount",
-#define CFSOPT_FGSIZE 17
- "fgsize",
-#define CFSOPT_POPSIZE 18
- "popsize",
-#define CFSOPT_ACREGMIN 19
- "acregmin",
-#define CFSOPT_ACREGMAX 20
- "acregmax",
-#define CFSOPT_ACDIRMIN 21
- "acdirmin",
-#define CFSOPT_ACDIRMAX 22
- "acdirmax",
-#define CFSOPT_ACTIMEO 23
- "actimeo",
-#define CFSOPT_SLIDE 24
- "slide",
-#define CFSOPT_NOSETSEC 25
- "nosec", /* XXX should we use MNTOPT_NOTSETSEC? */
-#define CFSOPT_LLOCK 26
- "llock",
-#define CFSOPT_NONOTIFY 27
- "nonotify",
-#define CFSOPT_SNR 28
- "snr",
-#define CFSOPT_NOFILL 29
- "nofill",
-#ifdef CFS_NFSV3_PASSTHROUGH
-#define CFSOPT_NFSV3PASSTHROUGH 30
- "nfsv3pass",
-#endif /* CFS_NFSV3_PASSTHROUGH */
- NULL
-};
-
-#define MNTTYPE_CFS "cachefs" /* XXX - to be added to mntent.h */
- /* XXX - and should be cachefs */
-#define CFS_DEF_DIR "/cache" /* XXX - should be added to cfs.h */
-
-#define bad(val) (val == NULL || !isdigit(*val))
-
-#define VFS_PATH "/usr/lib/fs"
-#define ALT_PATH "/etc/fs"
-
-/* forward references */
-void usage(char *msgp);
-void pr_err(char *fmt, ...);
-int set_cfs_args(char *optionp, struct cachefs_mountargs *margsp, int *mflagp,
- char **backfstypepp, char **reducepp, int *notifyp, int *nfsv3pass);
-int get_mount_point(char *cachedirp, char *specp, char **pathpp);
-int dobackmnt(struct cachefs_mountargs *margsp, char *reducep, char *specp,
- char *backfstypep, char *mynamep, int readonly);
-void doexec(char *fstype, char **newargv, char *myname);
-char *get_back_fsid(char *specp);
-char *get_cacheid(char *, char *);
-void record_mount(char *mntp, char *specp, char *backfsp, char *backfstypep,
- char *cachedirp, char *cacheidp, char *optionp, char *reducep);
-int daemon_notify(char *cachedirp, char *cacheidp);
-int pingserver(char *backmntp);
-int check_cache(char *cachedirp);
-uint32_t cachefs_get_back_nfsvers(char *cfs_backfs, int nomnttab);
-int cfs_nfsv4_build_opts(char *optionp, char *cfs_nfsv4ops);
-
-int nomnttab;
-int quiet;
-/*
- *
- * main
- *
- * Description:
- * Main routine for the cachefs mount program.
- * Arguments:
- * argc number of command line arguments
- * argv list of command line arguments
- * Returns:
- * Returns 0 for success, 1 an error was encountered.
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- char *myname;
- char *optionp;
- char *opigp;
- int mflag;
- int readonly;
- struct cachefs_mountargs margs;
- char *backfstypep;
- char *reducep;
- char *specp;
- int xx;
- int stat_loc;
- char *newargv[20];
- char *mntp;
- pid_t pid;
- int mounted;
- int c;
- int lockid;
- int Oflg;
- char *strp;
- char servname[33];
- int notify = 1;
- struct stat64 statb;
- struct mnttagdesc mtdesc;
- char mops[MAX_MNTOPT_STR];
- char cfs_nfsv4ops[MAX_MNTOPT_STR];
- uint32_t nfsvers = 0;
- uint32_t nfsvers_error = FALSE;
- int nfsv3pass = 0;
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- if (argv[0]) {
- myname = strrchr(argv[0], '/');
- if (myname)
- myname++;
- else
- myname = argv[0];
- } else {
- myname = "path unknown";
- }
-
- optionp = NULL;
- nomnttab = 0;
- quiet = 0;
- readonly = 0;
- Oflg = 0;
- cfs_nfsv4ops[0] = '\0';
-
- /* process command line options */
- while ((c = getopt(argc, argv, "mo:Orq")) != EOF) {
- switch (c) {
- case 'm': /* no entry in /etc/mnttab */
- nomnttab = 1;
- break;
-
- case 'o':
- optionp = optarg;
- break;
-
- case 'O':
- Oflg++;
- break;
-
- case 'r': /* read only mount */
- readonly = 1;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- default:
- usage("invalid option");
- return (1);
- }
- }
-
- /* if -o not specified */
- if (optionp == NULL) {
- usage(gettext("\"-o backfstype\" must be specified"));
- return (1);
- }
-
- /* verify special device and mount point are specified */
- if (argc - optind < 2) {
- usage(gettext("must specify special device and mount point"));
- return (1);
- }
-
- /* Store mount point and special device. */
- specp = argv[argc - 2];
- mntp = argv[argc - 1];
-
- /* Initialize default mount values */
- margs.cfs_options.opt_flags = CFS_ACCESS_BACKFS;
- margs.cfs_options.opt_popsize = DEF_POP_SIZE;
- margs.cfs_options.opt_fgsize = DEF_FILEGRP_SIZE;
- margs.cfs_fsid = NULL;
- memset(margs.cfs_cacheid, 0, sizeof (margs.cfs_cacheid));
- margs.cfs_cachedir = CFS_DEF_DIR;
- margs.cfs_backfs = NULL;
- margs.cfs_acregmin = 0;
- margs.cfs_acregmax = 0;
- margs.cfs_acdirmin = 0;
- margs.cfs_acdirmax = 0;
- mflag = MS_OPTIONSTR;
- if (nomnttab)
- mflag |= MS_NOMNTTAB;
- backfstypep = NULL;
-
- /* process -o options */
- xx = set_cfs_args(optionp, &margs, &mflag, &backfstypep, &reducep,
- &notify, &nfsv3pass);
- if (xx) {
- return (1);
- }
- strcpy(mops, optionp);
-
- /* backfstype has to be specified */
- if (backfstypep == NULL) {
- usage(gettext("\"-o backfstype\" must be specified"));
- return (1);
- }
-
- if ((strcmp(backfstypep, "nfs") != 0) &&
- (strcmp(backfstypep, "hsfs") != 0)) {
- pr_err(gettext("%s as backfstype is not supported."),
- backfstypep);
- return (1);
- }
-
- /* set default write mode if not specified */
- if ((margs.cfs_options.opt_flags &
- (CFS_WRITE_AROUND|CFS_NONSHARED)) == 0) {
- margs.cfs_options.opt_flags |= CFS_WRITE_AROUND;
- if (strcmp(backfstypep, "hsfs") == 0)
- mflag |= MS_RDONLY;
- }
-
- /* if read-only was specified with the -r option */
- if (readonly) {
- mflag |= MS_RDONLY;
- }
-
- /* if overlay was specified with -O option */
- if (Oflg) {
- mflag |= MS_OVERLAY;
- }
-
- /* get the fsid of the backfs and the cacheid */
- margs.cfs_fsid = get_back_fsid(specp);
- if (margs.cfs_fsid == NULL) {
- pr_err(gettext("out of memory"));
- return (1);
- }
-
- /*
- * If using this cachedir to mount a file system for the first time
- * after reboot, the ncheck for the sanity of the cachedir
- */
- if (first_time_ab(margs.cfs_cachedir))
- if (check_cache(margs.cfs_cachedir))
- return (1);
-
- /* get the front file system cache id if necessary */
- if (margs.cfs_cacheid[0] == '\0') {
- char *cacheid = get_cacheid(margs.cfs_fsid, mntp);
-
- if (cacheid == NULL) {
- pr_err(gettext("default cacheid too long"));
- return (1);
- }
-
- strcpy(margs.cfs_cacheid, cacheid);
- }
-
- /* lock the cache directory shared */
- lockid = cachefs_dir_lock(margs.cfs_cachedir, 1);
- if (lockid == -1) {
- /* exit if could not get the lock */
- return (1);
- }
-
- /* if no mount point was specified and we are not remounting */
- mounted = 0;
- if ((margs.cfs_backfs == NULL) &&
- (((mflag & MS_REMOUNT) == 0) ||
- (margs.cfs_options.opt_flags & CFS_SLIDE))) {
- /* if a disconnectable mount */
- xx = 0;
- if (margs.cfs_options.opt_flags & CFS_DISCONNECTABLE) {
- /* see if the server is alive */
- xx = pingserver(specp);
- }
-
- /* attempt to mount the back file system */
- if (xx == 0) {
- xx = dobackmnt(&margs, reducep, specp, backfstypep,
- myname, readonly);
- /*
- * nfs mount exits with a value of 32 if a timeout
- * error occurs trying the mount.
- */
- if (xx && (xx != 32)) {
- cachefs_dir_unlock(lockid);
- rmdir(margs.cfs_backfs);
- return (1);
- }
- if (xx == 0)
- mounted = 1;
- }
- }
-
- /*
- * At this point the back file system should be mounted.
- * Get NFS version information for the back filesystem if
- * it is NFS. The version information is required
- * because NFS version 4 is incompatible with cachefs
- * and we provide pass-through support for NFS version 4
- * with cachefs, aka the cachefs mount is installed but
- * there is no caching. This is indicated to the kernel
- * during the mount by setting the CFS_BACKFS_NFSV4 flag.
- */
- if (margs.cfs_backfs != NULL && strcmp(backfstypep, "nfs") == 0) {
-
- nfsvers = cachefs_get_back_nfsvers(margs.cfs_backfs, nomnttab);
- switch (nfsvers) {
- case 2:
- break;
-
- case 3:
- if (nfsv3pass) {
- /* Force pass through (for debugging) */
- margs.cfs_options.opt_flags = CFS_BACKFS_NFSV4;
- if (cfs_nfsv4_build_opts(optionp,
- cfs_nfsv4ops) != 0) {
- nfsvers_error = TRUE;
- goto clean_backmnt;
- }
- }
- break;
-
- case 4:
- /*
- * overwrite old option flags with NFSv4 flag.
- * Note that will also operate in strict
- * consistency mode. Clean up the option string
- * to get rid of the cachefs-specific options
- * to be in sync with the opt flags, otherwise
- * these can make it into the mnttab and cause
- * problems (esp. the disconnected option).
- */
- margs.cfs_options.opt_flags = CFS_BACKFS_NFSV4;
- if (cfs_nfsv4_build_opts(optionp, cfs_nfsv4ops) != 0) {
- nfsvers_error = TRUE;
- goto clean_backmnt;
- }
- break;
-
- default:
- /* error, unknown version */
- nfsvers_error = TRUE;
- goto clean_backmnt;
- }
- }
-
- /*
- * Grab server name from special file arg if it is there or set
- * server name to "server unknown".
- */
- margs.cfs_hostname = servname;
- strncpy(servname, specp, sizeof (servname));
- servname[sizeof (servname) - 1] = '\0';
- strp = strchr(servname, ':');
- if (strp == NULL) {
- margs.cfs_hostname = "server unknown";
- margs.cfs_backfsname = specp;
- } else {
- *strp = '\0';
- /*
- * The rest of the special file arg is the name of
- * the back filesystem.
- */
- strp++;
- margs.cfs_backfsname = strp;
- }
-
- /* mount the cache file system */
- xx = mount((margs.cfs_backfs != NULL) ? margs.cfs_backfs : "nobackfs",
- mntp, mflag | MS_DATA, MNTTYPE_CFS,
- &margs, sizeof (margs),
- (cfs_nfsv4ops[0] == '\0' ? mops : cfs_nfsv4ops),
- MAX_MNTOPT_STR);
-clean_backmnt:
- if (xx == -1 || nfsvers_error) {
- if (nfsvers_error) {
- pr_err(gettext("nfs version error."));
- } else if (errno == ESRCH) {
- pr_err(gettext("mount failed, options do not match."));
- } else if ((errno == EAGAIN) && (margs.cfs_backfs == NULL)) {
- pr_err(gettext("mount failed, server not responding."));
- } else {
- pr_err(gettext("mount failed %s"), strerror(errno));
- }
-
- /* try to unmount the back file system if we mounted it */
- if (mounted) {
- xx = 1;
- newargv[xx++] = "umount";
- newargv[xx++] = margs.cfs_backfs;
- newargv[xx++] = NULL;
-
- /* fork */
- if ((pid = fork()) == -1) {
- pr_err(gettext("could not fork: %s"),
- strerror(errno));
- cachefs_dir_unlock(lockid);
- return (1);
- }
-
- /* if the child */
- if (pid == 0) {
- /* do the unmount */
- doexec(backfstypep, newargv, "umount");
- }
-
- /* else if the parent */
- else {
- wait(0);
- }
- rmdir(margs.cfs_backfs);
- }
-
- cachefs_dir_unlock(lockid);
- return (1);
- }
-
- /* release the lock on the cache directory */
- cachefs_dir_unlock(lockid);
-
- /* record the mount information in the fscache directory */
- record_mount(mntp, specp, margs.cfs_backfs, backfstypep,
- margs.cfs_cachedir, margs.cfs_cacheid,
- (cfs_nfsv4ops[0] == '\0' ? optionp : cfs_nfsv4ops), reducep);
-
- /* notify the daemon of the mount */
- if (notify)
- daemon_notify(margs.cfs_cachedir, margs.cfs_cacheid);
-
- /* update mnttab file if necessary */
- if (!nomnttab) {
- /*
- * If we added the back file system, tag it with ignore,
- * however, don't fail the mount after its done
- * if the tag can't be added (eg., this would cause
- * automounter problems).
- */
- if (mounted) {
- FILE *mt;
- struct extmnttab mnt;
-
- if ((mt = fopen(MNTTAB, "r")) == NULL)
- return (1);
- while (getextmntent(mt, &mnt, sizeof (mnt)) != -1) {
- if (mnt.mnt_mountp != NULL &&
- strcmp(margs.cfs_backfs,
- mnt.mnt_mountp) == 0) {
- /* found it, do tag ioctl */
- mtdesc.mtd_major = mnt.mnt_major;
- mtdesc.mtd_minor = mnt.mnt_minor;
- mtdesc.mtd_mntpt = margs.cfs_backfs;
- mtdesc.mtd_tag = MNTOPT_IGNORE;
-
- (void) ioctl(fileno(mt),
- MNTIOC_SETTAG, &mtdesc);
- break;
- }
- }
- fclose(mt);
- }
- }
-
- /* return success */
- return (0);
-}
-
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a short usage message.
- * Arguments:
- * msgp message to include with the usage message
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp) {
- pr_err(gettext("%s"), msgp);
- }
-
- fprintf(stderr,
- gettext("Usage: mount -F cachefs [generic options] "
- "-o backfstype=file_system_type[FSTypespecific_options] "
- "special mount_point\n"));
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("mount -F cachefs: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
-
-/*
- *
- * set_cfs_args
- *
- * Description:
- * Parse the comma delimited set of options specified by optionp
- * and puts the results in margsp, mflagp, and backfstypepp.
- * A string is constructed of options which are not specific to
- * cfs and is placed in reducepp.
- * Pointers to strings are invalid if this routine is called again.
- * No initialization is done on margsp, mflagp, or backfstypepp.
- * Arguments:
- * optionp string of comma delimited options
- * margsp option results for the mount dataptr arg
- * mflagp option results for the mount mflag arg
- * backfstypepp set to name of back file system type
- * reducepp set to the option string without cfs specific options
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(optionp)
- * precond(margsp)
- * precond(mflagp)
- * precond(backfstypepp)
- * precond(reducepp)
- */
-
-int
-set_cfs_args(char *optionp, struct cachefs_mountargs *margsp, int *mflagp,
- char **backfstypepp, char **reducepp, int *notifyp, int *nfsv3pass)
-{
- static char *optstrp = NULL;
- static char *reducep = NULL;
- char *savep, *strp, *valp;
- int badopt;
- int ret;
- int o_backpath = 0;
- int o_writemode = 0;
- int xx;
- uint_t yy;
- struct stat64 sinfo;
- char *pbuf;
-
- /* free up any previous options */
- free(optstrp);
- optstrp = NULL;
- free(reducep);
- reducep = NULL;
-
- /* make a copy of the options so we can modify it */
- optstrp = strp = strdup(optionp);
- reducep = malloc(strlen(optionp) + 1000);
- if ((strp == NULL) || (reducep == NULL)) {
- pr_err(gettext("out of memory"));
- return (-1);
- }
- *reducep = '\0';
-
- /* parse the options */
- badopt = 0;
- ret = 0;
- while (*strp) {
- savep = strp;
- switch (getsubopt(&strp, cfs_opts, &valp)) {
-
- case CFSOPT_BACKFSTYPE:
- if (valp == NULL)
- badopt = 1;
- else
- *backfstypepp = valp;
- break;
-
- case CFSOPT_CACHEDIR:
- if (valp == NULL)
- badopt = 1;
- else {
- margsp->cfs_cachedir = valp;
- if (valp[0] != '/') {
- pbuf = (char *)malloc(MAXPATHLEN +
- strlen(valp) + 3);
- if (pbuf == NULL) {
- pr_err(gettext("out of memory"));
- badopt = 1;
- break;
- }
- if (getcwd(pbuf, MAXPATHLEN+1) == NULL) {
- pr_err(gettext("cachedir too long"));
- badopt = 1;
- break;
- }
- if (pbuf[strlen(pbuf)-1] != '/')
- strcat(pbuf, "/");
- strcat(pbuf, valp);
- margsp->cfs_cachedir = pbuf;
- }
- }
- break;
-
- case CFSOPT_CACHEID:
- if (valp == NULL) {
- badopt = 1;
- break;
- }
-
- if (strlen(valp) >= (size_t)C_MAX_MOUNT_FSCDIRNAME) {
- pr_err(gettext("cacheid too long"));
- badopt = 1;
- break;
- }
-
- memset(margsp->cfs_cacheid, 0, C_MAX_MOUNT_FSCDIRNAME);
- strcpy(margsp->cfs_cacheid, valp);
- break;
-
- case CFSOPT_BACKPATH:
- if (valp == NULL)
- badopt = 1;
- else {
- margsp->cfs_backfs = valp;
- o_backpath = 1;
- }
- break;
-
- case CFSOPT_WRITEAROUND:
- margsp->cfs_options.opt_flags |= CFS_WRITE_AROUND;
- o_writemode++;
- break;
-
- case CFSOPT_NONSHARED:
- margsp->cfs_options.opt_flags |= CFS_NONSHARED;
- o_writemode++;
- break;
-
- case CFSOPT_NOCONST:
- margsp->cfs_options.opt_flags |= CFS_NOCONST_MODE;
- break;
-
- case CFSOPT_CODCONST:
- margsp->cfs_options.opt_flags |= CFS_CODCONST_MODE;
- break;
-
- case CFSOPT_LOCALACCESS:
- margsp->cfs_options.opt_flags &= ~CFS_ACCESS_BACKFS;
- break;
-
- case CFSOPT_NOSETSEC:
- margsp->cfs_options.opt_flags |= CFS_NOACL;
- break;
-
- case CFSOPT_LLOCK:
- margsp->cfs_options.opt_flags |= CFS_LLOCK;
- strcat(reducep, ",");
- strcat(reducep, savep);
- break;
-
- case CFSOPT_REMOUNT:
- *mflagp |= MS_REMOUNT;
- break;
-
- case CFSOPT_SLIDE:
- margsp->cfs_options.opt_flags |= CFS_SLIDE;
- break;
-
- case CFSOPT_FGSIZE:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_options.opt_fgsize = atoi(valp);
- break;
-
- case CFSOPT_POPSIZE:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_options.opt_popsize =
- atoi(valp) * 1024;
- break;
-
- case CFSOPT_ACREGMIN:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_acregmin = atoi(valp);
- break;
-
- case CFSOPT_ACREGMAX:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_acregmax = atoi(valp);
- break;
-
- case CFSOPT_ACDIRMIN:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_acdirmin = atoi(valp);
- break;
-
- case CFSOPT_ACDIRMAX:
- if (bad(valp))
- badopt = 1;
- else
- margsp->cfs_acdirmax = atoi(valp);
- break;
-
- case CFSOPT_ACTIMEO:
- if (bad(valp))
- badopt = 1;
- else {
- yy = atoi(valp);
- margsp->cfs_acregmin = yy;
- margsp->cfs_acregmax = yy;
- margsp->cfs_acdirmin = yy;
- margsp->cfs_acdirmax = yy;
- }
- /*
- * Note that we do not pass the actimeo options
- * to the back file system. This change was
- * made for Chart. Chart needs noac or actimeo=0
- * so it makes no sense to pass these options on.
- * In theory it should be okay to not pass these
- * options on for regular cachefs mounts since
- * cachefs perform the required attribute caching.
- */
- break;
-
-#if 0
- case CFSOPT_LAZYMOUNT:
- margsp->cfs_options.opt_flags |= CFS_LAZYMOUNT;
- break;
-#endif
-
- case CFSOPT_DISCONNECTABLE:
- case CFSOPT_SNR:
- margsp->cfs_options.opt_flags |= CFS_DISCONNECTABLE;
- break;
-
- case CFSOPT_NOFILL:
- margsp->cfs_options.opt_flags |= CFS_NOFILL;
- break;
-
- case CFSOPT_SOFT:
- margsp->cfs_options.opt_flags |= CFS_SOFT;
- break;
-
- case CFSOPT_NONOTIFY:
- *notifyp = 0;
- break;
-
-#ifdef CFS_NFSV3_PASSTHROUGH
- case CFSOPT_NFSV3PASSTHROUGH:
- *nfsv3pass = 1;
- break;
-#endif /* CFS_NFSV3_PASSTHROUGH */
-
- default:
- /*
- * unknown or vfs layer option, save for the back
- * file system
- */
- strcat(reducep, ",");
- strcat(reducep, savep);
- break;
- }
-
- /* if a lexical error occurred */
- if (badopt) {
- pr_err(gettext("invalid argument to option: \"%s\""),
- savep);
- badopt = 0;
- ret = -1;
- }
- }
-
- /*
- * Should mount backfs soft if disconnectable & non-shared options
- * are used. NFS soft option allows reads and writes to TIMEOUT
- * when the server is not responding, which is crucial for
- * disconnectable option to work all the time in non-shared mode.
- *
- * Should mount backfs semisoft if disconnectable & write-around
- * are used. NFS semisoft option allows reads to TIMEOUT and
- * write to block when the server is not responding, which is
- * good for write around option because it is shared.
- *
- * Since disconnectable and strict options are conflicting,
- * when disconnectable option is used, default option is set to
- * demandconst.
- */
-
- if (margsp->cfs_options.opt_flags & (CFS_DISCONNECTABLE | CFS_SOFT))
- if (margsp->cfs_options.opt_flags & CFS_NONSHARED) {
- strcat(reducep, ",soft,noprint");
- margsp->cfs_options.opt_flags |= CFS_CODCONST_MODE;
- }
- else
- strcat(reducep, ",semisoft,noprint");
-
- if (!(margsp->cfs_options.opt_flags & CFS_DISCONNECTABLE)) {
- /* not snr, no need to notify the cachefsd */
- *notifyp = 0;
- }
-
- /* additional nfs options needed so disconnectable will work */
- if (margsp->cfs_options.opt_flags & CFS_DISCONNECTABLE) {
- /*
- * retry=0 so cachefs can mount if nfs mount fails
- * even with this nfs takes 3 minutes to give up
- * actimeo=0 because NFS does not pick up new ctime after
- * rename
- */
- strcat(reducep, ",retry=0");
- if (margsp->cfs_options.opt_flags & CFS_NONSHARED)
- strcat(reducep, ",actimeo=0");
- }
-
- /* check for conflicting options */
- xx = margsp->cfs_options.opt_flags;
- if (o_backpath & (xx & CFS_DISCONNECTABLE)) {
- pr_err(gettext("backpath cannot be used with disconnectable"));
- ret = -1;
- }
- if (margsp->cfs_acregmin > margsp->cfs_acregmax) {
- pr_err(gettext("acregmin cannot be greater than acregmax"));
- ret = -1;
- }
- if (margsp->cfs_acdirmin > margsp->cfs_acdirmax) {
- pr_err(gettext("acdirmin cannot be greater than acdirmax"));
- ret = -1;
- }
-
- xx = CFS_NOCONST_MODE | CFS_CODCONST_MODE;
- if ((margsp->cfs_options.opt_flags & xx) == xx) {
- pr_err(gettext("only one of noconst and demandconst"
- " may be specified"));
- ret = -1;
- }
-
- if (o_writemode > 1) {
- pr_err(gettext(
- "only one of write-around or non-shared"
- " may be specified"));
- ret = -1;
- }
-
- /* if an error occured */
- if (ret)
- return (-1);
-
- /* if there are any options which are not mount specific */
- if (*reducep)
- *reducepp = reducep + 1;
- else
- *reducepp = NULL;
-
- /* return success */
- return (0);
-}
-
-/*
- *
- * get_mount_point
- *
- * Description:
- * Makes a suitable mount point for the back file system.
- * The name of the mount point created is stored in a malloced
- * buffer in pathpp
- * Arguments:
- * cachedirp the name of the cache directory
- * specp the special name of the device for the file system
- * pathpp where to store the mount point
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- * precond(cachedirp)
- * precond(specp)
- * precond(pathpp)
- */
-
-int
-get_mount_point(char *cachedirp, char *specp, char **pathpp)
-{
- char *strp;
- char *namep;
- struct stat64 stat1, stat2;
- int xx;
- int index;
- int max;
-
- /* make a copy of the special device name */
- specp = strdup(specp);
- if (specp == NULL) {
- pr_err(gettext("out of memory"));
- return (-1);
- }
-
- /* convert the special device name into a file name */
- strp = specp;
- while (strp = strchr(strp, '/')) {
- *strp = '_';
- }
-
- /* get some space for the path name */
- strp = malloc(MAXPATHLEN);
- if (strp == NULL) {
- pr_err(gettext("out of memory"));
- return (-1);
- }
-
- /* see if the mount directory is valid */
- /* backfs can contain large files */
- sprintf(strp, "%s/%s", cachedirp, BACKMNT_NAME);
- xx = stat64(strp, &stat1);
- if ((xx == -1) || !S_ISDIR(stat1.st_mode)) {
- pr_err(gettext("%s is not a valid cache."), strp);
- return (-1);
- }
-
- /* find a directory name we can use */
- max = 10000;
- namep = strp + strlen(strp);
- for (index = 1; index < max; index++) {
-
- /* construct a directory name to consider */
- if (index == 1)
- sprintf(namep, "/%s", specp);
- else
- sprintf(namep, "/%s_%d", specp, index);
-
- /* try to create the directory */
- xx = mkdir(strp, 0755);
- if (xx == 0) {
- /* done if the create succeeded */
- break;
- }
- }
-
- /* if the search failed */
- if (index >= max) {
- pr_err(gettext("could not create a directory"));
- return (-1);
- }
-
- /* return success */
- *pathpp = strp;
- return (0);
-}
-
-
-int
-dobackmnt(struct cachefs_mountargs *margsp, char *reducep, char *specp,
- char *backfstypep, char *mynamep, int readonly)
-{
- int xx;
- pid_t pid;
- char *newargv[20];
- int stat_loc;
-
- /* get a suitable mount point */
- xx = get_mount_point(margsp->cfs_cachedir, specp, &margsp->cfs_backfs);
- if (xx)
- return (1);
-
- /* construct argument list for mounting the back file system */
- xx = 1;
- newargv[xx++] = "mount";
- if (readonly)
- newargv[xx++] = "-r";
- if (nomnttab)
- newargv[xx++] = "-m";
- if (quiet)
- newargv[xx++] = "-q";
- if (reducep) {
- newargv[xx++] = "-o";
- newargv[xx++] = reducep;
- }
- newargv[xx++] = specp;
- newargv[xx++] = margsp->cfs_backfs;
- newargv[xx++] = NULL;
-
- /* fork */
- if ((pid = fork()) == -1) {
- pr_err(gettext("could not fork %s"), strerror(errno));
- return (1);
- }
-
- /* if the child */
- if (pid == 0) {
- /* do the mount */
- doexec(backfstypep, newargv, mynamep);
- }
-
- /* else if the parent */
- else {
- /* wait for the child to exit */
- if (wait(&stat_loc) == -1) {
- pr_err(gettext("wait failed %s"), strerror(errno));
- return (1);
- }
-
- if (!WIFEXITED(stat_loc)) {
- pr_err(gettext("back mount did not exit"));
- return (1);
- }
-
- xx = WEXITSTATUS(stat_loc);
- if (xx) {
- pr_err(gettext("back mount failed"));
- return (xx);
- }
- }
-
- return (0);
-}
-
-/*
- *
- * doexec
- *
- * Description:
- * Execs the specified program with the specified command line arguments.
- * This function never returns.
- * Arguments:
- * fstype type of file system
- * newargv command line arguments
- * progp name of program to exec
- * Returns:
- * Preconditions:
- * precond(fstype)
- * precond(newargv)
- */
-
-void
-doexec(char *fstype, char *newargv[], char *progp)
-{
- char full_path[PATH_MAX];
- char alter_path[PATH_MAX];
- char *vfs_path = VFS_PATH;
- char *alt_path = ALT_PATH;
-
- /* build the full pathname of the fstype dependent command. */
- sprintf(full_path, "%s/%s/%s", vfs_path, fstype, progp);
- sprintf(alter_path, "%s/%s/%s", alt_path, fstype, progp);
-
- /* if the program exists */
- if (access(full_path, 0) == 0) {
- /* invoke the program */
- execv(full_path, &newargv[1]);
-
- /* if wrong permissions */
- if (errno == EACCES) {
- pr_err(gettext("cannot execute %s %s"),
- full_path, strerror(errno));
- }
-
- /* if it did not work and the shell might make it */
- if (errno == ENOEXEC) {
- newargv[0] = "sh";
- newargv[1] = full_path;
- execv("/sbin/sh", &newargv[0]);
- }
- }
-
- /* try the alternate path */
- execv(alter_path, &newargv[1]);
-
- /* if wrong permissions */
- if (errno == EACCES) {
- pr_err(gettext("cannot execute %s %s"),
- alter_path, strerror(errno));
- }
-
- /* if it did not work and the shell might make it */
- if (errno == ENOEXEC) {
- newargv[0] = "sh";
- newargv[1] = alter_path;
- execv("/sbin/sh", &newargv[0]);
- }
-
- pr_err(gettext("operation not applicable to FSType %s"), fstype);
- exit(1);
-}
-
-/*
- *
- * get_back_fsid
- *
- * Description:
- * Determines a unique identifier for the back file system.
- * Arguments:
- * specp the special file of the back fs
- * Returns:
- * Returns a malloc string which is the unique identifer
- * or NULL on failure. NULL is only returned if malloc fails.
- * Preconditions:
- * precond(specp)
- */
-
-char *
-get_back_fsid(char *specp)
-{
- return (strdup(specp));
-}
-
-/*
- *
- * get_cacheid
- *
- * Description:
- * Determines an identifier for the front file system cache.
- * The returned string points to a static buffer which is
- * overwritten on each call.
- * The length of the returned string is < C_MAX_MOUNT_FSCDIRNAME.
- * Arguments:
- * fsidp back file system id
- * mntp front file system mount point
- * Returns:
- * Returns a pointer to the string identifier, or NULL if the
- * identifier was overflowed.
- * Preconditions:
- * precond(fsidp)
- * precond(mntp)
- */
-
-char *
-get_cacheid(char *fsidp, char *mntp)
-{
- char *c1;
- static char buf[PATH_MAX];
- char mnt_copy[PATH_MAX];
-
- /* strip off trailing space in mountpoint -- autofs fallout */
- if (strlen(mntp) >= sizeof (mnt_copy))
- return (NULL);
- (void) strcpy(mnt_copy, mntp);
- c1 = mnt_copy + strlen(mnt_copy) - 1;
- if (*c1 == ' ')
- *c1 = '\0';
-
- if ((strlen(fsidp) + strlen(mnt_copy) + 2) >=
- (size_t)C_MAX_MOUNT_FSCDIRNAME)
- return (NULL);
-
- strcpy(buf, fsidp);
- strcat(buf, ":");
- strcat(buf, mnt_copy);
- c1 = buf;
- while ((c1 = strpbrk(c1, "/")) != NULL)
- *c1 = '_';
- return (buf);
-}
-
-
-/*
- *
- * check_cache
- *
- * Description:
- * Checks the cache we are about to use.
- * Arguments:
- * cachedirp cachedirectory to check
- * Returns:
- * Returns 0 for success, -1 for an error.
- * Preconditions:
- */
-int
-check_cache(cachedirp)
- char *cachedirp;
-{
- char *fsck_argv[4];
- int status = 0;
- pid_t pid;
-
- fsck_argv[1] = "fsck";
- fsck_argv[2] = cachedirp;
- fsck_argv[3] = NULL;
-
- /* fork */
- if ((pid = fork()) == -1) {
- pr_err(gettext("could not fork %s"),
- strerror(errno));
- return (1);
- }
-
- if (pid == 0) {
- /* do the fsck */
- doexec("cachefs", fsck_argv, "fsck");
- } else {
- /* wait for the child to exit */
- if (wait(&status) == -1) {
- pr_err(gettext("wait failed %s"),
- strerror(errno));
- return (1);
- }
-
- if (!WIFEXITED(status)) {
- pr_err(gettext("cache fsck did not exit"));
- return (1);
- }
-
- if (WEXITSTATUS(status) != 0) {
- pr_err(gettext("cache fsck mount failed"));
- return (1);
- }
- }
- return (0);
-}
-
-/*
- *
- * record_mount
- *
- * Description:
- * Records mount information in a file in the fscache directory.
- * Arguments:
- * Returns:
- * Preconditions:
- */
-
-void
-record_mount(char *mntp, char *specp, char *backfsp, char *backfstypep,
- char *cachedirp, char *cacheidp, char *optionp, char *reducep)
-{
- char buf[MAXPATHLEN*2];
- FILE *fout;
- time_t tval;
-
- tval = time(NULL);
-
- /* this file is < 2GB */
- sprintf(buf, "%s/%s/%s", cachedirp, cacheidp, CACHEFS_MNT_FILE);
- fout = fopen(buf, "w");
- if (fout == NULL) {
- pr_err(gettext("could not open %s, %d"), buf, errno);
- return;
- }
-
- fprintf(fout, "cachedir: %s\n", cachedirp);
- fprintf(fout, "mnt_point: %s\n", mntp);
- if (specp) {
- fprintf(fout, "special: %s\n", specp);
- }
- if (backfsp)
- fprintf(fout, "backpath: %s\n", backfsp);
- fprintf(fout, "backfstype: %s\n", backfstypep);
- fprintf(fout, "cacheid: %s\n", cacheidp);
- fprintf(fout, "cachefs_options: %s\n", optionp);
- if (reducep)
- fprintf(fout, "backfs_options: %s\n", reducep);
- fprintf(fout, "mount_time: %u\n", tval);
-
- fclose(fout);
-}
-
-int
-daemon_notify(char *cachedirp, char *cacheidp)
-{
- CLIENT *clnt;
- enum clnt_stat retval;
- int ret;
- int xx;
- int result;
- char *hostp;
- struct utsname info;
- struct cachefsd_fs_mounted args;
-
- /* get the host name */
- xx = uname(&info);
- if (xx == -1) {
- pr_err(gettext("cannot get host name, errno %d"), errno);
- return (1);
- }
- hostp = info.nodename;
-
- /* creat the connection to the daemon */
- clnt = clnt_create(hostp, CACHEFSDPROG, CACHEFSDVERS, "local");
- if (clnt == NULL) {
- pr_err(gettext("cachefsd is not running"));
- return (1);
- }
-
- args.mt_cachedir = cachedirp;
- args.mt_cacheid = cacheidp;
- retval = cachefsd_fs_mounted_1(&args, NULL, clnt);
- if (retval != RPC_SUCCESS) {
- clnt_perror(clnt, gettext("cachefsd is not responding"));
- clnt_destroy(clnt);
- return (1);
- }
-
- ret = 0;
-
- clnt_destroy(clnt);
-
- return (ret);
-}
-
-/* returns 0 if the server is alive, -1 if an error */
-int
-pingserver(char *backmntp)
-{
- CLIENT *clnt;
- static struct timeval TIMEOUT = { 25, 0 };
- enum clnt_stat retval;
- int ret;
- int xx;
- char *hostp;
- char buf[MAXPATHLEN];
- char *pc;
-
- /* get the host name */
- strcpy(buf, backmntp);
- pc = strchr(buf, ':');
- if (pc == NULL) {
- /* no host name, pretend it works */
- return (0);
- }
- *pc = '\0';
- hostp = buf;
-
- /* create the connection to the mount daemon */
- clnt = clnt_create(hostp, NFS_PROGRAM, NFS_VERSION, "udp");
- if (clnt == NULL) {
- return (-1);
- }
-
- ret = 0;
-
- /* see if the mountd responds */
- retval = clnt_call(clnt, 0, xdr_void, NULL, xdr_void, NULL,
- TIMEOUT);
- if (retval != RPC_SUCCESS) {
- ret = -1;
- }
-
- clnt_destroy(clnt);
-
- return (ret);
-}
-
-/*
- * first_time_ab : first time after boot - returns non-zero value
- * if the cachedir is being used for the first time
- * after the system reboot, otherwise zero.
- */
-int
-first_time_ab(char *buf)
-{
- struct stat sinfo;
- char name[MAXPATHLEN];
- int ufd;
- time32_t btime;
-
- sprintf(name, "%s/%s", buf, CACHEFS_UNMNT_FILE);
- if (stat(name, &sinfo) != 0)
- return (1);
- if (sinfo.st_size == 0)
- return (1);
- if ((ufd = open(name, O_RDONLY)) == -1)
- return (1);
- if (read(ufd, &btime, sizeof (time32_t)) == -1)
- return (1);
- close(ufd);
- if (get_boottime() != btime)
- return (1);
- return (0);
-}
-
-/*
- * cachefs_get_back_nfsvers
- *
- * Returns: nfs version
- *
- * Params:
- * cfs_backfs - backfile system mountpoint
- * nomnttab - mnttab entry does not exist
- *
- * Uses the kstat interface to extract the nfs version for
- * the mount.
- */
-uint32_t
-cachefs_get_back_nfsvers(char *cfs_backfs, int nomnttab)
-{
- kstat_ctl_t *kc = NULL;
- FILE *mnttab = NULL;
- struct extmnttab mnt;
- kstat_t *ksp;
- dev_t my_fsid = NODEV;
- struct mntinfo_kstat mik;
- uint32_t nfsvers = 0;
- struct stat64 st;
-
- /*
- * Initialize kernel statistics facility.
- */
- if ((kc = kstat_open()) == NULL) {
- pr_err(gettext("kstat_open() can't open /dev/kstat: %s"),
- strerror(errno));
- goto end;
- }
-
- /*
- * Locate the mount information in the mnttab if the nomnttab
- * flag is not set, otherwise look for the entry by doing
- * stat'ting the mountpoint.
- */
- if (!nomnttab) {
- if ((mnttab = fopen(MNTTAB, "r")) == NULL) {
- pr_err(gettext("can't open /etc/mnttab: %s"),
- strerror(errno));
- goto end;
- }
-
- while (getextmntent(mnttab, &mnt, sizeof (mnt)) != -1) {
- if (mnt.mnt_mountp == NULL ||
- strcmp(cfs_backfs, mnt.mnt_mountp) != 0) {
- continue;
- }
- my_fsid = makedev(mnt.mnt_major, mnt.mnt_minor);
- break;
- }
- }
-
- if (my_fsid == NODEV) {
- if (stat64(cfs_backfs, &st) == -1) {
- pr_err(gettext("can't stat mountpoint: %s"),
- strerror(errno));
- goto end;
- } else {
- my_fsid = st.st_dev;
- }
-
- }
-
- /*
- * Walk the kstat control structures to locate the
- * structure that describes the nfs module/mntinfo
- * statistics for the mounted backfilesystem.
- */
- for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
-
- if (ksp->ks_type != KSTAT_TYPE_RAW)
- continue;
- if (strcmp(ksp->ks_module, "nfs") != 0)
- continue;
- if (strcmp(ksp->ks_name, "mntinfo") != 0)
- continue;
- if ((my_fsid & MAXMIN) != ksp->ks_instance)
- continue;
-
- /*
- * At this point we have located the
- * kstat info for the mount, read the
- * statistics and return version info.
- */
- if (kstat_read(kc, ksp, &mik) == -1) {
- pr_err(gettext("kstat_read() can't read %s/%s: %s"),
- ksp->ks_module, ksp->ks_name, strerror(errno));
- goto end;
- }
-
- nfsvers = mik.mik_vers;
- break;
- }
-
-end:
- if (kc)
- kstat_close(kc);
- if (mnttab)
- fclose(mnttab);
-
- return (nfsvers);
-}
-
-/*
- * cfs_nfsv4_build_opts
- *
- * Returns: 0 on success, -1 on failure
- *
- * Params:
- * optionp - original option pointer
- * cfs_nfsv4ops - modified options for nfsv4 cachefs mount
- *
- * Parse the comma delimited set of options specified by optionp
- * and clean out options that we don't want to use with NFSv4.
- */
-int
-cfs_nfsv4_build_opts(char *optionp, char *cfs_nfsv4ops)
-{
- char *optstrp;
- char *strp;
- char *savep;
- char *valp;
- uint32_t first = TRUE;
-
- /* Make a copy of the options so we can modify it */
- optstrp = strp = strdup(optionp);
- if (strp == NULL) {
- pr_err(gettext("out of memory"));
- return (-1);
- }
-
- /* Parse the options, cfs_nfsv4ops is initialized in main */
- while (*strp) {
- savep = strp;
- switch (getsubopt(&strp, cfs_opts, &valp)) {
-
- /* Ignore options that set cfs option flags */
- case CFSOPT_WRITEAROUND:
- case CFSOPT_NONSHARED:
- case CFSOPT_NOCONST:
- case CFSOPT_CODCONST:
- case CFSOPT_LOCALACCESS:
- case CFSOPT_NOSETSEC:
- case CFSOPT_LLOCK:
- case CFSOPT_SLIDE:
- case CFSOPT_DISCONNECTABLE:
- case CFSOPT_SNR:
- case CFSOPT_NOFILL:
- case CFSOPT_SOFT:
- break;
-
- default:
- /*
- * Copy in option for cachefs nfsv4 mount.
- */
- snprintf(cfs_nfsv4ops, MAX_MNTOPT_STR,
- "%s%s%s", cfs_nfsv4ops, first ? "" : ",",
- savep);
- first = FALSE;
- break;
- }
- }
- free(optstrp);
-
- return (0);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/share/Makefile b/usr/src/cmd/fs.d/cachefs/share/Makefile
deleted file mode 100644
index 665482f321..0000000000
--- a/usr/src/cmd/fs.d/cachefs/share/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# cmd/fs.d/cachefs/share
-#
-
-FSTYPE= cachefs
-LIBPROG= share
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= $(PROGSRCS:%.c=%.o)
-
-PROGSRCS= $(LIBPROG:%=%.c)
-
-$(LIBPROG): $(PROGOBJS)
- $(LINK.c) -o $@ $(PROGOBJS)
- $(POST_PROCESS)
-
-clean:
- $(RM) $(PROGOBJS) $(LIBPROG)
diff --git a/usr/src/cmd/fs.d/cachefs/share/share.c b/usr/src/cmd/fs.d/cachefs/share/share.c
deleted file mode 100644
index 62ee4bdd1a..0000000000
--- a/usr/src/cmd/fs.d/cachefs/share/share.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * cachefs share - dummy utility to accomodate cachefs inclusion in
- * /etc/dfs/fstypes
- */
-#include <stdio.h>
-#include <libintl.h>
-
-int
-main(int argc, char **argv)
-{
- fprintf(stderr, gettext("cachefs share is not supported.\n"));
- return(1);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/umount/Makefile b/usr/src/cmd/fs.d/cachefs/umount/Makefile
deleted file mode 100644
index 3002f5b816..0000000000
--- a/usr/src/cmd/fs.d/cachefs/umount/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/fs.d/cachefs/umount
-#
-
-FSTYPE= cachefs
-LIBPROG= umount
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= umount.o $(FSLIB)
-
-include ../Makefile.cachefs
-
-CPPFLAGS += -I../..
-LDLIBS += -lnsl
-
-$(LIBPROG) : $(CFSLIB)
-
-$(PROGOBJS) : $(CACHEFSDIR)/subr.h $(CACHEFSDIR)/cachefsd.h
diff --git a/usr/src/cmd/fs.d/cachefs/umount/umount.c b/usr/src/cmd/fs.d/cachefs/umount/umount.c
deleted file mode 100644
index d2718f01e0..0000000000
--- a/usr/src/cmd/fs.d/cachefs/umount/umount.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * 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
- */
-/*
- * -----------------------------------------------------------------
- *
- * umount.c
- *
- * CFS specific umount command.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <wait.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/fs/cachefs_fs.h>
-#include <fslib.h>
-#include <sys/utsname.h>
-#include <rpc/rpc.h>
-#include "../common/subr.h"
-#include "../common/cachefsd.h"
-
-/* forward references */
-void pr_err(char *fmt, ...);
-void usage(char *msgp);
-int daemon_unmount(char *mntptp, int);
-
-/*
- *
- * main
- *
- * Description:
- * Main routine for the cfs umount program.
- * Arguments:
- * argc number of command line arguments
- * argv list of command line arguments
- * Returns:
- * Returns 0 for success or 1 if an error occurs.
- * Preconditions:
- */
-
-int
-main(int argc, char **argv)
-{
- char *strp;
- int xx;
- int ret;
- struct mnttab mget;
- struct mnttab mref;
- FILE *finp;
- char mnt_front[PATH_MAX];
- char mnt_back[PATH_MAX];
- char *p, mnt_frontns[PATH_MAX];
- pid_t pid;
- int stat_loc;
- char *cachedirp, *s;
- int ufd, c;
- int flag = 0;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /*
- * Set options
- */
- while ((c = getopt(argc, argv, "f")) != EOF) {
- switch (c) {
- case 'f':
- flag |= MS_FORCE; /* forced unmount is desired */
- break;
- default:
- usage("Incorrect number of arguments specified");
- return (1);
- }
- }
- if (flag & MS_FORCE)
- strcpy(mnt_front, argv[2]);
- else
- strcpy(mnt_front, argv[1]);
- mnt_back[0] = '\0';
-
- if (strlen(argv[1]) >= (size_t)PATH_MAX) {
- pr_err(gettext("name too long"));
- return (1);
- }
-
- /*
- * An unmount from autofs may have a
- * space appended to the path.
- * Trim it off before attempting to
- * match the mountpoint in mnttab
- */
- strcpy(mnt_frontns, mnt_front);
- p = &mnt_frontns[strlen(mnt_frontns) - 1];
- if (*p == ' ')
- *p = '\0';
-
- /* get the mount point and the back file system mount point */
- finp = fopen(MNTTAB, "r");
- if (finp) {
- mntnull(&mref);
- mref.mnt_mountp = mnt_frontns;
- mref.mnt_fstype = "cachefs";
- ret = getmntany(finp, &mget, &mref);
-
- cachedirp = (char *)malloc(strlen(mget.mnt_special) + 1);
- strcpy(cachedirp, mget.mnt_special);
- /*
- * AutoClient mounts do not have .cfs_mnt_points string in
- * them, so strstr would return NULL. So .cfs_unmnt file
- * is not updated.
- */
- if ((s = strstr(cachedirp, ".cfs_mnt_points")) != NULL) {
- time32_t btime;
-
- xx = -1;
- cachedirp[s-cachedirp] = '\0';
- strcat(cachedirp, CACHEFS_UNMNT_FILE);
- if ((ufd = open(cachedirp, O_WRONLY|O_CREAT|O_TRUNC,
- 0600)) > 0) {
- if ((btime = get_boottime()) != -1)
- xx = write(ufd, &btime, sizeof (time32_t));
- close(ufd);
- }
- if (xx < 0)
- pr_err(gettext(".cfs_unmnt error"));
- }
-
- if (ret != -1) {
- if (mget.mnt_special)
- strcpy(mnt_back, mget.mnt_special);
- } else {
- mref.mnt_special = mref.mnt_mountp;
- mref.mnt_mountp = NULL;
- rewind(finp);
- ret = getmntany(finp, &mget, &mref);
- if (ret != -1) {
- strcpy(mnt_front, mget.mnt_mountp);
- if (mget.mnt_special)
- strcpy(mnt_back, mget.mnt_special);
- } else {
- pr_err(gettext("warning: %s not in mnttab"),
- mref.mnt_special);
- }
- }
- fclose(finp);
- }
-
- /* try to get the daemon to unmount this file system for us */
- xx = daemon_unmount(mnt_front, flag);
- if (xx == ENOTSUP)
- return (1);
- if (xx == EBUSY) {
- pr_err(gettext("%s %s"), mnt_front, strerror(xx));
- return (1);
- }
- if (xx == EIO) {
- /* try to unmount the file system directly */
- if (umount2(mnt_front, flag) == -1) {
- pr_err(gettext("%s %s"), mnt_front, strerror(errno));
- return (1);
- }
- }
-
- /* if we do not know the name of the back file system mount point */
- if (mnt_back[0] == '\0') {
- /* all done */
- return (0);
- }
-
- /*
- * If the back file system was mounted on a directory with a
- * parent name of BACKMNT_NAME then we assume that we
- * mounted it and that it is okay to try to umount it.
- */
- if (strstr(mnt_back, BACKMNT_NAME) == NULL)
- return (0);
-
- /* if no back file system mounted */
- if (strcmp(mnt_back, "nobackfs") == 0)
- return (0);
-
- /* fork */
- if ((pid = fork()) == -1) {
- pr_err(gettext("could not fork %s"), strerror(errno));
- return (1);
- }
-
- /* if the child */
- if (pid == 0) {
- /* invoke the umount command on the back file system */
- xx = execl("/sbin/umount", "/sbin/umount", mnt_back, NULL);
- pr_err(gettext("could not exec /sbin/umount"
- " on back file system %s"), strerror(errno));
- }
-
- /* else if the parent */
- else {
- /* wait for the child to exit */
- if (wait(&stat_loc) == -1) {
- pr_err(gettext("wait failed %s"), strerror(errno));
- return (1);
- }
-
- if (!WIFEXITED(stat_loc)) {
- pr_err(gettext("back umount did not exit"));
- return (1);
- }
-
- xx = WEXITSTATUS(stat_loc);
- if (xx) {
- pr_err(gettext("back umount failed"));
- return (xx);
- }
- }
-
- /* delete the back file system mount point since we created it */
- rmdir(mnt_back);
-
- return (xx);
-}
-
-/*
- *
- * pr_err
- *
- * Description:
- * Prints an error message to stderr.
- * Arguments:
- * fmt printf style format
- * ... arguments for fmt
- * Returns:
- * Preconditions:
- * precond(fmt)
- */
-
-void
-pr_err(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void) fprintf(stderr, gettext("umount -F cachefs: "));
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
- va_end(ap);
-}
-
-/*
- *
- * usage
- *
- * Description:
- * Prints a usage message.
- * Arguments:
- * An optional additional message to be displayed.
- * Returns:
- * Preconditions:
- */
-
-void
-usage(char *msgp)
-{
- if (msgp)
- pr_err(gettext("%s"), msgp);
- fprintf(stderr, gettext("Usage: umount -F cachefs dir"));
-}
-
-/*
- *
- * daemon_unmount
- *
- * Description:
- * Notifies the cachefsd of an unmount request.
- * Arguments:
- * Mount point to unmount.
- * Returns:
- * Returns 0 if the cachefsd unmounted the file system
- * EIO if should try unmount directly
- * EBUSY if did not unmount because busy
- * EAGAIN if umounted but should not unmount nfs mount
- *
- * Preconditions:
- * precond(mntptp)
- */
-
-int
-daemon_unmount(char *mntptp, int flag)
-{
- CLIENT *clnt;
- enum clnt_stat retval;
- int xx;
- int result;
- char *hostp;
- struct utsname info;
- static struct timeval TIMEOUT = { 60*60, 0 };
- static struct timeval create_timeout = { 5, 0};
- struct cachefsd_fs_unmounted uargs;
-
- /* get the host name */
- xx = uname(&info);
- if (xx == -1) {
- pr_err(gettext("cannot get host name, errno %d"), errno);
- return (EIO);
- }
- hostp = info.nodename;
- uargs.mntpt = mntptp;
- uargs.flag = flag;
-
- /* creat the connection to the daemon */
- clnt = clnt_create_timed(hostp, CACHEFSDPROG, CACHEFSDVERS, "local",
- &create_timeout);
- if (clnt == NULL) {
- pr_err(gettext("cachefsd is not running"));
- return (EIO);
- }
- clnt_control(clnt, CLSET_TIMEOUT, (char *)&TIMEOUT);
-
- retval = cachefsd_fs_unmounted_1(&uargs, &result, clnt);
- if (retval != RPC_SUCCESS) {
- clnt_perror(clnt, gettext("cachefsd is not responding"));
- clnt_destroy(clnt);
- return (EIO);
- }
-
- clnt_destroy(clnt);
-
- return (result);
-}
diff --git a/usr/src/cmd/fs.d/cachefs/unshare/Makefile b/usr/src/cmd/fs.d/cachefs/unshare/Makefile
deleted file mode 100644
index 0ec97437e7..0000000000
--- a/usr/src/cmd/fs.d/cachefs/unshare/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1999 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-# cmd/fs.d/cachefs/unshare
-#
-
-FSTYPE= cachefs
-LIBPROG= unshare
-ATTMK= $(LIBPROG)
-
-include ../../Makefile.fstype
-
-PROGOBJS= $(PROGSRCS:%.c=%.o)
-
-PROGSRCS= $(LIBPROG:%=%.c)
-
-$(LIBPROG): $(PROGOBJS)
- $(LINK.c) -o $@ $(PROGOBJS)
- $(POST_PROCESS)
-
-clean:
- $(RM) $(PROGOBJS) $(LIBPROG)
diff --git a/usr/src/cmd/fs.d/cachefs/unshare/unshare.c b/usr/src/cmd/fs.d/cachefs/unshare/unshare.c
deleted file mode 100644
index e63091926c..0000000000
--- a/usr/src/cmd/fs.d/cachefs/unshare/unshare.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * cachefs unshare - dummy utility to accomodate cachefs inclusion in
- * /etc/dfs/fstypes
- */
-#include <stdio.h>
-#include <libintl.h>
-
-int
-main(int argc, char **argv)
-{
- fprintf(stderr, gettext("cachefs unshare is not supported.\n"));
- return(1);
-}
diff --git a/usr/src/cmd/fs.d/df.xcl b/usr/src/cmd/fs.d/df.xcl
index 1097220b7a..fe279a1b07 100644
--- a/usr/src/cmd/fs.d/df.xcl
+++ b/usr/src/cmd/fs.d/df.xcl
@@ -85,7 +85,6 @@ msgid "%s -F %s "
msgid " %s"
msgid "/sbin/sh"
msgid "yes"
-msgid "cachefs"
msgid "fork"
msgid "exec"
msgid "r+b"
diff --git a/usr/src/cmd/fs.d/mount.c b/usr/src/cmd/fs.d/mount.c
index 5d73ba8a30..04a867b235 100644
--- a/usr/src/cmd/fs.d/mount.c
+++ b/usr/src/cmd/fs.d/mount.c
@@ -27,7 +27,7 @@
* Use is subject to license terms.
*/
/*
- * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdio.h>
@@ -139,15 +139,6 @@ int exitcode;
int aflg, cflg, fflg, Fflg, gflg, oflg, pflg, rflg, vflg, Vflg, mflg, Oflg,
dashflg, questflg, dflg, qflg;
-/*
- * Currently, mounting cachefs instances simultaneously uncovers various
- * problems. For the short term, we serialize cachefs activity while we fix
- * these cachefs bugs.
- */
-#define CACHEFS_BUG
-#ifdef CACHEFS_BUG
-int cachefs_running; /* parallel cachefs not supported yet */
-#endif
/*
* Each vfsent_t describes a vfstab entry. It is used to manage and cleanup
@@ -1295,15 +1286,6 @@ do_mounts(void)
while (nrun >= maxrun && (dowait() != -1)) /* throttle */
;
-#ifdef CACHEFS_BUG
- if (vp->v.vfs_fstype &&
- (strcmp(vp->v.vfs_fstype, "cachefs") == 0)) {
- while (cachefs_running && (dowait() != -1))
- ;
- cachefs_running = 1;
- }
-#endif
-
if ((child = fork()) == -1) {
perror("fork");
cleanup(-1);
@@ -1474,11 +1456,6 @@ cleanupkid(pid_t pid, int wstat)
lofsfail++;
}
-#ifdef CACHEFS_BUG
- if (vp->v.vfs_fstype && (strcmp(vp->v.vfs_fstype, "cachefs") == 0))
- cachefs_running = 0;
-#endif
-
vp->exitcode = ret;
return (ret);
}
diff --git a/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c b/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
index 50b597d0f8..64381da71e 100644
--- a/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
+++ b/usr/src/cmd/fs.d/nfs/nfsstat/nfsstat.c
@@ -25,6 +25,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -1115,33 +1116,9 @@ mi_print(void)
list = mrp;
}
- /*
- * If something got ignored, go to the beginning of the mnttab
- * and look for the cachefs entries since they are the one
- * causing this. The mount point saved for the ignored entries
- * is matched against the special to get the actual mount point.
- * We are interested in the acutal mount point so that the output
- * look nice too.
- */
- if (ignored) {
- rewind(mt);
- resetmnttab(mt);
- while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) {
-
- /* ignore non "cachefs" */
- if (strcmp(m.mnt_fstype, MNTTYPE_CACHEFS) != 0)
- continue;
+ (void) fclose(mt);
- for (mrp = list; mrp; mrp = mrp->next) {
- if (mrp->ig_path == 0)
- continue;
- if (strcmp(mrp->ig_path, m.mnt_special) == 0) {
- mrp->ig_path = 0;
- (void) strcpy(mrp->my_dir,
- m.mnt_mountp);
- }
- }
- }
+ if (ignored) {
/*
* Now ignored entries which do not have
* the my_dir initialized are really ignored; This never
@@ -1157,9 +1134,6 @@ mi_print(void)
}
}
- (void) fclose(mt);
-
-
for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
int i;
diff --git a/usr/src/cmd/fs.d/nfs/share/fstypes b/usr/src/cmd/fs.d/nfs/share/fstypes
index 53c17c5ac2..78d17689d5 100644
--- a/usr/src/cmd/fs.d/nfs/share/fstypes
+++ b/usr/src/cmd/fs.d/nfs/share/fstypes
@@ -1,4 +1,3 @@
nfs NFS Utilities
autofs AUTOFS Utilities
-cachefs CACHEFS Utilities
smbfs CIFS Utilities
diff --git a/usr/src/cmd/fs.d/nfs/svc/nfs-client b/usr/src/cmd/fs.d/nfs/svc/nfs-client
index 4a52cc9fe7..4ad4654a33 100644
--- a/usr/src/cmd/fs.d/nfs/svc/nfs-client
+++ b/usr/src/cmd/fs.d/nfs/svc/nfs-client
@@ -23,8 +23,8 @@
#
# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
-#ident "%Z%%M% %I% %E% SMI"
#
# Start/stop client NFS service
@@ -34,7 +34,6 @@
stop_nfsclnt()
{
- /sbin/umountall -F cachefs
/sbin/umountall -F nfs
}
@@ -42,7 +41,6 @@ case "$1" in
'start')
/sbin/mountall -F nfs
- /sbin/mountall -F cachefs
/sbin/swapadd
;;
diff --git a/usr/src/cmd/fs.d/umount.c b/usr/src/cmd/fs.d/umount.c
index da08a82432..a50665c9a0 100644
--- a/usr/src/cmd/fs.d/umount.c
+++ b/usr/src/cmd/fs.d/umount.c
@@ -21,6 +21,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -79,17 +80,6 @@ char resolve[MAXPATHLEN];
static char ibuf[BUFSIZ];
/*
- * Currently, mounting cachefs's simultaneous uncovers various problems.
- * For the short term, we serialize cachefs activity while we fix
- * these cachefs bugs.
- */
-#define CACHEFS_BUG
-#ifdef CACHEFS_BUG
-#include <sys/fs/cachefs_fs.h> /* for BACKMNT_NAME */
-int cachefs_running; /* parallel cachefs not supported yet */
-#endif
-
-/*
* The basic mount struct that describes an mnttab entry.
* It is used both in an array and as a linked list elem.
*/
@@ -818,23 +808,6 @@ do_umounts(mountent_t **mntarray)
while (nrun >= maxrun && (dowait() != -1)) /* throttle */
;
-#ifdef CACHEFS_BUG
- /*
- * If this is the back file system, then let cachefs/umount
- * unmount it.
- */
- if (strstr(mp->ment.mnt_mountp, BACKMNT_NAME))
- continue;
-
-
- if (mp->ment.mnt_fstype &&
- (strcmp(mp->ment.mnt_fstype, "cachefs") == 0)) {
- while (cachefs_running && (dowait() != -1))
- ;
- cachefs_running = 1;
- }
-#endif
-
if ((pid = fork()) == -1) {
perror("fork");
cleanup(-1);
@@ -944,12 +917,6 @@ dowait(void)
(strcmp(mp->ment.mnt_fstype, MNTTYPE_LOFS) == 0))
lofscnt--;
-#ifdef CACHEFS_BUG
- if (mp->ment.mnt_fstype &&
- (strcmp(mp->ment.mnt_fstype, "cachefs") == 0))
- cachefs_running = 0;
-#endif
-
return (ret);
}
diff --git a/usr/src/cmd/initpkg/init.d/Makefile b/usr/src/cmd/initpkg/init.d/Makefile
index b8ef85b083..d1665cdf79 100644
--- a/usr/src/cmd/initpkg/init.d/Makefile
+++ b/usr/src/cmd/initpkg/init.d/Makefile
@@ -32,7 +32,6 @@ i386_PROG=
PROG= \
README \
- cachefs.daemon \
sysetup \
uucp \
$($(MACH)_PROG)
diff --git a/usr/src/cmd/initpkg/init.d/cachefs.daemon b/usr/src/cmd/initpkg/init.d/cachefs.daemon
deleted file mode 100644
index d6e8734186..0000000000
--- a/usr/src/cmd/initpkg/init.d/cachefs.daemon
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/sbin/sh
-#
-# 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.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-# If /usr is a cachefs file system then start up the
-# cachefsd for it and any other cachefs file system.
-
-if [ "x`/usr/lib/fs/cachefs/cfsfstype /usr/lib 2>/dev/null`" != xcachefs ]; then
- exit 0
-fi
-
-rpcprogram=100235
-rpcvers=1
-cachefsd_fmri="network/rpc-${rpcprogram}_${rpcvers}/rpc_ticotsord:ticotsord"
-cachefsd=/usr/lib/fs/cachefs/cachefsd
-inetconf=/etc/inet/inetd.conf
-svcfound=no
-
-enabled=`/usr/bin/svcprop -p general/enabled $cachefsd_fmri 2>/dev/null`
-if [ $? != 0 ]; then
- echo "WARNING: cachefs service not present" >& 2
- exit 1
-fi
-if [ "$enabled" != "true" ]; then
- echo "WARNING: cachefs service not enabled" >& 2
- exit 1
-fi
-
-for i in 1 2 3 4 5; do
- if /usr/bin/rpcinfo -l `/usr/bin/uname -n` $rpcprogram $rpcvers \
- 2>/dev/null | /usr/bin/grep 100235 >/dev/null 2>&1; then
- svcfound=yes
- break
- fi
-
- sleep 1
-done
-
-if [ $svcfound = no ]; then
- echo "WARNING: Timed out waiting for cachefs service to register" >&2
-fi
-
-/usr/lib/fs/cachefs/cfsadmin -C /dev/null 2>/dev/null
-
-/usr/lib/fs/cachefs/cachefspack /usr/lib/fs/cachefs \
- /etc/netconfig /etc/vfstab /etc/inittab /etc/cachefstab
diff --git a/usr/src/cmd/initpkg/mountall.sh b/usr/src/cmd/initpkg/mountall.sh
index 56f2798e18..fa59a20a41 100644
--- a/usr/src/cmd/initpkg/mountall.sh
+++ b/usr/src/cmd/initpkg/mountall.sh
@@ -24,6 +24,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
# All Rights Reserved
@@ -409,7 +410,7 @@ if [ -n "$FSType" ]; then
exit
fi
-# Some remote filesystems (e.g. cachefs or autofs) shouldn't be be mounted
+# Some remote filesystems (e.g. autofs) shouldn't be mounted
# with mountall, so the list here is explicit (not from /etc/dfs/fstypes)
if [ "$RFLAG" ]; then
/sbin/mount -a -F nfs
diff --git a/usr/src/cmd/initpkg/rc2.d/mk.rc2.d.sh b/usr/src/cmd/initpkg/rc2.d/mk.rc2.d.sh
index 7ea11a79fd..c9dedbbb28 100644
--- a/usr/src/cmd/initpkg/rc2.d/mk.rc2.d.sh
+++ b/usr/src/cmd/initpkg/rc2.d/mk.rc2.d.sh
@@ -23,12 +23,12 @@
# All Rights Reserved
#
# Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
COMMON_STARTLST="\
20sysetup \
-70uucp \
-73cachefs.daemon"
+70uucp"
INSDIR=${ROOT}/etc/rc2.d
diff --git a/usr/src/cmd/stmsboot/mpxio-upgrade b/usr/src/cmd/stmsboot/mpxio-upgrade
index 3e6b875257..a959c554ed 100644
--- a/usr/src/cmd/stmsboot/mpxio-upgrade
+++ b/usr/src/cmd/stmsboot/mpxio-upgrade
@@ -21,6 +21,7 @@
#
#
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
. /lib/svc/share/fs_include.sh
@@ -173,59 +174,39 @@ mpxio_mount_usr()
;;
esac
- if [ "$fstype" = "cachefs" ]; then
- # Mount read-only without the cache.
- case "$mntopts" in
- *backfstype=nfs*)
- cfsbacktype=nfs
- ;;
- *backfstype=hsfs*)
- cfsbacktype=hsfs
- ;;
- *)
- cecho 'stmsboot: invalid vfstab entry for /usr'
- cfsbacktype=nfs
- ;;
- esac
- # see the comment below for /dev/null
- $MOUNT -m -F $cfsbacktype -o ro $new_special $mountp \
->/dev/null 2>&1
- ret_val=$?
+ #
+ # Must use -o largefiles here to ensure the read-only
+ # mount does not fail as a result of having a large
+ # file present on /usr.
+ #
+ if [ "$mntopts" = "-" ]; then
+ mntopts='ro,largefiles'
else
- #
- # Must use -o largefiles here to ensure the read-only
- # mount does not fail as a result of having a large
- # file present on /usr.
- #
- if [ "$mntopts" = "-" ]; then
- mntopts='ro,largefiles'
- else
- checkopt largefiles $mntopts
- if [ "$option" != "largefiles" ]; then
- mntopts="largefiles,$mntopts"
- fi
+ checkopt largefiles $mntopts
+ if [ "$option" != "largefiles" ]; then
+ mntopts="largefiles,$mntopts"
+ fi
- checkopt ro $mntopts
- if [ "$option" != "ro" ]; then
- mntopts="ro,$mntopts"
- fi
+ checkopt ro $mntopts
+ if [ "$option" != "ro" ]; then
+ mntopts="ro,$mntopts"
+ fi
- # Requesting logging on a read-only mount
- # causes errors to be displayed, so remove
- # "logging" from the list of options.
- checkopt logging $mntopts
- if [ "$option" = "logging" ]; then
- mntopts="$otherops"
- fi
+ # Requesting logging on a read-only mount
+ # causes errors to be displayed, so remove
+ # "logging" from the list of options.
+ checkopt logging $mntopts
+ if [ "$option" = "logging" ]; then
+ mntopts="$otherops"
fi
+ fi
- # In case of a manual restart of the service, mount
- # will emit messages if /usr is already mounted.
- # So redirect the output to /dev/null.
- $MOUNT -m -F $fstype -o $mntopts $new_special /usr \
+ # In case of a manual restart of the service, mount
+ # will emit messages if /usr is already mounted.
+ # So redirect the output to /dev/null.
+ $MOUNT -m -F $fstype -o $mntopts $new_special /usr \
>/dev/null 2>&1
- ret_val=$?
- fi
+ ret_val=$?
if [ $ret_val -eq 0 ]; then
usrmounted=1
fi
diff --git a/usr/src/cmd/stmsboot/stmsboot.sh b/usr/src/cmd/stmsboot/stmsboot.sh
index fac9e65f7e..313dcaa676 100644
--- a/usr/src/cmd/stmsboot/stmsboot.sh
+++ b/usr/src/cmd/stmsboot/stmsboot.sh
@@ -21,6 +21,7 @@
#
#
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
#
PATH=/usr/bin:/usr/sbin:$PATH; export PATH
@@ -549,12 +550,8 @@ $STMSBOOTUTIL -i
if [ "$cmd" = "enable" -o "$cmd" = "disable" -o "$cmd" = "update" ]; then
- #
- # The bootup script doesn't work on cache-only-clients as the script
- # is executed before the plumbing for cachefs mounting of root is done.
- #
- if $MOUNT -v | $EGREP -s " on / type (nfs|cachefs) "; then
- gettext "This command option is not supported on systems with an nfs or cachefs mounted root filesystem.\n" 1>&2
+ if $MOUNT -v | $EGREP -s " on / type nfs "; then
+ gettext "This command option is not supported on systems with an nfs mounted root filesystem.\n" 1>&2
exit 1
fi
diff --git a/usr/src/cmd/svc/shell/smf_include.sh b/usr/src/cmd/svc/shell/smf_include.sh
index d0dc387246..77a1453cbb 100644
--- a/usr/src/cmd/svc/shell/smf_include.sh
+++ b/usr/src/cmd/svc/shell/smf_include.sh
@@ -22,6 +22,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
smf_present () {
@@ -134,7 +135,7 @@ smf_netstrategy () {
set -- `/sbin/netstrategy`
if [ $? -eq 0 ]; then
- [ "$1" = "nfs" -o "$1" = "cachefs" ] && \
+ [ "$1" = "nfs" ] && \
_INIT_NET_IF="$2" export _INIT_NET_IF
_INIT_NET_STRATEGY="$3" export _INIT_NET_STRATEGY
else
diff --git a/usr/src/cmd/svr4pkg/libinst/mntinfo.c b/usr/src/cmd/svr4pkg/libinst/mntinfo.c
index 67bba5165a..086762899c 100644
--- a/usr/src/cmd/svr4pkg/libinst/mntinfo.c
+++ b/usr/src/cmd/svr4pkg/libinst/mntinfo.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
@@ -105,11 +106,6 @@ struct fstable **fs_tab = NULL;
#define HOST_NM_LN MNT_LINE_MAX
-/* These cachefs definitions should be in mntent.h. Maybe some day. */
-#define MNTTYPE_CFS "cachefs"
-#define MNTOPT_BACKFSTYPE "backfstype"
-#define MNTTYPE_AUTO "autofs"
-
/*
* Utilities for getting filesystem information from the mount table.
*
@@ -227,7 +223,7 @@ get_server_host(uint32_t n)
if (n < fs_tab_used) {
(void) strcpy(hostname, fs_tab[n]->remote_name);
if ((host_end = strchr(hostname, ':')) == NULL) {
- if ((strcmp(fs_tab[n]->fstype, MNTTYPE_AUTO)) == NULL)
+ if ((strcmp(fs_tab[n]->fstype, MNTTYPE_AUTOFS)) == NULL)
return ("automounter");
else
return (fs_tab[n]->fstype);
@@ -714,7 +710,7 @@ construct_mt(struct mnttab *mt)
* allowed to mount ourself with "NFS", "NFS" must be remote.
* The automount will translate "nfs:self" to a lofs mount.
*/
- if (strcmp(mt->mnt_fstype, MNTTYPE_AUTO) == 0 ||
+ if (strcmp(mt->mnt_fstype, MNTTYPE_AUTOFS) == 0 ||
strcmp(mt->mnt_fstype, MNTTYPE_NFS) == 0 ||
is_remote_src(mt->mnt_special) == REAL_REMOTE)
nfte->remote = 1;
@@ -963,9 +959,6 @@ get_mntinfo(int map_client, char *vfstab_file)
/*
* We also skip the entry if the vfs_special
* path and the client_path are the same.
- * There's no need to mount it, it's just a
- * cachefs optimization that mounts a
- * directory over itself from this server.
*/
if ((is_remote == SELF_SERVE) &&
strcmp(path_part(vfs->vfs_special),
diff --git a/usr/src/lib/libefi/common/rdwr_efi.c b/usr/src/lib/libefi/common/rdwr_efi.c
index 83dc815fbe..5311515276 100644
--- a/usr/src/lib/libefi/common/rdwr_efi.c
+++ b/usr/src/lib/libefi/common/rdwr_efi.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright 2014 Toomas Soome <tsoome@me.com>
*/
@@ -55,7 +55,7 @@ static struct uuid_to_ptag {
{ EFI_VAR },
{ EFI_HOME },
{ EFI_ALTSCTR },
- { 0 }, /* CACHE (cachefs) is never used */
+ { 0 }, /* CACHE is never used */
{ EFI_RESERVED },
{ EFI_SYSTEM },
{ EFI_LEGACY_MBR },
diff --git a/usr/src/lib/libpkg/common/isdir.c b/usr/src/lib/libpkg/common/isdir.c
index 55b59d5e67..4589b0a56b 100644
--- a/usr/src/lib/libpkg/common/isdir.c
+++ b/usr/src/lib/libpkg/common/isdir.c
@@ -22,6 +22,7 @@
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -345,10 +346,9 @@ _InitRemoteFstypes(void)
if ((fp = fopen(REMOTE_FS_DBFILE, "r")) == NULL) {
/* no remote type database: use predefined remote types */
remoteFstypes = (char **)realloc(remoteFstypes,
- sizeof (char *) * (numRemoteFstypes+3));
+ sizeof (char *) * (numRemoteFstypes+2));
remoteFstypes[numRemoteFstypes++] = "nfs"; /* +1 */
remoteFstypes[numRemoteFstypes++] = "autofs"; /* +2 */
- remoteFstypes[numRemoteFstypes++] = "cachefs"; /* +3 */
return;
}
@@ -365,7 +365,6 @@ _InitRemoteFstypes(void)
*
* nfs NFS Utilities
* autofs AUTOFS Utilities
- * cachefs CACHEFS Utilities
*/
while (fgets(line_buf, sizeof (line_buf), fp) != NULL) {
@@ -375,13 +374,13 @@ _InitRemoteFstypes(void)
if (format[0] == '\0') {
/* create bounded format: %ns */
(void) snprintf(format, sizeof (format),
- "%%%ds", sizeof (buf)-1);
+ "%%%ds", sizeof (buf)-1);
}
(void) sscanf(line_buf, format, buf);
remoteFstypes = realloc(remoteFstypes,
- sizeof (char *) * (numRemoteFstypes+1));
+ sizeof (char *) * (numRemoteFstypes+1));
remoteFstypes[numRemoteFstypes++] = strdup(buf);
}
diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c
index 6ae73b9f3b..91502b6a2f 100644
--- a/usr/src/lib/libzonecfg/common/libzonecfg.c
+++ b/usr/src/lib/libzonecfg/common/libzonecfg.c
@@ -22,6 +22,7 @@
/*
* Copyright 2014 Gary Mills
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <libsysevent.h>
@@ -5817,8 +5818,7 @@ zonecfg_valid_fs_type(const char *type)
if (strcmp(type, "proc") == 0 ||
strcmp(type, "mntfs") == 0 ||
strcmp(type, "autofs") == 0 ||
- strncmp(type, "nfs", sizeof ("nfs") - 1) == 0 ||
- strcmp(type, "cachefs") == 0)
+ strncmp(type, "nfs", sizeof ("nfs") - 1) == 0)
return (B_FALSE);
/*
* The caller may do more detailed verification to make sure other
diff --git a/usr/src/lib/lvm/libmeta/common/meta_check.c b/usr/src/lib/lvm/libmeta/common/meta_check.c
index 8b32ed4c8e..c52b9b876d 100644
--- a/usr/src/lib/lvm/libmeta/common/meta_check.c
+++ b/usr/src/lib/lvm/libmeta/common/meta_check.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -66,7 +67,6 @@ static char *skip_these_mntents[] = {
"autofs",
"proc",
"tmpfs",
- "cachefs",
"rfs",
"fd",
"mntfs",
diff --git a/usr/src/lib/lvm/libmeta/common/meta_mount.c b/usr/src/lib/lvm/libmeta/common/meta_mount.c
index 968334d261..efaf7885cd 100644
--- a/usr/src/lib/lvm/libmeta/common/meta_mount.c
+++ b/usr/src/lib/lvm/libmeta/common/meta_mount.c
@@ -21,9 +21,9 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* return mount association with meta device
@@ -73,7 +73,6 @@ meta_get_mountp(
(strcmp(m.mnt_fstype, "autofs") == 0) ||
(strcmp(m.mnt_fstype, "proc") == 0) ||
(strcmp(m.mnt_fstype, "tmpfs") == 0) ||
- (strcmp(m.mnt_fstype, "cachefs") == 0) ||
(strcmp(m.mnt_fstype, "lofs") == 0) ||
(strcmp(m.mnt_fstype, "rfs") == 0) ||
(strcmp(m.mnt_fstype, "fd") == 0))
diff --git a/usr/src/man/man1/filesync.1 b/usr/src/man/man1/filesync.1
index b671a5b557..15b43119bc 100644
--- a/usr/src/man/man1/filesync.1
+++ b/usr/src/man/man1/filesync.1
@@ -1,9 +1,10 @@
'\" te
.\" Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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 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]
-.TH FILESYNC 1 "Nov 6, 2000"
+.TH FILESYNC 1 "Sep 8, 2015"
.SH NAME
filesync \- synchronize ordinary, directory or special files
.SH SYNOPSIS
@@ -19,7 +20,6 @@ filesync \- synchronize ordinary, directory or special files
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBfilesync\fR utility \fIsynchronizes\fR files between multiple computer
systems, typically a server and a portable computer. \fBfilesync\fR
@@ -40,8 +40,8 @@ There are two forms of the \fBfilesync\fR command. The first form of
\fBfilesync\fR is invoked without file arguments. This form of \fBfilesync\fR
reconciles differences between the files and systems specified in the
\fB$HOME/.packingrules\fR file. \fB$HOME/.packingrules\fR is a packing rules
-list for \fBfilesync\fR and \fBcachefspack\fR, and contains a list of files to
-be kept synchronized. See \fBpackingrules\fR(4) and \fBcachefspack\fR(1M).
+list for \fBfilesync\fR and contains a list of files to
+be kept synchronized. See \fBpackingrules\fR(4).
.sp
.LP
The second form of \fBfilesync\fR copies specific files from a directory on the
@@ -56,7 +56,6 @@ Multiple \fBfilesync\fR commands are cumulative (that is, the specified files
are added to the already existing packing rules file list). See \fBMultiple
filesync Commands\fR.
.SS "Reconciling and Synchronizing Files"
-.sp
.LP
\fBfilesync\fR synchronizes files between computer systems by performing the
following two tasks:
@@ -90,20 +89,17 @@ printed out, asking the user to resolve the conflict manually. See
\fBResolving filesync Conflicts\fR.
.RE
.SS "Resolving filesync Conflicts"
-.sp
.LP
In cases where files on both sides have changed, \fBfilesync\fR attempts to
determine which version should be chosen. If \fBfilesync\fR cannot
automatically determine which version should be selected, it prints out a
warning message and leaves the two incompatible versions of the file
unreconciled.
-.sp
.LP
In these cases, you must either resolve the differences manually, or tell
\fBfilesync\fR how to choose which file should win. Use the \fB-o\fR and
\fB-f\fR options to tell \fBfilesync\fR how to resolve conflicts (see
\fBOPTIONS\fR).
-.sp
.LP
Alternatively, for each conflicting file, you can examine the two versions,
determine which one should be kept, and manually bring the two versions into
@@ -111,17 +107,14 @@ agreement (by copying, deleting, or changing the ownership or protection to be
correct). You can then re-run \fBfilesync\fR to see whether or not any other
conflicts remain.
.SS "Packing Rules File"
-.sp
.LP
The packing rules file \fB$HOME/.packingrules\fR contains a list of files to be
kept synchronized. The syntax of this file is described in
\fBpackingrules\fR(4).
-.sp
.LP
The \fB$HOME/.packingrules\fR file is automatically created if users invoke
\fBfilesync\fR with filename arguments. By using \fBfilesync\fR options, users
can augment the packing rules in \fB$HOME/.packingrules\fR.
-.sp
.LP
Many users choose to create the packing rules file manually and edit it by
hand. Users can edit \fB$HOME/.packingrules\fR (using any editor) to
@@ -130,7 +123,6 @@ more powerful options that are not available from the command line (such as
\fBIGNORE\fR commands). It is much easier to enter complex wildcard expressions
by editing the \fB$HOME/.packingrules\fR file.
.SS "Baseline File"
-.sp
.LP
\fB$HOME/.filesync-base\fR is the \fBfilesync\fR baseline summary file.
\fBfilesync\fR uses the information in \fB$HOME/.filesync-base\fR to identify
@@ -139,7 +131,6 @@ process. Users do not create or edit the baseline file. It is created
automatically by \fBfilesync\fR and records the last known state of agreement
between all of the files being maintained.
.SS "Multiple filesync Commands"
-.sp
.LP
Over a period of time, the set of files you want to keep synchronized can
change. It is common, for instance, to want to keep files pertaining to only a
@@ -147,7 +138,6 @@ few active projects on your notebook. If you continue to keep files associated
with every project you have ever worked on synchronized, your notebook's disk
will fill up with old files. Each \fBfilesync\fR command will waste a lot of
time updating files you no longer care about.
-.sp
.LP
If you delete the files from your notebook, \fBfilesync\fR will want to perform
the corresponding deletes on the server, which would not be what you wanted.
@@ -165,17 +155,14 @@ want to delete.
Delete \fB$HOME/.packingrules\fR. Use the \fBfilesync\fR command to specify
the files that you want synchronized.
.RE
-.sp
.LP
Either way works, and you can choose the one that seems easiest to you. For
minor changes, it is probably easier to just edit \fB$HOME/.packingrules\fR.
For major changes it is probably easier to start from scratch.
-.sp
.LP
Once \fBfilesync\fR is no longer synchronizing a set of files, you can delete
them from your notebook without having any effect on the server.
.SS "Nomadic Machines"
-.sp
.LP
When using \fBfilesync\fR to keep files synchronized between nomadic machines
and a server, store the packing rules and baseline files on the nomadic
@@ -183,7 +170,6 @@ machines, not the server. If, when logged into your notebook, the \fBHOME\fR
environment variable does not normally point to a directory on your notebook,
you can use the \fBFILESYNC\fR environment variable to specify an alternate
location for the packing rules and baseline files.
-.sp
.LP
Each nomadic machine should carry its own packing rules and baseline file.
Incorrect file synchronization can result if a server carries a baseline file
@@ -191,14 +177,12 @@ and multiple nomadic machines attempt to reconcile against the server's
baseline file. In this case, a nomadic machine could be using a baseline file
that does not accurately describe the state of its files. This might result in
incorrect reconciliations.
-.sp
.LP
To safeguard against the dangers associated with a single baseline file being
shared by more than two machines, \fBfilesync\fR adds a default rule to each
new packing rules file. This default rule prevents the packing rules and
baseline files from being copied.
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
@@ -414,7 +398,6 @@ confirm these prompts.
.RE
.SH OPERANDS
-.sp
.LP
The following operands are supported:
.sp
@@ -481,7 +464,6 @@ switches).
.RE
.SH ENVIRONMENT VARIABLES
-.sp
.ne 2
.na
\fB\fBFILESYNC\fR\fR
@@ -505,7 +487,6 @@ itself (in most cases, U.S. English).
.RE
.SH EXIT STATUS
-.sp
.LP
Normally, if all files are already up-to-date, or if all files were
successfully reconciled, \fBfilesync\fR will exit with a status of \fB0\fR.
@@ -594,7 +575,6 @@ Miscellaneous other failures.
.RE
.SH FILES
-.sp
.ne 2
.na
\fB\fB$HOME/.packingrules\fR\fR
@@ -613,6 +593,5 @@ baseline summary file
.RE
.SH SEE ALSO
-.sp
.LP
-\fBcachefspack\fR(1M), \fBpackingrules\fR(4), \fBattributes\fR(5)
+\fBpackingrules\fR(4), \fBattributes\fR(5)
diff --git a/usr/src/man/man1m/Intro.1m b/usr/src/man/man1m/Intro.1m
index cf75eb641d..8f4e7f396b 100644
--- a/usr/src/man/man1m/Intro.1m
+++ b/usr/src/man/man1m/Intro.1m
@@ -1,24 +1,23 @@
'\" te
.\" Copyright 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" Copyright 1989 AT&T
.\" 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 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]
-.TH INTRO 1M "Nov 17, 2008"
+.TH INTRO 1M "Sep 8, 2015"
.SH NAME
Intro, intro \- introduction to maintenance commands and application programs
.SH DESCRIPTION
-.sp
.LP
This section describes, in alphabetical order, commands that are used chiefly
for system maintenance and administration purposes.
-.sp
.LP
Because of command restructuring for the Virtual File System architecture,
there are several instances of multiple manual pages that begin with the same
name. For example, the \fBmount\fR, pages \(mi \fBmount\fR(1M),
-\fBmount_cachefs\fR(1M), \fBmount_hsfs\fR(1M), \fBmount_nfs\fR(1M), \fB
-mount_tmpfs\fR(1M), and \fBmount_ufs\fR(1M). In each such case the first of the
+\fBmount_hsfs\fR(1M), \fBmount_nfs\fR(1M), \fBmount_tmpfs\fR(1M),
+and \fBmount_ufs\fR(1M). In each such case the first of the
multiple pages describes the syntax and options of the generic command, that
is, those options applicable to all FSTypes (file system types). The succeeding
pages describe the functionality of the FSType-specific modules of the command.
@@ -29,7 +28,6 @@ of them. Thus the FSType-specific manual pages should not be viewed as
describing distinct commands, but rather as detailing those aspects of a
command that are specific to a particular FSType.
.SH COMMAND SYNTAX
-.sp
.LP
Unless otherwise noted, commands described in this section accept options and
other arguments according to the following syntax:
@@ -40,7 +38,6 @@ other arguments according to the following syntax:
.fi
.in -2
-.sp
.LP
where:
.sp
@@ -103,26 +100,21 @@ Pathname (or other command argument) \fInot\fR beginning with \fB\(mi\fR or,
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for a discussion of the attributes listed in this
section.
.SH ACKNOWLEDGMENTS
-.sp
.LP
Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to
reproduce portions of its copyrighted documentation. Original documentation
from The Open Group can be obtained online at
http://www.opengroup.org/bookstore/\&.
-.sp
.LP
The Institute of Electrical and Electronics Engineers and The Open Group, have
given us permission to reprint portions of their documentation.
-.sp
.LP
In the following statement, the phrase ``this text'' refers to portions of the
system documentation.
-.sp
.LP
Portions of this text are reprinted and reproduced in electronic form in the
SunOS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for
@@ -133,15 +125,12 @@ any discrepancy between these versions and the original IEEE and The Open Group
Standard, the original IEEE and The Open Group Standard is the referee
document. The original Standard can be obtained online at
http://www.opengroup.org/unix/online.html\&.
-.sp
.LP
This notice shall appear on any product containing this material.
.SH SEE ALSO
-.sp
.LP
\fBgetopt\fR(1), \fBgetopt\fR(3C), \fBattributes\fR(5)
.SH DIAGNOSTICS
-.sp
.LP
Upon termination, each command returns 0 for normal termination and non-zero to
indicate troubles such as erroneous parameters, bad or inaccessible data, or
@@ -149,6 +138,5 @@ other inability to cope with the task at hand. It is called variously ``exit
code,'' ``exit status,'' or ``return code,'' and is described only where
special conventions are involved.
.SH NOTES
-.sp
.LP
Unfortunately, not all commands adhere to the standard syntax.
diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile
index ddeddbafd5..8dbf7331b1 100644
--- a/usr/src/man/man1m/Makefile
+++ b/usr/src/man/man1m/Makefile
@@ -12,7 +12,7 @@
#
# Copyright 2011, Richard Lowe
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
-# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
include $(SRC)//Makefile.master
@@ -53,11 +53,6 @@ _MANFILES= 6to4relay.1m \
bootadm.1m \
bootconfchk.1m \
busstat.1m \
- cachefsd.1m \
- cachefslog.1m \
- cachefspack.1m \
- cachefsstat.1m \
- cachefswssize.1m \
captoinfo.1m \
catman.1m \
cfgadm.1m \
@@ -71,7 +66,6 @@ _MANFILES= 6to4relay.1m \
cfgadm_scsi.1m \
cfgadm_sysctrl.1m \
cfgadm_usb.1m \
- cfsadmin.1m \
chat.1m \
check-hostname.1m \
check-permissions.1m \
@@ -141,7 +135,6 @@ _MANFILES= 6to4relay.1m \
format.1m \
fruadm.1m \
fsck.1m \
- fsck_cachefs.1m \
fsck_pcfs.1m \
fsck_udfs.1m \
fsck_ufs.1m \
@@ -325,7 +318,6 @@ _MANFILES= 6to4relay.1m \
modload.1m \
modunload.1m \
mount.1m \
- mount_cachefs.1m \
mount_hsfs.1m \
mount_nfs.1m \
mount_pcfs.1m \
diff --git a/usr/src/man/man1m/automount.1m b/usr/src/man/man1m/automount.1m
index ccae4f8718..6a3ad25e41 100644
--- a/usr/src/man/man1m/automount.1m
+++ b/usr/src/man/man1m/automount.1m
@@ -1,10 +1,11 @@
'\" te
.\" Copyright 1989 AT&T
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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 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]
-.TH AUTOMOUNT 1M "Mar 28, 2008"
+.TH AUTOMOUNT 1M "Sep 8, 2015"
.SH NAME
automount \- install automatic mount points
.SH SYNOPSIS
@@ -14,7 +15,6 @@ automount \- install automatic mount points
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBautomount\fR utility installs \fBautofs\fR mount points and associates
an automount map with each mount point. It starts the \fBautomountd\fR(1M)
@@ -63,7 +63,6 @@ the master map. Subsequently, it may be run to install \fBautofs\fR mounts for
new entries in the master map or the direct map, or to perform unmounts for
entries that have been removed from these maps.
.SS "Automount with Solaris Trusted Extensions"
-.sp
.LP
If a system is configured with Solaris Trusted Extensions, additional
processing is performed to facilitate multilevel home directory access. A list
@@ -77,7 +76,6 @@ it is explicitly or implicitly listed in the master map. Instead of
\fBauto_home\fR file appended with its own zone name. Each zone's
\fBauto_home\fR map is uniquely named so that it can be maintained and shared
by all zones using a common name server.
-.sp
.LP
By default, the home directories of lower-level zones are mounted read-only
under \fB/zone/\fI<zonename>\fR/export/home\fR when each zone is booted. The
@@ -99,7 +97,6 @@ specification. If this loopback match occurs and the name corresponds to a
valid user whose home directory does not exist in the public zone, the
directory is automatically created on behalf of the user.
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
@@ -124,7 +121,6 @@ information.
.SH USAGE
.SS "Map Entry Format"
-.sp
.LP
A simple map entry (mapping) takes the form:
.sp
@@ -135,13 +131,12 @@ key [ -\fImount-options\fR ] \fIlocation\fR .\|.\|.
.in -2
.sp
-.sp
.LP
where \fBkey\fR is the full pathname of the directory to mount when used in a
direct map, or the simple name of a subdirectory in an indirect map.
\fImount-options\fR is a comma-separated list of \fBmount\fR options, and
\fIlocation\fR specifies a file system from which the directory may be mounted.
-In the case of a simple \fBNFS\fR mount, the options that can be used are as
+In the case of a simple \fBNFS\fR mount, the options that can be used are
specified in \fBmount_nfs\fR(1M), and \fIlocation\fR takes the form:
.sp
.in +2
@@ -151,16 +146,13 @@ specified in \fBmount_nfs\fR(1M), and \fIlocation\fR takes the form:
.in -2
.sp
-.sp
.LP
\fIhost\fR is the name of the host from which to mount the file system, and
\fIpathname\fR is the absolute pathname of the directory to mount.
-.sp
.LP
-Options to other file systems are documented on the other \fBmount_*\fR
-reference manual pages, for example, \fBmount_cachefs\fR(1M).
+Options to other file systems are documented in the other \fBmount_*\fR
+reference manual pages.
.SS "Replicated File Systems"
-.sp
.LP
Multiple \fIlocation\fR fields can be specified for replicated \fBNFS\fR file
systems, in which case \fBautomount\fR and the kernel will each try to use that
@@ -176,7 +168,6 @@ unmount has been possible, and a remount is done. Servers on the same local
subnet are given the strongest preference, and servers on the local net are
given the second strongest preference. Among servers equally far away, response
times will determine the order if no weighting factors (see below) are used.
-.sp
.LP
If the list includes server locations using both the \fBNFS\fR Version 2
Protocol and the \fBNFS\fR Version 3 Protocol, \fBautomount\fR will choose only
@@ -184,7 +175,6 @@ a subset of the server locations on the list, so that all entries will be the
same protocol. It will choose servers with the \fBNFS\fR Version 3 Protocol so
long as an \fBNFS\fR Version 2 Protocol server on a local subnet will not be
ignored. See the \fI\fR for additional details.
-.sp
.LP
If each \fIlocation\fR in the list shares the same \fIpathname\fR then a single
\fIlocation\fR may be used with a comma-separated list of hostnames:
@@ -196,7 +186,6 @@ If each \fIlocation\fR in the list shares the same \fIpathname\fR then a single
.in -2
.sp
-.sp
.LP
Requests for a server may be weighted, with the weighting factor appended to
the server name as an integer in parentheses. Servers without a weighting are
@@ -210,11 +199,9 @@ higher values decrease the chance of being selected. In the example,
.in -2
.sp
-.sp
.LP
hosts \fBalpha\fR and \fBbravo\fR have the highest priority; host \fBdelta\fR
has the lowest.
-.sp
.LP
Server proximity takes priority in the selection process. In the example above,
if the server \fBdelta\fR is on the same network segment as the client, but the
@@ -223,7 +210,6 @@ the weighting value is ignored. The weighting has effect only when selecting
between servers with the same network proximity. The automounter always selects
the localhost over other servers on the same network segment, regardless of
weighting.
-.sp
.LP
In cases where each server has a different export point, the weighting can
still be applied. For example:
@@ -236,13 +222,11 @@ man -ro alpha:/usr/man bravo,charlie(1):/usr/share/man
.in -2
.sp
-.sp
.LP
A mapping can be continued across input lines by escaping the \fBNEWLINE\fR
with a backslash (\e) Comments begin with a number sign (\fB#\fR) and end at
the subsequent NEWLINE.
.SS "Map Key Substitution"
-.sp
.LP
The ampersand (\fB&\fR) character is expanded to the value of the \fBkey\fR
field for the entry in which it occurs. In this case:
@@ -254,11 +238,9 @@ field for the entry in which it occurs. In this case:
.in -2
.sp
-.sp
.LP
the \fB&\fR expands to \fBjane\fR.
.SS "Wildcard Key"
-.sp
.LP
The asterisk (\fB*\fR) character, when supplied as the \fBkey\fR field, is
recognized as the catch-all entry. Such an entry will match any key not
@@ -272,7 +254,6 @@ indirect map for \fB/config\fR:
.in -2
.sp
-.sp
.LP
this would allow automatic mounts in \fB/config\fR of any remote file system
whose location could be specified as:
@@ -284,12 +265,10 @@ hostname\|:\|/export/config/hostname
.in -2
.sp
-.sp
.LP
Note that the wildcard key does not work in conjunction with the \fB-browse\fR
option.
.SS "Variable Substitution"
-.sp
.LP
Client specific variables can be used within an \fBautomount\fR map. For
instance, if \fB$HOST\fR appeared within a map, \fBautomount\fR would expand it
@@ -327,12 +306,10 @@ T}
.TE
-.sp
.LP
If a reference needs to be protected from affixed characters, you can surround
the variable name with curly braces (\fB\|{\|}\|\fR).
.SS "Multiple Mounts"
-.sp
.LP
A multiple mount entry takes the form:
.sp
@@ -343,14 +320,12 @@ key [\fI-mount-options\fR] [\|[\fImountpoint\fR] [\fI-mount-options\fR] \fIlocat
.in -2
.sp
-.sp
.LP
The initial \fB/\fR[\fImountpoint\fR\|] is optional for the first mount and
mandatory for all subsequent mounts. The optional \fImountpoint\fR is taken as
a pathname relative to the directory named by \fBkey\fR. If \fImountpoint\fR is
omitted in the first occurrence, a \fImountpoint\fR of \fB/\fR (root) is
implied.
-.sp
.LP
Given an entry in the indirect map for \fB/src\fR
.sp
@@ -364,14 +339,12 @@ beta -ro\e
.in -2
.sp
-.sp
.LP
All offsets must exist on the server under \fBbeta\fR. \fBautomount\fR will
automatically mount \fB/src/beta\fR, \fB/src/beta/1.0\fR, and
\fB/src/beta/1.0/man\fR, as needed, from either \fBsvr1\fR or \fBsvr2\fR,
whichever host is nearest and responds first.
.SS "Other File System Types"
-.sp
.LP
The automounter assumes \fBNFS\fR mounts as a default file system type. Other
file system types can be described using the \fBfstype\fR mount option. Other
@@ -387,7 +360,6 @@ character must be prepended, for instance, to mount a CD file system:
.in -2
.sp
-.sp
.LP
or to perform an \fBautofs\fR mount:
.sp
@@ -398,39 +370,21 @@ or to perform an \fBautofs\fR mount:
.in -2
.sp
-.sp
.LP
Use this procedure only if you are not using Volume Manager.
-.sp
-.LP
-Mounts using CacheFS are most useful when applied to an entire map as map
-defaults. The following entry in the master map describes cached home directory
-mounts. It assumes the default location of the cache directory, \fB/cache\fR.
-.sp
-.in +2
-.nf
-\fB/home auto_home\fR \fB-fstype\fR \fB=cachefs,backfstype=nfs\fR
-.fi
-.in -2
-.sp
-
-.sp
.LP
See the \fBNOTES\fR section for information on option inheritance.
.SS "Indirect Maps"
-.sp
.LP
An indirect map allows you to specify mappings for the subdirectories you wish
to mount under the \fBdirectory\fR indicated on the command line. In an
indirect map, each \fBkey\fR consists of a simple name that refers to one or
more file systems that are to be mounted as needed.
.SS "Direct Maps"
-.sp
.LP
Entries in a direct map are associated directly with \fBautofs\fR mount points.
Each \fIkey\fR is the full pathname of an \fBautofs\fR mount point. The direct
map as a whole is not associated with any single directory.
-.sp
.LP
Direct maps are distinguished from indirect maps by the \fB/-\fR key. For
example:
@@ -448,7 +402,6 @@ example:
.sp
.SS "Included Maps"
-.sp
.LP
The contents of another map can be included within a map with an entry of the
form
@@ -460,7 +413,6 @@ form
.in -2
.sp
-.sp
.LP
If \fImapname\fR begins with a slash, it is assumed to be the pathname of a
local file. Otherwise, the location of the map is determined by the policy of
@@ -474,13 +426,11 @@ automount: files nis
.in -2
.sp
-.sp
.LP
If the name service is \fBfiles\fR, then the name is assumed to be that of a
local file in \fB/etc\fR. If the key being searched for is not found in the
included map, the search continues with the next entry.
.SS "Special Maps"
-.sp
.LP
There are two special maps available: \fB-hosts\fR and \fB-null\fR. The
\fB-hosts\fR map is used with the \fB/net\fR directory and assumes that the map
@@ -488,7 +438,6 @@ key is the hostname of an \fBNFS\fR server. The \fBautomountd\fR daemon
dynamically constructs a map entry from the server's list of exported file
systems. References to a directory under \fB/net/hermes\fR will refer to the
corresponding directory relative to \fBhermes\fR root.
-.sp
.LP
The \fB-null\fR map cancels a previous map for the directory indicated. This is
most useful in the \fB/etc/auto_master\fR for cancelling entries that would
@@ -496,7 +445,6 @@ otherwise be inherited from the \fB+auto_master\fR include entry. To be
effective, the \fB-null\fR entries must be inserted before the included map
entry.
.SS "Executable Maps"
-.sp
.LP
Local maps that have the execute bit set in their file permissions will be
executed by the automounter and provided with a key to be looked up as an
@@ -504,19 +452,16 @@ argument. The executable map is expected to return the content of an
automounter map entry on its stdout or no output if the entry cannot be
determined. A direct map cannot be made executable.
.SS "Configuration and the auto_master Map"
-.sp
.LP
When initiated without arguments, \fBautomount\fR consults the master map for a
list of \fBautofs\fR mount points and their maps. It mounts any \fBautofs\fR
mounts that are not already mounted, and unmounts \fBautofs\fR mounts that have
been removed from the master map or direct map.
-.sp
.LP
The master map is assumed to be called \fBauto_master\fR and its location is
determined by the name service switch policy. Normally the master map is
located initially as a local file \fB/etc/auto_master\fR.
.SS "Browsing"
-.sp
.LP
The \fBautomount\fR daemon supports browsability of indirect maps. This allows
all of the potential mount points to be visible, whether or not they are
@@ -531,21 +476,17 @@ map to disable browsing. For example:
.in -2
.sp
-.sp
.LP
In this case, any \fIhostnames\fR would only be visible in \fB/net\fR after
they are mounted, but all potential mount points would be visible under
\fB/home\fR. The \fB-browse\fR option enables browsability of \fBautofs\fR file
systems. This is the default for all indirect maps.
-.sp
.LP
The \fB-browse\fR option does not work in conjunction with the wildcard key.
.SS "Restricting Mount Maps"
-.sp
.LP
Options specified for a map are used as the default options for all the entries
in that map. They are ignored when map entries specify their own mount options.
-.sp
.LP
In some cases, however, it is desirable to force \fBnosuid\fR, \fBnodevices\fR,
\fBnosetuid\fR, or \fBnoexec\fR for a complete mount map and its submounts.
@@ -558,7 +499,6 @@ This can be done by specifying the additional mount option, \fB-restrict\fR.
.in -2
.sp
-.sp
.LP
The \fB-restrict\fR option forces the inheritance of all the restrictive
options \fBnosuid\fR, \fBnodevices\fR, \fBnosetuid\fR, and \fBnoexec\fR as well
@@ -568,7 +508,6 @@ as the restrict option itself. In this particular example, the \fBnosuid\fR and
enforced for auto mounts established by programs with fewer than all privileges
available in their zone.
.SH EXIT STATUS
-.sp
.LP
The following exit values are returned:
.sp
@@ -590,7 +529,6 @@ An error occurred.
.RE
.SH FILES
-.sp
.ne 2
.na
\fB\fB/etc/auto_master\fR\fR
@@ -628,60 +566,49 @@ Name service switch configuration file. See \fBnsswitch.conf\fR(4).
.RE
.SH SEE ALSO
-.sp
.LP
\fBisainfo\fR(1), \fBls\fR(1), \fBsvcs\fR(1), \fBuname\fR(1),
-\fBautomountd\fR(1M), \fBmount\fR(1M), \fBmount_cachefs\fR( 1M),
-\fBmount_nfs\fR(1M), \fBsvcadm\fR(1M), \fBautofs\fR(4), \fBattributes\fR(5),
+\fBautomountd\fR(1M), \fBmount\fR(1M), \fBmount_nfs\fR(1M),
+\fBsvcadm\fR(1M), \fBautofs\fR(4), \fBattributes\fR(5),
\fBnfssec\fR(5), \fBsmf\fR(5)
-.sp
.LP
\fI\fR
.SH NOTES
-.sp
.LP
\fBautofs\fR mount points must not be hierarchically related. \fBautomount\fR
does not allow an \fBautofs\fR mount point to be created within another
\fBautofs\fR mount.
-.sp
.LP
Since each direct map entry results in a new \fBautofs\fR mount such maps
should be kept short.
-.sp
.LP
Entries in both direct and indirect maps can be modified at any time. The new
information is used when \fBautomountd\fR next uses the map entry to do a
mount.
-.sp
.LP
New entries added to a master map or direct map will not be useful until the
automount command is run to install them as new \fBautofs\fR mount points. New
entries added to an indirect map may be used immediately.
-.sp
.LP
As of the Solaris 2.6 release, a listing (see \fBls\fR(1)) of the \fBautofs\fR
directory associated with an indirect map shows all potential mountable
entries. The attributes associated with the potential mountable entries are
temporary. The real file system attributes will only be shown once the file
system has been mounted.
-.sp
.LP
Default mount options can be assigned to an entire map when specified as an
optional third field in the master map. These options apply only to map entries
that have no mount options. Note that map entities with options override the
default options, as at this time, the options do not concatenate. The
concatenation feature is planned for a future release.
-.sp
.LP
When operating on a map that invokes an NFS mount, the default number of
retries for the automounter is 0, that is, a single mount attempt, with no
retries. Note that this is significantly different from the default (10000) for
the \fBmount_nfs\fR(1M) utility.
-.sp
.LP
The Network Information Service (NIS) was formerly known as Sun Yellow Pages
(YP). The functionality of the two remains the same.
-.sp
.LP
The \fBautomount\fR service is managed by the service management facility,
\fBsmf\fR(5), under the service identifier:
@@ -693,7 +620,6 @@ svc:/system/filesystem/autofs:default
.in -2
.sp
-.sp
.LP
Administrative actions on this service, such as enabling, disabling, or
requesting restart, can be performed using \fBsvcadm\fR(1M). The service's
diff --git a/usr/src/man/man1m/cachefsd.1m b/usr/src/man/man1m/cachefsd.1m
deleted file mode 100644
index d2e41432d0..0000000000
--- a/usr/src/man/man1m/cachefsd.1m
+++ /dev/null
@@ -1,88 +0,0 @@
-'\" te
-.\" Copyright (c) 2000, Sun Microsystems, Inc. All Rights Reserved.
-.\" 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 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]
-.TH CACHEFSD 1M "Oct 2, 2000"
-.SH NAME
-cachefsd \- CacheFS daemon
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/lib/fs/cachefs/cachefsd\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcachefsd\fR server implements features of the cache filesystem
-(CacheFS). It is invoked at boot time and run if the \fB/\fR (root) and
-\fB/usr\fR filesystems are being cached. If \fB/usr\fR is being cached,
-\fBcachefsd\fR is invoked by \fBinetd\fR(1M) from \fBinetd.conf\fR(4). At run
-time, \fBcachefsd\fR is invoked by the \fBinetd\fR mechanism in response to an
-RPC request from a user command such as \fBmount_cachefs\fR(1M).
-.sp
-.LP
-The \fBcachefsd\fR server supports the "disconnected mode" of CacheFS. In this
-mode, a user can continue to read and, depending on the option selected, write
-to files in a cached filesystem when the NFS server for the cached files is not
-available.
-.sp
-.LP
-The \fBcachefsd\fR daemon performs the following functions in support of the
-CacheFS:
-.RS +4
-.TP
-.ie t \(bu
-.el o
-Implements the connection policy. The daemon determines whether the NFS server
-backing the cache is connected or disconnected from the cache, or is in
-transition from the connected or disconnected states.
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-Implements "log rolling," wherein the daemon monitors a disconnected NFS server
-for reconnection. After such a server returns to a connected state,
-\fBcachefsd\fR rolls any local changes to cached files (kept in a log) back to
-the server.
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-Manages "packing," wherein \fBcachefsd\fR makes a best effort to ensure that
-files in a user-specified list are available in the cache in disconnected mode.
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-Supports user interfaces by supplying statistics, reporting conflicts between
-the cache and the back filesystem, and supporting a list of files for packing.
-.RE
-.sp
-.LP
-The running of \fBcachefsd\fR is required for the disconnected mode of CacheFS.
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB-r\fR\fR
-.ad
-.RS 6n
-Used for invoking \fBcachefsd\fR for the \fB/\fR filesystem.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcachefspack\fR(1M), \fBcfsadmin\fR(1M), \fBmount_cachefs\fR(1M),
-\fBinetd.conf\fR(4), \fBattributes\fR(5)
-.sp
-.LP
-\fI\fR
diff --git a/usr/src/man/man1m/cachefslog.1m b/usr/src/man/man1m/cachefslog.1m
deleted file mode 100644
index 3b9770eed6..0000000000
--- a/usr/src/man/man1m/cachefslog.1m
+++ /dev/null
@@ -1,160 +0,0 @@
-'\" te
-.\" Copyright (c) 1997, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH CACHEFSLOG 1M "Feb 7, 1997"
-.SH NAME
-cachefslog \- Cache File System logging
-.SH SYNOPSIS
-.LP
-.nf
-\fBcachefslog\fR [\fB-f\fR \fIlogfile\fR | \fB-h\fR] \fIcachefs_mount_point\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcachefslog\fR command displays where CacheFS statistics are being
-logged. Optionally, it sets where CacheFS statistics are being logged, or it
-halts logging for a cache specified by \fIcachefs_mount_point\fR. The
-\fIcachefs_mount_point\fR argument is a mount point of a cache file system.
-All file systems cached under the same cache as \fIcachefs_mount_point\fR will
-be logged.
-.SH OPTIONS
-.sp
-.LP
-The following options are supported. You must be super-user to use the \fB-f\fR
-and \fB-h\fR options.
-.sp
-.ne 2
-.na
-\fB\fB-f\fR \fIlogfile\fR\fR
-.ad
-.RS 14n
-Specify the log file to be used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.RS 14n
-Halt logging.
-.RE
-
-.SH OPERANDS
-.sp
-.ne 2
-.na
-\fB\fIcachefs_mount_point\fR\fR
-.ad
-.RS 23n
-A mount point of a cache file system.
-.RE
-
-.SH USAGE
-.sp
-.LP
-See \fBlargefile\fR(5) for the description of the behavior of \fBcachefslog\fR
-when encountering files greater than or equal to 2 Gbyte ( 2^31 bytes).
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRChecking the Logging of a directory.
-.sp
-.LP
-The example below checks if the directory \fB/home/sam\fR is being logged:
-
-.sp
-.in +2
-.nf
-example% cachefslog /home/sam
-not logged: /home/sam\fI\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRChanging the \fIlogfile\fR.
-.sp
-.LP
-The example below changes the \fIlogfile\fR of \fB/home/sam\fR to
-\fB/var/tmp/samlog\fR:
-
-.sp
-.in +2
-.nf
-example# cachefslog -f /var/tmp/samlog /home/sam
-/var/tmp/samlog: /home/sam \fI\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 3 \fRVerifying the change of a \fIlogfile\fR.
-.sp
-.LP
-The example below verifies the change of the previous example:
-
-.sp
-.in +2
-.nf
-example% cachefslog /home/sam
-/var/tmp/samlog: /home/sam \fI\fR
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 4 \fRHalting the logging of a directory.
-.sp
-.LP
-The example below halts logging for the \fB/home/sam\fR directory:
-
-.sp
-.in +2
-.nf
-example# cachefslog -h /home/sam
-not logged: /home/sam\fI\fR
-.fi
-.in -2
-.sp
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 12n
-success
-.RE
-
-.sp
-.ne 2
-.na
-\fBnon-zero\fR
-.ad
-.RS 12n
-an error has occurred.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcachefsstat\fR(1M), \fBcachefswssize\fR(1M), \fBcfsadmin\fR(1M),
-\fBattributes\fR(5), \fBlargefile\fR(5)
-.SH DIAGNOSTICS
-.sp
-.ne 2
-.na
-\fB\fBInvalid path\fR\fR
-.ad
-.RS 16n
-It is illegal to specify a path within a cache file system.
-.RE
-
diff --git a/usr/src/man/man1m/cachefspack.1m b/usr/src/man/man1m/cachefspack.1m
deleted file mode 100644
index ccc602fb04..0000000000
--- a/usr/src/man/man1m/cachefspack.1m
+++ /dev/null
@@ -1,237 +0,0 @@
-'\" te
-.\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH CACHEFSPACK 1M "Mar 18, 2004"
-.SH NAME
-cachefspack \- pack files and file systems in the cache
-.SH SYNOPSIS
-.LP
-.nf
-\fBcachefspack\fR [\fB-h\fR] [\fB-i\fR | \fB-p\fR | \fB-u\fR] [\fB-f\fR \fIpacking-list\fR]
- [\fB-U\fR \fIcache-directory\fR] [\fIfile\fR]...
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcachefspack\fR utility is used to set up and maintain files in the
-cache. This utility affords greater control over the cache, ensuring that the
-specified files are in the cache whenever possible.
-.sp
-.LP
-\fBcachefspack\fR does not pack files when the backfileystem type for the
-\fBcachefs\fR mount is NFSv4. This is because only pass-through support is
-available for \fBcachefs\fR with NFSv4.
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB\fR\fB-f\fR\fB \fR\fIpacking-list\fR\fR
-.ad
-.RS 22n
-Specify a file containing a list of files and directories to be packed. Options
-within subdirectories and files can also be specified. The format and rules
-governing \fIpacking-list\fR are described on the \fBpackingrules\fR(4) manual
-page. Directories are packed recursively. Symlinks that match a regular
-expression on a \fBLIST\fR command are followed. Symlinks encountered while
-recursively processing directories are not followed.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-h\fR\fR
-.ad
-.RS 22n
-Help. Print a brief summary of all the options.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-i\fR\fR
-.ad
-.RS 22n
-View information about the packed files.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR\fR
-.ad
-.RS 22n
-Pack the file or files specified by \fBfile\fR. This is the default behavior.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-u\fR\fR
-.ad
-.RS 22n
-Unpack the file or files specified by \fBfile\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB\fR\fB-U\fR\fB \fR\fIcache-directory\fR\fR
-.ad
-.RS 22n
-Unpack all files in the specified cache directory.
-.RE
-
-.SH OPERANDS
-.sp
-.LP
-The following operands are supported:
-.sp
-.ne 2
-.na
-\fB\fBfile\fR\fR
-.ad
-.RS 8n
-A path name of a file to be packed or unpacked.
-.RE
-
-.SH USAGE
-.sp
-.LP
-See \fBlargefile\fR(5) for the description of the behavior of \fBcachefspack\fR
-when encountering files greater than or equal to 2 Gbyte ( 2^31 bytes).
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRPacking a File in the Cache
-.sp
-.LP
-The following example packs the file \fBprojects\fR in the cache:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-p\fR projects
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRPackint Files in the Cache
-.sp
-.LP
-The following example packs the files \fBprojects\fR, \fBupdates\fR, and
-\fBmaster_plan\fR in the cache:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-p\fR projects updates master_plan
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 3 \fRUnpacking a File From the Cache
-.sp
-.LP
-The following example unpacks the file \fBprojects\fR from the cache:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-u\fR projects
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 4 \fRUnpacking Files From the Cache
-.sp
-.LP
-The following example unpacks the files \fBprojects\fR, \fBupdates\fR, and
-\fBmaster_plan\fR from the cache:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-u\fR projects updates master_plan
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 5 \fRUnpacking All Files From in a Cache Directory
-.sp
-.LP
-The following example unpacks all files in the cache directory \fBcache1\fR:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-U\fR /cache/cache1
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 6 \fRUsing a Packing List
-.sp
-.LP
-The following example illustrates the use of a packing list to specify files to
-be packed in the cache.
-
-.sp
-.LP
-The contents of \fBlists.pkg\fR are as follows:
-
-.sp
-.in +2
-.nf
-IGNORE SCCS BASE /src/junk LIST *.c LIST *.h
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-The following command packs all files in the \fB/src/junk\fR directory which
-have \fB\&.c\fR and \fB\&.h\fR extensions, and do contain the string SCCS in
-the file's path name:
-
-.sp
-.in +2
-.nf
-% cachefspack \fB-f\fR lists.pkg
-.fi
-.in -2
-.sp
-
-.SH EXIT STATUS
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 6n
-Successful completion.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB>0\fR\fR
-.ad
-.RS 6n
-An error occurred.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcfsadmin\fR(1M), \fBmount_cachefs\fR(1M), \fBpackingrules\fR(4),
-\fBattributes\fR(5), \fBlargefile\fR(5)
diff --git a/usr/src/man/man1m/cachefsstat.1m b/usr/src/man/man1m/cachefsstat.1m
deleted file mode 100644
index 07f050842b..0000000000
--- a/usr/src/man/man1m/cachefsstat.1m
+++ /dev/null
@@ -1,139 +0,0 @@
-'\" te
-.\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH CACHEFSSTAT 1M "Oct 9, 2003"
-.SH NAME
-cachefsstat \- Cache File System statistics
-.SH SYNOPSIS
-.LP
-.nf
-\fB/usr/bin/cachefsstat\fR [\fB-z\fR] [\fIpath\fR]...
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcachefsstat\fR command displays statistical information about the cache
-file system mounted on \fIpath\fR. The statistical information includes cache
-hits and misses, consistency checking, and modification operations. If
-\fIpath\fR is not specified, all mounted cache file systems are used.
-.sp
-.LP
-\fBcachefsstat\fR can also be used to reinitialize this information (see
-\fB-z\fR option).
-.sp
-.LP
-The statistical information has the following format:
-.sp
-.in +2
-.nf
-<\fIcache hit rate\fR>
-<\fIconsistency checks\fR>
-<\fImodifies\fR>
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-where:
-.sp
-.ne 2
-.na
-\fB\fIhit rate\fR\fR
-.ad
-.RS 22n
-The percentage of cache hits over the total number of attempts, followed by the
-actual numbers of hits and misses.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fIconsistency checks\fR\fR
-.ad
-.RS 22n
-The number of consistency checks performed, followed by the number that passed,
-and the number that failed.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fImodifies\fR\fR
-.ad
-.RS 22n
-The number of modify operations, including writes, creates, etc.
-.RE
-
-.SH OPTIONS
-.sp
-.LP
-The following option is supported:
-.sp
-.ne 2
-.na
-\fB\fB-z\fR\fR
-.ad
-.RS 6n
-Zero (reinitialize) statistics. Execute \fBcachefsstat\fR \fB-z\fR before
-executing \fBcachefsstat\fR again to gather statistics on the cache
-performance. This option can only be use by the superuser. The statistics
-printed reflect those just before the statistics are reinitialized.
-.RE
-
-.SH USAGE
-.sp
-.LP
-See \fBlargefile\fR(5) for the description of the behavior of \fBcachefsstat\fR
-when encountering files greater than or equal to 2 Gbyte (2^31 bytes).
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRUsing \fBcachefsstat\fR
-.sp
-.LP
-The following example shows the \fBcachefsstat\fR command run on file system
-\fB/test\fR:
-
-.sp
-.in +2
-.nf
-example# cachefsstat /test
- /test
- cache hit rate: 100% (0 hits, 0 misses)
- consistency checks: 0 (0 pass, 0 fail)
- modifies: 0
-garbage collection: 0
-.fi
-.in -2
-.sp
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 12n
-Successful completion.
-.RE
-
-.sp
-.ne 2
-.na
-\fBnon-zero\fR
-.ad
-.RS 12n
-An error occurred.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcachefslog\fR(1M), \fBcachefswssize\fR(1M), \fBcfsadmin\fR(1M),
-\fBattributes\fR(5), \fBlargefile\fR(5)
diff --git a/usr/src/man/man1m/cachefswssize.1m b/usr/src/man/man1m/cachefswssize.1m
deleted file mode 100644
index fdef9dfc1a..0000000000
--- a/usr/src/man/man1m/cachefswssize.1m
+++ /dev/null
@@ -1,107 +0,0 @@
-'\" te
-.\" Copyright (c) 1996, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH CACHEFSWSSIZE 1M "Sep 16, 1996"
-.SH NAME
-cachefswssize \- determine working set size for cachefs
-.SH SYNOPSIS
-.LP
-.nf
-\fBcachefswssize\fR \fIlogfile\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcachefswssize\fR command displays the workspace size determined from
-\fIlogfile\fR. This includes the amount of cache space needed for each
-filesystem that was mounted under the cache, as well as a total.
-.SH USAGE
-.sp
-.LP
-See \fBlargefile\fR(5) for the description of the behavior of
-\fBcachefswssize\fR when encountering files greater than or equal to 2 Gbyte (
-2^31 bytes).
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRA sample output of \fBcachefswssize\fR.
-.sp
-.LP
-\fBexample% cachefswssize /var/tmp/samlog\fR
-
-.sp
-
-.sp
-.TS
-l l l
-l l l .
-\fB/home/sam\fR
- \fBend size:\fR \fB10688k\fR
- \fBhigh water size:\fR \fB10704k\fR
-
-\fB/foo\fR
- \fBend size:\fR \fB128k\fR
- \fBhigh water size:\fR \fB128k\fR
-
-\fB/usr/dist\fR
- \fBend size:\fR \fB1472k\fR
- \fBhigh water size:\fR \fB1472k\fR
-
-\fBtotal for cache\fR
- \fBinitial size:\fR \fB110960k\fR
- \fBend size:\fR \fB12288k\fR
- \fBhigh water size:\fR \fB12304k\fR
-.TE
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 12n
-success
-.RE
-
-.sp
-.ne 2
-.na
-\fBnon-zero\fR
-.ad
-.RS 12n
-an error has occurred.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcachefslog\fR(1M), \fBcachefsstat\fR(1M), \fBcfsadmin\fR(1M),
-\fBattributes\fR(5), \fBlargefile\fR(5)
-.SH DIAGNOSTICS
-.sp
-.ne 2
-.na
-\fB\fBproblems were encountered writing log file\fR\fR
-.ad
-.sp .6
-.RS 4n
-There were problems encountered when the kernel was writing the logfile. The
-most common problem is running out of disk space.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBinvalid log\fR \fBfile\fR\fR
-.ad
-.sp .6
-.RS 4n
-The logfile is not a valid logfile or was created with a newer version of
-Solaris than the one where \fBcachefswssize\fR is running.
-.RE
-
diff --git a/usr/src/man/man1m/cfsadmin.1m b/usr/src/man/man1m/cfsadmin.1m
deleted file mode 100644
index 942ee1c067..0000000000
--- a/usr/src/man/man1m/cfsadmin.1m
+++ /dev/null
@@ -1,414 +0,0 @@
-'\" te
-.\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH CFSADMIN 1M "Feb 21, 2004"
-.SH NAME
-cfsadmin \- administer disk space used for caching file systems with the Cache
-File-System (CacheFS)
-.SH SYNOPSIS
-.LP
-.nf
-\fBcfsadmin\fR \fB-c\fR [\fB-o\fR \fIcacheFS-parameters\fR] \fIcache_directory\fR
-.fi
-
-.LP
-.nf
-\fBcfsadmin\fR \fB-d\fR {\fIcache_ID\fR | all} \fIcache_directory\fR
-.fi
-
-.LP
-.nf
-\fBcfsadmin\fR \fB-l\fR \fIcache_directory\fR
-.fi
-
-.LP
-.nf
-\fBcfsadmin\fR \fB-s\fR {\fImntpt1 ....\fR} | all
-.fi
-
-.LP
-.nf
-\fBcfsadmin\fR \fB-u\fR [\fB-o\fR \fIcacheFS-parameters\fR] \fIcache_directory\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBcfsadmin\fR command provides the following functions:
-.RS +4
-.TP
-.ie t \(bu
-.el o
-cache creation
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-deletion of cached file systems
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-listing of cache contents and statistics
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-resource parameter adjustment when the file system is unmounted.
-.RE
-.sp
-.LP
-You must always supply an option for \fBcfsadmin\fR. For each form of the
-command except \fB-s\fR, you must specify a cache directory, that is, the
-directory under which the cache is actually stored. A path name in the front
-file system identifies the cache directory. For the \fB-s\fR form of the
-command, you must specify a mount point.
-.sp
-.LP
-You can specify a cache ID when you mount a file system with CacheFS, or you
-can let the system generate one for you. The \fB-l\fR option includes the cache
-ID in its listing of information. You must know the cache ID to delete a cached
-file system.
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB-c\fR [ \fB-o\fR \fIcacheFS-parameters\fR ] \fIcache_directory\fR\fR
-.ad
-.sp .6
-.RS 4n
-Create a cache under the directory specified by \fIcache_directory\fR. This
-directory must not exist prior to cache creation.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-d\fR { \fIcache_ID\fR | all } \fIcache_directory\fR\fR
-.ad
-.sp .6
-.RS 4n
-Remove the file system whose cache ID you specify and release its resources, or
-remove all file systems in the cache by specifying \fBall\fR. After deleting a
-file system from the cache, you must run the \fBfsck_cachefs\fR(1M) command to
-correct the resource counts for the cache.
-.sp
-As indicated by the syntax above, you must supply either a \fIcache_ID\fR or
-\fBall\fR, in addition to \fIcache_directory\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-l\fR \fIcache_directory\fR\fR
-.ad
-.sp .6
-.RS 4n
-List file systems stored in the specified cache, as well as statistics about
-them. Each cached file system is listed by cache ID. The statistics document
-resource utilization and cache resource parameters.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-s\fR { \fImntpt1\fR ... } | all\fR
-.ad
-.sp .6
-.RS 4n
-Request a consistency check on the specified file system (or all \fBcachefs\fR
-mounted file systems). The \fB-s\fR option only works if the cache file system
-was mounted with \fBdemandconst\fR enabled (see \fBmount_cachefs\fR(1M)). Each
-file in the specified cache file system is checked for consistency with its
-corresponding file in the back file system. Note that the consistency check is
-performed file by file as files are accessed. If no files are accessed, no
-checks are performed. Use of this option does not result in a sudden "storm" of
-consistency checks.
-.sp
-As indicated by the syntax above, you must supply one or more mount points, or
-\fBall\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-u\fR [ \fB-o\fR \fIcacheFS-parameters\fR ] \fIcache_directory\fR\fR
-.ad
-.sp .6
-.RS 4n
-Update resource parameters of the specified cache directory. Parameter values
-can only be increased. To decrease the values, you must remove the cache and
-recreate it. All file systems in the cache directory must be unmounted when you
-use this option. Changes take effect the next time you mount any file system in
-the specified cache directory. The \fB-u\fR option with no \fB-o\fR option sets
-all parameters to their default values.
-.RE
-
-.SS "CacheFS Resource Parameters"
-.sp
-.LP
-You can specify the following CacheFS resource parameters as arguments to the
-\fB-o\fR option. Separate multiple parameters with commas.
-.sp
-.ne 2
-.na
-\fB\fBmaxblocks=\fR\fIn\fR\fR
-.ad
-.RS 18n
-Maximum amount of storage space that CacheFS can use, expressed as a percentage
-of the total number of blocks in the front file system. If CacheFS does not
-have exclusive use of the front file system, there is no guarantee that all the
-space the \fBmaxblocks\fR parameter allows is available. The default is
-\fB90\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBminblocks=\fR\fIn\fR\fR
-.ad
-.RS 18n
-Minimum amount of storage space, expressed as a percentage of the total number
-of blocks in the front file system, that CacheFS is always allowed to use
-without limitation by its internal control mechanisms. If CacheFS does not have
-exclusive use of the front file system, there is no guarantee that all the
-space the \fBminblocks\fR parameter attempts to reserve is available. The
-default is \fB0\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBthreshblocks=\fR\fIn\fR\fR
-.ad
-.RS 18n
-A percentage of the total blocks in the front file system beyond which CacheFS
-cannot claim resources once its block usage has reached the level specified by
-\fBminblocks\fR. The default is \fB85\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBmaxfiles=\fR\fIn\fR\fR
-.ad
-.RS 18n
-Maximum number of files that CacheFS can use, expressed as a percentage of the
-total number of inodes in the front file system. If CacheFS does not have
-exclusive use of the front file system, there is no guarantee that all the
-inodes the \fBmaxfiles\fR parameter allows is available. The default is
-\fB90\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBminfiles=\fR\fIn\fR\fR
-.ad
-.RS 18n
-Minimum number of files, expressed as a percentage of the total number of
-inodes in the front file system, that CacheFS is always allowed to use without
-limitation by its internal control mechanisms. If CacheFS does not have
-exclusive use of the front file system, there is no guarantee that all the
-inodes the \fBminfiles\fR parameter attempts to reserve is available. The
-default is \fB0\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBthreshfiles=\fR\fIn\fR\fR
-.ad
-.RS 18n
-A percentage of the total inodes in the front file system beyond which CacheFS
-cannot claim inodes once its usage has reached the level specified by
-\fBminfiles\fR. The default is \fB85\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBmaxfilesize=\fR\fIn\fR\fR
-.ad
-.RS 18n
-Largest file size, expressed in megabytes, that CacheFS is allowed to cache.
-The default is \fB3\fR. You cannot decrease the block or inode allotment for a
-cache. To decrease the size of a cache, you must remove it and create it again
-with different parameters.
-.sp
-Currently \fBmaxfilesize\fR is ignored by \fBcachefs\fR, therefore, setting it
-has no effect.
-.RE
-
-.SH OPERANDS
-.sp
-.ne 2
-.na
-\fB\fIcache_directory\fR\fR
-.ad
-.RS 19n
-The directory under which the cache is actually stored.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fImntpt1\fR\fR
-.ad
-.RS 19n
-The directory where the CacheFS is mounted.
-.RE
-
-.SH USAGE
-.sp
-.LP
-See \fBlargefile\fR(5) for the description of the behavior of \fBcfsadmin\fR
-when encountering files greater than or equal to 2 Gbyte ( 2^31 bytes).
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRCreating a Cache Directory
-.sp
-.LP
-The following example creates a cache directory named \fB/cache\fR:
-
-.sp
-.in +2
-.nf
-example# cfsadmin -c /cache
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRCreating a Cache
-.sp
-.LP
-The following example creates a cache named \fB/cache1\fR that can claim a
-maximum of 60 percent of the blocks in the front file system, can use 40
-percent of the front file system blocks without interference by CacheFS
-internal control mechanisms, and has a threshold value of 50 percent. The
-threshold value indicates that after CacheFS reaches its guaranteed minimum, it
-cannot claim more space if 50 percent of the blocks in the front file system
-are already used.
-
-.sp
-.in +2
-.nf
-example# cfsadmin \fB-c\fR \fB-o\fR maxblocks=60,minblocks=40,threshblocks=50 /cache1
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 3 \fRChanging the \fBmaxfilesize\fR Parameter
-.sp
-.LP
-The following example changes the \fBmaxfilesize\fR parameter for the cache
-directory \fB/cache2\fR to 2 megabytes:
-
-.sp
-.in +2
-.nf
-example# cfsadmin \fB-u\fR \fB-o\fR maxfilesize=2 /cache2
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 4 \fRListing the Contents of a Cache Directory
-.sp
-.LP
-The following example lists the contents of a cache directory named
-\fB/cache3\fR and provides statistics about resource utilization:
-
-.sp
-.in +2
-.nf
-example# cfsadmin \fB-l\fR /cache3
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 5 \fRRemoving a Cached File System
-.sp
-.LP
-The following example removes the cached file system with cache ID \fB23\fR
-from the cache directory \fB/cache3\fR and frees its resources (the cache ID is
-part of the information returned by \fBcfsadmin \fR\fB-l\fR):
-
-.sp
-.in +2
-.nf
-example# cfsadmin \fB-d\fR 23 /cache3
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 6 \fRRemoving All Cached File Systems
-.sp
-.LP
-The following example removes all cached file systems from the cache directory
-\fB/cache3\fR:
-
-.sp
-.in +2
-.nf
-example# cfsadmin \fB-d\fR all /cache3
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 7 \fRChecking for Consistency in File Systems
-.sp
-.LP
-The following example checks for consistency all file systems mounted with
-\fBdemandconst\fR enabled. No errors are reported if no \fBdemandconst\fR file
-systems were found.
-
-.sp
-.in +2
-.nf
-example# \fBcfsadmin\fR \fB-s\fR \fBall\fR
-.fi
-.in -2
-.sp
-
-.SH EXIT STATUS
-.sp
-.LP
-The following exit values are returned:
-.sp
-.ne 2
-.na
-\fB\fB0\fR\fR
-.ad
-.RS 5n
-Successful completion.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB1\fR\fR
-.ad
-.RS 5n
-An error occurred.
-.RE
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcachefslog\fR(1M), \fBcachefsstat\fR(1M), \fBcachefswssize\fR(1M),
-\fBfsck_cachefs\fR(1M), \fBmount_cachefs\fR(1M), \fBattributes\fR(5),
-\fBlargefile\fR(5)
diff --git a/usr/src/man/man1m/fsck.1m b/usr/src/man/man1m/fsck.1m
index a4e38760f1..9b415adfe6 100644
--- a/usr/src/man/man1m/fsck.1m
+++ b/usr/src/man/man1m/fsck.1m
@@ -1,10 +1,11 @@
'\" te
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" Copyright 1989 AT&T
.\" 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 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]
-.TH FSCK 1M "May 7, 2008"
+.TH FSCK 1M "Sep 8, 2015"
.SH NAME
fsck \- check and repair file systems
.SH SYNOPSIS
@@ -20,7 +21,6 @@ fsck \- check and repair file systems
.fi
.SH DESCRIPTION
-.sp
.LP
\fBfsck\fR audits and interactively repairs inconsistent file system
conditions. If the file system is inconsistent the default action for each
@@ -60,7 +60,6 @@ file systems eligible for checking may be checked in parallel. Consult the file
system-specific man page (for example, \fBfsck_ufs\fR(1M)) for more
information.
.SH OPTIONS
-.sp
.LP
The following generic options are supported:
.sp
@@ -215,7 +214,6 @@ Check writable file systems only.
.RE
.SH EXIT STATUS
-.sp
.ne 2
.na
\fB\fB0\fR\fR
@@ -316,12 +314,10 @@ file system is mounted read-only and is OK
.RE
.SH USAGE
-.sp
.LP
The \fBfsck\fR command is \fBlarge file aware\fR for UFS file systems, per the
\fBlargefile\fR(5) man page.
.SH FILES
-.sp
.ne 2
.na
\fB\fB/etc/default/fs\fR\fR
@@ -353,7 +349,6 @@ list of default parameters for each file system
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -369,14 +364,12 @@ Interface Stability Committed
.TE
.SH SEE ALSO
-.sp
.LP
-\fBclri\fR(1M), \fBfsck_cachefs\fR(1M), \fBfsck_ufs\fR(1M), \fBfsdb_ufs\fR(1M),
+\fBclri\fR(1M), \fBfsck_ufs\fR(1M), \fBfsdb_ufs\fR(1M),
\fBfsirand\fR(1M), \fBfstyp\fR(1M), \fBmkfs\fR(1M), \fBmkfs_ufs\fR(1M),
\fBmountall\fR(1M), \fBnewfs\fR(1M), \fBreboot\fR( 1M), \fBvfstab\fR(4),
\fBattributes\fR(5), \fBlargefile\fR(5), \fBufs\fR(7FS)
.SH WARNINGS
-.sp
.LP
The operating system buffers file system data. Running \fBfsck\fR on a mounted
file system can cause the operating system's buffers to become out of date with
@@ -386,10 +379,8 @@ system is quiescent and that it is rebooted immediately after \fBfsck\fR is
run. Quite often, however, this will not be sufficient. A panic will probably
occur if running \fBfsck\fR on a file system modifies the file system.
.SH NOTES
-.sp
.LP
This command may not be supported for all \fIFSTypes\fR.
-.sp
.LP
Starting with Solaris 9, \fBfsck\fR manages extended attribute data on the
disk. (See \fBfsattr\fR(5) for a description of extended file attributes.) A
diff --git a/usr/src/man/man1m/fsck_cachefs.1m b/usr/src/man/man1m/fsck_cachefs.1m
deleted file mode 100644
index f000383687..0000000000
--- a/usr/src/man/man1m/fsck_cachefs.1m
+++ /dev/null
@@ -1,66 +0,0 @@
-'\" te
-.\" Copyright (c) 2002, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH FSCK_CACHEFS 1M "Oct 9, 2002"
-.SH NAME
-fsck_cachefs \- check integrity of data cached with CacheFS
-.SH SYNOPSIS
-.LP
-.nf
-\fBfsck\fR \fB-F\fR cachefs [\fB-m\fR] [\fB-o\fR noclean] \fIcache_directory\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The CacheFS version of the \fBfsck\fR command checks the integrity of a cache
-directory.This utility corrects any CacheFS problems it finds by default. There
-is no interactive mode. The most likely invocation of \fBfsck\fR for CacheFS
-file systems is at boot time from an entry in the \fB/etc/vfstab\fR file. See
-\fBvfstab\fR(4).
-.SH OPTIONS
-.sp
-.LP
-The following options are supported:
-.sp
-.ne 2
-.na
-\fB\fB-m\fR\fR
-.ad
-.RS 14n
-Check, but do not repair.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-o\fR \fBnoclean\fR\fR
-.ad
-.RS 14n
-Force a check on the cache even if there is no reason to suspect there is a
-problem.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRUsing \fBfsck_cachefs\fR to Force a Check on the Cache
-Directory
-.sp
-.LP
-The following example forces a check on the cache directory \fB/cache3\fR:
-
-.sp
-.in +2
-.nf
-example% fsck -F cachefs -o noclean /cache3
-.fi
-.in -2
-.sp
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcfsadmin\fR(1M), \fBfsck\fR(1M), \fBmount_cachefs\fR(1M), \fBvfstab\fR(4),
-\fBattributes\fR(5)
diff --git a/usr/src/man/man1m/mount.1m b/usr/src/man/man1m/mount.1m
index ff6e079bae..06c4f10269 100644
--- a/usr/src/man/man1m/mount.1m
+++ b/usr/src/man/man1m/mount.1m
@@ -1,9 +1,10 @@
'\" te
.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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 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]
-.TH MOUNT 1M "May 29, 2008"
+.TH MOUNT 1M "Sep 8, 2015"
.SH NAME
mount, umount \- mount or unmount file systems and remote resources
.SH SYNOPSIS
@@ -41,25 +42,21 @@ mount, umount \- mount or unmount file systems and remote resources
.fi
.SH DESCRIPTION
-.sp
.LP
\fBmount\fR attaches a file system to the file system hierarchy at the
\fImount_point\fR, which is the pathname of a directory. If \fImount_point\fR
has any contents prior to the \fBmount\fR operation, these are hidden until the
file system is unmounted.
-.sp
.LP
\fBumount\fR unmounts a currently mounted file system, which may be specified
either as a \fImount_point\fR or as \fIspecial\fR, the device on which the file
system resides.
-.sp
.LP
The table of currently mounted file systems can be found by examining the
mounted file system information file. This is provided by a file system that is
usually mounted on \fB/etc/mnttab\fR. The mounted file system information is
described in \fBmnttab\fR(4). Mounting a file system adds an entry to the mount
table; a \fBumount\fR removes an entry from the table.
-.sp
.LP
When invoked with both the \fIspecial\fR and \fImount_point\fR arguments and
the \fB-F\fR option, \fBmount\fR validates all arguments except for
@@ -75,7 +72,6 @@ will be used. Otherwise the default remote file system type will be used. The
default remote file system type is determined by the first entry in the
\fB/etc/dfs/fstypes\fR file. After filling in missing arguments, \fBmount\fR
will invoke the \fIFSType\fR-specific \fBmount\fR module.
-.sp
.LP
For file system types that support it, a file can be mounted directly as a file
system by specifying the full path to the file as the special argument. In
@@ -83,13 +79,11 @@ such a case, the \fBnosuid\fR option is enforced. If specific file system
support for such loopback file mounts is not present, you can still use
\fBlofiadm\fR(1M) to mount a file system image. In this case, no special
options are enforced.
-.sp
.LP
Only a user with sufficient privilege (at least \fBPRIV_SYS_MOUNT\fR) can mount
or unmount file systems using \fBmount\fR and \fBumount\fR. However, any user
can use \fBmount\fR to list mounted file systems and resources.
.SH OPTIONS
-.sp
.ne 2
.na
\fB\fB-F\fR \fIFSType\fR\fR
@@ -390,13 +384,11 @@ The following commands mount and unmount a DVD image.
.sp
.SH USAGE
-.sp
.LP
See \fBlargefile\fR(5) for the description of the behavior of \fBmount\fR and
\fBumount\fR when encountering files greater than or equal to 2 Gbyte ( 2^31
bytes).
.SH FILES
-.sp
.ne 2
.na
\fB\fB/etc/mnttab\fR\fR
@@ -438,21 +430,15 @@ List of default parameters for each file system.
.RE
.SH SEE ALSO
-.sp
.LP
-\fBlofiadm\fR(1M), \fBmount_cachefs\fR(1M), \fBmount_hsfs\fR(1M),
-\fBmount_nfs\fR(1M), \fBmount_pcfs\fR(1M), \fBmount_smbfs\fR(1M),
-\fBmount_tmpfs\fR(1M), \fBmount_udfs\fR(1M), \fBmount_ufs\fR(1M),
-\fBmountall\fR(1M), \fBumountall\fR(1M), \fBfcntl\fR(2), \fBmmap\fR(2),
-\fBmnttab\fR(4), \fBvfstab\fR(4), \fBattributes\fR( 5), \fBlargefile\fR(5),
+\fBlofiadm\fR(1M), \fBmount_hsfs\fR(1M), \fBmount_nfs\fR(1M),
+\fBmount_pcfs\fR(1M), \fBmount_smbfs\fR(1M), \fBmount_tmpfs\fR(1M),
+\fBmount_udfs\fR(1M), \fBmount_ufs\fR(1M), \fBmountall\fR(1M),
+\fBumountall\fR(1M), \fBfcntl\fR(2), \fBmmap\fR(2), \fBmnttab\fR(4),
+\fBvfstab\fR(4), \fBattributes\fR(5), \fBlargefile\fR(5),
\fBprivileges\fR(5), \fBlofs\fR(7FS), \fBpcfs\fR(7FS)
.SH NOTES
-.sp
.LP
If the directory on which a file system is to be mounted is a symbolic link,
the file system is mounted on the directory to which the symbolic link refers,
rather than on top of the symbolic link itself.
-.SH BUGS
-.sp
-.LP
-The \fBmount\fR \fB-p\fR output is incorrect for \fBcachefs\fR.
diff --git a/usr/src/man/man1m/mount_cachefs.1m b/usr/src/man/man1m/mount_cachefs.1m
deleted file mode 100644
index 3890de0c8e..0000000000
--- a/usr/src/man/man1m/mount_cachefs.1m
+++ /dev/null
@@ -1,260 +0,0 @@
-'\" te
-.\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved
-.\" 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 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]
-.TH MOUNT_CACHEFS 1M "Mar 18, 2004"
-.SH NAME
-mount_cachefs \- mount CacheFS file systems
-.SH SYNOPSIS
-.LP
-.nf
-\fBmount\fR \fB-F\fR cachefs [\fIgeneric_options\fR] \fB-o\fR backfstype=\fIfile_system_type\fR
- [\fIspecific_options\fR]
- [\fB-O\fR] \fIspecial\fR \fImount_point\fR
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The CacheFS-specific version of the \fBmount\fR command mounts a cached file
-system; if necessary, it NFS-mounts its back file system. It also provides a
-number of CacheFS-specific options for controlling the caching process. For
-more information regarding back file systems, refer to the \fI\fR.
-.sp
-.LP
-\fBmount_cachefs\fR cannot be used with replicated NFS mounts.
-\fBmount_cachefs\fR creates a pass through when used with an NFS version 4
-mount. No caching is performed.
-.SH OPTIONS
-.sp
-.LP
-To mount a CacheFS file system, use the generic \fBmount\fR command with the
-\fB-F\fR option followed by the argument \fBcachefs\fR.
-.sp
-.LP
-See \fBmount\fR(1M) for a list of supported \fIgeneric_options\fR.
-.sp
-.ne 2
-.na
-\fB\fB\fR\fB-o\fR\fB \fR\fIspecific_options\fR\fR
-.ad
-.RS 23n
-Specify CacheFS file system specific options in a comma-separated list with no
-intervening spaces.
-.sp
-.ne 2
-.na
-\fB\fBacdirmax=\fR\fIn\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies that cached attributes are held for no more than \fIn\fR seconds
-after directory update. After \fIn\fR seconds, all directory information is
-purged from the cache. The default value is \fB30\fR seconds.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBacdirmin=\fR\fIn\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies that cached attributes are held for at least \fIn\fR seconds after
-directory update. After \fIn\fR seconds, CacheFS checks to see if the directory
-modification time on the back file system has changed. If it has, all
-information about the directory is purged from the cache and new data is
-retrieved from the back file system. The default value is \fB30\fR seconds.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBacregmax=\fR\fIn\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies that cached attributes are held for no more than \fIn\fR seconds
-after file modification. After \fIn\fR seconds, all file information is purged
-from the cache. The default value is \fB30\fR seconds.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBacregmin=\fR\fIn\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies that cached attributes are held for at least \fIn\fR seconds after
-file modification. After \fIn\fR seconds, CacheFS checks to see if the file
-modification time on the back file system has changed. If it has, all
-information about the file is purged from the cache and new data is retrieved
-from the back file system. The default value is \fB30\fR seconds.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBactimeo=\fR\fIn\fR\fR
-.ad
-.sp .6
-.RS 4n
-Sets \fBacregmin\fR, \fBacregmax\fR, \fBacdirmin\fR, and \fBacdirmax\fR to
-\fIn\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBbackfstype=\fR\fIfile_system_type\fR\fR
-.ad
-.sp .6
-.RS 4n
-The file system type of the back file system (can be \fBnfs\fR or \fBhsfs\fR).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBbackpath=\fR\fIpath\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies where the back file system is already mounted. If this argument is
-not supplied, CacheFS determines a mount point for the back file system. The
-back file system must be read-only.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBcachedir=\fR\fIdirectory\fR\fR
-.ad
-.sp .6
-.RS 4n
-The name of the cache directory.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBcacheid=\fR\fIID\fR\fR
-.ad
-.sp .6
-.RS 4n
-\fIID\fR is a string specifying a particular instance of a cache. If you do not
-specify a cache ID, CacheFS will construct one.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBdemandconst\fR\fR
-.ad
-.sp .6
-.RS 4n
-Verifies cache consistency only when explicitly requested, rather than the
-periodic checking that is done by default. A consistency check is requested by
-using the \fB-s\fR option of the \fBcfsadmin\fR(1M) command. This option is
-useful for back file systems that change infrequently, for example,
-\fB/usr/openwin\fR. \fBdemandconst\fR and \fBnoconst\fR are mutually exclusive.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBlocal-access\fR\fR
-.ad
-.sp .6
-.RS 4n
-Causes the front file system to interpret the mode bits used for access
-checking instead of having the back file system verify access permissions. Do
-not use this argument with secure \fBNFS\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBnoconst\fR\fR
-.ad
-.sp .6
-.RS 4n
-Disables cache consistency checking. By default, periodic consistency checking
-is enabled. Specify \fBnoconst\fR only when you know that the back file system
-will not be modified. Trying to perform cache consistency check using
-\fBcfsadmin\fR \fB-s\fR will result in error. \fBdemandconst\fR and
-\fBnoconst\fR are mutually exclusive.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBwrite-around\fR | \fBnon-shared\fR\fR
-.ad
-.sp .6
-.RS 4n
-Write modes for CacheFS. The \fBwrite-around\fR mode (the default) handles
-writes the same as \fBNFS\fR does; that is, writes are made to the back file
-system, and the affected file is purged from the cache. You can use the
-\fBnon-shared\fR mode when you are sure that no one else will be writing to the
-cached file system. In this mode, all writes are made to both the front and the
-back file system, and the file remains in the cache.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-O\fR\fR
-.ad
-.RS 23n
-Overlay mount. Allows the filesystem to be mounted over an existing mount
-point, making the underlying filesystem inaccessible. If a mount is attempted
-on a pre-existing mount point without setting this flag, mount will fail with
-the error: \fBmount \fR\fB-F\fR\fB cachefs: mount failed Device busy\fR.
-.RE
-
-.SH EXAMPLES
-.LP
-\fBExample 1 \fRCacheFS-mounting a File System
-.sp
-.LP
-The following example CacheFS-mounts the file system \fBserver1:/user2\fR,
-which is already NFS-mounted on \fB/usr/abc\fR as \fB/xyz\fR.
-
-.sp
-.in +2
-.nf
-example# mount -F cachefs -o backfstype=nfs,backpath=/usr/abc,
- cachedir=/cache1 server1:/user2 /xyz
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-The lines similar to the following appear in the \fB/etc/mnttab\fR file after
-the \fBmount\fR command is executed:
-
-.sp
-.in +2
-.nf
-server1:/user2 /usr/abc nfs
-/usr/abc /cache1/xyz cachefs backfstype=nfs
-.fi
-.in -2
-.sp
-
-.SH SEE ALSO
-.sp
-.LP
-\fBcfsadmin\fR(1M), \fBfsck_cachefs\fR(1M), \fBmount\fR(1M),
-\fBattributes\fR(5) \fI\fR
-.SH BUGS
-.sp
-.LP
-The output for the \fIgeneric_option\fR \fB-p\fR output is incorrect for
-\fBcachefs\fR.
diff --git a/usr/src/man/man1m/mount_nfs.1m b/usr/src/man/man1m/mount_nfs.1m
index badd63ca9a..e1ed473b4a 100644
--- a/usr/src/man/man1m/mount_nfs.1m
+++ b/usr/src/man/man1m/mount_nfs.1m
@@ -1,10 +1,11 @@
'\" te
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" Copyright 1989 AT&T
.\" 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 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]
-.TH MOUNT_NFS 1M "Jun 3, 2015"
+.TH MOUNT_NFS 1M "Sep 8, 2015"
.SH NAME
mount_nfs \- mount remote NFS resources
.SH SYNOPSIS
@@ -898,10 +899,6 @@ used in conjunction with \fBremount\fR) affect the root (\fB/\fR) entry in the
\fB/etc/vfstab\fR file.
.sp
.LP
-\fBmount_cachefs\fR cannot be used with replicated NFS mounts or any NFS
-Version 4 mount.
-.sp
-.LP
The NFS client service is managed by the service management facility,
\fBsmf\fR(5), under the service identifier:
.sp
diff --git a/usr/src/man/man1m/zoneadm.1m b/usr/src/man/man1m/zoneadm.1m
index 6006e53b65..1ddfc1356a 100644
--- a/usr/src/man/man1m/zoneadm.1m
+++ b/usr/src/man/man1m/zoneadm.1m
@@ -1,10 +1,10 @@
'\" te
-.\" Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
.\" 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 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]
-.TH ZONEADM 1M "Dec 26, 2014"
+.TH ZONEADM 1M "Sep 8, 2015"
.SH NAME
zoneadm \- administer zones
.SH SYNOPSIS
@@ -488,7 +488,7 @@ wrong.
.RS 4n
Any \fBfs\fR resources have their \fItype\fR value checked. An error is
reported if the value is one of \fBproc\fR, \fBmntfs\fR, \fBautofs\fR,
-\fBcachefs\fR, or \fBnfs\fR or the filesystem does not have an associated mount
+or \fBnfs\fR or the filesystem does not have an associated mount
binary at \fB/usr/lib/fs/\fI<fstype>\fR/mount\fR.
.sp
It is an error for the \fIdirectory\fR to be a relative path.
diff --git a/usr/src/man/man4/mnttab.4 b/usr/src/man/man4/mnttab.4
index 7376e01861..e188b308e2 100644
--- a/usr/src/man/man4/mnttab.4
+++ b/usr/src/man/man4/mnttab.4
@@ -1,14 +1,14 @@
'\" te
.\" Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" Copyright 1989 AT&T
.\" 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 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]
-.TH MNTTAB 4 "Dec 20, 2003"
+.TH MNTTAB 4 "Sep 8, 2015"
.SH NAME
mnttab \- mounted file system table
.SH DESCRIPTION
-.sp
.LP
The file \fB/etc/mnttab\fR is really a file system that provides read-only
access to the table of mounted file systems for the current host.
@@ -21,7 +21,6 @@ mount time. That is, the first mounted file system is first in the list and the
most recently mounted file system is last. When mounted on a mount point the
file system appears as a regular file containing the current \fBmnttab\fR
information.
-.sp
.LP
Each entry is a line of fields separated by TABs in the form:
.sp
@@ -31,7 +30,6 @@ Each entry is a line of fields separated by TABs in the form:
.fi
.in -2
-.sp
.LP
where:
.sp
@@ -80,14 +78,12 @@ section below.
The time at which the file system was mounted.
.RE
-.sp
.LP
Examples of entries for the \fIspecial\fR field include the pathname of a
block-special device, the name of a remote file system in the form of
\fIhost:pathname\fR, or the name of a \fBswap file\fR, for example, a file made
with \fBmkfile\fR(1M).
.SH IOCTLS
-.sp
.LP
The following \fBioctl\fR(2) calls are supported:
.sp
@@ -155,7 +151,6 @@ privilege.
.RE
.SH ERRORS
-.sp
.ne 2
.na
\fB\fBEFAULT\fR\fR
@@ -198,7 +193,6 @@ The calling process does not have \fB{PRIV_SYS_MOUNT}\fR privilege and either a
.RE
.SH FILES
-.sp
.ne 2
.na
\fB\fB/etc/mnttab\fR\fR
@@ -217,31 +211,26 @@ Header file that contains \fBIOCTL\fR definitions
.RE
.SH SEE ALSO
-.sp
.LP
-\fBmkfile\fR(1M), \fBmount_cachefs\fR(1M), \fBmount_hsfs\fR(1M),
-\fBmount_nfs\fR(1M), \fBmount_pcfs\fR(1M), \fBmount_ufs\fR(1M),
-\fBmount\fR(1M), \fBioctl\fR(2), \fBread\fR(2), \fBpoll\fR(2), \fBstat\fR(2),
+\fBmkfile\fR(1M), \fBmount_hsfs\fR(1M), \fBmount_nfs\fR(1M),
+\fBmount_pcfs\fR(1M), \fBmount_ufs\fR(1M), \fBmount\fR(1M),
+\fBioctl\fR(2), \fBread\fR(2), \fBpoll\fR(2), \fBstat\fR(2),
\fBgetmntent\fR(3C)
.SH WARNINGS
-.sp
.LP
The \fBmnttab\fR file system provides the previously undocumented
\fBdev=\fR\fIxxx\fR option in the option string for each mounted file system.
This is provided for legacy applications that might have been using the
\fBdev=information\fR option.
-.sp
.LP
Using \fBdev=\fR\fIoption\fR in applications is strongly discouraged. The
device number string represents a 32-bit quantity and might not contain correct
information in 64-bit environments.
-.sp
.LP
Applications requiring device number information for mounted file systems
should use the \fBgetextmntent\fR(3C) interface, which functions properly in
either 32- or 64-bit environments.
.SH NOTES
-.sp
.LP
The snapshot of the \fBmnttab\fR information is taken any time a \fBread\fR(2)
is performed at offset \fB0\fR (the beginning) of the \fBmnttab\fR file. The
diff --git a/usr/src/man/man4/packingrules.4 b/usr/src/man/man4/packingrules.4
index 7dce1fc07d..bc8c891541 100644
--- a/usr/src/man/man4/packingrules.4
+++ b/usr/src/man/man4/packingrules.4
@@ -1,11 +1,12 @@
'\" te
.\" Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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 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]
-.TH PACKINGRULES 4 "Dec 23, 1996"
+.TH PACKINGRULES 4 "Sep 8, 2015"
.SH NAME
-packingrules \- packing rules file for cachefs and filesync
+packingrules \- packing rules file for filesync
.SH SYNOPSIS
.LP
.nf
@@ -13,21 +14,17 @@ packingrules \- packing rules file for cachefs and filesync
.fi
.SH DESCRIPTION
-.sp
.LP
\fB$\fR\fBHOME\fR\fB/.packingrules\fR is a packing rules file for
-\fBfilesync\fR and \fBcachefspack\fR. \fB$\fR\fBHOME\fR\fB/.packingrules\fR
+\fBfilesync\fR. \fB$\fR\fBHOME\fR\fB/.packingrules\fR
contains a list of directories and files that are to be packed and
synchronized. It also contains a list of directories and files that are to be
-specifically excluded from packing and synchronization. See \fBfilesync\fR(1)
-and \fBcachefspack\fR(1M).
-.sp
+specifically excluded from packing and synchronization. See \fBfilesync\fR(1).
.LP
The \fB$\fR\fBHOME\fR\fB/.packingrules\fR file is automatically created if
users invoke \fBfilesync\fR with filename arguments. By using \fBfilesync\fR
options, users can augment the packing rules in
\fB$\fR\fBHOME\fR\fB/.packingrules\fR.
-.sp
.LP
Many users choose to manually create the packing rules file and edit it by
hand. Users can edit \fB$\fR\fBHOME\fR\fB/.packingrules\fR (using any editor)
@@ -35,14 +32,11 @@ to permanently change the \fB$\fR\fBHOME\fR\fB/.packingrules\fR file, or to
gain access to more powerful options that are not available from the command
line (such as \fBIGNORE\fR commands). It is much easier to enter complex
wildcard expressions by editing the \fB$\fR\fBHOME\fR\fB/.packingrules\fR file.
-.sp
.LP
Blank lines and lines that begin with a pound sign (`\fB#\fR') are ignored.
-.sp
.LP
Any line can be continued by placing a backslash (`\fB\e\fR\&') immediately
before the \fBNEWLINE.\fR
-.sp
.LP
All other lines in the \fB$\fR\fBHOME\fR\fB/.packingrules\fR file have one of
the following formats:
@@ -184,6 +178,5 @@ LIST !find . -type f -a -perm -111 -a -print
.sp
.SH SEE ALSO
-.sp
.LP
-\fBfile\fR(1), \fBfilesync\fR(1), \fBcachefspack\fR(1M)
+\fBfile\fR(1), \fBfilesync\fR(1)
diff --git a/usr/src/man/man4/vfstab.4 b/usr/src/man/man4/vfstab.4
index b80e2bbbc5..3b2bec5a69 100644
--- a/usr/src/man/man4/vfstab.4
+++ b/usr/src/man/man4/vfstab.4
@@ -1,14 +1,14 @@
'\" te
.\" Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 1989 AT&T
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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 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]
-.TH VFSTAB 4 "Mar 2, 2007"
+.TH VFSTAB 4 "Sep 8, 2015"
.SH NAME
vfstab \- table of file system defaults
.SH DESCRIPTION
-.sp
.LP
The file \fB/etc/vfstab\fR describes defaults for each file system. The
information is stored in a table with the following column headings:
@@ -46,7 +46,6 @@ area, the \fIdevice-to-mount\fR field contains the name of the swap file or
device, the \fIFS-type\fR is "swap", \fImount-at-boot\fR is "no" and all other
fields have no entry.
.SH EXAMPLES
-.sp
.LP
The following are \fBvfstab\fR entries for various file system types supported
in the Solaris operating environment.
@@ -142,36 +141,7 @@ above) for a \fBpcfs\fR logical drive. See \fBmount_pcfs\fR(1M) for syntax for
\fBpcfs\fR logical drives and for \fBpcfs\fR-specific mount options.
.LP
-\fBExample 3 \fRCacheFS Mount
-.sp
-.LP
-Below is an example for a CacheFS file system. Because of the length of this
-entry and the fact that \fBvfstab\fR entries cannot be continued to a second
-line, the \fBvfstab\fR fields are presented here in a vertical format. In
-re-creating such an entry in your own \fBvfstab\fR, you would enter values as
-you would for any \fBvfstab\fR entry, on a single line.
-
-.sp
-.in +2
-.nf
-device to mount: svr1:/export/abc
-device to fsck: /usr/abc
-mount point: /opt/cache
-FS type: cachefs
-fsck pass: 7
-mount at boot: yes
-mount options:
-local-access,bg,nosuid,demandconst,backfstype=nfs,cachedir=/opt/cache
-.fi
-.in -2
-.sp
-
-.sp
-.LP
-See \fBmount_cachefs\fR(1M) for CacheFS-specific mount options.
-
-.LP
-\fBExample 4 \fRLoopback File System Mount
+\fBExample 3 \fRLoopback File System Mount
.sp
.LP
The following is an example of mounting a loopback (\fBlofs\fR) file system:
@@ -189,9 +159,8 @@ The following is an example of mounting a loopback (\fBlofs\fR) file system:
See \fBlofs\fR(7FS) for an overview of the loopback file system.
.SH SEE ALSO
-.sp
.LP
-\fBfsck\fR(1M), \fBmount\fR(1M), \fBmount_cachefs\fR(1M), \fBmount_hsfs\fR(1M),
+\fBfsck\fR(1M), \fBmount\fR(1M), \fBmount_hsfs\fR(1M),
\fBmount_nfs\fR(1M), \fBmount_tmpfs\fR(1M), \fBmount_ufs\fR(1M),
\fBswap\fR(1M), \fBgetvfsent\fR(3C)
.sp
diff --git a/usr/src/man/man5/largefile.5 b/usr/src/man/man5/largefile.5
index 109f138489..3da728fe79 100644
--- a/usr/src/man/man5/largefile.5
+++ b/usr/src/man/man5/largefile.5
@@ -1,20 +1,19 @@
'\" te
.\" Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved
.\" Portions Copyright (c) 1982-2007 AT&T Knowledge Ventures
+.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
.\" 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
.\" 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]
-.TH LARGEFILE 5 "Nov 2, 2007"
+.TH LARGEFILE 5 "Sep 8, 2015"
.SH NAME
largefile \- large file status of utilities
.SH DESCRIPTION
-.sp
.LP
A \fIlarge file\fR is a regular file whose size is greater than or equal to 2
Gbyte ( 2^31 bytes). A \fIsmall file\fR is a regular file whose size is less
than 2 Gbyte.
.SS "Large file aware utilities"
-.sp
.LP
A utility is called \fIlarge file aware\fR if it can process large files in the
same manner as it does small files. A utility that is large file aware is able
@@ -28,7 +27,6 @@ will accept configuration or support files that are large files. If a large
file aware utility does not accept configuration or support files that are
large files, it will cause no data loss or corruption upon encountering such
files and will return an appropriate error.
-.sp
.LP
The following \fB/usr/bin\fR utilities are large file aware:
.sp
@@ -53,7 +51,6 @@ l l l l l .
\fBuudcode\fR \fBuuencode\fR \fBvacation\fR \fBwc\fR \fBzcat\fR
.TE
-.sp
.LP
The following \fB/usr/xpg4/bin\fR utilities are large file aware:
.sp
@@ -68,7 +65,6 @@ l l l l l .
\fBsh\fR sort tail tr
.TE
-.sp
.LP
The following \fB/usr/xpg6/bin\fR utilities are large file aware:
.sp
@@ -79,7 +75,6 @@ l l l l l .
\fBgetconf\fR \fBls\fR \fBtr\fR
.TE
-.sp
.LP
The following \fB/usr/sbin\fR utilities are large file aware:
.sp
@@ -92,7 +87,6 @@ l l l l l .
\fBmvdir\fR \fBswap\fR
.TE
-.sp
.LP
The following \fB/usr/lib\fR utilities are large file aware:
.sp
@@ -103,7 +97,6 @@ l l l l l .
\fBmail.local\fR \fBsendmail\fR \fBsmrsh\fR
.TE
-.sp
.LP
See the USAGE section of the \fBswap\fR(1M) manual page for limitations of
\fBswap\fR on block devices greater than 2 Gbyte on a 32-bit operating system.
@@ -120,43 +113,13 @@ l l l l l .
\fBsum\fR \fBtouch\fR
.TE
-.sp
.LP
The \fB/usr/bin/cpio\fR and \fB/usr/bin/pax\fR utilities are large file aware,
but cannot archive a file whose size exceeds 8 Gbyte - 1 byte.
-.sp
.LP
The \fB/usr/bin/truss\fR utilities has been modified to read a dump file and
display information relevant to large files, such as offsets.
-.SS "cachefs file systems"
-.sp
-.LP
-The following \fB/usr/bin\fR utilities are large file aware for \fBcachefs\fR
-file systems:
-.sp
-
-.sp
-.TS
-l l l l .
-\fBcachefspack\fR \fBcachefsstat\fR
-.TE
-
-.sp
-.LP
-The following \fB/usr/sbin\fR utilities are large file aware for \fBcachefs\fR
-file systems:
-.sp
-
-.sp
-.TS
-l l l l
-l l l l .
-\fBcachefslog\fR \fBcachefswssize\fR \fBcfsadmin\fR \fBfsck\fR
-\fBmount\fR \fBumount\fR
-.TE
-
.SS "nfs file systems"
-.sp
.LP
The following utilities are large file aware for \fBnfs\fR file systems:
.sp
@@ -170,28 +133,21 @@ l l .
.TE
.SS "ufs file systems"
-.sp
.LP
The following \fB/usr/bin\fR utility is large file aware for \fBufs\fR file
systems:
-.sp
.LP
\fBdf\fR
-.sp
.LP
The following \fB/usr/lib/nfs\fR utility is large file aware for \fBufs\fR file
systems:
-.sp
.LP
\fBrquotad\fR
-.sp
.LP
The following \fB/usr/xpg4/bin\fR utility is large file aware for \fBufs\fR
file systems:
-.sp
.LP
\fBdf\fR
-.sp
.LP
The following \fB/usr/sbin\fR utilities are large file aware for \fBufs\fR file
systems:
@@ -209,12 +165,10 @@ l l l l l .
.TE
.SS "Large file safe utilities"
-.sp
.LP
A utility is called \fBlarge file safe\fR if it causes no data loss or
corruption when it encounters a large file. A utility that is large file safe
is unable to process properly a large file, but returns an appropriate error.
-.sp
.LP
The following \fB/usr/bin\fR utilities are large file safe:
.sp
@@ -230,7 +184,6 @@ l l l l l .
\fBview\fR
.TE
-.sp
.LP
The following \fB/usr/xpg4/bin\fR utilities are large file safe:
.sp
@@ -241,7 +194,6 @@ l l l l l .
\fBed\fR \fBvi\fR \fBview\fR
.TE
-.sp
.LP
The following \fB/usr/xpg6/bin\fR utility is large file safe:
.sp
@@ -252,7 +204,6 @@ l l l l l .
\fBed\fR
.TE
-.sp
.LP
The following \fB/usr/sbin\fR utilities are large file safe:
.sp
@@ -263,7 +214,6 @@ l l l l l .
lpfilter lpforms
.TE
-.sp
.LP
The following \fB/usr/ucb\fR utilities are large file safe:
.sp
@@ -275,6 +225,5 @@ l l l l l .
.TE
.SH SEE ALSO
-.sp
.LP
\fBlf64\fR(5), \fBlfcompile\fR(5), \fBlfcompile64\fR(5)
diff --git a/usr/src/pkg/manifests/SUNWcs.man1m.inc b/usr/src/pkg/manifests/SUNWcs.man1m.inc
index 3bba753ce6..594c67f4ea 100644
--- a/usr/src/pkg/manifests/SUNWcs.man1m.inc
+++ b/usr/src/pkg/manifests/SUNWcs.man1m.inc
@@ -11,7 +11,7 @@
#
# Copyright 2011, Richard Lowe
-# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
file path=usr/share/man/man1m/6to4relay.1m
@@ -30,11 +30,6 @@ file path=usr/share/man/man1m/auditstat.1m
file path=usr/share/man/man1m/autopush.1m
file path=usr/share/man/man1m/bootadm.1m
file path=usr/share/man/man1m/busstat.1m
-file path=usr/share/man/man1m/cachefsd.1m
-file path=usr/share/man/man1m/cachefslog.1m
-file path=usr/share/man/man1m/cachefspack.1m
-file path=usr/share/man/man1m/cachefsstat.1m
-file path=usr/share/man/man1m/cachefswssize.1m
file path=usr/share/man/man1m/captoinfo.1m
file path=usr/share/man/man1m/cfgadm.1m
file path=usr/share/man/man1m/cfgadm_ac.1m
@@ -47,7 +42,6 @@ file path=usr/share/man/man1m/cfgadm_sbd.1m
file path=usr/share/man/man1m/cfgadm_scsi.1m
file path=usr/share/man/man1m/cfgadm_sysctrl.1m
file path=usr/share/man/man1m/cfgadm_usb.1m
-file path=usr/share/man/man1m/cfsadmin.1m
file path=usr/share/man/man1m/chroot.1m
file path=usr/share/man/man1m/clear_locks.1m
file path=usr/share/man/man1m/clinfo.1m
@@ -91,7 +85,6 @@ file path=usr/share/man/man1m/fiocompress.1m
file path=usr/share/man/man1m/fmthard.1m
file path=usr/share/man/man1m/format.1m
file path=usr/share/man/man1m/fsck.1m
-file path=usr/share/man/man1m/fsck_cachefs.1m
file path=usr/share/man/man1m/fsck_ufs.1m
file path=usr/share/man/man1m/fsdb.1m
file path=usr/share/man/man1m/fsdb_ufs.1m
@@ -163,7 +156,6 @@ file path=usr/share/man/man1m/modinfo.1m
file path=usr/share/man/man1m/modload.1m
file path=usr/share/man/man1m/modunload.1m
file path=usr/share/man/man1m/mount.1m
-file path=usr/share/man/man1m/mount_cachefs.1m
file path=usr/share/man/man1m/mount_hsfs.1m
file path=usr/share/man/man1m/mount_tmpfs.1m
file path=usr/share/man/man1m/mount_ufs.1m
diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf
index 89b3304d9d..3b8522b4d4 100644
--- a/usr/src/pkg/manifests/SUNWcs.mf
+++ b/usr/src/pkg/manifests/SUNWcs.mf
@@ -177,7 +177,6 @@ dir path=usr/lib/devfsadm/linkmod group=sys
dir path=usr/lib/fs group=sys
dir path=usr/lib/fs/autofs group=sys
dir path=usr/lib/fs/autofs/$(ARCH64) group=sys
-dir path=usr/lib/fs/cachefs group=sys
dir path=usr/lib/fs/ctfs group=sys
dir path=usr/lib/fs/dev group=sys
dir path=usr/lib/fs/fd group=sys
@@ -370,7 +369,6 @@ file path=etc/inet/services group=sys preserve=true
file path=etc/inet/wanboot.conf.sample group=sys mode=0444
file path=etc/init.d/PRESERVE group=sys mode=0744 preserve=true
file path=etc/init.d/README group=sys preserve=true
-file path=etc/init.d/cachefs.daemon group=sys mode=0744 preserve=true
file path=etc/init.d/sysetup group=sys mode=0744 preserve=true
file path=etc/inittab group=sys preserve=true
file path=etc/ioctl.syscon group=sys preserve=true
@@ -949,20 +947,6 @@ $(i386_ONLY)file path=usr/lib/devfsadm/linkmod/SUNW_xen_link.so group=sys
file path=usr/lib/diffh mode=0555
file path=usr/lib/expreserve mode=0555
file path=usr/lib/exrecover mode=0555
-file path=usr/lib/fs/cachefs/cachefsd mode=0555
-file path=usr/lib/fs/cachefs/cachefslog mode=0555
-file path=usr/lib/fs/cachefs/cachefspack mode=0555
-file path=usr/lib/fs/cachefs/cachefsstat mode=0555
-file path=usr/lib/fs/cachefs/cachefswssize mode=0555
-file path=usr/lib/fs/cachefs/cfsadmin mode=0555
-file path=usr/lib/fs/cachefs/cfsfstype mode=0555
-file path=usr/lib/fs/cachefs/cfstagchk mode=0555
-file path=usr/lib/fs/cachefs/dfshares mode=0555
-file path=usr/lib/fs/cachefs/fsck mode=0555
-file path=usr/lib/fs/cachefs/mount mode=0555
-file path=usr/lib/fs/cachefs/share mode=0555
-file path=usr/lib/fs/cachefs/umount mode=0555
-file path=usr/lib/fs/cachefs/unshare mode=0555
file path=usr/lib/fs/ctfs/mount mode=0555
file path=usr/lib/fs/fd/mount mode=0555
file path=usr/lib/fs/hsfs/fstyp.so.1 mode=0555
@@ -1469,8 +1453,6 @@ file path=var/saf/zsmon/log group=sys preserve=true
file path=var/spool/cron/crontabs/adm group=sys mode=0600 preserve=true
file path=var/spool/cron/crontabs/root group=sys mode=0600 preserve=true
hardlink path=etc/rc2.d/S20sysetup target=../../etc/init.d/sysetup
-hardlink path=etc/rc2.d/S73cachefs.daemon \
- target=../../etc/init.d/cachefs.daemon
hardlink path=etc/rc2.d/S89PRESERVE target=../../etc/init.d/PRESERVE
$(sparc_ONLY)hardlink path=etc/svc/profile/platform_SUNW,Sun-Fire-V890.xml \
target=./platform_SUNW,Sun-Fire-880.xml
@@ -1754,8 +1736,6 @@ link path=sbin/pfsh target=../usr/bin/pfexec
link path=sbin/sh target=../usr/bin/$(ARCH32)/ksh93
link path=sbin/su target=../usr/bin/su
link path=usr/adm target=../var/adm
-link path=usr/bin/cachefspack target=../lib/fs/cachefs/cachefspack
-link path=usr/bin/cachefsstat target=../lib/fs/cachefs/cachefsstat
link path=usr/bin/df target=../sbin/df
link path=usr/bin/jsh target=ksh93
link path=usr/bin/pwconv target=../sbin/pwconv
@@ -1790,9 +1770,6 @@ link path=usr/preserve target=../var/preserve
link path=usr/pub target=./share/lib/pub
link path=usr/sbin/autopush target=../../sbin/autopush
link path=usr/sbin/bootadm target=../../sbin/bootadm
-link path=usr/sbin/cachefslog target=../lib/fs/cachefs/cachefslog
-link path=usr/sbin/cachefswssize target=../lib/fs/cachefs/cachefswssize
-link path=usr/sbin/cfsadmin target=../lib/fs/cachefs/cfsadmin
link path=usr/sbin/cryptoadm target=../../sbin/cryptoadm
link path=usr/sbin/dcopy target=./clri
link path=usr/sbin/devnm target=./df
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index c095e30963..54ba88c061 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -22,7 +22,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012 by Delphix. All rights reserved.
-# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
# Copyright 2013 Saso Kiselkov. All rights reserved.
#
@@ -1010,13 +1010,6 @@ $(sparc_ONLY)file path=usr/include/sys/fpu/globals.h
$(sparc_ONLY)file path=usr/include/sys/fpu/ieee.h
file path=usr/include/sys/frame.h
file path=usr/include/sys/fs/autofs.h
-file path=usr/include/sys/fs/cachefs_dir.h
-file path=usr/include/sys/fs/cachefs_dlog.h
-file path=usr/include/sys/fs/cachefs_filegrp.h
-file path=usr/include/sys/fs/cachefs_fs.h
-file path=usr/include/sys/fs/cachefs_fscache.h
-file path=usr/include/sys/fs/cachefs_ioctl.h
-file path=usr/include/sys/fs/cachefs_log.h
file path=usr/include/sys/fs/decomp.h
file path=usr/include/sys/fs/dv_node.h
file path=usr/include/sys/fs/fifonode.h
diff --git a/usr/src/pkg/manifests/system-kernel.mf b/usr/src/pkg/manifests/system-kernel.mf
index 507d6355b6..862485dda8 100644
--- a/usr/src/pkg/manifests/system-kernel.mf
+++ b/usr/src/pkg/manifests/system-kernel.mf
@@ -22,6 +22,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2013 Saso Kiselkov. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -584,7 +585,6 @@ file path=kernel/exec/$(ARCH64)/intpexec group=sys mode=0755
$(i386_ONLY)file path=kernel/exec/elfexec group=sys mode=0755
$(i386_ONLY)file path=kernel/exec/intpexec group=sys mode=0755
file path=kernel/fs/$(ARCH64)/autofs group=sys mode=0755
-file path=kernel/fs/$(ARCH64)/cachefs group=sys mode=0755
file path=kernel/fs/$(ARCH64)/ctfs group=sys mode=0755
file path=kernel/fs/$(ARCH64)/dcfs group=sys mode=0755
file path=kernel/fs/$(ARCH64)/dev group=sys mode=0755
@@ -602,7 +602,6 @@ file path=kernel/fs/$(ARCH64)/specfs group=sys mode=0755
file path=kernel/fs/$(ARCH64)/tmpfs group=sys mode=0755
file path=kernel/fs/$(ARCH64)/ufs group=sys mode=0755
$(i386_ONLY)file path=kernel/fs/autofs group=sys mode=0755
-$(i386_ONLY)file path=kernel/fs/cachefs group=sys mode=0755
$(i386_ONLY)file path=kernel/fs/ctfs group=sys mode=0755
$(i386_ONLY)file path=kernel/fs/dcfs group=sys mode=0755
$(i386_ONLY)file path=kernel/fs/dev group=sys mode=0755
diff --git a/usr/src/tools/env/illumos.sh b/usr/src/tools/env/illumos.sh
index 02c77b7cdb..eb41bc7256 100644
--- a/usr/src/tools/env/illumos.sh
+++ b/usr/src/tools/env/illumos.sh
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2010, 2011 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
# Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
# Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
#
@@ -199,8 +199,8 @@ export MAKEFLAGS='k'
export UT_NO_USAGE_TRACKING='1'
# Build tools - don't change these unless you know what you're doing. These
-# variables allows you to get the compilers and onbld files locally or
-# through cachefs. Set BUILD_TOOLS to pull everything from one location.
+# variables allows you to get the compilers and onbld files locally.
+# Set BUILD_TOOLS to pull everything from one location.
# Alternately, you can set ONBLD_TOOLS to where you keep the contents of
# SUNWonbld and SPRO_ROOT to where you keep the compilers. SPRO_VROOT
# exists to make it easier to test new versions of the compiler.
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 6bb8f4ad00..3421b83719 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -1113,15 +1113,6 @@ JAVAEXEC_OBJS +=java.o
#
AUTOFS_OBJS += auto_vfsops.o auto_vnops.o auto_subr.o auto_xdr.o auto_sys.o
-CACHEFS_OBJS += cachefs_cnode.o cachefs_cod.o \
- cachefs_dir.o cachefs_dlog.o cachefs_filegrp.o \
- cachefs_fscache.o cachefs_ioctl.o cachefs_log.o \
- cachefs_module.o \
- cachefs_noopc.o cachefs_resource.o \
- cachefs_strict.o \
- cachefs_subr.o cachefs_vfsops.o \
- cachefs_vnops.o
-
DCFS_OBJS += dc_vnops.o
DEVFS_OBJS += devfs_subr.o devfs_vfsops.o devfs_vnops.o
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index 94d236a560..8446e0dcf5 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -208,10 +208,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/autofs/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
-$(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/cachefs/%.c
- $(COMPILE.c) -o $@ $<
- $(CTFCONVERT_O)
-
$(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/dcfs/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -1752,9 +1748,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/autofs/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
-$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/cachefs/%.c
- @($(LHEAD) $(LINT.c) $< $(LTAIL))
-
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/ctfs/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
diff --git a/usr/src/uts/common/cpr/cpr_misc.c b/usr/src/uts/common/cpr/cpr_misc.c
index 1c862cdfc0..b1906eb9fa 100644
--- a/usr/src/uts/common/cpr/cpr_misc.c
+++ b/usr/src/uts/common/cpr/cpr_misc.c
@@ -21,6 +21,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -1085,7 +1086,7 @@ cpr_is_zfs(struct vfs *vfsp)
* This is a list of file systems that are allowed to be writeable when a
* reusable statefile checkpoint is taken. They must not have any state that
* cannot be restored to consistency by simply rebooting using the checkpoint.
- * (In contrast to ufs, cachefs and pcfs which have disk state that could get
+ * (In contrast to ufs and pcfs which have disk state that could get
* out of sync with the in-kernel data).
*/
int
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_cnode.c b/usr/src/uts/common/fs/cachefs/cachefs_cnode.c
deleted file mode 100644
index f57b732eb0..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_cnode.c
+++ /dev/null
@@ -1,1965 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/buf.h>
-#include <netinet/in.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <rpc/auth.h>
-#include <rpc/clnt.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/modctl.h>
-#include <vm/pvn.h>
-
-#include <sys/fs/cachefs_fs.h>
-
-/*
- * cachefs_max_idle is a global that is tunable.
- * This value decides how frequently or when the
- * cachefs_cnode_idleclean is run.
- * The default value is set to CFS_FS_MAXIDLE.
- * The tunable if set to X triggers a cleanup when
- * the number of idle cnodes reach X, and cleans up
- * (.25 * X) idle cnodes.
- */
-int cachefs_max_idle = CFS_FS_MAXIDLE;
-
-
-struct kmem_cache *cachefs_cnode_cache = NULL;
-
-/*
- * Functions for cnode management.
- */
-
-/*
- * Puts cnode on idle list. Only call from an async thread or no
- * locks held.
- */
-/*ARGSUSED1*/
-void
-cachefs_cnode_idle(struct vnode *vp, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int cleanidle;
- vnode_t *unldvp;
- cred_t *unlcred;
- char *unlname;
- int error;
-
- /*
- * The key to this routine is not to drop the vnode count
- * while on the idle list. This prevents this routine from
- * being called again by vn_rele on an inactive cnode.
- * Nothing bad happens if an "active" cnode is put on the idle
- * list. It eventually gets pulled off.
- * Also this routine is only called from a thread message sent
- * by cachefs_inactive(). It is not safe for this routine
- * to be the "inactive" entry point because of the dnlc.
- */
-
- for (;;) {
- /* get access to the file system */
- error = cachefs_cd_access(fscp, 0, 1);
- ASSERT(error == 0);
-
- /* get exclusive access to this cnode */
- mutex_enter(&cp->c_statelock);
-
- /* done with this loop if not unlinking a file */
- if (cp->c_unldvp == NULL)
- break;
-
- /* get unlink info out of the cnode */
- unldvp = cp->c_unldvp;
- unlcred = cp->c_unlcred;
- unlname = cp->c_unlname;
- cp->c_unldvp = NULL;
- cp->c_unlcred = NULL;
- cp->c_unlname = NULL;
- mutex_exit(&cp->c_statelock);
-
- /* finish the remove operation */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_remove_connected(unldvp,
- unlname, unlcred, vp);
- } else {
- error = cachefs_remove_disconnected(unldvp,
- unlname, unlcred, vp);
- }
-
- /* reacquire cnode lock */
- mutex_enter(&cp->c_statelock);
-
- /* if a timeout occurred */
- if (CFS_TIMEOUT(fscp, error)) {
- /* restore cnode state */
- if (cp->c_unldvp == NULL) {
- cp->c_unldvp = unldvp;
- cp->c_unlcred = unlcred;
- cp->c_unlname = unlname;
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- continue;
- } else {
- cp->c_flags |= CN_PENDRM;
- mutex_exit(&cp->c_statelock);
- goto out;
- }
- }
- }
- /* free up resources */
- VN_RELE(unldvp);
- cachefs_kmem_free(unlname, MAXNAMELEN);
- crfree(unlcred);
- break;
- }
-
- ASSERT((cp->c_flags & CN_IDLE) == 0);
- /*
- * If we are going to destroy this cnode,
- * do it now instead of later.
- */
- if (cp->c_flags & (CN_DESTROY | CN_STALE)) {
- mutex_exit(&cp->c_statelock);
- (void) cachefs_cnode_inactive(vp, cr);
- goto out;
- }
-
- /*
- * mark cnode as idle, put it on the idle list, and increment the
- * number of idle cnodes
- */
- cp->c_flags |= CN_IDLE;
- mutex_enter(&fscp->fs_idlelock);
- cachefs_cnode_idleadd(cp);
- if ((fscp->fs_idlecnt > cachefs_max_idle) &&
- (fscp->fs_idleclean == 0) &&
- (fscp->fs_cdtransition == 0)) {
- fscp->fs_idleclean = 1;
- cleanidle = 1;
- } else {
- cleanidle = 0;
- }
- mutex_exit(&fscp->fs_idlelock);
-
- /* release cnode */
- mutex_exit(&cp->c_statelock);
-
- /* if should reduce the number of idle cnodes */
- if (cleanidle) {
- ASSERT(fscp->fs_idlecnt > 1);
- fscache_hold(fscp);
- cachefs_cnode_idleclean(fscp, 0);
- /* XXX race with cachefs_unmount() calling destroy */
- fscache_rele(fscp);
- }
-
-out:
- /* release hold on the file system */
- /* XXX unmount() could have called destroy after fscache_rele() */
- cachefs_cd_release(fscp);
-}
-
-/*
- * Removes cnodes from the idle list and destroys them.
- */
-void
-cachefs_cnode_idleclean(fscache_t *fscp, int unmount)
-{
- int remcnt;
- cnode_t *cp;
-
- mutex_enter(&fscp->fs_idlelock);
-
- /* determine number of cnodes to destroy */
- if (unmount) {
- /* destroy all plus any that go idle while in this routine */
- remcnt = fscp->fs_idlecnt * 2;
- } else {
- /* reduce to 75% of max allowed idle cnodes */
- remcnt = (fscp->fs_idlecnt - cachefs_max_idle) +
- (cachefs_max_idle >> 2);
- }
-
- for (; remcnt > 0; remcnt--) {
- /* get cnode on back of idle list and hold it */
- cp = fscp->fs_idleback;
- if (cp == NULL)
- break;
- VN_HOLD(CTOV(cp));
- mutex_exit(&fscp->fs_idlelock);
-
- /* if the cnode is still on the idle list */
- mutex_enter(&cp->c_statelock);
- if (cp->c_flags & CN_IDLE) {
- cp->c_flags &= ~CN_IDLE;
-
- /* remove cnode from the idle list */
- mutex_enter(&fscp->fs_idlelock);
- cachefs_cnode_idlerem(cp);
- mutex_exit(&fscp->fs_idlelock);
- mutex_exit(&cp->c_statelock);
-
- /* destroy the cnode */
- VN_RELE(CTOV(cp));
- (void) cachefs_cnode_inactive(CTOV(cp), kcred);
- } else {
- /* cnode went active, just skip it */
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- }
- mutex_enter(&fscp->fs_idlelock);
- }
-
- fscp->fs_idleclean = 0;
- mutex_exit(&fscp->fs_idlelock);
-}
-
-/*
- * This routine does the real work of inactivating a cachefs vnode.
- */
-int
-cachefs_cnode_inactive(register struct vnode *vp, cred_t *cr)
-{
- cnode_t *cp;
- struct fscache *fscp;
- struct filegrp *fgp;
- cachefscache_t *cachep;
- struct cachefs_metadata *mdp;
- int meta_destroyed = 0;
-
- cp = VTOC(vp);
-
- fscp = C_TO_FSCACHE(cp);
- cachep = fscp->fs_cache;
- ASSERT(cachep != NULL);
- fgp = cp->c_filegrp;
-
- ASSERT((cp->c_flags & CN_IDLE) == 0);
-
- /* truncate the front file if necessary */
- mutex_enter(&cp->c_statelock);
- if ((cp->c_flags & CN_NOCACHE) && (cp->c_metadata.md_flags & MD_FILE) &&
- cp->c_metadata.md_frontblks) {
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_INVALIDATE)
- printf("c_cnode_inactive: invalidating %llu\n",
- (u_longlong_t)cp->c_id.cid_fileno);
-#endif
- /*
- * If the cnode is being populated, and we're not the
- * populating thread, then block until the pop thread
- * completes. If we are the pop thread, then we may come in
- * here, but not to nuke the directory cnode at a critical
- * juncture.
- */
- while ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread))
- cv_wait(&cp->c_popcv, &cp->c_statelock);
-
- cachefs_inval_object(cp);
- }
- mutex_exit(&cp->c_statelock);
-
- for (;;) {
- /* see if vnode is really inactive */
- mutex_enter(&vp->v_lock);
- ASSERT(vp->v_count > 0);
- if (vp->v_count > 1) {
- /*
- * It's impossible for us to be cnode_inactive for
- * the root cnode _unless_ we are being called from
- * cachefs_unmount (where inactive is called
- * explictly). If the count is not 1, there is
- * still an outstanding reference to the root cnode,
- * and we return EBUSY; this allows cachefs_unmount
- * to fail.
- */
- if (cp->c_flags & CN_ROOT) {
- mutex_exit(&vp->v_lock);
- return (EBUSY);
- }
- cp->c_ipending = 0;
- vp->v_count--; /* release our hold from vn_rele */
- mutex_exit(&vp->v_lock);
- return (0);
- }
- mutex_exit(&vp->v_lock);
-
- /* get rid of any pages, do not care if cannot be pushed */
- if (vn_has_cached_data(vp)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- (void) cachefs_putpage_common(vp, (offset_t)0, 0,
- B_INVAL | B_FORCE, cr);
- }
-
- /* if need to sync metadata, the call is a no op for NFSv4 */
- if ((cp->c_flags & (CN_UPDATED | CN_DESTROY)) == CN_UPDATED) {
- (void) cachefs_sync_metadata(cp);
- continue;
- }
- break;
- }
-
- /*
- * Lock out possible race with makecachefsnode.
- * Makecachefsnode will fix up the rl/active list stuff to
- * be correct when it gets to run.
- * We have to do the rl/active stuff while the cnode is on the hash
- * list to sync actions on the rl/active list.
- */
- mutex_enter(&fgp->fg_cnodelock);
- mutex_enter(&cp->c_statelock);
-
- /* see if vnode is still inactive */
- mutex_enter(&vp->v_lock);
- ASSERT(vp->v_count > 0);
- if (vp->v_count > 1) {
- cp->c_ipending = 0;
- vp->v_count--;
- mutex_exit(&vp->v_lock);
- mutex_exit(&cp->c_statelock);
- mutex_exit(&fgp->fg_cnodelock);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_INVALIDATE)
- printf("cachefs_cnode_inactive: %u vp %p\n",
- vp->v_count, vp);
-#endif
- return (0);
- }
- mutex_exit(&vp->v_lock);
-
- /* check for race with remove */
- if (cp->c_unldvp) {
- mutex_exit(&cp->c_statelock);
- mutex_exit(&fgp->fg_cnodelock);
-
- /* this causes cachefs_inactive to be called again */
- VN_RELE(vp);
- return (0);
- }
-
- /* if any pages left, really get rid of them */
- if (vn_has_cached_data(vp)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- (void) pvn_vplist_dirty(vp, 0, NULL, B_INVAL | B_TRUNC, cr);
- }
- ASSERT(vp->v_count == 1);
-
- mdp = &cp->c_metadata;
-
- /* if we can (and should) destroy the front file and metadata */
- if ((cp->c_flags & (CN_DESTROY | CN_STALE)) &&
- (fgp->fg_flags & CFS_FG_WRITE) && !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- if (mdp->md_rlno) {
- cachefs_removefrontfile(mdp, &cp->c_id, fgp);
- cachefs_rlent_moveto(cachep, CACHEFS_RL_FREE,
- mdp->md_rlno, 0);
- mdp->md_rlno = 0;
- mdp->md_rltype = CACHEFS_RL_NONE;
- }
- if ((cp->c_flags & CN_ALLOC_PENDING) == 0) {
- (void) filegrp_destroy_metadata(fgp, &cp->c_id);
- meta_destroyed = 1;
- }
- }
-
- /* else put the front file on the gc list */
- else if (mdp->md_rlno &&
- (fgp->fg_flags & CFS_FG_WRITE) &&
- (cp->c_metadata.md_rltype == CACHEFS_RL_ACTIVE)) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(cachep, CACHEFS_RL_ACTIVE,
- mdp->md_rlno);
-#endif /* CFSDEBUG */
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_rlent_moveto(cachep, CACHEFS_RL_GC, mdp->md_rlno,
- mdp->md_frontblks);
- mdp->md_rltype = CACHEFS_RL_GC;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* if idlelist pointer(s) not null, remove from idle list */
- if ((cp->c_idlefront != NULL) || (cp->c_idleback != NULL)) {
- mutex_enter(&fscp->fs_idlelock);
- cachefs_cnode_idlerem(cp);
- mutex_exit(&fscp->fs_idlelock);
- }
-
- /* remove from the filegrp list prior to releasing the cnode lock */
- cachefs_cnode_listrem(cp);
-
- mutex_exit(&cp->c_statelock);
- if (! meta_destroyed)
- (void) cachefs_sync_metadata(cp);
-
- mutex_exit(&fgp->fg_cnodelock);
-
- if (cp->c_cred != NULL) {
- crfree(cp->c_cred);
- cp->c_cred = NULL;
- }
-
- if (cp->c_frontvp)
- VN_RELE(cp->c_frontvp);
-
- if (cp->c_backvp)
- VN_RELE(cp->c_backvp);
-
- if (cp->c_acldirvp)
- VN_RELE(cp->c_acldirvp);
-
- rw_destroy(&cp->c_rwlock);
- mutex_destroy(&cp->c_statelock);
- cv_destroy(&cp->c_popcv);
- mutex_destroy(&cp->c_iomutex);
- cv_destroy(&cp->c_iocv);
-
- /* free up cnode memory */
- vn_invalid(cp->c_vnode);
- vn_free(cp->c_vnode);
- kmem_cache_free(cachefs_cnode_cache, cp);
-
- filegrp_rele(fgp);
- (void) fscache_cnodecnt(fscp, -1);
- return (0);
-}
-
-/*
- * Add a cnode to the filegrp list.
- */
-void
-cachefs_cnode_listadd(struct cnode *cp)
-{
- filegrp_t *fgp = cp->c_filegrp;
-
- ASSERT(MUTEX_HELD(&fgp->fg_cnodelock));
- ASSERT(cp->c_next == NULL);
-
- cp->c_next = fgp->fg_cnodelist;
- fgp->fg_cnodelist = cp;
-}
-
-/*
- * Remove a cnode from the filegrp list.
- */
-void
-cachefs_cnode_listrem(struct cnode *cp)
-{
- filegrp_t *fgp = cp->c_filegrp;
- struct cnode **headpp;
-
-#ifdef CFSDEBUG
- int found = 0;
-#endif
-
- ASSERT(MUTEX_HELD(&fgp->fg_cnodelock));
- ASSERT(cp->c_idleback == NULL);
- ASSERT(cp->c_idlefront == NULL);
-
- for (headpp = &fgp->fg_cnodelist;
- *headpp != NULL; headpp = &(*headpp)->c_next) {
- if (*headpp == cp) {
- *headpp = cp->c_next;
- cp->c_next = NULL;
-#ifdef CFSDEBUG
- found++;
-#endif
- break;
- }
- }
-#ifdef CFSDEBUG
- ASSERT(found);
-#endif
-}
-
-/*
- * Add a cnode to the front of the fscache idle list.
- */
-void
-cachefs_cnode_idleadd(struct cnode *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(MUTEX_HELD(&fscp->fs_idlelock));
-
- /* put cnode on the front of the idle list */
- cp->c_idlefront = fscp->fs_idlefront;
- cp->c_idleback = NULL;
-
- if (fscp->fs_idlefront)
- fscp->fs_idlefront->c_idleback = cp;
- else {
- ASSERT(fscp->fs_idleback == NULL);
- fscp->fs_idleback = cp;
- }
- fscp->fs_idlefront = cp;
- fscp->fs_idlecnt++;
-}
-
-/*
- * Remove a cnode from the fscache idle list.
- */
-void
-cachefs_cnode_idlerem(struct cnode *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(MUTEX_HELD(&fscp->fs_idlelock));
-
- if (cp->c_idlefront == NULL) {
- ASSERT(fscp->fs_idleback == cp);
- fscp->fs_idleback = cp->c_idleback;
- if (fscp->fs_idleback != NULL)
- fscp->fs_idleback->c_idlefront = NULL;
- } else {
- cp->c_idlefront->c_idleback = cp->c_idleback;
- }
-
- if (cp->c_idleback == NULL) {
- ASSERT(fscp->fs_idlefront == cp);
- fscp->fs_idlefront = cp->c_idlefront;
- if (fscp->fs_idlefront != NULL)
- fscp->fs_idlefront->c_idleback = NULL;
- } else {
- cp->c_idleback->c_idlefront = cp->c_idlefront;
- cp->c_idleback = NULL;
- }
- cp->c_idlefront = NULL;
- fscp->fs_idlecnt--;
- ASSERT(fscp->fs_idlecnt >= 0);
-}
-
-/*
- * Search the cnode list of the input file group, looking for a cnode which
- * matches the supplied file ident fileno.
- *
- * Returns:
- * *cpp = NULL, if no valid matching cnode is found
- * *cpp = address of cnode with matching fileno, with c_statelock held
- * return status is 0 if no cnode found, or if found & cookies match
- * return status is 1 if a cnode was found, but the cookies don't match
- *
- * Note: must grab the c_statelock for each cnode, or its state could
- * change while we're processing it. Also, if a cnode is found, must return
- * with c_statelock still held, so that the cnode state cannot change until
- * the calling routine releases the lock.
- */
-int
-cachefs_cnode_find(filegrp_t *fgp, cfs_cid_t *cidp, fid_t *cookiep,
- struct cnode **cpp, struct vnode *backvp, vattr_t *vap)
-{
- struct cnode *cp;
- int badcookie = 0;
- uint32_t is_nfsv4;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- cmn_err(CE_NOTE, "cachefs_cnode_find: fileno %llu fgp %p\n",
- (u_longlong_t)cidp->cid_fileno, (void *)fgp);
-#endif
- ASSERT(MUTEX_HELD(&fgp->fg_cnodelock));
-
- *cpp = NULL;
- is_nfsv4 = CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp);
-
- /*
- * Cookie should be filled unless disconnected operation or
- * backfilesystem is NFSv4
- */
- if (cookiep == NULL && !CFS_ISFS_SNR(fgp->fg_fscp) &&
- !CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp)) {
- goto out;
- }
-
- for (cp = fgp->fg_cnodelist; cp != NULL; cp = cp->c_next) {
- mutex_enter(&cp->c_statelock);
-
- if ((cidp->cid_fileno != cp->c_id.cid_fileno &&
- (is_nfsv4 == FALSE || cp->c_backvp != backvp)) ||
- (cp->c_flags & (CN_STALE | CN_DESTROY))) {
- mutex_exit(&cp->c_statelock);
- continue;
- }
-
- /*
- * Having found a non stale, non destroy pending cnode with
- * matching fileno, will be exiting the for loop, after
- * determining return status
- */
- *cpp = cp;
-
- if ((cookiep != NULL) &&
- ((cookiep->fid_len != cp->c_cookie.fid_len) ||
- (bcmp((caddr_t)cookiep->fid_data,
- (caddr_t)&cp->c_cookie.fid_data, cookiep->fid_len)) != 0)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_GENERAL) {
- cmn_err(CE_NOTE,
- "cachefs: dup fileno %llu, cp %p\n",
- (u_longlong_t)cidp->cid_fileno, (void *)cp);
- }
-#endif
- badcookie = 1;
- }
-
- /*
- * For NFSv4 since there is no fid, add a check to
- * ensure the backvp and vap matches that in the cnode.
- * If it doesn't then someone tried to use a stale cnode.
- */
- if (is_nfsv4) {
- if (backvp && backvp != cp->c_backvp ||
- vap && vap->va_type != cp->c_attr.va_type ||
- cidp->cid_fileno != cp->c_id.cid_fileno) {
- CFS_DPRINT_BACKFS_NFSV4(C_TO_FSCACHE(cp),
- ("cachefs_cnode_find (nfsv4): stale cnode "
- "cnode %p, backvp %p, new-backvp %p, vap %p "
- "fileno=%llx cp-fileno=%llx\n",
- cp, cp->c_backvp, backvp, vap,
- cidp->cid_fileno, cp->c_id.cid_fileno));
- badcookie = 1;
- }
- }
- break;
- }
-out:
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- cmn_err(CE_NOTE, "cachefs_cnode_find: cp %p\n", (void *)*cpp);
-#endif
- return (badcookie);
-}
-
-/*
- * We have to initialize the cnode contents. Fill in the contents from the
- * cache (attrcache file), from the info passed in, whatever it takes.
- */
-static int
-cachefs_cnode_init(cfs_cid_t *cidp, cnode_t *cp, fscache_t *fscp,
- filegrp_t *fgp, fid_t *cookiep, vattr_t *vap, vnode_t *backvp,
- int flag, cred_t *cr)
-{
- int error = 0;
- int slotfound;
- vnode_t *vp;
- int null_cookie;
- cachefscache_t *cachep = fscp->fs_cache;
-
- bzero(cp, sizeof (cnode_t));
- cp->c_vnode = vn_alloc(KM_SLEEP);
-
- vp = CTOV(cp);
-
- vp->v_data = (caddr_t)cp;
-
- rw_init(&cp->c_rwlock, NULL, RW_DEFAULT, NULL);
- mutex_init(&cp->c_statelock, NULL, MUTEX_DEFAULT, NULL);
- cv_init(&cp->c_popcv, NULL, CV_DEFAULT, NULL);
- mutex_init(&cp->c_iomutex, NULL, MUTEX_DEFAULT, NULL);
- cv_init(&cp->c_iocv, NULL, CV_DEFAULT, NULL);
-
- vn_setops(vp, cachefs_getvnodeops());
- cp->c_id = *cidp;
- if (backvp != NULL) {
- cp->c_backvp = backvp;
- VN_HOLD(backvp);
- }
- cp->c_flags |= flag;
- filegrp_hold(fgp);
- cp->c_filegrp = fgp;
- if (cookiep)
- cp->c_cookie = *cookiep;
- mutex_enter(&cp->c_statelock);
-
- /*
- * if nocache is set then ignore anything cached for this file,
- * if nfsv4 flag is set, then create the cnode but don't do
- * any caching.
- */
- if (cp->c_flags & CN_NOCACHE || CFS_ISFS_BACKFS_NFSV4(fscp)) {
- /*
- * this case only happens while booting without a cache
- * or if NFSv4 is the backfilesystem
- */
- ASSERT(!CFS_ISFS_SNR(fscp));
- ASSERT(fscp->fs_cdconnected == CFS_CD_CONNECTED);
- if (cookiep || CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = CFSOP_INIT_COBJECT(fscp, cp, vap, cr);
- if (error)
- goto out;
- cp->c_flags |= CN_UPDATED | CN_ALLOC_PENDING;
- ASSERT(cp->c_attr.va_type != 0);
- VN_SET_VFS_TYPE_DEV(vp, fscp->fs_cfsvfsp,
- cp->c_attr.va_type, cp->c_attr.va_rdev);
- cachefs_cnode_setlocalstats(cp);
- } else
- error = ESTALE;
- goto out;
- }
-
- /*
- * see if there's a slot for this filegrp/cid fileno
- * if not, and there's no cookie info, nothing can be done, but if
- * there's cookie data indicate we need to create a metadata slot.
- */
- slotfound = cachefs_cid_inuse(cp->c_filegrp, cidp);
- if (slotfound == 0) {
- if (cookiep == NULL) {
- error = ENOENT;
- goto out;
- }
- cp->c_flags |= CN_ALLOC_PENDING;
- } else {
- /*
- * if a slot was found, then increment the slot in use count
- * and try to read the metadata.
- */
- cp->c_filegrp->fg_header->ach_count++;
- error = filegrp_read_metadata(cp->c_filegrp, cidp,
- &cp->c_metadata);
- }
- /*
- * if there wasn't a slot, or an attempt to read it results in ENOENT,
- * then init the cache object, create the vnode, etc...
- */
- if ((slotfound == 0) || (error == ENOENT)) {
- error = CFSOP_INIT_COBJECT(fscp, cp, vap, cr);
- if (error)
- goto out;
- ASSERT(cp->c_attr.va_type != 0);
- VN_SET_VFS_TYPE_DEV(vp, fscp->fs_cfsvfsp,
- cp->c_attr.va_type, cp->c_attr.va_rdev);
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
- } else if (error == 0) {
- /* slot found, no error occurred on the metadata read */
- cp->c_size = cp->c_attr.va_size;
-
- if ((cachep->c_flags & CACHE_CHECK_RLTYPE) &&
- (cp->c_metadata.md_rlno != 0) &&
- (cp->c_metadata.md_rltype == CACHEFS_RL_ACTIVE)) {
- rl_entry_t rl, *rlp;
-
- mutex_enter(&cachep->c_contentslock);
- error = cachefs_rl_entry_get(cachep,
- cp->c_metadata.md_rlno, &rlp);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
- rl = *rlp;
- mutex_exit(&cachep->c_contentslock);
- if (cp->c_metadata.md_rltype != rl.rl_current) {
- cp->c_flags |= CN_UPDATED;
- cp->c_metadata.md_rltype = rl.rl_current;
- }
- }
-
- /*
- * If no cookie is specified, or if this is a local file,
- * accept the one in the metadata.
- */
- null_cookie = 0;
- if ((cookiep == NULL) || (cp->c_id.cid_flags & CFS_CID_LOCAL)) {
- cookiep = &cp->c_metadata.md_cookie;
- null_cookie = 1;
- }
-
- /* if cookies do not match, reset the metadata */
- if ((cookiep->fid_len != cp->c_cookie.fid_len) ||
- (bcmp(&cookiep->fid_data, &cp->c_cookie.fid_data,
- (size_t)cookiep->fid_len) != 0)) {
- cp->c_cookie = *cookiep;
- cp->c_flags |= CN_UPDATED;
- cp->c_metadata.md_timestamp.tv_sec = 0;
- /* clear all but the front file bit */
- cp->c_metadata.md_flags &= MD_FILE;
- error = CFSOP_INIT_COBJECT(fscp, cp, vap, cr);
- ASSERT(cp->c_attr.va_type != 0);
- VN_SET_VFS_TYPE_DEV(vp, fscp->fs_cfsvfsp,
- cp->c_attr.va_type, cp->c_attr.va_rdev);
- }
-
- /* else if the consistency type changed, fix it up */
- else if (cp->c_metadata.md_consttype != fscp->fs_consttype) {
- ASSERT(cp->c_attr.va_type != 0);
- VN_SET_VFS_TYPE_DEV(vp, fscp->fs_cfsvfsp,
- cp->c_attr.va_type, cp->c_attr.va_rdev);
- CFSOP_CONVERT_COBJECT(fscp, cp, cr);
- if (!null_cookie) {
- error = CFSOP_CHECK_COBJECT(fscp, cp,
- C_BACK_CHECK, cr);
- }
- }
-
- /* else check the consistency of the data */
- else {
- ASSERT(cp->c_attr.va_type != 0);
- VN_SET_VFS_TYPE_DEV(vp, fscp->fs_cfsvfsp,
- cp->c_attr.va_type, cp->c_attr.va_rdev);
- if (!null_cookie) {
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- }
- }
- } else {
- goto out;
- }
- cachefs_cnode_setlocalstats(cp);
-
-out:
- mutex_exit(&cp->c_statelock);
- if (error) {
- if (cp->c_frontvp)
- VN_RELE(cp->c_frontvp);
- if (cp->c_backvp)
- VN_RELE(cp->c_backvp);
- if (cp->c_acldirvp)
- VN_RELE(cp->c_acldirvp);
- filegrp_rele(fgp);
- rw_destroy(&cp->c_rwlock);
- mutex_destroy(&cp->c_statelock);
- cv_destroy(&cp->c_popcv);
- mutex_destroy(&cp->c_iomutex);
- cv_destroy(&cp->c_iocv);
- }
- return (error);
-}
-
-/*
- * Finds the cnode for the specified fileno and fid.
- * Creates the cnode if it does not exist.
- * The cnode is returned held.
- */
-int
-cachefs_cnode_make(cfs_cid_t *cidp, fscache_t *fscp, fid_t *cookiep,
- vattr_t *vap, vnode_t *backvp, cred_t *cr, int flag, cnode_t **cpp)
-{
- struct cnode *cp;
- int error;
- struct filegrp *fgp;
- struct cachefs_metadata *mdp;
- fid_t cookie;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- printf("cachefs_cnode_make: ENTER fileno %llu\n",
- (u_longlong_t)cidp->cid_fileno);
-#endif
-
- /* get the file group that owns this file */
- mutex_enter(&fscp->fs_fslock);
- fgp = filegrp_list_find(fscp, cidp);
- if (fgp == NULL) {
- fgp = filegrp_create(fscp, cidp);
- filegrp_list_add(fscp, fgp);
- }
- filegrp_hold(fgp);
- mutex_exit(&fscp->fs_fslock);
-
- /* grab the cnode list lock */
- mutex_enter(&fgp->fg_cnodelock);
-
- if ((fgp->fg_flags & CFS_FG_READ) == 0)
- flag |= CN_NOCACHE;
-
- error = 0;
- cp = NULL;
-
- /* look for the cnode on the cnode list */
- error = cachefs_cnode_find(fgp, cidp, cookiep, &cp, backvp, vap);
-
- /*
- * If there already is a cnode with this cid but a different cookie,
- * (or backvp) we're not going to be using the one we found.
- */
- if (error && CFS_ISFS_BACKFS_NFSV4(fscp)) {
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- cachefs_cnode_stale(cp);
- mutex_exit(&cp->c_statelock);
- cp = NULL;
- error = 0;
- } else if (error) {
- ASSERT(cp);
- ASSERT(cookiep);
-
- mutex_exit(&cp->c_statelock);
-
- /*
- * If backvp is NULL then someone tried to use
- * a stale cookie.
- */
- if (backvp == NULL) {
- mutex_exit(&fgp->fg_cnodelock);
- error = ESTALE;
- goto out;
- }
-
- /* verify the backvp */
- error = cachefs_getcookie(backvp, &cookie, NULL, cr, TRUE);
- if (error ||
- ((cookiep->fid_len != cookie.fid_len) ||
- (bcmp(&cookiep->fid_data, cookie.fid_data,
- (size_t)cookiep->fid_len) != 0))) {
- mutex_exit(&fgp->fg_cnodelock);
- error = ESTALE;
- goto out;
- }
-
- /* make the old cnode give up its front file resources */
- VN_HOLD(CTOV(cp));
- (void) cachefs_sync_metadata(cp);
- mutex_enter(&cp->c_statelock);
- mdp = &cp->c_metadata;
- if (mdp->md_rlno) {
- /* XXX sam: should this assert be NOCACHE? */
- /* XXX sam: maybe we should handle NOFILL as no-op */
- ASSERT((fscp->fs_cache->c_flags & CACHE_NOFILL) == 0);
-
- /* if modified in the cache, move to lost+found */
- if ((cp->c_attr.va_type == VREG) &&
- (cp->c_metadata.md_rltype == CACHEFS_RL_MODIFIED)) {
- error = cachefs_cnode_lostfound(cp, NULL);
- if (error) {
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- mutex_exit(&fgp->fg_cnodelock);
- error = ESTALE;
- goto out;
- }
- }
-
- /* else nuke the front file */
- else {
- cachefs_cnode_stale(cp);
- }
- } else {
- cachefs_cnode_stale(cp);
- }
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- cp = NULL;
- error = 0;
- }
-
-
- /* if the cnode does not exist */
- if (cp == NULL) {
- /* XXX should we drop all locks for this? */
- cp = kmem_cache_alloc(cachefs_cnode_cache, KM_SLEEP);
-
- error = cachefs_cnode_init(cidp, cp, fscp, fgp,
- cookiep, vap, backvp, flag, cr);
- if (error) {
- mutex_exit(&fgp->fg_cnodelock);
- vn_free(cp->c_vnode);
- kmem_cache_free(cachefs_cnode_cache, cp);
- goto out;
- }
-
- if (cp->c_metadata.md_rlno &&
- (cp->c_metadata.md_rltype == CACHEFS_RL_GC) &&
- ((fscp->fs_cache->c_flags & CACHE_NOFILL) == 0)) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fscp->fs_cache,
- CACHEFS_RL_GC, cp->c_metadata.md_rlno);
-#endif /* CFSDEBUG */
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_ACTIVE, cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_ACTIVE;
- cp->c_flags |= CN_UPDATED;
- }
-
- cachefs_cnode_listadd(cp);
- vn_exists(cp->c_vnode);
- mutex_exit(&fgp->fg_cnodelock);
- (void) fscache_cnodecnt(fscp, 1);
- }
-
- /* else if the cnode exists */
- else {
- VN_HOLD(CTOV(cp));
-
- /* remove from idle list if on it */
- if (cp->c_flags & CN_IDLE) {
- cp->c_flags &= ~CN_IDLE;
-
- mutex_enter(&fscp->fs_idlelock);
- cachefs_cnode_idlerem(cp);
- mutex_exit(&fscp->fs_idlelock);
- VN_RELE(CTOV(cp));
- cp->c_ipending = 0;
- }
- mutex_exit(&cp->c_statelock);
- mutex_exit(&fgp->fg_cnodelock);
- }
-
- /*
- * Assertion to ensure the cnode matches
- * the backvp and attribute type information.
- */
- ASSERT((CFS_ISFS_BACKFS_NFSV4(fscp) == 0) ||
- ((cp->c_backvp == backvp) &&
- (cp->c_attr.va_type == vap->va_type)));
-out:
- *cpp = ((error == 0) ? cp : NULL);
- filegrp_rele(fgp);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- printf("cachefs_cnode_make: EXIT cp %p, error %d\n",
- (void *)*cpp, error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_cid_inuse()
- *
- * returns nonzero if a cid has any data in the cache; either a cnode
- * or metadata.
- */
-
-int
-cachefs_cid_inuse(filegrp_t *fgp, cfs_cid_t *cidp)
-{
- cnode_t *cp;
- int status = 0;
-
- ASSERT(MUTEX_HELD(&fgp->fg_cnodelock));
-
- /*
- * Since we don't care about the cookie data, we don't care about any
- * status that find might return.
- */
-
- cp = NULL;
- (void) cachefs_cnode_find(fgp, cidp, NULL, &cp, NULL, NULL);
- if (cp != NULL) {
- mutex_exit(&cp->c_statelock);
- status = 1;
- return (status);
- }
-
- /*
- * Don't want to use filegrp_read_metadata, since it will return
- * ENOENT if the metadata slot exists but hasn't been written to yet.
- * That condition still counts as the slot (metadata) being in use.
- * Instead, as long as the filegrp attrcache has been created and
- * there's a slot assigned for this cid, then the metadata is in use.
- */
- if (((fgp->fg_flags & CFS_FG_ALLOC_ATTR) == 0) &&
- (filegrp_cid_to_slot(fgp, cidp) != 0))
- status = 1;
-
- return (status);
-}
-
-/*
- * cachefs_fileno_inuse()
- *
- * returns nonzero if a fileno is known to the cache, as either a
- * local or a normal file.
- */
-
-int
-cachefs_fileno_inuse(fscache_t *fscp, ino64_t fileno)
-{
- cfs_cid_t cid;
- filegrp_t *fgp;
- int known = 0;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
- cid.cid_fileno = fileno;
-
- /* if there's no filegrp for this cid range, then there's no data */
- fgp = filegrp_list_find(fscp, &cid);
- if (fgp == NULL)
- return (known);
-
- filegrp_hold(fgp);
- mutex_enter(&fgp->fg_cnodelock);
-
- cid.cid_flags = CFS_CID_LOCAL;
- if (cachefs_cid_inuse(fgp, &cid)) {
- known = 1;
- goto out;
- }
- cid.cid_flags = 0;
- if (cachefs_cid_inuse(fgp, &cid))
- known = 1;
-out:
- mutex_exit(&fgp->fg_cnodelock);
- filegrp_rele(fgp);
- return (known);
-}
-
-/*
- * Creates a cnode from an unused inode in the cache.
- * The cnode is returned held.
- */
-int
-cachefs_cnode_create(fscache_t *fscp, vattr_t *vap, int flag, cnode_t **cpp)
-{
- struct cnode *cp;
- int error, found;
- struct filegrp *fgp;
- cfs_cid_t cid, cid2;
-
- ASSERT(CFS_ISFS_SNR(fscp));
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- cid.cid_flags = CFS_CID_LOCAL;
- cid2.cid_flags = 0;
-
- /* find an unused local file in the cache */
- for (;;) {
- mutex_enter(&fscp->fs_fslock);
-
- /* make sure we did not wrap */
- fscp->fs_info.fi_localfileno++;
- if (fscp->fs_info.fi_localfileno == 0)
- fscp->fs_info.fi_localfileno = 3;
- cid.cid_fileno = fscp->fs_info.fi_localfileno;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
-
- /* avoid fileno conflict in non-local space */
- cid2.cid_fileno = cid.cid_fileno;
- fgp = filegrp_list_find(fscp, &cid2);
- if (fgp != NULL) {
- filegrp_hold(fgp);
- mutex_enter(&fgp->fg_cnodelock);
- found = cachefs_cid_inuse(fgp, &cid2);
- mutex_exit(&fgp->fg_cnodelock);
- filegrp_rele(fgp);
- if (found) {
- mutex_exit(&fscp->fs_fslock);
- continue;
- }
- }
-
- /* get the file group that owns this fileno */
- fgp = filegrp_list_find(fscp, &cid);
- if (fgp == NULL) {
- fgp = filegrp_create(fscp, &cid);
- filegrp_list_add(fscp, fgp);
- }
-
- /* see if there is any room left in this file group */
- mutex_enter(&fgp->fg_mutex);
- if (fgp->fg_header &&
- (fgp->fg_header->ach_count ==
- fscp->fs_info.fi_fgsize)) {
- /* no more room, set up for the next file group */
- fscp->fs_info.fi_localfileno = fgp->fg_id.cid_fileno +
- fscp->fs_info.fi_fgsize;
- mutex_exit(&fgp->fg_mutex);
- mutex_exit(&fscp->fs_fslock);
- continue;
- }
- mutex_exit(&fgp->fg_mutex);
-
- filegrp_hold(fgp);
- mutex_exit(&fscp->fs_fslock);
-
- ASSERT((fgp->fg_flags &
- (CFS_FG_READ | CFS_FG_WRITE)) ==
- (CFS_FG_READ | CFS_FG_WRITE));
-
- /* grab the cnode list lock */
- mutex_enter(&fgp->fg_cnodelock);
-
- if ((fgp->fg_flags & CFS_FG_READ) == 0)
- flag |= CN_NOCACHE;
-
- /* keep looking if a cnode or metadata exist for this fileno */
- if (cachefs_cid_inuse(fgp, &cid)) {
- mutex_exit(&fgp->fg_cnodelock);
- filegrp_rele(fgp);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- cmn_err(CE_NOTE, "cachefs_cnode_create: "
- "fileno %llu exists.\n",
- (u_longlong_t)cid.cid_fileno);
-#endif
- continue;
- }
- break;
- }
-
- vap->va_nodeid = cid.cid_fileno;
-
- /* create space for the cnode */
- cp = kmem_cache_alloc(cachefs_cnode_cache, KM_SLEEP);
-
- /* set up the cnode */
- error = cachefs_cnode_init(&cid, cp, fscp, fgp,
- &cp->c_cookie, vap, NULL, flag, kcred);
- if (error) {
- mutex_exit(&fgp->fg_cnodelock);
- vn_free(cp->c_vnode);
- kmem_cache_free(cachefs_cnode_cache, cp);
- goto out;
- }
-
- /* save copy of fileno that is returned to the user */
- cp->c_metadata.md_flags |= MD_LOCALFILENO;
- cp->c_metadata.md_localfileno = cid.cid_fileno;
- cp->c_flags |= CN_UPDATED;
-
- cachefs_cnode_listadd(cp);
- mutex_exit(&fgp->fg_cnodelock);
- (void) fscache_cnodecnt(fscp, 1);
-
-out:
- *cpp = ((error == 0) ? cp : NULL);
- filegrp_rele(fgp);
- return (error);
-}
-
-/*
- * Moves the cnode to its new location in the cache.
- * Before calling this routine other steps must be taken
- * to ensure that other file system routines that operate
- * on cnodes do not run.
- */
-void
-cachefs_cnode_move(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cfs_cid_t cid;
- filegrp_t *fgp;
- filegrp_t *ofgp = cp->c_filegrp;
- struct cachefs_metadata *mdp;
- cnode_t *xcp;
- char oname[CFS_FRONTFILE_NAME_SIZE];
- char nname[CFS_FRONTFILE_NAME_SIZE];
- int ffnuke = 0;
- int error;
-
- ASSERT(CFS_ISFS_SNR(fscp));
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT(cp->c_id.cid_flags & CFS_CID_LOCAL);
- ASSERT(cp->c_attr.va_nodeid != 0);
-
- /* construct the cid of the new file location */
- cid.cid_fileno = cp->c_attr.va_nodeid;
- cid.cid_flags = 0;
-
- /* see if there already is a file occupying our slot */
- error = cachefs_cnode_make(&cid, fscp, NULL, NULL, NULL, kcred,
- 0, &xcp);
- if (error == 0) {
- mutex_enter(&xcp->c_statelock);
- cachefs_cnode_stale(xcp);
- mutex_exit(&xcp->c_statelock);
- VN_RELE(CTOV(xcp));
- xcp = NULL;
- error = 0;
- }
-
- /* get the file group that this file is moving to */
- mutex_enter(&fscp->fs_fslock);
- fgp = filegrp_list_find(fscp, &cid);
- if (fgp == NULL) {
- fgp = filegrp_create(fscp, &cid);
- filegrp_list_add(fscp, fgp);
- }
- filegrp_hold(fgp);
- mutex_exit(&fscp->fs_fslock);
-
- /* XXX fix to not have to create metadata to hold rl slot */
- /* get a metadata slot in the new file group */
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(fgp);
- }
- /* XXX can fix create_metadata to call allocattr if necessary? */
- error = filegrp_create_metadata(fgp, &cp->c_metadata, &cid);
- if (error)
- ffnuke = 1;
- if ((ffnuke == 0) && filegrp_ffhold(fgp))
- ffnuke = 1;
-
- /* move the front file to the new file group */
- if ((ffnuke == 0) && (cp->c_metadata.md_flags & MD_FILE)) {
- make_ascii_name(&cp->c_id, oname);
- make_ascii_name(&cid, nname);
- error = VOP_RENAME(ofgp->fg_dirvp, oname, fgp->fg_dirvp,
- nname, kcred, NULL, 0);
- if (error) {
- ffnuke = 1;
-#ifdef CFSDEBUG
- if (error != ENOSPC) {
- CFS_DEBUG(CFSDEBUG_CNODE)
- printf("cachefs: cnode_move "
- "1: error %d\n", error);
- }
-#endif
- }
- }
-
- /* remove the file from the old file group */
- mutex_enter(&ofgp->fg_cnodelock);
- mutex_enter(&cp->c_statelock);
- if (cp->c_frontvp) {
- VN_RELE(cp->c_frontvp);
- cp->c_frontvp = NULL;
- }
- if (cp->c_acldirvp) {
- VN_RELE(cp->c_acldirvp);
- cp->c_acldirvp = NULL;
- }
- mdp = &cp->c_metadata;
- if (mdp->md_rlno) {
- if (ffnuke) {
- cachefs_removefrontfile(mdp, &cp->c_id, ofgp);
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_FREE, mdp->md_rlno, 0);
- mdp->md_rlno = 0;
- mdp->md_rltype = CACHEFS_RL_NONE;
- } else {
- filegrp_ffrele(ofgp);
- }
- }
- if (ffnuke)
- mdp->md_flags &= ~MD_PACKED;
- if ((cp->c_flags & CN_ALLOC_PENDING) == 0) {
- (void) filegrp_destroy_metadata(ofgp, &cp->c_id);
- cp->c_flags |= CN_ALLOC_PENDING;
- }
- cachefs_cnode_listrem(cp);
- cp->c_filegrp = NULL;
- mutex_exit(&cp->c_statelock);
- mutex_exit(&ofgp->fg_cnodelock);
-
- /* add the cnode to the new file group */
- mutex_enter(&fgp->fg_cnodelock);
- mutex_enter(&cp->c_statelock);
- cp->c_id = cid;
- cp->c_filegrp = fgp;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
- cachefs_cnode_listadd(cp);
- if (mdp->md_rlno)
- cachefs_rl_changefileno(fscp->fs_cache, mdp->md_rlno,
- cp->c_id.cid_fileno);
- mutex_exit(&fgp->fg_cnodelock);
-
- filegrp_rele(ofgp);
-}
-
-/*
- * Syncs out the specified cnode.
- * Only called via cnode_traverse from fscache_sync
- */
-void
-cachefs_cnode_sync(cnode_t *cp)
-{
- vnode_t *vp = CTOV(cp);
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0;
-
- if (cp->c_flags & (CN_STALE | CN_DESTROY))
- return;
-
- if (fscp->fs_backvfsp && fscp->fs_backvfsp->vfs_flag & VFS_RDONLY)
- return;
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- /*
- * Getting file system access for reading is really cheating.
- * However we are getting called from sync so we do not
- * want to hang up if the cachefsd is not running.
- */
- error = cachefs_cd_access(fscp, 0, 0);
- if (error)
- break;
- held = 1;
-
- /* if a regular file, write out the pages */
- if ((vp->v_type == VREG) && vn_has_cached_data(vp)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = cachefs_putpage_common(vp, (offset_t)0,
- 0, 0, kcred);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else {
- /* cannot push, give up */
- break;
- }
- }
-
- /* clear the cnode error if putpage worked */
- if ((error == 0) && cp->c_error) {
- mutex_enter(&cp->c_statelock);
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
- }
-
- if (error)
- break;
- }
-
- /* if connected, sync the backvp */
- if ((fscp->fs_cdconnected == CFS_CD_CONNECTED) &&
- cp->c_backvp) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- error = VOP_FSYNC(cp->c_backvp, FSYNC, kcred,
- NULL);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else if (error && (error != EINTR))
- cp->c_error = error;
- }
- mutex_exit(&cp->c_statelock);
- }
-
- /* sync the metadata and the front file to the front fs */
- (void) cachefs_sync_metadata(cp);
- break;
- }
-
- if (held)
- cachefs_cd_release(fscp);
-}
-
-/*
- * Moves the specified file to the lost+found directory for the
- * cached file system.
- * Invalidates cached data and attributes.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_cnode_lostfound(cnode_t *cp, char *rname)
-{
- int error = 0;
- fscache_t *fscp;
- cachefscache_t *cachep;
- char oname[CFS_FRONTFILE_NAME_SIZE];
- filegrp_t *fgp;
- char *namep, *strp;
- char *namebuf = NULL;
- vnode_t *nvp;
- int index;
- int len;
-
- fscp = C_TO_FSCACHE(cp);
- cachep = fscp->fs_cache;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- fgp = cp->c_filegrp;
-
- /* set up the file group if necessary */
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- error = filegrp_allocattr(fgp);
- if (error)
- goto out;
- }
- ASSERT(fgp->fg_dirvp);
-
- namebuf = cachefs_kmem_alloc(MAXNAMELEN * 2, KM_SLEEP);
-
- if ((cp->c_attr.va_type != VREG) ||
- (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED) ||
- ((cp->c_metadata.md_flags & MD_POPULATED) == 0) ||
- ((cp->c_metadata.md_flags & MD_FILE) == 0) ||
- (cp->c_metadata.md_rlno == 0)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CNODE)
- printf("cachefs_cnode_lostfound cp %p cannot save\n",
- (void *)cp);
-#endif
- error = EINVAL;
- goto out;
- }
-
- /* lock out other users of the lost+found directory */
- mutex_enter(&cachep->c_contentslock);
-
- /* find a name we can use in lost+found */
- if (rname)
- namep = rname;
- else
- namep = "lostfile";
- error = VOP_LOOKUP(cachep->c_lostfoundvp, namep, &nvp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error == 0)
- VN_RELE(nvp);
- if (error != ENOENT) {
-#define MAXTRIES 1000
- strp = namep;
- for (index = 0; index < MAXTRIES; index++) {
- (void) sprintf(namebuf, "%s.%" PRIx64, strp,
- gethrestime_sec() * cp->c_id.cid_fileno * index);
- len = (int)strlen(namebuf) + 1;
- if (len > MAXNAMELEN)
- namep = &namebuf[len - MAXNAMELEN];
- else
- namep = namebuf;
- error = VOP_LOOKUP(cachep->c_lostfoundvp, namep, &nvp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error == 0)
- VN_RELE(nvp);
- if (error == ENOENT)
- break;
- }
- if (index == MAXTRIES) {
- error = EIO;
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
- }
-
- /* get the name of the front file */
- make_ascii_name(&cp->c_id, oname);
-
- /* rename the file into the lost+found directory */
- error = VOP_RENAME(fgp->fg_dirvp, oname, cachep->c_lostfoundvp,
- namep, kcred, NULL, 0);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
- mutex_exit(&cachep->c_contentslock);
-
- /* copy out the new name */
- if (rname)
- (void) strcpy(rname, namep);
-
-out:
- /* clean up */
- cachefs_cnode_stale(cp);
-
- if (namebuf)
- cachefs_kmem_free(namebuf, MAXNAMELEN * 2);
-
-#if 0 /* XXX until we can put filesystem in read-only mode */
- if (error) {
- /* XXX put file system in read-only mode */
- }
-#endif
-
- return (error);
-}
-
-/*
- * Traverses the list of cnodes on the fscache and calls the
- * specified routine with the held cnode.
- */
-void
-cachefs_cnode_traverse(fscache_t *fscp, void (*routinep)(cnode_t *))
-{
- filegrp_t *fgp, *ofgp;
- cnode_t *cp, *ocp;
- int index;
-
- /* lock the fscache while we traverse the file groups */
- mutex_enter(&fscp->fs_fslock);
-
- /* for each bucket of file groups */
- for (index = 0; index < CFS_FS_FGP_BUCKET_SIZE; index++) {
- ofgp = NULL;
-
- /* for each file group in a bucket */
- for (fgp = fscp->fs_filegrp[index];
- fgp != NULL;
- fgp = fgp->fg_next) {
-
- /* hold the file group */
- filegrp_hold(fgp);
-
- /* drop fscache lock so others can use it */
- mutex_exit(&fscp->fs_fslock);
-
- /* drop hold on previous file group */
- if (ofgp)
- filegrp_rele(ofgp);
- ofgp = fgp;
-
- /* lock the cnode list while we traverse it */
- mutex_enter(&fgp->fg_cnodelock);
- ocp = NULL;
-
- /* for each cnode in this file group */
- for (cp = fgp->fg_cnodelist;
- cp != NULL;
- cp = cp->c_next) {
-
- /* hold the cnode */
- VN_HOLD(CTOV(cp));
-
- /* drop cnode list lock so others can use it */
- mutex_exit(&fgp->fg_cnodelock);
-
- /* drop hold on previous cnode */
- if (ocp) {
- VN_RELE(CTOV(ocp));
- }
- ocp = cp;
-
- /*
- * Execute routine for this cnode.
- * At this point no locks are held.
- */
- (routinep)(cp);
-
- /* reacquire the cnode list lock */
- mutex_enter(&fgp->fg_cnodelock);
- }
-
- /* drop cnode list lock */
- mutex_exit(&fgp->fg_cnodelock);
-
- /* drop hold on last cnode */
- if (ocp) {
- VN_RELE(CTOV(ocp));
- }
-
- /* reacquire the fscache lock */
- mutex_enter(&fscp->fs_fslock);
- }
-
- /* drop hold on last file group */
- if (ofgp)
- filegrp_rele(ofgp);
- }
- mutex_exit(&fscp->fs_fslock);
-}
-
-void
-cachefs_cnode_disable_caching(struct cnode *cp)
-{
- mutex_enter(&cp->c_statelock);
- cp->c_flags |= CN_NOCACHE;
- if (cp->c_frontvp != NULL) {
- VN_RELE(cp->c_frontvp);
- cp->c_frontvp = NULL;
- }
- mutex_exit(&cp->c_statelock);
-}
-
-#define TIMEMATCH(a, b) ((a)->tv_sec == (b)->tv_sec && \
- (a)->tv_nsec == (b)->tv_nsec)
-
-static void
-cnode_enable_caching(struct cnode *cp)
-{
- struct vnode *iovp;
- struct filegrp *fgp;
- struct cachefs_metadata md;
- cachefscache_t *cachep = C_TO_FSCACHE(cp)->fs_cache;
- int error;
-
- ASSERT((cachep->c_flags & (CACHE_NOFILL | CACHE_NOCACHE)) == 0);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(cp)) == 0);
-
- iovp = NULL;
- if (CTOV(cp)->v_type == VREG)
- iovp = cp->c_backvp;
- if (iovp) {
- (void) VOP_PUTPAGE(iovp, (offset_t)0,
- (uint_t)0, B_INVAL, kcred, NULL);
- }
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- VN_RELE(cp->c_backvp);
- cp->c_backvp = NULL;
- }
- fgp = cp->c_filegrp;
- ASSERT(fgp);
- error = filegrp_read_metadata(fgp, &cp->c_id, &md);
- if (error == 0) {
- if ((cachep->c_flags & CACHE_CHECK_RLTYPE) &&
- (md.md_rlno != 0) &&
- (md.md_rltype == CACHEFS_RL_ACTIVE)) {
- rl_entry_t *rlp, rl;
-
- mutex_enter(&cachep->c_contentslock);
- error = cachefs_rl_entry_get(cachep, md.md_rlno, &rlp);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
-
- rl = *rlp;
- mutex_exit(&cachep->c_contentslock);
-
- if (rl.rl_current != md.md_rltype) {
- md.md_rltype = rl.rl_current;
- cp->c_flags |= CN_UPDATED;
- }
- }
-
- /*
- * A rudimentary consistency check
- * here. If the cookie and mtime
- * from the cnode match those from the
- * cache metadata, we assume for now that
- * the cached data is OK.
- */
- if (bcmp(&md.md_cookie.fid_data, &cp->c_cookie.fid_data,
- (size_t)cp->c_cookie.fid_len) == 0 &&
- TIMEMATCH(&cp->c_attr.va_mtime, &md.md_vattr.va_mtime)) {
- cp->c_metadata = md;
- } else {
- /*
- * Here we're skeptical about the validity of
- * the front file.
- * We'll keep the attributes already present in
- * the cnode, and bring along the parts of the
- * metadata that we need to eventually nuke this
- * bogus front file -- in inactive or getfrontfile,
- * whichever comes first...
- */
- if (cp->c_frontvp != NULL) {
- VN_RELE(cp->c_frontvp);
- cp->c_frontvp = NULL;
- }
- cp->c_metadata.md_flags = md.md_flags;
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_metadata.md_rlno = md.md_rlno;
- cp->c_metadata.md_rltype = md.md_rltype;
- cp->c_metadata.md_consttype = md.md_consttype;
- cp->c_metadata.md_fid = md.md_fid;
- cp->c_metadata.md_frontblks = md.md_frontblks;
- cp->c_metadata.md_timestamp.tv_sec = 0;
- cp->c_metadata.md_timestamp.tv_nsec = 0;
- bzero(&cp->c_metadata.md_allocinfo,
- cp->c_metadata.md_allocents *
- sizeof (struct cachefs_allocmap));
- cp->c_metadata.md_allocents = 0;
- cp->c_metadata.md_flags &= ~MD_POPULATED;
- if ((cp->c_metadata.md_rlno != 0) &&
- (cp->c_metadata.md_rltype == CACHEFS_RL_PACKED)) {
- cachefs_rlent_moveto(cachep,
- CACHEFS_RL_PACKED_PENDING,
- cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype =
- CACHEFS_RL_PACKED_PENDING;
- }
-
- cp->c_flags |= CN_UPDATED;
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_GENERAL) {
- printf(
- "fileno %lld ignores cached data due "
- "to cookie and/or mtime mismatch\n",
- (longlong_t)cp->c_id.cid_fileno);
- }
-#endif
- }
- if (cp->c_metadata.md_rltype == CACHEFS_RL_GC) {
- cachefs_rlent_moveto(cachep, CACHEFS_RL_ACTIVE,
- cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_ACTIVE;
- cp->c_flags |= CN_UPDATED;
- }
- }
-
-out:
- cp->c_flags &= ~CN_NOCACHE;
- mutex_exit(&cp->c_statelock);
-
- (void) cachefs_pack_common(CTOV(cp), kcred);
-}
-
-void
-cachefs_enable_caching(struct fscache *fscp)
-{
-
- /*
- * This function is only called when a remount occurs,
- * with "nocache" and "nofill" options configured
- * (currently these aren't supported). Since this
- * function can write into the cache, make sure that
- * its not in use with NFSv4.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp))
- return;
-
- /*
- * set up file groups so we can read them. Note that general
- * users (makecfsnode) will *not* start using them (i.e., all
- * newly created cnodes will be NOCACHE)
- * until we "enable_caching_rw" below.
- */
- mutex_enter(&fscp->fs_fslock);
- filegrp_list_enable_caching_ro(fscp);
- mutex_exit(&fscp->fs_fslock);
-
- cachefs_cnode_traverse(fscp, cnode_enable_caching);
-
- /* enable general use of the filegrps */
- mutex_enter(&fscp->fs_fslock);
- filegrp_list_enable_caching_rw(fscp);
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * This function makes a cnode stale by performing the following tasks:
- * 1) remove the front file
- * 2) Remove any resource file entries
- * 3) Remove any metadata entry from the attrcache file
- * 4) Set the stale bit in the cnode flags field
- */
-void
-cachefs_cnode_stale(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- struct cachefs_metadata *mdp;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /*
- * Remove a metadata entry if the file exists
- */
- mdp = &cp->c_metadata;
- if (mdp->md_rlno) {
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /*
- * destroy the frontfile
- */
- cachefs_removefrontfile(mdp, &cp->c_id, cp->c_filegrp);
- /*
- * Remove resource file entry
- */
- cachefs_rlent_moveto(fscp->fs_cache, CACHEFS_RL_FREE,
- mdp->md_rlno, 0);
- mdp->md_rlno = 0;
- mdp->md_rltype = CACHEFS_RL_NONE;
- }
-
- /*
- * Remove attrcache metadata
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp) == 0)
- (void) filegrp_destroy_metadata(cp->c_filegrp, &cp->c_id);
- mdp->md_flags = 0;
-
- if (cp->c_frontvp) {
- VN_RELE(cp->c_frontvp);
- cp->c_frontvp = NULL;
- }
-
- /*
- * For NFSv4 need to hang on to the backvp until vn_rele()
- * frees this cnode.
- */
- if (cp->c_backvp && !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- VN_RELE(cp->c_backvp);
- cp->c_backvp = NULL;
- }
- if (cp->c_acldirvp) {
- VN_RELE(cp->c_acldirvp);
- cp->c_acldirvp = NULL;
- }
-
- cp->c_flags |= CN_STALE | CN_ALLOC_PENDING | CN_NOCACHE;
-}
-
-/*
- * Sets up the local attributes in the metadata from the attributes.
- */
-void
-cachefs_cnode_setlocalstats(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* allow over writing of local attributes if a remount occurred */
- if (fscp->fs_info.fi_resettimes != mdp->md_resettimes) {
- mdp->md_flags &= ~(MD_LOCALCTIME | MD_LOCALMTIME);
- mdp->md_resettimes = fscp->fs_info.fi_resettimes;
- }
- if (fscp->fs_info.fi_resetfileno != mdp->md_resetfileno) {
- mdp->md_flags &= ~MD_LOCALFILENO;
- mdp->md_resetfileno = fscp->fs_info.fi_resetfileno;
- }
-
- /* overwrite old fileno and timestamps if not local versions */
- if ((mdp->md_flags & MD_LOCALFILENO) == 0)
- mdp->md_localfileno = mdp->md_vattr.va_nodeid;
- if ((mdp->md_flags & MD_LOCALCTIME) == 0)
- mdp->md_localctime = mdp->md_vattr.va_ctime;
- if ((mdp->md_flags & MD_LOCALMTIME) == 0)
- mdp->md_localmtime = mdp->md_vattr.va_mtime;
- cp->c_flags |= CN_UPDATED;
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_cod.c b/usr/src/uts/common/fs/cachefs/cachefs_cod.c
deleted file mode 100644
index be60ec4f40..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_cod.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <netinet/in.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/bootconf.h>
-#include <sys/modctl.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-
-#define C_CACHE_VALID(TOKEN_MTIME, NEW_MTIME) \
- ((TOKEN_MTIME.tv_sec == NEW_MTIME.tv_sec) && \
- (TOKEN_MTIME.tv_nsec == NEW_MTIME.tv_nsec))
-
-static int
-c_cod_init_cached_object(fscache_t *fscp, cnode_t *cp, vattr_t *vap,
- cred_t *cr)
-{
- int error;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(cr != NULL);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* NFSv4 option sets strict consistency */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* if attributes not passed in then get them */
- if (vap == NULL) {
- /* if not connected then cannot get attrs */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- return (ETIMEDOUT);
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- return (error);
- }
-
- /* get the attributes */
- cp->c_attr.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &cp->c_attr, 0, cr, NULL);
- if (error)
- return (error);
- } else {
- /* copy passed in attributes into the cnode */
- cp->c_attr = *vap;
- }
-
- cp->c_size = cp->c_attr.va_size;
- mdp->md_x_time = fscp->fs_cod_time;
- mdp->md_consttype = CFS_FS_CONST_CODCONST;
- cp->c_flags |= CN_UPDATED;
- return (0);
-}
-
-static int
-c_cod_check_cached_object(struct fscache *fscp, struct cnode *cp,
- int verify_what, cred_t *cr)
-{
- struct vattr attrs;
- int fail = 0, backhit = 0;
- int error = 0;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_cod_check_cached_object: ENTER cp %p\n", cp);
-#endif
- ASSERT(cr);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* nothing to do if not connected */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- goto out;
-
- /* done if do not have to check and cod button has not been pushed */
- if (((verify_what & C_BACK_CHECK) == 0) &&
- (C_CACHE_VALID(mdp->md_x_time, fscp->fs_cod_time)) &&
- ((mdp->md_flags & MD_NEEDATTRS) == 0))
- goto out;
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
-
- /*
- * If the cnode is being populated, and we're not the populating
- * thread, then block until the pop thread completes. If we are the
- * pop thread, then we may come in here, but not to nuke the directory
- * cnode at a critical juncture.
- */
-again:
- while ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread)) {
- cv_wait(&cp->c_popcv, &cp->c_statelock);
-
- /*
- * recheck backvp and connectivity - if backvp now null,
- * something bad happened, so don't bother trying to 'get' it
- */
- if ((cp->c_backvp == NULL) ||
- (fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL)) {
- if (cp->c_flags | CN_STALE) {
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- }
- goto out;
- }
- }
-
- /* get the file attributes from the back fs */
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- backhit = 1;
- if (error)
- goto out;
-
- /* if the mtime or size of the file has changed */
- if ((!C_CACHE_VALID(mdp->md_vattr.va_mtime, attrs.va_mtime) ||
- (cp->c_size != attrs.va_size)) &&
- ((mdp->md_flags & MD_NEEDATTRS) == 0)) {
- fail = 1;
- if (vn_has_cached_data(CTOV(cp))) {
- mutex_exit(&cp->c_statelock);
- error = cachefs_putpage_common(CTOV(cp),
- (offset_t)0, 0, B_INVAL, cr);
- mutex_enter(&cp->c_statelock);
- if (CFS_TIMEOUT(fscp, error))
- goto out;
- error = 0;
- /*
- * if an async pop started while the lock was
- * dropped, go back and try again
- */
- if ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread))
- goto again;
- }
- /*
- * We should properly handle the CN_NOCACHE flag here.
- * In fact, we should remember that cachefs_inval_object()
- * forcibly sets/unsets the flag, so we should keep a
- * state of the flag over the call.
- */
- if ((cp->c_flags & CN_NOCACHE) == 0)
- cachefs_inval_object(cp);
- else {
- cachefs_inval_object(cp);
- cp->c_flags |= CN_NOCACHE;
- }
- if ((CTOV(cp))->v_type == VREG) {
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error)
- goto out;
- }
- if (!vn_has_cached_data(CTOV(cp))) {
- cp->c_size = attrs.va_size;
-#ifdef CFSDEBUG
- } else {
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_cod_check: v_pages not null\n");
-#endif
- }
- }
-
- /* toss cached acl info if ctime changed */
- if (!C_CACHE_VALID(mdp->md_vattr.va_ctime, attrs.va_ctime)) {
- cachefs_purgeacl(cp);
- }
-
- cp->c_attr = attrs;
- if (attrs.va_size > cp->c_size)
- cp->c_size = attrs.va_size;
- mdp->md_x_time = fscp->fs_cod_time;
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (backhit != 0) {
- if (fail != 0)
- fscp->fs_stats.st_fails++;
- else
- fscp->fs_stats.st_passes++;
- }
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_cod_check_cached_object: EXIT\n");
-#endif
-
- return (error);
-}
-
-/*ARGSUSED*/
-static void
-c_cod_modify_cached_object(struct fscache *fscp, struct cnode *cp, cred_t *cr)
-{
- struct vattr attrs;
- int error = 0;
- nlink_t nlink;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(fscp->fs_cdconnected == CFS_CD_CONNECTED);
- ASSERT(fscp->fs_backvfsp);
-
- fscp->fs_stats.st_modifies++;
-
- /* from now on, make sure we're using the server's idea of time */
- mdp->md_flags &= ~(MD_LOCALCTIME | MD_LOCALMTIME);
- mdp->md_flags |= MD_NEEDATTRS;
-
- /* if in write-around mode, make sure file is nocached */
- if (CFS_ISFS_WRITE_AROUND(fscp)) {
- if ((cp->c_flags & CN_NOCACHE) == 0)
- cachefs_nocache(cp);
-
- /*
- * If a directory, then defer getting the new attributes
- * until requested. Might be a little bit faster this way.
- */
- if (CTOV(cp)->v_type == VDIR)
- goto out;
- }
-
- /* get the new mtime so the next call to check_cobject does not fail */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error) {
- mdp->md_vattr.va_mtime.tv_sec = 0;
- goto out;
- }
- }
- attrs.va_mask = AT_ALL;
- ASSERT(cp->c_backvp != NULL);
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error) {
- mdp->md_vattr.va_mtime.tv_sec = 0;
- goto out;
- }
- nlink = cp->c_attr.va_nlink;
- cp->c_attr = attrs;
- cp->c_attr.va_nlink = nlink;
- if ((attrs.va_size > cp->c_size) || !vn_has_cached_data(CTOV(cp)))
- cp->c_size = attrs.va_size;
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
-out:
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_cod_invalidate_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- mdp->md_vattr.va_mtime.tv_sec = 0;
- mdp->md_flags |= MD_NEEDATTRS;
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_cod_convert_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- mdp->md_flags |= MD_NEEDATTRS;
- mdp->md_consttype = CFS_FS_CONST_CODCONST;
- cp->c_flags |= CN_UPDATED;
-}
-
-struct cachefsops codcfsops = {
- c_cod_init_cached_object,
- c_cod_check_cached_object,
- c_cod_modify_cached_object,
- c_cod_invalidate_cached_object,
- c_cod_convert_cached_object
-};
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_dir.c b/usr/src/uts/common/fs/cachefs/cachefs_dir.c
deleted file mode 100644
index d77b4ab36a..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_dir.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/modctl.h>
-#include <sys/dirent.h>
-#include <sys/fbuf.h>
-#include <rpc/types.h>
-#include <vm/seg.h>
-#include <vm/faultcode.h>
-#include <vm/hat.h>
-#include <vm/seg_map.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dir.h>
-#include <sys/fs/cachefs_log.h>
-
-/* forward declarations */
-static int cachefs_dir_getentrys(struct cnode *, u_offset_t, u_offset_t *,
- uint_t *, uint_t, caddr_t, int *);
-static int cachefs_dir_stuff(cnode_t *dcp, uint_t count, caddr_t buf,
- vnode_t *frontvp, u_offset_t *offsetp, u_offset_t *fsizep);
-static int cachefs_dir_extend(cnode_t *, u_offset_t *, int incr_frontblks);
-static int cachefs_dir_fill_common(cnode_t *dcp, cred_t *cr,
- vnode_t *frontvp, vnode_t *backvp, u_offset_t *frontsize);
-static int cachefs_dir_complete(fscache_t *fscp, vnode_t *backvp,
- vnode_t *frontvp, cred_t *cr, int acltoo);
-
-
-
-/*
- * cachefs_dir_look() called mainly by lookup (and create), looks up the cached
- * directory for an entry and returns the information there. If the directory
- * entry doesn't exist return ENOENT, if it is incomplete, return EINVAL.
- * Should only call this routine if the dir is populated.
- * Returns ENOTDIR if dir gets nuked because of front file problems.
- */
-int
-cachefs_dir_look(cnode_t *dcp, char *nm, fid_t *cookiep, uint_t *flagp,
- u_offset_t *d_offsetp, cfs_cid_t *cidp)
-{
- int error;
- struct vattr va;
- u_offset_t blockoff = 0LL;
- uint_t offset = 0; /* offset inside the block of size MAXBSIZE */
- vnode_t *dvp;
- struct fscache *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int nmlen;
- struct fbuf *fbp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_look: ENTER dcp %p nm %s\n", (void *)dcp,
- nm);
-#endif
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT(dcp->c_metadata.md_flags & MD_POPULATED);
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ENOTDIR;
- goto out;
- }
-
- dvp = dcp->c_frontvp;
- va.va_mask = AT_SIZE; /* XXX should save dir size */
- error = VOP_GETATTR(dvp, &va, 0, kcred, NULL);
- if (error) {
- cachefs_inval_object(dcp);
- error = ENOTDIR;
- goto out;
- }
-
- ASSERT(va.va_size != 0LL);
- nmlen = (int)strlen(nm);
- while (blockoff < va.va_size) {
- offset = 0;
- error =
- fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
-
- while (offset < MAXBSIZE && (blockoff + offset) < va.va_size) {
- struct c_dirent *dep;
-
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr +
- offset);
- if ((dep->d_flag & CDE_VALID) &&
- (nmlen == dep->d_namelen) &&
- strcmp(dep->d_name, nm) == 0) {
- if (dep->d_flag & CDE_COMPLETE) {
- if (cookiep) {
- CACHEFS_FID_COPY(&dep->d_cookie,
- cookiep);
- }
- if (flagp)
- *flagp = dep->d_flag;
- error = 0;
- } else {
- error = EINVAL;
- }
- if (cidp)
- *cidp = dep->d_id;
- if (d_offsetp)
- *d_offsetp = offset + blockoff;
- fbrelse(fbp, S_OTHER);
- goto out;
- }
- ASSERT(dep->d_length != 0);
- offset += dep->d_length;
- }
- fbrelse(fbp, S_OTHER);
- blockoff += MAXBSIZE;
- }
- error = ENOENT;
-
-out:
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_RFDIR))
- cachefs_log_rfdir(cachep, error, fscp->fs_cfsvfsp,
- &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno, 0);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("c_dir_look: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * creates a new directory and populates it with "." and ".."
- */
-int
-cachefs_dir_new(cnode_t *dcp, cnode_t *cp)
-{
- int error = 0;
- struct c_dirent *dep;
- u_offset_t size;
- int len;
- struct fbuf *fbp;
-#ifdef CFSDEBUG
- struct vattr va;
-
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("c_dir_new: ENTER dcp %p cp %p\n", (void *)dcp,
- (void *)cp);
-#endif
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(CTOV(cp)->v_type == VDIR);
- ASSERT((cp->c_flags & CN_ASYNC_POPULATE) == 0);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(dcp)) == 0);
-
- if (cp->c_frontvp == NULL) {
- error = cachefs_getfrontfile(cp);
- if (error)
- goto out;
- }
-
-#ifdef CFSDEBUG
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(cp->c_frontvp, &va, 0, kcred, NULL);
- if (error)
- goto out;
- ASSERT(va.va_size == 0);
-#endif
-
- /*
- * Extend the directory by one MAXBSIZE chunk
- */
- size = 0LL;
- error = cachefs_dir_extend(cp, &size, 1);
- if (error != 0)
- goto out;
- error = fbread(cp->c_frontvp, (offset_t)0, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
-
- /*
- * Insert "." and ".."
- */
- len = (int)CDE_SIZE(".");
- dep = (struct c_dirent *)fbp->fb_addr;
- dep->d_length = len;
- dep->d_offset = (offset_t)len;
- dep->d_flag = CDE_VALID | CDE_COMPLETE;
- CACHEFS_FID_COPY(&cp->c_cookie, &dep->d_cookie);
- dep->d_id = cp->c_id;
- dep->d_namelen = 1;
- bcopy(".", dep->d_name, 2);
-
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + len);
- dep->d_length = MAXBSIZE - len;
- dep->d_offset = MAXBSIZE;
- dep->d_flag = CDE_VALID | CDE_COMPLETE;
- CACHEFS_FID_COPY(&dcp->c_cookie, &dep->d_cookie);
- dep->d_id = dcp->c_id;
- dep->d_namelen = 2;
- bcopy("..", dep->d_name, 3);
-
- (void) fbdwrite(fbp);
-#ifdef INVALREADDIR
- cp->c_metadata.md_flags |= MD_POPULATED | MD_INVALREADDIR;
-#else
- cp->c_metadata.md_flags |= MD_POPULATED;
-#endif
- cp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_new: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_dir_enter adds a new directory entry. Takes as input a fid,
- * fileno and a sync flag. Most of the time, the caller is content with the
- * write to the (front) directory being done async. The exception being - for
- * local files, we should make sure that the directory entry is made
- * synchronously. That is notified by the caller.
- * issync == 0 || issync == SM_ASYNC !
- *
- * The new entry is inserted at the end, so that we can generate local offsets
- * which are compatible with the backfs offsets (which are used when
- * disconnected.
- */
-int
-cachefs_dir_enter(cnode_t *dcp, char *nm, fid_t *cookiep, cfs_cid_t *cidp,
- int issync)
-{
- struct vattr va;
- int offset;
- u_offset_t blockoff = 0LL;
- u_offset_t prev_offset;
- int error = 0;
- vnode_t *dvp;
- struct c_dirent *dep;
- uint_t esize;
- u_offset_t dirsize;
- struct fbuf *fbp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("c_dir_enter: ENTER dcp %p nm %s dirflg %x\n",
- (void *)dcp, nm, dcp->c_metadata.md_flags);
-#endif
-
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
- ASSERT(dcp->c_metadata.md_flags & MD_POPULATED);
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT(issync == 0 || issync == SM_ASYNC);
- ASSERT(strlen(nm) <= MAXNAMELEN);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ENOTDIR;
- goto out;
- }
- dvp = dcp->c_frontvp;
-
- /*
- * Get the current EOF for the directory(data file)
- */
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(dvp, &va, 0, kcred, NULL);
- if (error) {
- cachefs_inval_object(dcp);
- error = ENOTDIR;
- goto out;
- }
-
- /*
- * Get the last block of the directory
- */
- dirsize = va.va_size;
- ASSERT(dirsize != 0LL);
- ASSERT(!(dirsize & MAXBOFFSET));
- ASSERT(dirsize <= MAXOFF_T);
- blockoff = dirsize - MAXBSIZE;
- error = fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
-
- /*
- * Find the last entry
- */
- offset = 0;
- prev_offset = blockoff;
- for (;;) {
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + offset);
- if (offset + dep->d_length == MAXBSIZE)
- break;
- prev_offset = dep->d_offset;
- offset += dep->d_length;
- ASSERT(offset < MAXBSIZE);
- }
- esize = C_DIRSIZ(dep);
-
- if (dep->d_length - esize >= CDE_SIZE(nm)) {
- /*
- * It has room. If the entry is not valid, we can just use
- * it. Otherwise, we need to adjust its length and offset
- */
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR) {
- if (prev_offset >= dep->d_offset) {
- printf("cachefs_dir_enter: looks like "
- "we might fail the assert\n");
- printf("addr %p, offset %x, "
- "prev_offset %llx, dep->d_offset %llx\n",
- (void *)fbp->fb_addr, offset, prev_offset,
- dep->d_offset);
- offset = 0;
- prev_offset = blockoff;
- for (;;) {
- dep = (struct c_dirent *)
- ((uintptr_t)fbp->fb_addr + offset);
- printf("offset %x, prev_offset %llx\n",
- offset, prev_offset);
- printf("dep->d_offset %llx, "
- "dep->d_length %x\n",
- dep->d_offset, dep->d_length);
- if (offset + dep->d_length == MAXBSIZE)
- break;
- prev_offset = dep->d_offset;
- offset += dep->d_length;
- }
- }
- }
-#endif /* CFSDEBUG */
-
- if (offset)
- ASSERT(prev_offset < dep->d_offset);
- if (dep->d_flag & CDE_VALID) {
- dep->d_length = esize;
- dep->d_offset = prev_offset + (u_offset_t)esize;
- dep = (struct c_dirent *)((uintptr_t)dep + esize);
- }
- dep->d_length = (int)((offset_t)MAXBSIZE -
- ((uintptr_t)dep - (uintptr_t)fbp->fb_addr));
- } else {
- /*
- * No room - so extend the file by one more
- * MAXBSIZE chunk, and fit the entry there.
- */
- fbrelse(fbp, S_OTHER);
- error = cachefs_dir_extend(dcp, &dirsize, 1);
- if (error != 0)
- goto out;
- error =
- fbread(dvp, (offset_t)va.va_size, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
- dep = (struct c_dirent *)fbp->fb_addr;
- dep->d_length = MAXBSIZE;
- }
-
- /*
- * Fill in the rest of the new entry
- */
- dep->d_offset = dirsize;
- dep->d_flag = CDE_VALID;
- if (cookiep) {
- dep->d_flag |= CDE_COMPLETE;
- CACHEFS_FID_COPY(cookiep, &dep->d_cookie);
- }
- dep->d_id = *cidp;
- dep->d_namelen = (ushort_t)strlen(nm);
- (void) bcopy(nm, dep->d_name, dep->d_namelen + 1);
-
-#ifdef INVALREADDIR
- dcp->c_metadata.md_flags |= MD_INVALREADDIR;
-#endif
- dcp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
- if (issync)
- (void) fbwrite(fbp);
- else
- (void) fbdwrite(fbp);
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_enter: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * Quite simple, if the deleted entry is the first in the MAXBSIZE block,
- * we simply mark it invalid. Otherwise, the deleted entries d_length is
- * just added to the previous entry.
- */
-int
-cachefs_dir_rmentry(cnode_t *dcp, char *nm)
-{
- u_offset_t blockoff = 0LL;
- int offset = 0;
- struct vattr va;
- int error = ENOENT;
- vnode_t *dvp;
- int nmlen;
- struct fbuf *fbp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_rmentry: ENTER dcp %p nm %s\n",
- (void *)dcp, nm);
-#endif
- ASSERT(dcp->c_metadata.md_flags & MD_POPULATED);
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ENOTDIR;
- goto out;
- }
- dvp = dcp->c_frontvp;
-
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT((dcp->c_flags & CN_NOCACHE) == 0);
- ASSERT(dvp != NULL);
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(dvp, &va, 0, kcred, NULL);
- if (error) {
- cachefs_inval_object(dcp);
- error = ENOTDIR;
- goto out;
- }
- ASSERT(va.va_size != 0LL);
-
- nmlen = (int)strlen(nm);
- while (blockoff < va.va_size) {
- uint_t *last_len;
-
- offset = 0;
- last_len = NULL;
- error =
- fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
- while (offset < MAXBSIZE && (blockoff + offset) < va.va_size) {
- struct c_dirent *dep;
-
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr +
- offset);
- if ((dep->d_flag & CDE_VALID) &&
- (nmlen == dep->d_namelen) &&
- strcmp(dep->d_name, nm) == 0) {
- /*
- * Found the entry. If this was the first entry
- * in the MAXBSIZE block, Mark it invalid. Else
- * add it's length to the previous entry's
- * length.
- */
- if (last_len == NULL) {
- ASSERT(offset == 0);
- dep->d_flag = 0;
- } else
- *last_len += dep->d_length;
- (void) fbdwrite(fbp);
- dcp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
- goto out;
- }
- last_len = &dep->d_length;
- offset += dep->d_length;
- }
- fbrelse(fbp, S_OTHER);
- blockoff += MAXBSIZE;
- }
- error = ENOENT;
-
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_rmentry: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-#if 0
-/*
- * This function is used only in cachefs_lookup_back() routine but
- * is inside #if 0 directive in this routine. So I am keeping this
- * routine also in #if 0 directive.
- */
-
-/*
- * This function fills in the cookie and file no of the directory entry
- * at the offset specified by offset - In other words, makes the entry
- * "complete".
- */
-int
-cachefs_dir_modentry(cnode_t *dcp, u_offset_t offset, fid_t *cookiep,
- cfs_cid_t *cidp)
-{
- struct c_dirent *dep;
- u_offset_t blockoff = (offset & (offset_t)MAXBMASK);
- uint_t off = (uint_t)(offset & (offset_t)MAXBOFFSET);
- struct fbuf *fbp;
- vnode_t *dvp;
- int error = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_modentry: ENTER dcp %p offset %lld\n",
- (void *)dcp, offset);
-#endif
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT(dcp->c_metadata.md_flags & MD_POPULATED);
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- return;
- }
- dvp = dcp->c_frontvp;
-
- error = fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- if (cookiep) {
- dep->d_flag |= CDE_COMPLETE;
- CACHEFS_FID_COPY(cookiep, &dep->d_cookie);
- }
- if (cidp)
- dep->d_id = *cidp;
- (void) fbdwrite(fbp);
- dcp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
-
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_modentry: EXIT\n");
-#endif
- return (error);
-}
-
-#endif /* of #if 0 */
-
-/*
- * Called by cachefs_read_dir(). Gets a bunch if directory entries into buf and
- * packs them into buf.
- */
-static int
-cachefs_dir_getentrys(struct cnode *dcp, u_offset_t beg_off,
- u_offset_t *last_offp, uint_t *cntp, uint_t bufsize,
- caddr_t buf, int *eofp)
-{
-
-#define DIR_ENDOFF 0x7fffffffLL
-
- struct vattr va;
- struct c_dirent *dep;
- struct fbuf *fbp = NULL;
- struct dirent64 *gdp;
- u_offset_t blockoff;
- uint_t off;
- int error;
- vnode_t *dvp = dcp->c_frontvp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_getentrys: "
- "ENTER dcp %p beg_off %lld mdflags %x cflags %x\n",
- dcp, beg_off, dcp->c_metadata.md_flags, dcp->c_flags);
-#endif
-
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- /*
- * blockoff has the offset of the MAXBSIZE block that contains the
- * entry to start with. off contains the offset relative to the
- * begining of the MAXBSIZE block.
- */
- if (eofp)
- *eofp = 0;
- gdp = (struct dirent64 *)buf;
- *cntp = bufsize;
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(dvp, &va, 0, kcred, NULL);
- if (error) {
- *cntp = 0;
- *last_offp = 0;
- if (eofp)
- *eofp = 1;
- goto out;
- }
- ASSERT(va.va_size != 0LL);
-
- if (beg_off == DIR_ENDOFF) {
- *cntp = 0;
- *last_offp = DIR_ENDOFF;
- if (eofp)
- *eofp = 1;
- goto out;
- }
-
- /*
- * locate the offset where we start reading.
- */
- for (blockoff = 0; blockoff < va.va_size; blockoff += MAXBSIZE) {
- error =
- fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- goto out;
- dep = (struct c_dirent *)fbp->fb_addr;
- off = 0;
- while (off < MAXBSIZE && dep->d_offset <= beg_off) {
- off += dep->d_length;
- dep =
- (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- }
- if (off < MAXBSIZE)
- break;
- fbrelse(fbp, S_OTHER);
- fbp = NULL;
- }
-
- if (blockoff >= va.va_size) {
- *cntp = 0;
- *last_offp = DIR_ENDOFF;
- if (eofp)
- *eofp = 1;
- goto out;
- }
-
- /*
- * Just load up the buffer with directory entries.
- */
- for (;;) {
- uint_t size;
- int this_reclen;
-
- ASSERT((uintptr_t)dep < ((uintptr_t)fbp->fb_addr + MAXBSIZE));
- if (dep->d_flag & CDE_VALID) {
- this_reclen = DIRENT64_RECLEN(dep->d_namelen);
- size = C_DIRSIZ(dep);
- ASSERT(size < MAXBSIZE);
- if (this_reclen > bufsize)
- break;
- ASSERT(dep->d_namelen <= MAXNAMELEN);
- ASSERT(dep->d_offset > (*last_offp));
- gdp->d_ino = dep->d_id.cid_fileno;
- gdp->d_off = dep->d_offset;
-
- /* use strncpy(9f) to zero out uninitialized bytes */
-
- ASSERT(strlen(dep->d_name) + 1 <=
- DIRENT64_NAMELEN(this_reclen));
- (void) strncpy(gdp->d_name, dep->d_name,
- DIRENT64_NAMELEN(this_reclen));
-
- gdp->d_reclen = (ushort_t)this_reclen;
- bufsize -= this_reclen;
- gdp = (struct dirent64 *)((uintptr_t)gdp +
- gdp->d_reclen);
- *last_offp = dep->d_offset;
- }
-
- /*
- * Increment the offset. If we've hit EOF, fill in
- * the lastoff and current entries d_off field.
- */
- off += dep->d_length;
- ASSERT(off <= MAXBSIZE);
- if ((blockoff + off) >= va.va_size) {
- *last_offp = DIR_ENDOFF;
- if (eofp)
- *eofp = 1;
- break;
- }
- /*
- * If off == MAXBSIZE, then we need to adjust our
- * window to the next MAXBSIZE block of the directory.
- * Adjust blockoff, off and map it in. Also, increment
- * the directory and buffer pointers.
- */
- if (off == MAXBSIZE) {
- fbrelse(fbp, S_OTHER);
- fbp = NULL;
- off = 0;
- blockoff += MAXBSIZE;
- error = fbread(dvp, (offset_t)blockoff, MAXBSIZE,
- S_OTHER, &fbp);
- if (error)
- goto out;
- }
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- }
- *cntp -= bufsize;
-out:
- /*
- * Release any buffer and maping that may exist.
- */
- if (fbp)
- (void) fbrelse(fbp, S_OTHER);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("ccachefs_dir_getentrys: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * Called by cachefs_readdir(). Fills a directory request from the cache
- */
-int
-cachefs_dir_read(struct cnode *dcp, struct uio *uiop, int *eofp)
-{
- int error;
- uint_t count;
- uint_t size;
- caddr_t buf;
- u_offset_t next = uiop->uio_loffset;
- struct fscache *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- caddr_t chrp, end;
- dirent64_t *de;
-
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT(RW_READ_HELD(&dcp->c_rwlock));
-
- ASSERT(next <= MAXOFF_T);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_read: ENTER dcp %p\n", (void *)dcp);
-#endif
- ASSERT((dcp->c_metadata.md_flags & (MD_FILE|MD_POPULATED)) ==
- (MD_FILE|MD_POPULATED));
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ENOTDIR;
- goto out;
- }
-
- size = (uint_t)uiop->uio_resid;
- buf = cachefs_kmem_alloc(size, KM_SLEEP);
- error = cachefs_dir_getentrys(dcp, next, &next, &count, size,
- buf, eofp);
- if (error == 0 && (int)count > 0) {
- ASSERT(count <= size);
- if (fscp->fs_inum_size > 0) {
- ino64_t newinum;
-
- mutex_exit(&dcp->c_statelock);
- mutex_enter(&fscp->fs_fslock);
- end = (caddr_t)((uintptr_t)buf + count);
- for (chrp = buf; chrp < end; chrp += de->d_reclen) {
- de = (dirent64_t *)chrp;
-
- newinum = cachefs_inum_real2fake(fscp,
- de->d_ino);
- if (newinum == 0)
- newinum = cachefs_fileno_conflict(fscp,
- de->d_ino);
- de->d_ino = newinum;
- }
- mutex_exit(&fscp->fs_fslock);
- mutex_enter(&dcp->c_statelock);
- }
- error = uiomove(buf, count, UIO_READ, uiop);
- if (error == 0)
- uiop->uio_loffset = next;
- }
- (void) cachefs_kmem_free(buf, size);
-out:
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_RFDIR))
- cachefs_log_rfdir(cachep, error, fscp->fs_cfsvfsp,
- &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno, 0);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_read: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * Fully (including cookie) populates the directory from the back filesystem.
- */
-int
-cachefs_dir_fill(cnode_t *dcp, cred_t *cr)
-{
- int error = 0;
- u_offset_t frontsize;
- struct fscache *fscp = C_TO_FSCACHE(dcp);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_fill: ENTER dcp %p\n", (void *)dcp);
-#endif
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
-
- /* XXX for now return success if async populate is scheduled */
- if (dcp->c_flags & CN_ASYNC_POPULATE)
- goto out;
-
- /* get the back vp */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- goto out;
- }
- }
-
- /* get the front file vp */
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if (dcp->c_flags & CN_NOCACHE) {
- error = ENOTDIR;
- goto out;
- }
-
- /* if dir was modified, toss old contents */
- if (dcp->c_metadata.md_flags & MD_INVALREADDIR) {
- cachefs_inval_object(dcp);
- if (dcp->c_flags & CN_NOCACHE) {
- error = ENOTDIR;
- goto out;
- }
- }
-
- error = cachefs_dir_fill_common(dcp, cr,
- dcp->c_frontvp, dcp->c_backvp, &frontsize);
- if (error == 0)
- error = cachefs_dir_complete(fscp, dcp->c_backvp,
- dcp->c_frontvp, cr, 0);
- if (error != 0)
- goto out;
-
- /*
- * Mark the directory as not empty. Also bang the flag that says that
- * this directory needs to be sync'ed on inactive.
- */
- dcp->c_metadata.md_flags |= MD_POPULATED;
- dcp->c_metadata.md_flags &= ~MD_INVALREADDIR;
- dcp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
- /*LINTED alignment okay*/
- dcp->c_metadata.md_frontblks = frontsize / MAXBSIZE;
-
-out:
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_INVALIDATE)
- printf("c_dir_fill: invalidating %llu\n",
- (u_longlong_t)dcp->c_id.cid_fileno);
-#endif
- cachefs_inval_object(dcp);
- }
-
- return (error);
-}
-
-/*
- * Does work of populating directory.
- * Must be called while holding dcp->c_statelock
- */
-
-static int
-cachefs_dir_fill_common(cnode_t *dcp, cred_t *cr,
- vnode_t *frontvp, vnode_t *backvp, u_offset_t *frontsize)
-{
- int error = 0;
- struct uio uio;
- struct iovec iov;
- caddr_t buf = NULL;
- int count;
- int eof = 0;
- u_offset_t frontoff;
- struct fscache *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
-#ifdef DEBUG
- int loop_count = 0;
-#endif
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_fill_common: ENTER dcp %p\n", (void *)dcp);
-#endif
-
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
-
- frontoff = *frontsize = 0LL;
-
- buf = cachefs_kmem_alloc(MAXBSIZE, KM_SLEEP);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_fmode = 0;
- uio.uio_extflg = UIO_COPY_CACHED;
- uio.uio_loffset = 0;
- for (;;) {
-#ifdef DEBUG
- loop_count++;
-#endif
- /*
- * Read in a buffer's worth of dirents and enter them in to the
- * directory.
- */
- uio.uio_resid = MAXBSIZE;
- iov.iov_base = buf;
- iov.iov_len = MAXBSIZE;
- (void) VOP_RWLOCK(backvp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READDIR(backvp, &uio, cr, &eof, NULL, 0);
- VOP_RWUNLOCK(backvp, V_WRITELOCK_FALSE, NULL);
- if (error)
- goto out;
-
- /*LINTED alignment okay*/
- count = MAXBSIZE - (int)uio.uio_resid;
- ASSERT(count >= 0);
- if (count > 0) {
- if (error = cachefs_dir_stuff(dcp, count, buf,
- frontvp, &frontoff, frontsize))
- goto out;
- ASSERT((*frontsize) != 0LL);
- }
- if (eof || count == 0)
- break;
- }
-
- if (*frontsize == 0LL) {
- /* keep us from caching an empty directory */
- error = EINVAL;
- goto out;
- }
-
-out:
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_FILLDIR))
- cachefs_log_filldir(cachep, error, fscp->fs_cfsvfsp,
- &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno,
- *frontsize);
- if (buf)
- cachefs_kmem_free(buf, (uint_t)MAXBSIZE);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_fill: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * If the directory contains only the elements "." and "..", then this returns
- * 0, otherwise returns an error.
- */
-int
-cachefs_dir_empty(cnode_t *dcp)
-{
- struct vattr va;
- u_offset_t blockoff = 0;
- int offset;
- struct fbuf *fbp;
- int error;
- vnode_t *dvp = dcp->c_frontvp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_dir_empty: ENTER dcp %p\n", (void *)dcp);
-#endif
- ASSERT(CTOV(dcp)->v_type == VDIR);
- ASSERT(dcp->c_metadata.md_flags & MD_POPULATED);
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
-
- if (dcp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(dcp);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0)
- return (ENOTDIR);
-
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(dvp, &va, 0, kcred, NULL);
- if (error)
- return (ENOTDIR);
-
- ASSERT(va.va_size != 0LL);
- while (blockoff < va.va_size) {
- offset = 0;
- error =
- fbread(dvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- return (error);
- while (offset < MAXBSIZE && (blockoff + offset) < va.va_size) {
- struct c_dirent *dep;
-
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr +
- offset);
- if ((dep->d_flag & CDE_VALID) &&
- ((strcmp(dep->d_name, ".") != 0) &&
- (strcmp(dep->d_name, "..") != 0))) {
- (void) fbrelse(fbp, S_OTHER);
- return (0);
- }
- offset += dep->d_length;
- }
- (void) fbrelse(fbp, S_OTHER);
- blockoff += MAXBSIZE;
- }
- return (EEXIST);
-}
-
-/*
- * Called by cachefs_dir_fill() to stuff a buffer of dir entries into
- * a front file. This is more efficient than repeated calls to
- * cachefs_dir_enter, and it also allows us to maintain entries in backfs
- * order (readdir requires that entry offsets be ascending).
- */
-static int
-cachefs_dir_stuff(cnode_t *dcp, uint_t count, caddr_t buf,
- vnode_t *frontvp, u_offset_t *offsetp, u_offset_t *fsizep)
-{
- int error = 0;
- struct fbuf *fbp;
- struct c_dirent *cdep, *last;
- struct dirent64 *dep;
- int inblk, entsize;
- u_offset_t blockoff = (*offsetp & (offset_t)MAXBMASK);
- /*LINTED alignment okay*/
- uint_t off = (uint_t)(*offsetp & (offset_t)MAXBOFFSET);
-
- /*LINTED want count != 0*/
- ASSERT(count > 0);
-
- if (*offsetp >= *fsizep) {
- error = cachefs_dir_extend(dcp, fsizep, 0);
- if (error)
- return (error);
- }
-
- ASSERT(*fsizep != 0LL);
- last = NULL;
- error = fbread(frontvp, (offset_t)blockoff, MAXBSIZE, S_OTHER, &fbp);
- if (error)
- return (error);
- cdep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- inblk = MAXBSIZE-off;
- if (*offsetp != 0) {
- ASSERT(cdep->d_length == inblk);
- inblk -= C_DIRSIZ(cdep);
- last = cdep;
- last->d_length -= inblk;
- off += last->d_length;
- cdep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- }
- dep = (struct dirent64 *)buf;
- /*LINTED want count != 0*/
- while (count > 0) {
- if (last) {
- ASSERT(dep->d_off > last->d_offset);
- }
- entsize = (int)CDE_SIZE(dep->d_name);
- if (entsize > inblk) {
- if (last) {
- last->d_length += inblk;
- }
- (void) fbwrite(fbp);
- error = cachefs_dir_extend(dcp, fsizep, 0);
- if (error)
- return (error);
- ASSERT(*fsizep != 0LL);
- blockoff += MAXBSIZE;
- error = fbread(frontvp, (offset_t)blockoff, MAXBSIZE,
- S_OTHER, &fbp);
- if (error)
- return (error);
- off = 0;
- cdep = (struct c_dirent *)fbp->fb_addr;
- inblk = MAXBSIZE;
- last = NULL;
- }
- cdep->d_length = entsize;
- cdep->d_id.cid_fileno = dep->d_ino;
- cdep->d_id.cid_flags = 0;
- cdep->d_namelen = (ushort_t)strlen(dep->d_name);
- cdep->d_flag = CDE_VALID;
- bcopy(dep->d_name, cdep->d_name, cdep->d_namelen+1);
- cdep->d_offset = dep->d_off;
- inblk -= entsize;
- count -= dep->d_reclen;
- dep = (struct dirent64 *)((uintptr_t)dep + dep->d_reclen);
- *offsetp = blockoff + (u_offset_t)off;
- off += entsize;
- last = cdep;
- cdep = (struct c_dirent *)((uintptr_t)fbp->fb_addr + off);
- }
- if (last) {
- last->d_length += inblk;
- }
- (void) fbwrite(fbp);
- return (error);
-}
-
-static int
-cachefs_dir_extend(cnode_t *dcp, u_offset_t *cursize, int incr_frontblks)
-{
- struct vattr va;
- cachefscache_t *cachep = C_TO_FSCACHE(dcp)->fs_cache;
- int error = 0;
- struct fscache *fscp = VFS_TO_FSCACHE(CTOV(dcp)->v_vfsp);
-
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
- ASSERT(((*cursize) & (MAXBSIZE-1)) == 0);
-
- va.va_mask = AT_SIZE;
- va.va_size = (u_offset_t)(*cursize + MAXBSIZE);
- error = cachefs_allocblocks(cachep, 1, dcp->c_metadata.md_rltype);
- if (error)
- return (error);
- error = VOP_SETATTR(dcp->c_frontvp, &va, 0, kcred, NULL);
- if (error) {
- cachefs_freeblocks(cachep, 1, dcp->c_metadata.md_rltype);
- return (error);
- }
- if (incr_frontblks)
- dcp->c_metadata.md_frontblks++;
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- dcp->c_size += MAXBSIZE;
- dcp->c_attr.va_size = dcp->c_size;
- }
- *cursize += MAXBSIZE;
- ASSERT(*cursize != 0LL);
- if (incr_frontblks)
- dcp->c_flags |= CN_UPDATED;
- return (0);
-}
-
-int
-cachefs_async_populate_dir(struct cachefs_populate_req *pop, cred_t *cr,
- vnode_t *backvp, vnode_t *frontvp)
-{
- vnode_t *dvp = pop->cpop_vp;
- struct cnode *dcp = VTOC(dvp);
- u_offset_t frontsize;
- int error = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_async_populate_dir: ENTER dvp %p\n",
- (void *)dvp);
-#endif
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
- ASSERT(dvp->v_type == VDIR);
- ASSERT((dcp->c_metadata.md_flags & MD_POPULATED) == 0);
- ASSERT(dcp->c_frontvp == frontvp);
- ASSERT(dcp->c_backvp == backvp);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(dcp)) == 0);
-
- /* if dir was modified, toss old contents */
- if (dcp->c_metadata.md_flags & MD_INVALREADDIR) {
- cachefs_inval_object(dcp);
- if (dcp->c_flags & CN_NOCACHE) {
- error = ENOTDIR;
- goto out;
- } else {
- dcp->c_metadata.md_flags &= ~MD_INVALREADDIR;
- }
- }
-
-
- error = cachefs_dir_fill_common(dcp, cr, frontvp, backvp, &frontsize);
- if (error != 0)
- goto out;
- ASSERT(frontsize != 0LL);
- mutex_exit(&dcp->c_statelock);
- /*
- * I don't like to break lock here but cachefs_dir_complete()
- * needs it.
- */
- error = cachefs_dir_complete(C_TO_FSCACHE(dcp), backvp,
- frontvp, cr, 1);
- mutex_enter(&dcp->c_statelock);
- if (error != 0)
- goto out;
- /* if went nocache while lock was dropped, get out */
- if ((dcp->c_flags & CN_NOCACHE) || (dcp->c_frontvp == NULL)) {
- error = EINVAL;
- } else {
- /* allocfile and allocblocks have already happened. */
- dcp->c_metadata.md_frontblks = frontsize / MAXBSIZE;
- }
-
-out:
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("cachefs_async_populate_dir: EXIT error = %d\n", error);
-#endif
-
- return (error);
-}
-
-static int
-cachefs_dir_complete(fscache_t *fscp, vnode_t *backvp, vnode_t *frontvp,
- cred_t *cr, int acltoo)
-{
- struct c_dirent *dep;
- caddr_t buf = kmem_alloc(MAXBSIZE, KM_SLEEP);
- struct vattr va;
- u_offset_t blockoff;
- int offset;
- u_offset_t dir_size;
- struct fbuf *fbp;
- cnode_t *cp;
- fid_t cookie;
- vnode_t *entry_vp;
- int error = 0;
-
- /*
- * note: caller better not hold a c_statelock if acltoo is set.
- */
-
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(frontvp, &va, 0, cr, NULL);
- if (error)
- goto out;
-
- ASSERT(va.va_size != 0LL);
- dir_size = va.va_size;
- ASSERT(dir_size <= MAXOFF_T);
-
- for (blockoff = 0; blockoff < dir_size; blockoff += MAXBSIZE) {
- if (error = fbread(frontvp, (offset_t)blockoff,
- MAXBSIZE, S_OTHER, &fbp))
- goto out;
-
- /*
- * We cannot hold any page locks across the below VOP
- * operations. We thus copy the directory entries into a
- * staging buffer, and release the page lock on the directory
- * by calling fbrelse(). Once any necessary cnodes have
- * been created, we'll reacquire the page lock with fbread()
- * and copy the staging buffer back into the frontvp at
- * blockoff.
- */
- bcopy(fbp->fb_addr, buf, MAXBSIZE);
- fbrelse(fbp, S_OTHER);
-
- for (offset = 0;
- offset < MAXBSIZE &&
- (blockoff + (u_offset_t)offset) < dir_size;
- offset += dep->d_length) {
-
- dep = (struct c_dirent *)((uintptr_t)buf + offset);
- ASSERT(dep->d_length != 0);
- if ((dep->d_flag & (CDE_VALID | CDE_COMPLETE)) !=
- CDE_VALID)
- continue;
-
- error = VOP_LOOKUP(backvp, dep->d_name,
- &entry_vp, (struct pathname *)NULL, 0,
- (vnode_t *)NULL, cr, NULL, NULL, NULL);
- if (error) {
- /* lookup on .. in / on coc gets ENOENT */
- if (error == ENOENT) {
- error = 0;
- continue;
- }
- goto out;
- }
-
- error = cachefs_getcookie(entry_vp, &cookie, NULL, cr,
- TRUE);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DIR)
- printf("\t%s: getcookie error\n",
- dep->d_name);
-#endif /* CFSDEBUG */
- VN_RELE(entry_vp);
- goto out;
- }
- CACHEFS_FID_COPY(&cookie, &dep->d_cookie);
- dep->d_flag |= CDE_COMPLETE;
-
- if ((! acltoo) ||
- (! cachefs_vtype_aclok(entry_vp)) ||
- (fscp->fs_info.fi_mntflags & CFS_NOACL)) {
- VN_RELE(entry_vp);
- continue;
- }
-
- error = cachefs_cnode_make(&dep->d_id, fscp, &cookie,
- NULL, entry_vp, cr, 0, &cp);
- VN_RELE(entry_vp);
- if (error != 0)
- goto out;
-
- ASSERT(cp != NULL);
- mutex_enter(&cp->c_statelock);
-
- if ((cp->c_flags & CN_NOCACHE) ||
- (cp->c_metadata.md_flags & MD_ACL)) {
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- continue;
- }
-
- (void) cachefs_cacheacl(cp, NULL);
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- }
-
- /*
- * We must now re-lock the page corresponding to the frontvp,
- * and copy our staging buffer onto it.
- */
- if (error = fbread(frontvp, (offset_t)blockoff,
- MAXBSIZE, S_OTHER, &fbp))
- goto out;
-
- bcopy(buf, fbp->fb_addr, MAXBSIZE);
- (void) fbdwrite(fbp);
- }
-
-out:
- kmem_free(buf, MAXBSIZE);
- return (error);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_dlog.c b/usr/src/uts/common/fs/cachefs/cachefs_dlog.c
deleted file mode 100644
index 5781d7a4d1..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_dlog.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-#include <sys/vfs.h>
-#include <sys/file.h>
-#include <sys/filio.h>
-#include <sys/uio.h>
-#include <sys/buf.h>
-#include <sys/mman.h>
-#include <sys/tiuser.h>
-#include <sys/pathname.h>
-#include <sys/dirent.h>
-#include <sys/conf.h>
-#include <sys/debug.h>
-#include <sys/vmsystm.h>
-#include <sys/fcntl.h>
-#include <sys/flock.h>
-#include <sys/swap.h>
-#include <sys/errno.h>
-#include <sys/sysmacros.h>
-#include <sys/disp.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/vtrace.h>
-#include <sys/mount.h>
-#include <sys/bootconf.h>
-#include <sys/dnlc.h>
-#include <sys/stat.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <fs/fs_subr.h>
-
-static int cachefs_dlog_mapreserve(fscache_t *fscp, int size);
-
-#ifdef _LP64
-
-static void cachefs_dlog_attrchk(vattr_t *vap, char *funcname);
-
-#define CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1) \
- { \
- int ovferr = 0; \
- CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, ovferr); \
- if (ovferr) \
- cmn_err(CE_WARN, "%s%s overflow", str, str1); \
- }
-
-#define CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1) \
- { \
- int ovferr = 0; \
- CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, ovferr); \
- if (ovferr) \
- cmn_err(CE_WARN, "%s%s 0x%lx -> 0x%x overflow", \
- str, str1, in_dev, (dev32_t)(out_dev)); \
- }
-
-#define CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str) \
- { \
- int ovferr = 0; \
- CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, ovferr); \
- if (ovferr) \
- cachefs_dlog_attrchk(in_vap, str); \
- }
-
-/*
- * 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
-cachefs_dlog_attrchk(vattr_t *vap, char *str)
-{
- dev_t tmpdev;
- cfs_timestruc_t ts;
-
- if (vap->va_mask & AT_FSID) {
- CACHEFS_DLOG_DEV_COPY(vap->va_fsid, tmpdev, str, ".va_fsid");
- }
- if (vap->va_mask & AT_RDEV) {
- CACHEFS_DLOG_DEV_COPY(vap->va_rdev, tmpdev, str, ".va_rdev");
- }
- if (vap->va_mask & AT_MTIME) {
- CACHEFS_DLOG_TS_COPY(&vap->va_mtime, &ts, str, ".va_mtime");
- }
- if (vap->va_mask & AT_ATIME) {
- CACHEFS_DLOG_TS_COPY(&vap->va_atime, &ts, str, ".va_atime");
- }
- if (vap->va_mask & AT_CTIME) {
- CACHEFS_DLOG_TS_COPY(&vap->va_ctime, &ts, str, ".va_ctime");
- }
-}
-
-#else /* not _LP64 */
-
-#define CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1) \
- CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error)
-
-#define CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1) \
- CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error)
-
-#define CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str) \
- CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, error)
-
-#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
-copy_cred(cred_t *src, dl_cred_t *dst)
-{
- int n;
- const gid_t *sgrp = crgetgroups(src);
-
- n = MIN(NGROUPS_MAX_DEFAULT, crgetngroups(src));
-
- /* copy the fixed fields */
- dst->cr_uid = crgetuid(src);
- dst->cr_ruid = crgetruid(src);
- dst->cr_suid = crgetsuid(src);
- dst->cr_gid = crgetgid(src);
- dst->cr_rgid = crgetrgid(src);
- dst->cr_sgid = crgetsgid(src);
- dst->cr_groups[0] = sgrp[0];
-
- dst->cr_ngroups = n;
- bcopy(sgrp, (void *)(dst + 1), (n - 1) * sizeof (gid_t));
- return (sizeof (dl_cred_t) + (n - 1) * sizeof (gid_t));
-}
-
-/*
- * Sets up for writing to the log files.
- */
-int
-cachefs_dlog_setup(fscache_t *fscp, int createfile)
-{
- struct vattr vattr;
- int error = 0;
- int createdone = 0;
- int lookupdone = 0;
- int version = CFS_DLOG_VERSION;
- off_t offset;
- struct cfs_dlog_trailer trailer;
-
- mutex_enter(&fscp->fs_dlock);
-
- /* all done if the log files already exist */
- if (fscp->fs_dlogfile) {
- ASSERT(fscp->fs_dmapfile);
- goto out;
- }
-
- /* see if the log file exists */
- error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
- &fscp->fs_dlogfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error && (createfile == 0))
- goto out;
-
- /* if the lookup failed then create file log files */
- if (error) {
- createdone++;
-
- vattr.va_mode = S_IFREG | 0666;
- vattr.va_uid = 0;
- vattr.va_gid = 0;
- vattr.va_type = VREG;
- vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
- error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
- &vattr, 0, 0666, &fscp->fs_dlogfile, kcred, 0, NULL, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: log file create fail %d\n",
- error);
-#endif
- goto out;
- }
-
- /* write the version number into the log file */
- error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)&version,
- sizeof (version), (offset_t)0, UIO_SYSSPACE, FSYNC,
- RLIM_INFINITY, kcred, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: log file init fail %d\n",
- error);
-#endif
- goto out;
- }
-
- vattr.va_mode = S_IFREG | 0666;
- vattr.va_uid = 0;
- vattr.va_gid = 0;
- vattr.va_type = VREG;
- vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
- error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
- &vattr, 0, 0666, &fscp->fs_dmapfile, kcred, 0, NULL, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: map file create fail %d\n",
- error);
-#endif
- goto out;
- }
-
- fscp->fs_dlogoff = sizeof (version);
- 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 */
- vattr.va_mask = AT_ALL;
- error = VOP_GETATTR(fscp->fs_dlogfile, &vattr, 0, kcred, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: log file getattr fail %d\n",
- error);
-#endif
- goto out;
- }
- /*LINTED alignment okay*/
- ASSERT(vattr.va_size <= MAXOFF_T);
- fscp->fs_dlogoff = (off_t)vattr.va_size;
-
- offset = vattr.va_size - sizeof (struct cfs_dlog_trailer);
- /*
- * 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.
- */
- error = vn_rdwr(UIO_READ, fscp->fs_dlogfile, (caddr_t)&trailer,
- sizeof (struct cfs_dlog_trailer), (offset_t)offset,
- UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
- if (error == 0) {
- if (trailer.dl_op == CFS_DLOG_TRAILER) {
- fscp->fs_dlogseq = trailer.dl_seq;
- /*
- * Set the offset of the next record to be
- * written, to over write the current
- * trailer.
- */
- fscp->fs_dlogoff = offset;
- } else {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG) {
- cmn_err(CE_WARN,
- "cachefs: can't find dlog trailer");
- cmn_err(CE_WARN,
- "cachefs: fsck required");
- }
-#endif /* CFSDEBUG */
- /*LINTED alignment okay*/
- fscp->fs_dlogseq = (uint_t)vattr.va_size;
- }
- } else {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- cmn_err(CE_WARN,
- "cachefs: error reading dlog trailer");
-#endif /* CFSDEBUG */
- /*LINTED alignment okay*/
- fscp->fs_dlogseq = (uint_t)vattr.va_size;
- }
-
-
- error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
- &fscp->fs_dmapfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: map file lookup fail %d\n",
- error);
-#endif
- goto out;
- }
-
- vattr.va_mask = AT_ALL;
- error = VOP_GETATTR(fscp->fs_dmapfile, &vattr, 0, kcred, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_DLOG)
- printf("cachefs: map file getattr fail %d\n",
- error);
-#endif
- goto out;
- }
- fscp->fs_dmapoff = (off_t)vattr.va_size;
- fscp->fs_dmapsize = (off_t)vattr.va_size;
- }
-
-out:
- if (error) {
- if (createdone) {
- if (fscp->fs_dlogfile) {
- VN_RELE(fscp->fs_dlogfile);
- fscp->fs_dlogfile = NULL;
- (void) VOP_REMOVE(fscp->fs_fscdirvp,
- CACHEFS_DLOG_FILE, kcred, NULL, 0);
- }
- if (fscp->fs_dmapfile) {
- VN_RELE(fscp->fs_dmapfile);
- fscp->fs_dmapfile = NULL;
- (void) VOP_REMOVE(fscp->fs_fscdirvp,
- CACHEFS_DMAP_FILE, kcred, NULL, 0);
- }
- }
- if (lookupdone) {
- if (fscp->fs_dlogfile) {
- VN_RELE(fscp->fs_dlogfile);
- fscp->fs_dlogfile = NULL;
- }
- if (fscp->fs_dmapfile) {
- VN_RELE(fscp->fs_dmapfile);
- fscp->fs_dmapfile = NULL;
- }
- }
- }
-
- mutex_exit(&fscp->fs_dlock);
- return (error);
-}
-
-/*
- * Drops reference to the log file.
- */
-void
-cachefs_dlog_teardown(fscache_t *fscp)
-{
- vattr_t va;
- /*LINTED: set but not used */
- int error;
-
- mutex_enter(&fscp->fs_dlock);
-
- /* clean up the log file */
- if (fscp->fs_dlogfile) {
- VN_RELE(fscp->fs_dlogfile);
- fscp->fs_dlogfile = NULL;
- }
-
- /* clean up the map file */
- if (fscp->fs_dmapfile) {
- /* set the map file to the actual size needed */
- va.va_mask = AT_SIZE;
- va.va_size = fscp->fs_dmapoff;
- error = VOP_SETATTR(fscp->fs_dmapfile, &va, 0, kcred, NULL);
-#ifdef CFSDEBUG
- if (error) {
- cmn_err(CE_WARN, "cachefs: map setattr failed %d",
- error);
- }
-#endif
- VN_RELE(fscp->fs_dmapfile);
- fscp->fs_dmapfile = NULL;
- }
- mutex_exit(&fscp->fs_dlock);
-}
-
-/*
- * Outputs a dlog message to the log file.
- */
-static off_t
-cachefs_dlog_output(fscache_t *fscp, cfs_dlog_entry_t *entp, uint_t *seqp)
-{
- int error;
- off_t offset;
- int xx;
- uint_t seq;
- int len;
- struct cfs_dlog_trailer *trail;
-
- ASSERT(entp->dl_len <= CFS_DLOG_ENTRY_MAXSIZE);
-
- if (fscp->fs_dlogfile == NULL) {
- error = cachefs_dlog_setup(fscp, 1);
- if (error) {
- offset = 0;
- goto out;
- }
- }
-
- /* round up length to a 4 byte boundary */
- len = entp->dl_len;
- xx = len & 0x03;
- if (xx) {
- xx = 4 - xx;
- bzero((void *)((uintptr_t)entp + len), (size_t)xx);
- len += xx;
- entp->dl_len = len;
- }
-
- /* XXX turn this on/off in sync with code in cachefs_dlog_setsecattr */
-#if 0
- /* XXX debugging hack, round up to 16 byte boundary */
- len = entp->dl_len;
- xx = 16 - (len & 0x0f);
- bcopy("UUUUUUUUUUUUUUUU", (void *)((uintptr_t)entp + len), (size_t)xx);
- len += xx;
- entp->dl_len = len;
-#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.
- */
- trail = (struct cfs_dlog_trailer *)((uintptr_t)entp + entp->dl_len);
- trail->dl_len = sizeof (struct cfs_dlog_trailer);
- trail->dl_op = CFS_DLOG_TRAILER;
- trail->dl_valid = CFS_DLOG_VAL_COMMITTED;
- mutex_enter(&fscp->fs_dlock);
- ASSERT(fscp->fs_dlogfile);
-
- /* get a sequence number for this log entry */
- seq = fscp->fs_dlogseq + 1;
- if (seq == 0) {
- mutex_exit(&fscp->fs_dlock);
- offset = 0;
-#ifdef CFSDEBUG
- cmn_err(CE_WARN, "cachefs: logging failed, seq overflow");
-#endif
- goto out;
- }
- fscp->fs_dlogseq++;
- trail->dl_seq = fscp->fs_dlogseq;
-
- /* add the sequence number to the record */
- entp->dl_seq = seq;
-
- /* get offset into file to write record */
- offset = fscp->fs_dlogoff;
-
- /* 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.
- */
- error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)entp,
- entp->dl_len+trail->dl_len, (offset_t)offset, UIO_SYSSPACE, FSYNC,
- RLIM_INFINITY, kcred, NULL);
-
- if (error) {
- offset = 0;
- cmn_err(CE_WARN, "cachefs: logging failed (%d)", error);
- } else {
- fscp->fs_dlogoff += entp->dl_len;
-
- /* get offset of valid field */
- offset += offsetof(struct cfs_dlog_entry, dl_valid);
- }
-
- mutex_exit(&fscp->fs_dlock);
-
- /* return sequence number used if requested */
- if (seqp)
- *seqp = seq;
-
-out:
- return (offset);
-}
-
-/*
- * Commits a previously written dlog message.
- */
-int
-cachefs_dlog_commit(fscache_t *fscp, off_t offset, int error)
-{
- cfs_dlog_val_t valid;
-
- if (error)
- valid = CFS_DLOG_VAL_ERROR;
- else
- valid = CFS_DLOG_VAL_COMMITTED;
-
- error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile,
- (caddr_t)&valid, sizeof (valid), (offset_t)offset,
- UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
-
- if (error)
- cmn_err(CE_WARN, "cachefs: logging commit failed (%d)", error);
- return (error);
-}
-
-/*
- * Reserves space in the map file.
- */
-static int
-cachefs_dlog_mapreserve(fscache_t *fscp, int size)
-{
- int error = 0;
- int len;
- char *bufp;
-
- if (fscp->fs_dmapfile == NULL) {
- error = cachefs_dlog_setup(fscp, 1);
- if (error) {
- return (error);
- }
- }
-
- mutex_enter(&fscp->fs_dlock);
- ASSERT(fscp->fs_dmapoff <= fscp->fs_dmapsize);
- ASSERT(fscp->fs_dmapfile);
-
- if ((fscp->fs_dmapoff + size) > fscp->fs_dmapsize) {
- /* reserve 20% for optimal hashing */
- size += MAXBSIZE / 5;
-
- /* grow file by a MAXBSIZE chunk */
- len = MAXBSIZE;
- ASSERT((fscp->fs_dmapoff + size) < (fscp->fs_dmapsize + len));
-
- bufp = cachefs_kmem_zalloc(len, KM_SLEEP);
- error = vn_rdwr(UIO_WRITE, fscp->fs_dmapfile, (caddr_t)bufp,
- len, (offset_t)fscp->fs_dmapsize, UIO_SYSSPACE, FSYNC,
- RLIM_INFINITY, kcred, NULL);
- if (error == 0) {
- fscp->fs_dmapoff += size;
- fscp->fs_dmapsize += len;
- } else {
- cmn_err(CE_WARN, "cachefs: logging secondary "
- "failed (%d)", error);
- }
- cachefs_kmem_free(bufp, len);
- } else {
- fscp->fs_dmapoff += size;
- }
- mutex_exit(&fscp->fs_dlock);
- return (error);
-}
-
-/*
- * Reserves space for one cid mapping in the mapping file.
- */
-int
-cachefs_dlog_cidmap(fscache_t *fscp)
-{
- int error;
- error = cachefs_dlog_mapreserve(fscp,
- sizeof (struct cfs_dlog_mapping_space));
- return (error);
-}
-
-off_t
-cachefs_dlog_setattr(fscache_t *fscp, struct vattr *vap, int flags,
- cnode_t *cp, cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_setattr *up;
- size_t len;
- off_t offset;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_SETATTR;
- up = &entp->dl_u.dl_setattr;
- CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
- "cachefs_dlog_setattr: dl_attr");
- up->dl_flags = flags;
- up->dl_cid = cp->c_id;
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime, "cachefs_dlog_setattr: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime, "cachefs_dlog_setattr: ", "ctime");
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* Calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-/*ARGSUSED*/
-cachefs_dlog_setsecattr(fscache_t *fscp, vsecattr_t *vsec, int flags,
- cnode_t *cp, cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_setsecattr *up;
- size_t alen, clen, len;
- off_t offset = 0;
- aclent_t *aclp;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* paranoia */
- ASSERT((vsec->vsa_mask & VSA_ACL) || (vsec->vsa_aclcnt == 0));
- ASSERT((vsec->vsa_mask & VSA_DFACL) || (vsec->vsa_dfaclcnt == 0));
- if ((vsec->vsa_mask & VSA_ACL) == 0)
- vsec->vsa_aclcnt = 0;
- if ((vsec->vsa_mask & VSA_DFACL) == 0)
- vsec->vsa_dfaclcnt = 0;
-
- /* calculate length of ACL and cred data */
- alen = sizeof (aclent_t) * (vsec->vsa_aclcnt + vsec->vsa_dfaclcnt);
- clen = sizeof (dl_cred_t) + (((long)crgetngroups(cr)) * sizeof (gid_t));
-
- /*
- * 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.
- */
-
- len = sizeof (cfs_dlog_entry_t) - sizeof (up->dl_buffer) -
- sizeof (up->dl_cred) + alen + clen;
-
-
-#if 0
- /* make up for weird behavior in cachefs_dlog_output */
- /* XXX turn this on/off in sync with code in cachefs_dlog_output */
- entp = cachefs_kmem_alloc(len + 32 + sizeof (struct cfs_dlog_trailer),
- KM_SLEEP);
-#else
- entp = cachefs_kmem_alloc(len, KM_SLEEP);
-#endif
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_SETSECATTR;
-
- up = &entp->dl_u.dl_setsecattr;
- up->dl_cid = cp->c_id;
-
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime, "cachefs_dlog_setsecattr: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime, "cachefs_dlog_setsecattr: ", "ctime");
-
- /* get the creds */
- (void) copy_cred(cr, &up->dl_cred);
-
- /* mask and counts */
- up->dl_mask = vsec->vsa_mask;
- up->dl_aclcnt = vsec->vsa_aclcnt;
- up->dl_dfaclcnt = vsec->vsa_dfaclcnt;
-
- /* get the acls themselves */
- aclp = (aclent_t *)((uintptr_t)(&up->dl_cred) + clen);
- if (vsec->vsa_aclcnt > 0) {
- bcopy(vsec->vsa_aclentp, aclp,
- vsec->vsa_aclcnt * sizeof (aclent_t));
- aclp += vsec->vsa_aclcnt;
- }
- if (vsec->vsa_dfaclcnt > 0) {
- bcopy(vsec->vsa_dfaclentp, aclp,
- vsec->vsa_dfaclcnt * sizeof (aclent_t));
- }
-
- entp->dl_len = (int)len;
-
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
-#if 0
- /* XXX turn on/off in sync with code in cachefs_dlog_output */
- cachefs_kmem_free(entp, len + 32 + sizeof (struct cfs_dlog_trailer));
-#else
- cachefs_kmem_free(entp, len);
-#endif
-
- return (offset);
-}
-
-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)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_create *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_CREATE;
- up = &entp->dl_u.dl_create;
- up->dl_parent_cid = pcp->c_id;
- up->dl_new_cid = cp->c_id;
- CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
- "cachefs_dlog_create: dl_attr");
- up->dl_excl = excl;
- up->dl_mode = mode;
- up->dl_exists = exists;
- bzero(&up->dl_fid, sizeof (up->dl_fid));
- if (exists) {
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime,
- "cachefs_dlog_create: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime,
- "cachefs_dlog_create: ", "ctime");
- } else {
- up->dl_times.tm_ctime.tv_sec = 0;
- up->dl_times.tm_ctime.tv_nsec = 0;
- up->dl_times.tm_mtime.tv_sec = 0;
- up->dl_times.tm_mtime.tv_nsec = 0;
- }
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the created name */
- len = strlen(nm) + 1;
- bcopy(nm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_remove(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
- cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_remove *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_REMOVE;
- up = &entp->dl_u.dl_remove;
- up->dl_parent_cid = pcp->c_id;
- up->dl_child_cid = cp->c_id;
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime, "cachefs_dlog_remove: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime, "cachefs_dlog_remove: ", "ctime");
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the removed name */
- len = strlen(nm) + 1;
- bcopy(nm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_link(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
- cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_link *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_LINK;
- up = &entp->dl_u.dl_link;
- up->dl_parent_cid = pcp->c_id;
- up->dl_child_cid = cp->c_id;
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime, "cachefs_dlog_link: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime, "cachefs_dlog_link: ", "ctime");
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the link name */
- len = strlen(nm) + 1;
- bcopy(nm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-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)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_rename *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_RENAME;
- up = &entp->dl_u.dl_rename;
- up->dl_oparent_cid = odcp->c_id;
- up->dl_nparent_cid = ndcp->c_id;
- up->dl_child_cid = cp->c_id;
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime, "cachefs_dlog_rename: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime, "cachefs_dlog_rename: ", "ctime");
- if (delcp) {
- up->dl_del_cid = delcp->c_id;
- CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_mtime,
- &up->dl_del_times.tm_mtime,
- "cachefs_dlog_rename: ", "del mtime");
- CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_ctime,
- &up->dl_del_times.tm_ctime,
- "cachefs_dlog_rename: ", "del ctime");
- } else {
- up->dl_del_cid.cid_fileno = 0;
- up->dl_del_cid.cid_flags = 0;
- up->dl_del_times.tm_mtime.tv_sec = 0;
- up->dl_del_times.tm_mtime.tv_nsec = 0;
- up->dl_del_times.tm_ctime.tv_sec = 0;
- up->dl_del_times.tm_ctime.tv_nsec = 0;
- }
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the old name */
- len = strlen(onm) + 1;
- bcopy(onm, curp, len);
-
- /* store the new name */
- curp += len;
- len = strlen(nnm) + 1;
- bcopy(nnm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_mkdir(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *nm,
- vattr_t *vap, cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_mkdir *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_MKDIR;
- up = &entp->dl_u.dl_mkdir;
- up->dl_parent_cid = pcp->c_id;
- up->dl_child_cid = cp->c_id;
- CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
- "cachefs_dlog_mkdir: dl_attr");
- bzero(&up->dl_fid, sizeof (up->dl_fid));
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the new directory name */
- len = strlen(nm) + 1;
- bcopy(nm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the dlog */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_rmdir(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
- cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_rmdir *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- /* if not a local dir, log the cid to fid mapping */
- if ((cp->c_id.cid_flags & CFS_CID_LOCAL) == 0) {
- if (cachefs_dlog_mapfid(fscp, cp))
- return (0);
- if (cachefs_dlog_cidmap(fscp))
- return (0);
- }
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_RMDIR;
- up = &entp->dl_u.dl_rmdir;
- up->dl_parent_cid = pcp->c_id;
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the created name */
- len = strlen(nm) + 1;
- bcopy(nm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_symlink(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *lnm,
- vattr_t *vap, char *tnm, cred_t *cr)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_symlink *up;
- size_t len;
- caddr_t curp;
- off_t offset;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_SYMLINK;
- up = &entp->dl_u.dl_symlink;
- up->dl_parent_cid = pcp->c_id;
- up->dl_child_cid = cp->c_id;
- CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
- "cachefs_dlog_symlink: dl_attr");
- up->dl_times.tm_ctime.tv_sec = 0;
- up->dl_times.tm_ctime.tv_nsec = 0;
- up->dl_times.tm_mtime.tv_sec = 0;
- up->dl_times.tm_mtime.tv_nsec = 0;
- bzero(&up->dl_fid, sizeof (up->dl_fid));
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* find the address in buffer past where the creds are stored */
- curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
-
- /* store the link name */
- len = strlen(lnm) + 1;
- bcopy(lnm, curp, len);
-
- /* store new name */
- curp += len;
- len = strlen(tnm) + 1;
- bcopy(tnm, curp, len);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-off_t
-cachefs_dlog_modify(fscache_t *fscp, cnode_t *cp, cred_t *cr, uint_t *seqp)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_modify *up;
- off_t offset;
- uint_t seq;
- size_t len;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_CRASH;
- entp->dl_op = CFS_DLOG_MODIFIED;
- up = &entp->dl_u.dl_modify;
- up->dl_cid = cp->c_id;
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
- &up->dl_times.tm_mtime,
- "cachefs_dlog_modify: ", "mtime");
- CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
- &up->dl_times.tm_ctime,
- "cachefs_dlog_modify: ", "ctime");
-
- up->dl_next = 0;
-
- /* store the cred info */
- len = copy_cred(cr, &up->dl_cred);
-
- /* calculate the length of this record */
- entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, &seq);
-
- /* return sequence number */
- *seqp = seq;
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset);
-}
-
-int
-cachefs_dlog_mapfid(fscache_t *fscp, cnode_t *cp)
-{
- struct cfs_dlog_entry *entp;
- struct cfs_dlog_mapfid *up;
- off_t offset;
-
- entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
-
- entp->dl_valid = CFS_DLOG_VAL_COMMITTED;
- entp->dl_op = CFS_DLOG_MAPFID;
- up = &entp->dl_u.dl_mapfid;
- up->dl_cid = cp->c_id;
- CACHEFS_FID_COPY(&cp->c_cookie, &up->dl_fid);
-
- /* calculate the length of this record */
- /* entp->dl_len = ((caddr_t)up - (caddr_t)entp + sizeof (*up)); */
- entp->dl_len = (int)(offsetof(struct cfs_dlog_entry, dl_u.dl_mapfid) +
- sizeof (struct cfs_dlog_mapfid));
-
- /* write the record in the log */
- offset = cachefs_dlog_output(fscp, entp, NULL);
-
- cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
- return (offset == 0);
-}
-
-/* Returns the next sequence number, 0 if an error */
-uint_t
-cachefs_dlog_seqnext(fscache_t *fscp)
-{
- int error;
- uint_t seq;
-
- if (fscp->fs_dlogfile == NULL) {
- error = cachefs_dlog_setup(fscp, 1);
- if (error)
- return (0);
- }
-
- mutex_enter(&fscp->fs_dlock);
- ASSERT(fscp->fs_dlogfile);
-
- /* get a sequence number for this log entry */
- seq = fscp->fs_dlogseq + 1;
- if (seq != 0) {
- fscp->fs_dlogseq++;
- }
-#ifdef CFSDEBUG
- else {
- cmn_err(CE_WARN, "cachefs: logging failed, seq overflow 2.");
- }
-#endif
- mutex_exit(&fscp->fs_dlock);
- return (seq);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_filegrp.c b/usr/src/uts/common/fs/cachefs/cachefs_filegrp.c
deleted file mode 100644
index 9e430fa0fb..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_filegrp.c
+++ /dev/null
@@ -1,1819 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/bootconf.h>
-#include <sys/modctl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-
-struct kmem_cache *cachefs_filegrp_cache = NULL;
-
-#if (defined(_SYSCALL32_IMPL) || defined(_LP64))
-
-#define CACHEFS_ALLOC_CFS_METADATA(p, inp) \
- p = cachefs_kmem_zalloc(sizeof (struct cfs_cachefs_metadata), KM_SLEEP)
-
-#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 */
-#define CACHEFS_COPY_COMMON_METADATA_FIELDS(inmdp, outmdp) \
- (outmdp)->md_aclclass = (inmdp)->md_aclclass; \
- CACHEFS_FID_COPY(&(inmdp)->md_cookie, &(outmdp)->md_cookie); \
- (outmdp)->md_flags = (inmdp)->md_flags; \
- (outmdp)->md_rlno = (inmdp)->md_rlno; \
- (outmdp)->md_rltype = (inmdp)->md_rltype; \
- (outmdp)->md_consttype = (inmdp)->md_consttype; \
- CACHEFS_FID_COPY(&(inmdp)->md_fid, &(outmdp)->md_fid); \
- (outmdp)->md_frontblks = (inmdp)->md_frontblks; \
- (outmdp)->md_gen = (inmdp)->md_gen; \
- (outmdp)->md_parent = (inmdp)->md_parent; \
- (outmdp)->md_resettimes = (inmdp)->md_resettimes; \
- (outmdp)->md_localfileno = (inmdp)->md_localfileno; \
- (outmdp)->md_resetfileno = (inmdp)->md_resetfileno; \
- (outmdp)->md_seq = (inmdp)->md_seq; \
- (outmdp)->md_allocents = (inmdp)->md_allocents; \
- bcopy(&(inmdp)->md_allocinfo, &(outmdp)->md_allocinfo, \
- MIN(sizeof (inmdp)->md_allocinfo, sizeof (outmdp)->md_allocinfo))
-
-#define CACHEFS_COPY_METADATA_TO_CFS_METADATA(inmdp, outmdp, error) \
- CACHEFS_VATTR_TO_CFS_VATTR_COPY(&(inmdp)->md_vattr, \
- &(outmdp)->md_vattr, error); \
- CACHEFS_TS_TO_CFS_TS_COPY(&(inmdp)->md_timestamp, \
- &(outmdp)->md_timestamp, error); \
- CACHEFS_TS_TO_CFS_TS_COPY(&(inmdp)->md_x_time, \
- &(outmdp)->md_x_time, error); \
- CACHEFS_TS_TO_CFS_TS_COPY(&(inmdp)->md_localmtime, \
- &(outmdp)->md_localmtime, error); \
- CACHEFS_TS_TO_CFS_TS_COPY(&(inmdp)->md_localctime, \
- &(outmdp)->md_localctime, error); \
- CACHEFS_COPY_COMMON_METADATA_FIELDS(inmdp, outmdp)
-
-#define CACHEFS_COPY_CFS_METADATA_TO_METADATA(inmdp, outmdp) \
- CACHEFS_CFS_VATTR_TO_VATTR_COPY(&(inmdp)->md_vattr, \
- &(outmdp)->md_vattr); \
- CACHEFS_CFS_TS_TO_TS_COPY(&(inmdp)->md_timestamp, \
- &(outmdp)->md_timestamp); \
- CACHEFS_CFS_TS_TO_TS_COPY(&(inmdp)->md_x_time, \
- &(outmdp)->md_x_time); \
- CACHEFS_CFS_TS_TO_TS_COPY(&(inmdp)->md_localmtime, \
- &(outmdp)->md_localmtime); \
- CACHEFS_CFS_TS_TO_TS_COPY(&(inmdp)->md_localctime, \
- &(outmdp)->md_localctime); \
- CACHEFS_COPY_COMMON_METADATA_FIELDS(inmdp, outmdp)
-
-#else /* not (_SYSCALL32_IMPL || _LP64) */
-
-#define CACHEFS_ALLOC_CFS_METADATA(p, inp) \
- p = (cfs_cachefs_metadata_t *)(inp)
-
-#define CACHEFS_FREE_CFS_METADATA(p)
-
-#define CACHEFS_COPY_METADATA_TO_CFS_METADATA(inmdp, outmdp, error)
-
-#define CACHEFS_COPY_CFS_METADATA_TO_METADATA(inmdp, outmdp)
-
-#endif /* _SYSCALL32_IMPL || _LP64 */
-
-/* forward references */
-int filegrp_write_space(vnode_t *vp, offset_t offset, ssize_t cnt);
-int filegrpattr_find(struct filegrp *fgp);
-int filegrpattr_create(struct filegrp *fgp);
-
-int
-/*ARGSUSED*/
-filegrp_cache_create(void *voidp, void *cdrarg, int kmflags)
-{
- filegrp_t *fgp = (filegrp_t *)voidp;
-
- mutex_init(&fgp->fg_mutex, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&fgp->fg_cnodelock, NULL, MUTEX_DEFAULT, NULL);
- return (0);
-}
-
-void
-/*ARGSUSED*/
-filegrp_cache_destroy(void *voidp, void *cdrarg)
-{
- filegrp_t *fgp = (filegrp_t *)voidp;
-
- mutex_destroy(&fgp->fg_mutex);
- mutex_destroy(&fgp->fg_cnodelock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_t *
-filegrp_create(struct fscache *fscp, cfs_cid_t *cidp)
-{
- filegrp_t *fgp;
- int fgsize;
- int flags;
- ino64_t nfgsize;
-
- fgsize = fscp->fs_info.fi_fgsize;
-
- fgp = (filegrp_t *)
- kmem_cache_alloc(cachefs_filegrp_cache, KM_SLEEP);
-
- fgp->fg_flags = CFS_FG_ALLOC_ATTR | CFS_FG_ALLOC_FILE;
- fgp->fg_count = 0;
- fgp->fg_id = *cidp;
-#ifdef Bugid_1249206_notfixed
- if (bugid_1249206)
- cmn_err(CE_CONT, "fg_id assigned value is %" PRId64 "\n",
- fgp->fg_id.cid_fileno);
-#endif
- nfgsize = (fgp->fg_id.cid_fileno / (ino64_t)fgsize);
- fgp->fg_id.cid_fileno = (ino64_t)(nfgsize * (ino64_t)fgsize);
-#ifdef Bugid_1249206_notfixed
- if (bugid_1249206) {
- cmn_err(CE_CONT,
- "cid_fileno for fscp %p fgp %p is %" PRId64 "\n",
- (void *)fscp, (void *)fgp,
- fgp->fg_id.cid_fileno);
- cmn_err(CE_CONT,
- "sent fileno is %" PRId64 " fgsize %d nfgsize %" PRId64
- "\n", cidp->cid_fileno, fgsize, nfgsize);
- }
-#endif
- fgp->fg_fscp = fscp;
- fgp->fg_cnodelist = NULL;
- fgp->fg_next = NULL;
- fgp->fg_dirvp = NULL;
- fgp->fg_attrvp = NULL;
- fgp->fg_header = NULL;
- fgp->fg_offsets = NULL;
- fgp->fg_alloclist = NULL;
-
- fgp->fg_headersize = (uint_t)sizeof (struct attrcache_header) +
- (fgsize * (uint_t)sizeof (struct attrcache_index)) +
- ((fgsize + 7) >> 3);
-
- fgp->fg_filesize = fgp->fg_headersize +
- (fgsize * (uint_t)sizeof (struct cfs_cachefs_metadata));
-
- flags = fscp->fs_flags;
- if (flags & CFS_FS_READ) {
- fgp->fg_flags |= CFS_FG_READ;
- if (flags & CFS_FS_WRITE) {
- fgp->fg_flags |= CFS_FG_WRITE;
- }
- }
-
- if (fgp->fg_flags & CFS_FG_READ) {
- /* 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
-filegrp_destroy(filegrp_t *fgp)
-{
- struct fscache *fscp = fgp->fg_fscp;
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
- int error;
-
- ASSERT(fgp->fg_count == 0);
- ASSERT(fgp->fg_next == NULL);
-
- if (fgp->fg_attrvp) {
- if (fgp->fg_flags & CFS_FG_UPDATED) {
- error = filegrp_sync(fgp);
- if (error)
- cmn_err(CE_WARN,
- "cachefs: UFS error on cache, "
- "run fsck %d", error);
- }
- VN_RELE(fgp->fg_attrvp);
- }
- if (fgp->fg_header) {
- /*
- * If there are no attrcache entries in use and
- * if we can modify the cache.
- */
- if ((fgp->fg_header->ach_count == 0) &&
- (fgp->fg_flags & CFS_FG_WRITE)) {
- ASSERT(fgp->fg_header->ach_nffs == 0);
-
- /* remove attrcache file from the rl list */
- ASSERT(fgp->fg_header->ach_rl_current ==
- CACHEFS_RL_GC);
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fscp->fs_cache, CACHEFS_RL_GC,
- fgp->fg_header->ach_rlno);
-#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 */
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- error = VOP_REMOVE(fscp->fs_fsattrdir, fname, kcred,
- NULL, 0);
- if (error) {
- cmn_err(CE_WARN,
- "cachefs: error in cache, run fsck");
- } else {
- cachefs_freefile(fscp->fs_cache);
- cachefs_freeblocks(fscp->fs_cache,
- fgp->fg_header->ach_nblks, CACHEFS_RL_GC);
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_FREE, fgp->fg_header->ach_rlno,
- 0);
- }
- }
- cachefs_kmem_free(fgp->fg_header, fgp->fg_headersize);
- }
- if (fgp->fg_dirvp) {
- VN_RELE(fgp->fg_dirvp);
- }
- kmem_cache_free(cachefs_filegrp_cache, fgp);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_allocattr(filegrp_t *fgp)
-{
- int error = 0;
-
- mutex_enter(&fgp->fg_mutex);
-
- /* if we do not yet have the attrcache file */
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- /* fail if we tried to create it but failed previously */
- if (fgp->fg_flags & CFS_FG_NOCACHE) {
- error = ENOENT;
- goto out;
- }
-
- /* fail if we cannot read from the cache */
- if ((fgp->fg_flags & CFS_FG_READ) == 0) {
- error = ENOENT;
- goto out;
- }
-
- /* try to find the attrcache file in the cache */
- error = filegrpattr_find(fgp);
- if (error == ENOENT) {
- /* fail if we cannot create the attrcache file */
- if ((fgp->fg_flags & CFS_FG_WRITE) == 0) {
- error = ENOENT;
- goto out;
- }
-
- /* try to create the attrcache file */
- error = filegrpattr_create(fgp);
- }
- }
-out:
- mutex_exit(&fgp->fg_mutex);
-
- 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
-filegrp_hold(filegrp_t *fgp)
-{
- mutex_enter(&fgp->fg_mutex);
-
- fgp->fg_count++;
-
- /* remove attrcache file from the rl list if necessary */
- if ((fgp->fg_flags & CFS_FG_WRITE) &&
- (fgp->fg_header != NULL) &&
- (fgp->fg_header->ach_rl_current == CACHEFS_RL_GC)) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_GC, fgp->fg_header->ach_rlno);
-#endif /* CFSDEBUG */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, fgp->fg_header->ach_rlno,
- fgp->fg_header->ach_nblks);
- fgp->fg_header->ach_rl_current = CACHEFS_RL_ATTRFILE;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
-
- mutex_exit(&fgp->fg_mutex);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_rele(filegrp_t *fgp)
-{
- mutex_enter(&fgp->fg_mutex);
- ASSERT(fgp->fg_count > 0);
-
- /* move attrcache file to the rl list if necessary */
- if (((fgp->fg_flags & CFS_FG_ALLOC_ATTR) == 0) &&
- (fgp->fg_flags & CFS_FG_WRITE) &&
- (fgp->fg_header->ach_rl_current != CACHEFS_RL_GC) &&
- (fgp->fg_count == 1) &&
- (fgp->fg_header->ach_nffs == 0)) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, fgp->fg_header->ach_rlno);
-#endif /* CFSDEBUG */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_GC, fgp->fg_header->ach_rlno,
- fgp->fg_header->ach_nblks);
- fgp->fg_header->ach_rl_current = CACHEFS_RL_GC;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
-
- fgp->fg_count--;
-
- mutex_exit(&fgp->fg_mutex);
-
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_ffhold(filegrp_t *fgp)
-{
- int error = 0;
-
- cachefs_cache_dirty(fgp->fg_fscp->fs_cache, 1);
-
- mutex_enter(&fgp->fg_mutex);
- ASSERT(fgp->fg_flags & CFS_FG_WRITE);
- ASSERT(fgp->fg_count > 0);
-
- /* if the filegrp is no good, bail out with warning */
- if (fgp->fg_flags & CFS_FG_NOCACHE) {
- error = EINVAL;
- goto out;
- }
-
- /* if we do not have the directory vp yet */
- if (fgp->fg_flags & CFS_FG_ALLOC_FILE) {
-
- /* create the directory if necessary */
- if (fgp->fg_header->ach_nffs == 0) {
- error = filegrpdir_create(fgp);
- if (error)
- goto out;
- }
-
- /* else find the directory */
- else {
- error = filegrpdir_find(fgp);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FILEGRP)
- printf("ffhold: no dir, errno %d, "
- "fileno %llx\n",
- error, (u_longlong_t)fgp->fg_id.cid_fileno);
-#endif
- goto out;
- }
- }
- }
- ASSERT(fgp->fg_dirvp);
-
-#ifdef CFSDEBUG
- if (fgp->fg_header->ach_nffs == 0) {
- ASSERT(fgp->fg_header->ach_rl_current == CACHEFS_RL_ATTRFILE);
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, fgp->fg_header->ach_rlno);
-
- /*
- * 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 */
-
- fgp->fg_header->ach_nffs++;
- fgp->fg_flags |= CFS_FG_UPDATED;
- ASSERT(fgp->fg_header->ach_nffs <= fgp->fg_header->ach_count);
-
-out:
- mutex_exit(&fgp->fg_mutex);
-
- 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
-filegrp_ffrele(filegrp_t *fgp)
-{
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
- struct fscache *fscp = fgp->fg_fscp;
- int error = 0;
-
- /* if the filegrp is corrupt, bail out with warning */
- if (fgp->fg_flags & CFS_FG_NOCACHE) {
- return;
- }
-
- cachefs_cache_dirty(fgp->fg_fscp->fs_cache, 1);
-
- mutex_enter(&fgp->fg_mutex);
- ASSERT(fgp->fg_flags & CFS_FG_WRITE);
- ASSERT((fgp->fg_flags & CFS_FG_ALLOC_FILE) == 0);
- ASSERT(fgp->fg_dirvp != NULL);
- ASSERT(fgp->fg_count > 0);
- ASSERT(fgp->fg_header->ach_nffs > 0);
- ASSERT(fgp->fg_header->ach_nffs <= fgp->fg_header->ach_count);
-
- fgp->fg_header->ach_nffs--;
- fgp->fg_flags |= CFS_FG_UPDATED;
-
- if (fgp->fg_header->ach_nffs == 0) {
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- error = VOP_RMDIR(fscp->fs_fscdirvp, fname,
- fscp->fs_fscdirvp, kcred, NULL, 0);
- if (error == 0) {
- cachefs_freefile(fscp->fs_cache);
- cachefs_freeblocks(fscp->fs_cache, 1,
- fgp->fg_header->ach_rl_current);
- VN_RELE(fgp->fg_dirvp);
- fgp->fg_dirvp = NULL;
- fgp->fg_flags |= CFS_FG_ALLOC_FILE;
- } else {
- fgp->fg_flags |= CFS_FG_NOCACHE;
- cmn_err(CE_WARN, "cachefs_ffrele:"
- " frontfs cache error %d, run fsck", error);
- }
-
- /*
- * XXX sam: this used to move from `NONE' to
- * `CACHEFS_RL_ACTIVE'. now, we're on
- * CACHEFS_RL_ATTRFILE if count and/or nffs is
- * nonzero, and CACHEFS_RL_GC otherwise. since we
- * just asserted that count > 0, there's nothing to
- * do. right?
- */
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, fgp->fg_header->ach_rlno);
-#endif /* CFSDEBUG */
- }
- mutex_exit(&fgp->fg_mutex);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_sync(filegrp_t *fgp)
-{
- int error = 0;
-
- mutex_enter(&fgp->fg_mutex);
-
- if (((fgp->fg_flags & CFS_FG_UPDATED) == 0) ||
- (fgp->fg_flags & CFS_FG_ALLOC_ATTR) ||
- CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp)) {
- mutex_exit(&fgp->fg_mutex);
- return (0);
- }
-
- ASSERT(fgp->fg_header->ach_nffs <= fgp->fg_header->ach_count);
-
- error = vn_rdwr(UIO_WRITE, fgp->fg_attrvp, (caddr_t)fgp->fg_header,
- fgp->fg_headersize, 0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY,
- kcred, NULL);
-
- if (error == 0)
- error = VOP_FSYNC(fgp->fg_attrvp, FSYNC, kcred, NULL);
-
- if (error == 0)
- fgp->fg_flags &= ~CFS_FG_UPDATED;
-
- mutex_exit(&fgp->fg_mutex);
-
- 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
-filegrp_read_metadata(filegrp_t *fgp, cfs_cid_t *cidp,
- struct cachefs_metadata *mdp)
-{
- int slot;
- int error;
- int index;
- struct cfs_cachefs_metadata *tmpmdp;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- mutex_enter(&fgp->fg_mutex);
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
- slot = filegrp_cid_to_slot(fgp, cidp);
- if (slot == 0) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
-
- /* see if metadata was ever written */
- index = (int)(cidp->cid_fileno - fgp->fg_id.cid_fileno);
- if (fgp->fg_offsets[index].ach_written == 0) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
- CACHEFS_ALLOC_CFS_METADATA(tmpmdp, mdp);
-
- error = vn_rdwr(UIO_READ, fgp->fg_attrvp,
- (caddr_t)tmpmdp, sizeof (struct cfs_cachefs_metadata),
- (offset_t)slot,
- UIO_SYSSPACE, 0, (long long)0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN,
- "cachefs_read_metadata:"
- " frontfs cache error %d, run fsck", error);
- }
- CACHEFS_COPY_CFS_METADATA_TO_METADATA(tmpmdp, mdp);
- CACHEFS_FREE_CFS_METADATA(tmpmdp);
-
- mutex_exit(&fgp->fg_mutex);
- 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
-filegrp_create_metadata(filegrp_t *fgp, struct cachefs_metadata *md,
- cfs_cid_t *cidp)
-{
- struct fscache *fscp = fgp->fg_fscp;
- cachefscache_t *cachep = fscp->fs_cache;
- int slot;
- int bitno;
- uchar_t mask;
- int last;
- int xx;
- int index;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- cachefs_cache_dirty(cachep, 1);
-
- mutex_enter(&fgp->fg_mutex);
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
- slot = filegrp_cid_to_slot(fgp, cidp);
- if (slot) {
- mutex_exit(&fgp->fg_mutex);
- return (0);
- }
-
- index = (int)(cidp->cid_fileno - fgp->fg_id.cid_fileno);
-
- ASSERT(index < fgp->fg_fscp->fs_info.fi_fgsize);
-
- last = (((fgp->fg_fscp->fs_info.fi_fgsize + 7) & ~(7)) / 8);
- for (xx = 0; xx < last; xx++) {
- if (fgp->fg_alloclist[xx] != (uchar_t)0xff) {
- for (mask = 1, bitno = 0; bitno < 8; bitno++) {
- if ((mask & fgp->fg_alloclist[xx]) == 0) {
- slot = (xx * 8) + bitno;
- goto found;
- }
- mask <<= 1;
- }
- }
- }
-found:
- if (xx == last) {
- cmn_err(CE_WARN, "cachefs: attrcache error, run fsck");
- mutex_exit(&fgp->fg_mutex);
- return (ENOMEM);
- }
-
- slot = (slot * (int)sizeof (struct cfs_cachefs_metadata)) +
- fgp->fg_headersize;
-
- ASSERT(fgp->fg_header->ach_nffs <= fgp->fg_header->ach_count);
- fgp->fg_header->ach_count++;
- fgp->fg_offsets[index].ach_offset = slot;
- fgp->fg_offsets[index].ach_written = 0;
- fgp->fg_alloclist[xx] |= mask;
- fgp->fg_flags |= CFS_FG_UPDATED;
-
- mutex_exit(&fgp->fg_mutex);
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_MDCREATE))
- cachefs_log_mdcreate(cachep, 0,
- fscp->fs_cfsvfsp, &md->md_cookie, cidp->cid_fileno,
- fgp->fg_header->ach_count);
-
- 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
-filegrp_write_metadata(filegrp_t *fgp, cfs_cid_t *cidp,
- struct cachefs_metadata *mdp)
-{
- int error = 0;
- int slot;
- blkcnt64_t nblks;
- int index;
- struct fscache *fscp = fgp->fg_fscp;
- struct cfs_cachefs_metadata *tmpmdp;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- cachefs_cache_dirty(fscp->fs_cache, 1);
- mutex_enter(&fgp->fg_mutex);
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- error = ENOENT;
- goto out;
- }
-
- slot = filegrp_cid_to_slot(fgp, cidp);
- if (slot == 0) {
- error = ENOENT;
- goto out;
- }
-
- /* allocate blocks for the data if necessary */
- nblks = slot + sizeof (struct cfs_cachefs_metadata);
- nblks = (nblks + MAXBSIZE - 1) / MAXBSIZE;
- nblks -= fgp->fg_header->ach_nblks;
- if (nblks > 0) {
- error = cachefs_allocblocks(fscp->fs_cache, nblks,
- fgp->fg_header->ach_rl_current);
- if (error)
- goto out;
- error = filegrp_write_space(fgp->fg_attrvp,
- (offset_t)fgp->fg_header->ach_nblks * MAXBSIZE,
- nblks * MAXBSIZE);
- if (error) {
- cachefs_freeblocks(fscp->fs_cache, nblks,
- fgp->fg_header->ach_rl_current);
- goto out;
- }
- } else
- nblks = 0;
-
- CACHEFS_ALLOC_CFS_METADATA(tmpmdp, mdp);
- CACHEFS_COPY_METADATA_TO_CFS_METADATA(mdp, tmpmdp, error);
- /* write the metadata */
- if (!error)
- error = vn_rdwr(UIO_WRITE, fgp->fg_attrvp, (caddr_t)tmpmdp,
- sizeof (struct cfs_cachefs_metadata), (offset_t)slot,
- UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
-
- CACHEFS_FREE_CFS_METADATA(tmpmdp);
-
- if (error) {
- if (error == EOVERFLOW) {
- cmn_err(CE_WARN, "cachefs_write_metadata:"
- " time/dev overflow error %d", error);
- } else if (error != ENOSPC) {
- cmn_err(CE_WARN,
- "cachefs: UFS write error %d, run fsck",
- error);
- }
- cachefs_freeblocks(fscp->fs_cache, nblks,
- fgp->fg_header->ach_rl_current);
- goto out;
- }
-
- /* mark metadata as having been written */
- index = (int)(cidp->cid_fileno - fgp->fg_id.cid_fileno);
- fgp->fg_offsets[index].ach_written = 1;
-
- /* update number of blocks used by the attrcache file */
- fgp->fg_header->ach_nblks += nblks;
-
- /* force sync to be done eventually */
- fgp->fg_flags |= CFS_FG_UPDATED;
-
-out:
- mutex_exit(&fgp->fg_mutex);
- 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
-filegrp_destroy_metadata(filegrp_t *fgp, cfs_cid_t *cidp)
-{
- int i;
- int bitno;
- uchar_t mask = 1;
-
- int slot;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- cachefs_cache_dirty(fgp->fg_fscp->fs_cache, 1);
- mutex_enter(&fgp->fg_mutex);
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
- slot = filegrp_cid_to_slot(fgp, cidp);
- if (slot == 0) {
- mutex_exit(&fgp->fg_mutex);
- return (ENOENT);
- }
-
- i = (int)(cidp->cid_fileno - fgp->fg_id.cid_fileno);
- fgp->fg_offsets[i].ach_offset = 0;
- fgp->fg_offsets[i].ach_written = 0;
- i = (slot - fgp->fg_headersize) /
- (int)sizeof (struct cfs_cachefs_metadata);
- bitno = i & 7;
- i = i >> 3;
- mask <<= bitno;
- if (fgp->fg_alloclist[i] & mask)
- fgp->fg_alloclist[i] &= ~mask;
- else
- cmn_err(CE_WARN,
- "filegrp_destroy_metadata:"
- " fileno %" PRId64 " slot %d-%d fgp %p not allocated",
- cidp->cid_fileno, i, bitno, (void *)fgp);
-
- fgp->fg_header->ach_count--;
- ASSERT(fgp->fg_header->ach_nffs <= fgp->fg_header->ach_count);
- fgp->fg_flags |= CFS_FG_UPDATED;
- mutex_exit(&fgp->fg_mutex);
-
- 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)
- */
-
-filegrp_t *
-filegrp_list_find(struct fscache *fscp, cfs_cid_t *cidp)
-{
- int fgsize = fscp->fs_info.fi_fgsize;
- struct filegrp *fgp;
- ino64_t fxx;
- int findex;
- ino64_t fileno;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- /* get fileno of filegrp */
- fxx = (ino64_t)(cidp->cid_fileno / fgsize);
- fileno = fxx * fgsize;
-
- /* hash into array of file groups */
- findex = (int)(fxx & (CFS_FS_FGP_BUCKET_SIZE - 1));
-
- /* search set of file groups for this hash bucket */
- for (fgp = fscp->fs_filegrp[findex];
- fgp != NULL;
- fgp = fgp->fg_next) {
- if ((fgp->fg_id.cid_fileno == fileno) &&
- (fgp->fg_id.cid_flags == cidp->cid_flags))
- 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
-filegrp_list_add(struct fscache *fscp, filegrp_t *fgp)
-{
- int findex;
- int fgsize = fscp->fs_info.fi_fgsize;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
- ASSERT(fgp->fg_next == NULL);
-
- /* hash into array of file groups */
- findex = (int)((fgp->fg_id.cid_fileno / fgsize) &
- (CFS_FS_FGP_BUCKET_SIZE - 1));
-
- fgp->fg_next = fscp->fs_filegrp[findex];
- fscp->fs_filegrp[findex] = fgp;
- fscp->fs_ref++;
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_list_remove(struct fscache *fscp, filegrp_t *fgp)
-{
- struct filegrp *fp;
- struct filegrp **pfgp;
- int found = 0;
- int findex;
- int fgsize = fscp->fs_info.fi_fgsize;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- /* hash into array of file groups */
- findex = (int)((fgp->fg_id.cid_fileno / fgsize) &
- (CFS_FS_FGP_BUCKET_SIZE - 1));
- fp = fscp->fs_filegrp[findex];
- pfgp = &fscp->fs_filegrp[findex];
-
- while (fp != NULL) {
- if (fp == fgp) {
- *pfgp = fp->fg_next;
- fp->fg_next = NULL;
- found++;
- break;
- }
- pfgp = &fp->fg_next;
- fp = fp->fg_next;
- }
- ASSERT(found);
- fscp->fs_ref--;
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_list_gc(struct fscache *fscp)
-{
- struct filegrp *next, *fgp;
- int xx;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- for (xx = 0; xx < CFS_FS_FGP_BUCKET_SIZE; xx++) {
- for (fgp = fscp->fs_filegrp[xx]; fgp != NULL; fgp = next) {
- next = fgp->fg_next;
- mutex_enter(&fgp->fg_mutex);
- if (fgp->fg_count > 0) {
- mutex_exit(&fgp->fg_mutex);
- continue;
- }
- mutex_exit(&fgp->fg_mutex);
- filegrp_list_remove(fscp, fgp);
- filegrp_destroy(fgp);
- }
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_setup(struct filegrp *fgp, int flags, int dorl)
-{
- ASSERT(MUTEX_HELD(&fgp->fg_mutex));
-
- /* turn on the specified flags */
- if (flags)
- fgp->fg_flags |= flags;
-
- /* if the attrcache file exists, find it */
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR)
- (void) filegrpattr_find(fgp);
-
- /* if the attrcache directory exists, find it */
- if (((fgp->fg_flags & CFS_FG_ALLOC_ATTR) == 0) &&
- (fgp->fg_flags & CFS_FG_ALLOC_FILE) &&
- (fgp->fg_header->ach_nffs > 0)) {
- (void) filegrpdir_find(fgp);
- }
-
- /* move from gc list to attrfile list if necessary */
- if ((dorl != 0) &&
- ((fgp->fg_flags & CFS_FG_ALLOC_ATTR) == 0) &&
- (fgp->fg_header->ach_rl_current == CACHEFS_RL_GC)) {
- ASSERT(fgp->fg_header->ach_nffs == 0);
- if (fgp->fg_count > 0) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_GC, fgp->fg_header->ach_rlno);
-#endif /* CFSDEBUG */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, fgp->fg_header->ach_rlno,
- fgp->fg_header->ach_nblks);
- fgp->fg_header->ach_rl_current = CACHEFS_RL_ATTRFILE;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_list_enable_caching_ro(struct fscache *fscp)
-{
- struct filegrp *fgp;
- int xx;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- for (xx = 0; xx < CFS_FS_FGP_BUCKET_SIZE; xx++) {
- for (fgp = fscp->fs_filegrp[xx]; fgp != NULL;
- fgp = fgp->fg_next) {
- mutex_enter(&fgp->fg_mutex);
- filegrp_setup(fgp, 0, 0);
- mutex_exit(&fgp->fg_mutex);
- }
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrp_list_enable_caching_rw(struct fscache *fscp)
-{
- struct filegrp *fgp;
- int xx;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- for (xx = 0; xx < CFS_FS_FGP_BUCKET_SIZE; xx++) {
- for (fgp = fscp->fs_filegrp[xx]; fgp != NULL;
- fgp = fgp->fg_next) {
- mutex_enter(&fgp->fg_mutex);
- filegrp_setup(fgp, CFS_FG_READ|CFS_FG_WRITE, 1);
- mutex_exit(&fgp->fg_mutex);
- }
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * 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
-filegrpdir_find(filegrp_t *fgp)
-{
- int error;
- vnode_t *dirvp;
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
- struct fscache *fscp = fgp->fg_fscp;
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR)
- return (ENOENT);
- ASSERT(fgp->fg_flags & CFS_FG_ALLOC_FILE);
-
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- error = VOP_LOOKUP(fscp->fs_fscdirvp, fname, &dirvp, NULL,
- 0, NULL, kcred, NULL, NULL, NULL);
- if (error == 0) {
- fgp->fg_dirvp = dirvp;
- fgp->fg_flags &= ~CFS_FG_ALLOC_FILE;
-#ifdef CFSDEBUG
- if (fgp->fg_header->ach_nffs == 0) {
- CFS_DEBUG(CFSDEBUG_FILEGRP)
- printf("filegrpdir_find: "
- "%s found but no front files\n", fname);
- }
-#endif
- }
-#ifdef CFSDEBUG
- else if (fgp->fg_header->ach_nffs != 0) {
- CFS_DEBUG(CFSDEBUG_FILEGRP)
- printf("filegrpdir_find: "
- "%s NOT found but %d front files\n",
- fname, fgp->fg_header->ach_nffs);
- }
-#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
-filegrpattr_find(struct filegrp *fgp)
-{
- int error = 0;
- struct fscache *fscp = fgp->fg_fscp;
- cachefscache_t *cachep = fscp->fs_cache;
- vnode_t *attrvp;
- struct attrcache_header *ahp;
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
-
- if (fgp->fg_flags & CFS_FG_NOCACHE)
- return (ENOENT);
-
- ASSERT(fgp->fg_flags & CFS_FG_ALLOC_ATTR);
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- error = VOP_LOOKUP(fscp->fs_fsattrdir, fname,
- &attrvp, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error) {
- return (error);
- }
- ahp = (struct attrcache_header *)cachefs_kmem_zalloc(
- fgp->fg_headersize, KM_SLEEP);
-
- error = vn_rdwr(UIO_READ, attrvp, (caddr_t)ahp,
- fgp->fg_headersize, 0LL, UIO_SYSSPACE,
- 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: Read attrcache error %d, run fsck",
- error);
- cachefs_kmem_free(ahp, fgp->fg_headersize);
- fgp->fg_flags |= CFS_FG_NOCACHE;
- VN_RELE(attrvp);
- } else {
- ASSERT(ahp->ach_nffs <= ahp->ach_count);
- fgp->fg_attrvp = attrvp;
- fgp->fg_header = ahp;
- fgp->fg_offsets = (struct attrcache_index *)(ahp + 1);
- fgp->fg_alloclist = ((uchar_t *)fgp->fg_offsets) +
- (fscp->fs_info.fi_fgsize *
- sizeof (struct attrcache_index));
- fgp->fg_flags &= ~CFS_FG_ALLOC_ATTR;
-
- if ((cachep->c_flags & CACHE_CHECK_RLTYPE) &&
- (ahp->ach_rl_current == CACHEFS_RL_ATTRFILE)) {
- rl_entry_t *rlp, rl;
-
- mutex_enter(&cachep->c_contentslock);
- error = cachefs_rl_entry_get(cachep, ahp->ach_rlno,
- &rlp);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- cachefs_kmem_free(ahp, fgp->fg_headersize);
- fgp->fg_flags |= CFS_FG_NOCACHE;
- VN_RELE(attrvp);
- return (error);
- }
-
- rl = *rlp;
- mutex_exit(&cachep->c_contentslock);
-
- if (rl.rl_current != ahp->ach_rl_current) {
- ahp->ach_rl_current = rl.rl_current;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
- }
-
- /* if the attr file is on the rl */
- if (fgp->fg_header->ach_rl_current == CACHEFS_RL_GC) {
-#ifdef CFSDEBUG
- if (fgp->fg_flags & CFS_FG_WRITE)
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_GC,
- fgp->fg_header->ach_rlno);
-#endif /* CFSDEBUG */
- if ((fgp->fg_count > 0) &&
- (fgp->fg_flags & CFS_FG_WRITE)) {
- /* remove from rl, put on active */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE,
- fgp->fg_header->ach_rlno,
- fgp->fg_header->ach_nblks);
- fgp->fg_header->ach_rl_current =
- CACHEFS_RL_ATTRFILE;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
- } else {
- ASSERT(fgp->fg_header->ach_rl_current ==
- CACHEFS_RL_ATTRFILE);
-#ifdef CFSDEBUG
- if (fgp->fg_flags & CFS_FG_WRITE)
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE,
- fgp->fg_header->ach_rlno);
-#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
-filegrpdir_create(filegrp_t *fgp)
-{
- int error;
- vnode_t *dirvp = NULL;
- struct vattr *attrp = NULL;
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
- struct fscache *fscp = fgp->fg_fscp;
-
- ASSERT(fgp->fg_flags & CFS_FG_WRITE);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT(MUTEX_HELD(&fgp->fg_mutex));
-
- if (fgp->fg_flags & (CFS_FG_ALLOC_ATTR | CFS_FG_NOCACHE))
- return (ENOENT);
-
- /* allocate a 1 block file for the directory */
- error = cachefs_allocfile(fscp->fs_cache);
- if (error) {
- return (error);
- }
- error = cachefs_allocblocks(fscp->fs_cache, 1,
- fgp->fg_header->ach_rl_current);
- if (error) {
- cachefs_freefile(fscp->fs_cache);
- return (error);
- }
-
- /*
- * Construct a name for this file group directory and then do a mkdir
- */
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- attrp = (struct vattr *)cachefs_kmem_alloc(sizeof (struct vattr),
- KM_SLEEP);
- attrp->va_mode = S_IFDIR | 0777;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VDIR;
- attrp->va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- error = VOP_MKDIR(fscp->fs_fscdirvp, fname, attrp, &dirvp, kcred, NULL,
- 0, NULL);
- if (error) {
- fgp->fg_flags |= CFS_FG_NOCACHE;
- cachefs_freefile(fscp->fs_cache);
- cachefs_freeblocks(fscp->fs_cache, 1,
- fgp->fg_header->ach_rl_current);
- } else {
- fgp->fg_dirvp = dirvp;
- fgp->fg_flags &= ~CFS_FG_ALLOC_FILE;
- }
-
- if (attrp)
- cachefs_kmem_free(attrp, sizeof (*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
-filegrpattr_create(struct filegrp *fgp)
-{
- int error;
- vnode_t *attrvp = NULL;
- struct attrcache_header *ahp = NULL;
- int nblks = 0;
- int gotrlent = 0;
- struct vattr *attrp = NULL;
- char name[CFS_FRONTFILE_NAME_SIZE];
- char *fname;
- struct fscache *fscp = fgp->fg_fscp;
- rl_entry_t rl_ent;
-
- ASSERT(fgp->fg_flags & CFS_FG_WRITE);
-
- if (fgp->fg_flags & CFS_FG_NOCACHE)
- return (ENOENT);
-
- cachefs_cache_dirty(fscp->fs_cache, 1);
-
- /* allocate a file for the attrcache */
- error = cachefs_allocfile(fscp->fs_cache);
- if (error) {
- goto out;
- }
-
- make_ascii_name(&fgp->fg_id, name);
- fname = name;
- attrp = cachefs_kmem_alloc(sizeof (struct vattr), KM_SLEEP);
- attrp->va_mode = S_IFREG | 0666;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VREG;
- attrp->va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- error = VOP_CREATE(fscp->fs_fsattrdir, fname, attrp, EXCL, 0666,
- &attrvp, kcred, 0, NULL, NULL);
- if (error) {
- cachefs_freefile(fscp->fs_cache);
- goto out;
- }
-
- /* alloc blocks for the attrcache header */
- nblks = (fgp->fg_headersize + MAXBSIZE - 1) / MAXBSIZE;
- error = cachefs_allocblocks(fscp->fs_cache, nblks, CACHEFS_RL_NONE);
- if (error) {
- nblks = 0;
- goto out;
- }
-
- /* Construct an attrcache header */
- ahp = cachefs_kmem_zalloc(fgp->fg_headersize, KM_SLEEP);
-
- /* write out the header to allocate space on ufs */
- error = vn_rdwr(UIO_WRITE, attrvp, (caddr_t)ahp,
- fgp->fg_headersize, 0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY,
- kcred, NULL);
- if (error)
- goto out;
- error = filegrp_write_space(attrvp, (offset_t)fgp->fg_headersize,
- (nblks * MAXBSIZE) - fgp->fg_headersize);
- if (error)
- goto out;
- error = VOP_FSYNC(attrvp, FSYNC, kcred, NULL);
- if (error)
- goto out;
-
- /* allocate an rl entry and mark it as an attrcache entry */
- rl_ent.rl_fileno = fgp->fg_id.cid_fileno;
- rl_ent.rl_local = (fgp->fg_id.cid_flags & CFS_CID_LOCAL) ? 1 : 0;
- rl_ent.rl_fsid = fscp->fs_cfsid;
- rl_ent.rl_attrc = 1;
- error = cachefs_rl_alloc(fscp->fs_cache, &rl_ent, &ahp->ach_rlno);
- if (error)
- goto out;
- gotrlent = 1;
- if (fgp->fg_count == 0) {
- /* put on the gc */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache, CACHEFS_RL_GC,
- ahp->ach_rlno, nblks);
- ahp->ach_rl_current = CACHEFS_RL_GC;
- } else {
- /* put on attrfile list */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ATTRFILE, ahp->ach_rlno, nblks);
- ahp->ach_rl_current = CACHEFS_RL_ATTRFILE;
- }
-
-out:
- if (error) {
- fgp->fg_flags |= CFS_FG_NOCACHE;
- if (attrvp) {
- VN_RELE(attrvp);
- (void) VOP_REMOVE(fscp->fs_fsattrdir, fname, kcred,
- NULL, 0);
- cachefs_freefile(fscp->fs_cache);
- }
- if (nblks)
- cachefs_freeblocks(fscp->fs_cache, nblks,
- CACHEFS_RL_NONE);
- if (gotrlent)
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_FREE, ahp->ach_rlno, 0);
- if (ahp)
- cachefs_kmem_free(ahp, fgp->fg_headersize);
- } else {
- fgp->fg_attrvp = attrvp;
- fgp->fg_header = ahp;
- fgp->fg_offsets = (struct attrcache_index *)(ahp + 1);
- fgp->fg_alloclist = ((uchar_t *)fgp->fg_offsets) +
- (fscp->fs_info.fi_fgsize *
- sizeof (struct attrcache_index));
- ahp->ach_count = 0;
- ahp->ach_nffs = 0;
- ahp->ach_nblks = nblks;
- fgp->fg_flags &= ~CFS_FG_ALLOC_ATTR;
- fgp->fg_flags |= CFS_FG_UPDATED;
- }
-
- if (attrp)
- cachefs_kmem_free(attrp, sizeof (*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
-filegrp_cid_to_slot(filegrp_t *fgp, cfs_cid_t *cidp)
-{
- int xx;
- int slot;
- int index;
-
- index = (int)(cidp->cid_fileno - fgp->fg_id.cid_fileno);
-
- if (index > fgp->fg_fscp->fs_info.fi_fgsize) {
- cmn_err(CE_WARN, "cachefs: attrcache error, run fsck");
- return (0);
- }
-
- slot = fgp->fg_offsets[index].ach_offset;
- if (slot == 0)
- return (0);
-
- xx = fgp->fg_filesize - (int)sizeof (struct cfs_cachefs_metadata);
- if ((slot < fgp->fg_headersize) || (xx < slot)) {
- cmn_err(CE_WARN, "cachefs: attrcache error, run fsck");
- 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
-filegrp_write_space(vnode_t *vp, offset_t offset, ssize_t cnt)
-{
- char *bufp;
- int xx;
- int error = 0;
-
- bufp = (char *)cachefs_kmem_zalloc(MAXBSIZE, KM_SLEEP);
- while (cnt > 0) {
- if (cnt > MAXBSIZE)
- xx = MAXBSIZE;
- else
- xx = (int)cnt;
- error = vn_rdwr(UIO_WRITE, vp, (caddr_t)bufp,
- xx, offset, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY,
- kcred, NULL);
- if (error)
- break;
- offset += xx;
- cnt -= xx;
- }
- cachefs_kmem_free(bufp, MAXBSIZE);
- return (error);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_fscache.c b/usr/src/uts/common/fs/cachefs/cachefs_fscache.c
deleted file mode 100644
index 6dcb5430f2..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_fscache.c
+++ /dev/null
@@ -1,1323 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/file.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/modctl.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/fbuf.h>
-#include <rpc/types.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-
-/* external references */
-extern struct cachefsops nopcfsops, strictcfsops, codcfsops;
-
-/* forward references */
-int fscdir_create(cachefscache_t *cachep, char *namep, fscache_t *fscp);
-int fscdir_find(cachefscache_t *cachep, ino64_t fsid, fscache_t *fscp);
-static int fscache_info_sync(fscache_t *fscp);
-
-struct kmem_cache *cachefs_fscache_cache = NULL;
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_create
- *
- * Description:
- * Creates a fscache object.
- * Arguments:
- * cachep cache to create fscache object for
- * Returns:
- * Returns a fscache object.
- * Preconditions:
- * precond(cachep)
- */
-
-fscache_t *
-fscache_create(cachefscache_t *cachep)
-{
- fscache_t *fscp;
-
- /* create and initialize the fscache object */
- fscp = kmem_cache_alloc(cachefs_fscache_cache, KM_SLEEP);
-
- bzero(fscp, sizeof (*fscp));
-
- mutex_init(&fscp->fs_fslock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&fscp->fs_idlelock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&fscp->fs_dlock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&fscp->fs_cdlock, NULL, MUTEX_DEFAULT, NULL);
- cv_init(&fscp->fs_cdwaitcv, NULL, CV_DEFAULT, NULL);
-
- fscp->fs_cache = cachep;
- fscp->fs_info.fi_mntflags = CFS_WRITE_AROUND;
- fscp->fs_info.fi_popsize = DEF_POP_SIZE;
- fscp->fs_info.fi_fgsize = DEF_FILEGRP_SIZE;
- fscp->fs_cfsops = &nopcfsops;
- fscp->fs_consttype = CFS_FS_CONST_NOCONST;
- fscp->fs_acregmin = 30;
- fscp->fs_acregmax = 30;
- fscp->fs_acdirmin = 30;
- fscp->fs_acdirmax = 30;
- fscp->fs_cdconnected = CFS_CD_CONNECTED;
- fscp->fs_mntpt = NULL;
- fscp->fs_hostname = NULL;
- fscp->fs_backfsname = NULL;
- cachefs_workq_init(&fscp->fs_workq);
- return (fscp);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_destroy
- *
- * Description:
- * Destroys the fscache object.
- * Arguments:
- * fscp the fscache object to destroy
- * Returns:
- * Preconditions:
- * precond(fscp)
- * precond(fs_ref == 0)
- */
-
-void
-fscache_destroy(fscache_t *fscp)
-{
- size_t strl;
-
- ASSERT(fscp->fs_ref == 0);
-
- (void) fscache_info_sync(fscp);
-
- if (fscp->fs_mntpt) {
- strl = strlen(fscp->fs_mntpt);
- if (strl != 0)
- kmem_free(fscp->fs_mntpt, strl + 1);
- }
- if (fscp->fs_hostname) {
- strl = strlen(fscp->fs_hostname);
- if (strl != 0)
- kmem_free(fscp->fs_hostname, strl + 1);
- }
- if (fscp->fs_backfsname) {
- strl = strlen(fscp->fs_backfsname);
- if (strl != 0)
- kmem_free(fscp->fs_backfsname, strl + 1);
- }
-
- /* drop the inum translation table */
- if (fscp->fs_inum_size > 0)
- cachefs_kmem_free(fscp->fs_inum_trans,
- fscp->fs_inum_size * sizeof (cachefs_inum_trans_t));
-
- /* drop references to the fscache directory */
- if (fscp->fs_fscdirvp)
- VN_RELE(fscp->fs_fscdirvp);
- if (fscp->fs_fsattrdir)
- VN_RELE(fscp->fs_fsattrdir);
- if (fscp->fs_infovp)
- VN_RELE(fscp->fs_infovp);
-
- /* drop logging references */
- cachefs_dlog_teardown(fscp);
-
- mutex_destroy(&fscp->fs_fslock);
- mutex_destroy(&fscp->fs_idlelock);
- mutex_destroy(&fscp->fs_dlock);
- mutex_destroy(&fscp->fs_cdlock);
- cv_destroy(&fscp->fs_cdwaitcv);
-
- kmem_cache_free(cachefs_fscache_cache, fscp);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_setup
- *
- * Description:
- * Activates a fscache by associating the fscache object
- * with on disk data.
- * If the fscache directory of the specified fsid exists then
- * it will be used.
- * Otherwise a new fscache directory will be created using namep
- * and optp with fsid being ignored. However if namep or optp
- * are not NULL or the cache is in NOFILL then this routine fails.
- * Arguments:
- * fscp the fscache object to activate
- * fsid unique identifier for the cache
- * namep name of the cache
- * optp options for the cache
- * Returns:
- * Returns 0 for success, !0 on failure.
- * Preconditions:
- * precond(fscp)
- * precond(the cache must not be in NOCACHE mode)
- * precond(the cache must not alread by active)
- */
-
-static int
-fscache_setup(fscache_t *fscp, ino64_t fsid, char *namep,
- struct cachefsoptions *optp, ino64_t backfileno, int setflags)
-{
- int error;
- cachefscache_t *cachep = fscp->fs_cache;
-
- ASSERT((cachep->c_flags & CACHE_NOCACHE) == 0);
-
- /* see if the fscache directory already exists */
- error = fscdir_find(cachep, fsid, fscp);
- if (error) {
- /* return error if cannot create the directory */
- if ((namep == NULL) || (optp == NULL) ||
- (cachep->c_flags & CACHE_NOFILL)) {
- return (error);
- }
- if (backfileno == 0)
- return (EAGAIN);
-
- /* remember the root back fileno for disconnected mounts */
- fscp->fs_info.fi_root = backfileno;
-
- /* copy options into the fscache */
- fscp->fs_info.fi_mntflags = optp->opt_flags;
- fscp->fs_info.fi_popsize = optp->opt_popsize;
- fscp->fs_info.fi_fgsize = optp->opt_fgsize;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
-
- /* create the directory */
- error = fscdir_create(cachep, namep, fscp);
- if (error) {
- if (error == ENOSPC)
- cmn_err(CE_WARN,
- "CacheFS: not enough space to create %s",
- namep);
- else
- cmn_err(CE_WARN,
- "CacheFS: error %d creating %s",
- error, namep);
- return (error);
- }
- } else if (optp) {
- /* compare the options to make sure they are compatible */
- error = fscache_compare_options(fscp, optp);
- if (error) {
- cmn_err(CE_WARN,
- "CacheFS: mount failed, options do not match.");
- return (error);
- }
-
- /* copy options into the fscache */
- fscp->fs_info.fi_mntflags = optp->opt_flags;
- fscp->fs_info.fi_popsize = optp->opt_popsize;
- fscp->fs_info.fi_fgsize = optp->opt_fgsize;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
-
- /*
- * The fileid of the root of the filesystem can change
- * in NFSv4, so make sure we update the fi_root
- * with the new filenumber.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp) &&
- fscp->fs_info.fi_root != backfileno) {
- fscp->fs_info.fi_root = backfileno;
- }
- }
-
- if (setflags) {
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_flags |= CFS_FS_READ;
- if ((cachep->c_flags & CACHE_NOFILL) == 0)
- fscp->fs_flags |= CFS_FS_WRITE;
- mutex_exit(&fscp->fs_fslock);
- }
-
- return (0);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_activate
- *
- * Description:
- * A wrapper routine for fscache_setup, telling it to setup the
- * fscache for general use.
- *
- */
-int
-fscache_activate(fscache_t *fscp, ino64_t fsid, char *namep,
- struct cachefsoptions *optp, ino64_t backfileno)
-{
- return (fscache_setup(fscp, fsid, namep, optp, backfileno, 1));
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_enable
- *
- * Description:
- * A wrapper routine for fscache_setup, telling it to create a
- * fscache that can be used during remount. In this case the
- * fscache flags that allow general use are not yet turned on.
- * A later call to fscache_activate_rw will set the flags.
- *
- */
-int
-fscache_enable(fscache_t *fscp, ino64_t fsid, char *namep,
- struct cachefsoptions *optp, ino64_t backfileno)
-{
- return (fscache_setup(fscp, fsid, namep, optp, backfileno, 0));
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_activate_rw
- *
- * Description:
- * Makes the fscache both readable and writable.
- * Arguments:
- * fscp fscache object
- * Returns:
- * Preconditions:
- * precond(fscp)
- */
-
-void
-fscache_activate_rw(fscache_t *fscp)
-{
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_flags |= (CFS_FS_WRITE|CFS_FS_READ);
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_hold
- *
- * Description:
- * Increments the reference count on the fscache object
- * Arguments:
- * fscp fscache object to incriment reference count on
- * Returns:
- * Preconditions:
- * precond(fscp)
- */
-
-void
-fscache_hold(fscache_t *fscp)
-{
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_ref++;
- ASSERT(fscp->fs_ref > 0);
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_rele
- *
- * Description:
- * Decriments the reference count on the fscache object
- * Arguments:
- * fscp fscache object to decriment reference count on
- * Returns:
- * Preconditions:
- * precond(fscp)
- */
-
-void
-fscache_rele(fscache_t *fscp)
-{
- mutex_enter(&fscp->fs_fslock);
- ASSERT(fscp->fs_ref > 0);
- fscp->fs_ref--;
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_cnodecnt
- *
- * Description:
- * Changes the count of number of cnodes on this fscache
- * by the specified amount.
- * Arguments:
- * fscp fscache object to to modify count on
- * cnt amount to adjust by
- * Returns:
- * Returns new count of number of cnodes.
- * Preconditions:
- * precond(fscp)
- */
-
-int
-fscache_cnodecnt(fscache_t *fscp, int cnt)
-{
- int xx;
-
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_cnodecnt += cnt;
- ASSERT(fscp->fs_cnodecnt >= 0);
- xx = fscp->fs_cnodecnt;
- mutex_exit(&fscp->fs_fslock);
- return (xx);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_mounted
- *
- * Description:
- * Called to indicate the the fscache is mounted.
- * Arguments:
- * fscp fscache object
- * cfsvfsp cachefs vfsp
- * backvfsp vfsp of back file system
- * Returns:
- * Returns 0 for success, -1 if the cache is already mounted.
- * Preconditions:
- * precond(fscp)
- */
-
-int
-fscache_mounted(fscache_t *fscp, struct vfs *cfsvfsp, struct vfs *backvfsp)
-{
- int error = 0;
-
- mutex_enter(&fscp->fs_fslock);
- if (fscp->fs_flags & CFS_FS_MOUNTED) {
- error = -1;
- goto out;
- }
-
- fscp->fs_backvfsp = backvfsp;
- fscp->fs_cfsvfsp = cfsvfsp;
- gethrestime(&fscp->fs_cod_time);
- fscp->fs_flags |= CFS_FS_MOUNTED;
-
- if (CFS_ISFS_SNR(fscp)) {
- /*
- * If there is a dlog file present, then we assume the cache
- * was left in disconnected mode.
- * Also if the back file system was not mounted we also
- * start off in disconnected mode.
- */
- error = cachefs_dlog_setup(fscp, 0);
- if (!error || (backvfsp == NULL)) {
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cdconnected = CFS_CD_DISCONNECTED;
- fscp->fs_cdtransition = 0;
- cv_broadcast(&fscp->fs_cdwaitcv);
- mutex_exit(&fscp->fs_cdlock);
- }
-
- /* invalidate any local fileno mappings */
- fscp->fs_info.fi_resetfileno++;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
-
- /* if connected, invalidate any local time mappings */
- if (backvfsp)
- fscp->fs_info.fi_resettimes++;
- }
-
- error = 0;
-
- /* set up the consistency mode */
- if (fscp->fs_info.fi_mntflags & CFS_NOCONST_MODE) {
- fscp->fs_cfsops = &nopcfsops;
- fscp->fs_consttype = CFS_FS_CONST_NOCONST;
- } else if (fscp->fs_info.fi_mntflags & CFS_CODCONST_MODE) {
- fscp->fs_cfsops = &codcfsops;
- fscp->fs_consttype = CFS_FS_CONST_CODCONST;
- } else {
- fscp->fs_cfsops = &strictcfsops;
- fscp->fs_consttype = CFS_FS_CONST_STRICT;
- }
-
-out:
- mutex_exit(&fscp->fs_fslock);
- (void) fscache_info_sync(fscp);
- return (error);
-}
-
-/*
- * Compares fscache state with new mount options
- * to make sure compatible.
- * Returns ESRCH if not compatible or 0 for success.
- */
-int
-fscache_compare_options(fscache_t *fscp, struct cachefsoptions *optp)
-{
- if ((fscp->fs_info.fi_popsize == optp->opt_popsize) &&
- (fscp->fs_info.fi_fgsize == optp->opt_fgsize)) {
- return (0);
- } else {
- return (ESRCH);
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_sync
- *
- * Description:
- * Syncs any data for this fscache to the front file system.
- * Arguments:
- * fscp fscache to sync
- * Returns:
- * Preconditions:
- * precond(fscp)
- */
-
-void
-fscache_sync(struct fscache *fscp)
-{
- struct filegrp *fgp;
- int xx;
-
- (void) fscache_info_sync(fscp);
-
- /* sync the cnodes */
- cachefs_cnode_traverse(fscp, cachefs_cnode_sync);
-
- mutex_enter(&fscp->fs_fslock);
-
- /* sync the attrcache files */
- for (xx = 0; xx < CFS_FS_FGP_BUCKET_SIZE; xx++) {
- for (fgp = fscp->fs_filegrp[xx]; fgp != NULL;
- fgp = fgp->fg_next) {
- (void) filegrp_sync(fgp);
- }
- }
-
- /* garbage collect any unused file groups */
- filegrp_list_gc(fscp);
-
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_acset
- *
- * Description:
- * Sets the ac timeout values for the fscache.
- * Arguments:
- * fscp fscache object
- * Returns:
- * Preconditions:
- * precond(fscp)
- */
-
-void
-fscache_acset(fscache_t *fscp,
- uint_t acregmin, uint_t acregmax, uint_t acdirmin, uint_t acdirmax)
-{
- mutex_enter(&fscp->fs_fslock);
- if (acregmin > acregmax)
- acregmin = acregmax;
- if (acdirmin > acdirmax)
- acdirmin = acdirmax;
- if (acregmin != 0)
- fscp->fs_acregmin = acregmin;
- if (acregmax != 0)
- fscp->fs_acregmax = acregmax;
- if (acdirmin != 0)
- fscp->fs_acdirmin = acdirmin;
- if (acdirmax != 0)
- fscp->fs_acdirmax = acdirmax;
- mutex_exit(&fscp->fs_fslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_list_find
- *
- * Description:
- * Finds the desired fscache structure on a cache's
- * file system list.
- * Arguments:
- * cachep holds the list of fscache objects to search
- * fsid the numeric identifier of the fscache
- * Returns:
- * Returns an fscache object on success or NULL on failure.
- * Preconditions:
- * precond(cachep)
- * precond(the fslistlock must be held)
- */
-
-fscache_t *
-fscache_list_find(cachefscache_t *cachep, ino64_t fsid)
-{
- fscache_t *fscp = cachep->c_fslist;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
-
- while (fscp != NULL) {
- if (fscp->fs_cfsid == fsid) {
- ASSERT(fscp->fs_cache == cachep);
- break;
- }
- fscp = fscp->fs_next;
- }
-
- return (fscp);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_list_add
- *
- * Description:
- * Adds the specified fscache object to the list on
- * the specified cachep.
- * Arguments:
- * cachep holds the list of fscache objects
- * fscp fscache object to add to list
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(fscp)
- * precond(fscp cannot already be on a list)
- * precond(the fslistlock must be held)
- */
-
-void
-fscache_list_add(cachefscache_t *cachep, fscache_t *fscp)
-{
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
-
- fscp->fs_next = cachep->c_fslist;
- cachep->c_fslist = fscp;
- cachep->c_refcnt++;
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_list_remove
- *
- * Description:
- * Removes the specified fscache object from the list
- * on the specified cachep.
- * Arguments:
- * cachep holds the list of fscache objects
- * fscp fscache object to remove from list
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(fscp)
- * precond(the fslistlock must be held)
- */
-
-void
-fscache_list_remove(cachefscache_t *cachep, fscache_t *fscp)
-{
- struct fscache **pfscp = &cachep->c_fslist;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
-
- while (*pfscp != NULL) {
- if (fscp == *pfscp) {
- *pfscp = fscp->fs_next;
- cachep->c_refcnt--;
- break;
- }
- pfscp = &(*pfscp)->fs_next;
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_list_gc
- *
- * Description:
- * Traverses the list of fscache objects on the cachep
- * list and destroys any that are not mounted and
- * that are not referenced.
- * Arguments:
- * cachep holds the list of fscache objects
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(the fslistlock must be held)
- */
-
-void
-fscache_list_gc(cachefscache_t *cachep)
-{
- struct fscache *next, *fscp;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
-
- for (fscp = cachep->c_fslist; fscp != NULL; fscp = next) {
- next = fscp->fs_next;
- mutex_enter(&fscp->fs_fslock);
- if (((fscp->fs_flags & CFS_FS_MOUNTED) == 0) &&
- (fscp->fs_ref == 0)) {
- mutex_exit(&fscp->fs_fslock);
- fscache_list_remove(cachep, fscp);
- fscache_destroy(fscp);
- } else {
- mutex_exit(&fscp->fs_fslock);
- }
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_list_mounted
- *
- * Description:
- * Returns the number of fscache objects that are mounted.
- * Arguments:
- * cachep holds the list of fscache objects
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(the fslistlock must be held)
- */
-
-int
-fscache_list_mounted(cachefscache_t *cachep)
-{
- struct fscache *fscp;
- int count;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
-
- count = 0;
- for (fscp = cachep->c_fslist; fscp != NULL; fscp = fscp->fs_next) {
- mutex_enter(&fscp->fs_fslock);
- if (fscp->fs_flags & CFS_FS_MOUNTED)
- count++;
- mutex_exit(&fscp->fs_fslock);
- }
-
- return (count);
-}
-
-/*
- * Creates the fs cache directory.
- * The directory name is the ascii version of the fsid.
- * Also makes a symlink to the directory using the specified name.
- */
-int
-fscdir_create(cachefscache_t *cachep, char *namep, fscache_t *fscp)
-{
- int error;
- vnode_t *fscdirvp = NULL;
- vnode_t *infovp = NULL;
- vnode_t *attrvp = NULL;
- struct vattr *attrp = (struct vattr *)NULL;
- char name[CFS_FRONTFILE_NAME_SIZE];
- int files;
- int blocks = 0;
- cfs_cid_t cid;
- ino64_t fsid;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
- ASSERT(fscp->fs_infovp == NULL);
- ASSERT(fscp->fs_fscdirvp == NULL);
- ASSERT(fscp->fs_fsattrdir == NULL);
-
- /* directory, symlink and options file + attrcache dir */
- files = 0;
- while (files < 4) {
- error = cachefs_allocfile(cachep);
- if (error)
- goto out;
- files++;
- }
- error = cachefs_allocblocks(cachep, 4, CACHEFS_RL_NONE);
- if (error)
- goto out;
- blocks = 4;
-
- attrp = cachefs_kmem_alloc(sizeof (struct vattr), KM_SLEEP);
- attrp->va_mode = S_IFDIR | 0777;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VDIR;
- attrp->va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- error = VOP_MKDIR(cachep->c_dirvp, namep, attrp, &fscdirvp, kcred,
- NULL, 0, NULL);
- if (error) {
- cmn_err(CE_WARN, "Can't create fs cache directory");
- goto out;
- }
-
- /*
- * Created the directory. Get the fileno. That'll be the cachefs_fsid.
- */
- attrp->va_mask = AT_NODEID;
- error = VOP_GETATTR(fscdirvp, attrp, 0, kcred, NULL);
- if (error) {
- goto out;
- }
- fsid = attrp->va_nodeid;
- attrp->va_mode = S_IFREG | 0666;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VREG;
- attrp->va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- error = VOP_CREATE(fscdirvp, CACHEFS_FSINFO, attrp, EXCL,
- 0600, &infovp, kcred, 0, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "Can't create fs option file");
- goto out;
- }
- attrp->va_size = MAXBSIZE;
- attrp->va_mask = AT_SIZE;
- error = VOP_SETATTR(infovp, attrp, 0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "Can't set size of fsinfo file");
- goto out;
- }
-
- /* write out the info file */
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
- error = fscache_info_sync(fscp);
- if (error)
- goto out;
-
- /*
- * Install the symlink from cachefs_fsid -> directory.
- */
- cid.cid_flags = 0;
- cid.cid_fileno = fsid;
- make_ascii_name(&cid, name);
- error = VOP_RENAME(cachep->c_dirvp, namep, cachep->c_dirvp,
- name, kcred, NULL, 0);
- if (error) {
- cmn_err(CE_WARN, "Can't rename cache directory");
- goto out;
- }
- attrp->va_mask = AT_MODE | AT_TYPE;
- attrp->va_mode = 0777;
- attrp->va_type = VLNK;
- error = VOP_SYMLINK(cachep->c_dirvp, namep, attrp, name, kcred, NULL,
- 0);
- if (error) {
- cmn_err(CE_WARN, "Can't create cache directory symlink");
- goto out;
- }
-
- /*
- * Finally, make the attrcache directory
- */
- attrp->va_mode = S_IFDIR | 0777;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VDIR;
- attrp->va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- error = VOP_MKDIR(fscdirvp, ATTRCACHE_NAME, attrp, &attrvp, kcred, NULL,
- 0, NULL);
- if (error) {
- cmn_err(CE_WARN, "Can't create attrcache dir for fscache");
- goto out;
- }
-
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_cfsid = fsid;
- fscp->fs_fscdirvp = fscdirvp;
- fscp->fs_fsattrdir = attrvp;
- fscp->fs_infovp = infovp;
- mutex_exit(&fscp->fs_fslock);
-
-out:
-
- if (error) {
- while (files-- > 0)
- cachefs_freefile(cachep);
- if (fscdirvp)
- VN_RELE(fscdirvp);
- if (blocks)
- cachefs_freeblocks(cachep, blocks, CACHEFS_RL_NONE);
- if (attrvp)
- VN_RELE(attrvp);
- if (infovp)
- VN_RELE(infovp);
- }
- if (attrp)
- cachefs_kmem_free(attrp, sizeof (struct vattr));
- return (error);
-}
-
-/*
- * Tries to find the fscache directory indicated by fsid.
- */
-int
-fscdir_find(cachefscache_t *cachep, ino64_t fsid, fscache_t *fscp)
-{
- int error;
- vnode_t *infovp = NULL;
- vnode_t *fscdirvp = NULL;
- vnode_t *attrvp = NULL;
- char dirname[CFS_FRONTFILE_NAME_SIZE];
- cfs_cid_t cid;
- cachefs_fsinfo_t fsinfo;
- caddr_t addr;
-
- ASSERT(MUTEX_HELD(&cachep->c_fslistlock));
- ASSERT(fscp->fs_infovp == NULL);
- ASSERT(fscp->fs_fscdirvp == NULL);
- ASSERT(fscp->fs_fsattrdir == NULL);
-
- /* convert the fsid value to the name of the directory */
- cid.cid_flags = 0;
- cid.cid_fileno = fsid;
- make_ascii_name(&cid, dirname);
-
- /* try to find the directory */
- error = VOP_LOOKUP(cachep->c_dirvp, dirname, &fscdirvp, NULL,
- 0, NULL, kcred, NULL, NULL, NULL);
- if (error)
- goto out;
-
- /* this better be a directory or we are hosed */
- if (fscdirvp->v_type != VDIR) {
- cmn_err(CE_WARN, "cachefs: fscdir_find_a: cache corruption"
- " run fsck, %s", dirname);
- error = ENOTDIR;
- goto out;
- }
-
- /* try to find the info file */
- error = VOP_LOOKUP(fscdirvp, CACHEFS_FSINFO, &infovp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: fscdir_find_b: cache corruption"
- " run fsck, %s", dirname);
- goto out;
- }
-
- /* read in info struct */
- addr = segmap_getmapflt(segkmap, infovp, (offset_t)0,
- MAXBSIZE, 1, S_READ);
-
- /*LINTED alignment okay*/
- fsinfo = *(cachefs_fsinfo_t *)addr;
- error = segmap_release(segkmap, addr, 0);
- if (error) {
- cmn_err(CE_WARN, "cachefs: fscdir_find_c: cache corruption"
- " run fsck, %s", dirname);
- goto out;
- }
-
- /* try to find the attrcache directory */
- error = VOP_LOOKUP(fscdirvp, ATTRCACHE_NAME,
- &attrvp, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: fscdir_find_d: cache corruption"
- " run fsck, %s", dirname);
- goto out;
- }
-
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_info = fsinfo;
- fscp->fs_cfsid = fsid;
- fscp->fs_fscdirvp = fscdirvp;
- fscp->fs_fsattrdir = attrvp;
- fscp->fs_infovp = infovp;
- mutex_exit(&fscp->fs_fslock);
-
-out:
- if (error) {
- if (infovp)
- VN_RELE(infovp);
- if (fscdirvp)
- VN_RELE(fscdirvp);
- }
- return (error);
-}
-
-/*
- * fscache_info_sync
- * Writes out the fs_info data if necessary.
- */
-static int
-fscache_info_sync(fscache_t *fscp)
-{
- caddr_t addr;
- int error = 0;
-
- mutex_enter(&fscp->fs_fslock);
-
- if (fscp->fs_cache->c_flags & CACHE_NOFILL) {
- error = EROFS;
- goto out;
- }
-
- /* if the data is dirty and we have the file vnode */
- if ((fscp->fs_flags & CFS_FS_DIRTYINFO) && fscp->fs_infovp) {
- addr = segmap_getmapflt(segkmap, fscp->fs_infovp, 0,
- MAXBSIZE, 1, S_WRITE);
-
- /*LINTED alignment okay*/
- *(cachefs_fsinfo_t *)addr = fscp->fs_info;
- error = segmap_release(segkmap, addr, SM_WRITE);
-
- if (error) {
- cmn_err(CE_WARN,
- "cachefs: Can not write to info file.");
- } else {
- fscp->fs_flags &= ~CFS_FS_DIRTYINFO;
- }
- }
-
-out:
-
- mutex_exit(&fscp->fs_fslock);
-
- return (error);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * fscache_name_to_fsid
- *
- * Description:
- * Takes the name of a cache and determines it corresponding
- * fsid.
- * Arguments:
- * cachep cache object to find name of fs cache in
- * namep the name of the fs cache
- * fsidp set to the fsid if found
- * Returns:
- * Returns 0 on success, !0 on error.
- * Preconditions:
- * precond(cachep)
- * precond(namep)
- * precond(fsidp)
- */
-
-int
-fscache_name_to_fsid(cachefscache_t *cachep, char *namep, ino64_t *fsidp)
-{
- int error;
- char dirname[CFS_FRONTFILE_NAME_SIZE];
- vnode_t *linkvp = NULL;
- struct uio uio;
- struct iovec iov;
- ino64_t nodeid;
- char *pd;
- int xx;
- int c;
-
- /* get the vnode of the name */
- error = VOP_LOOKUP(cachep->c_dirvp, namep, &linkvp, NULL, 0, NULL,
- kcred, NULL, NULL, NULL);
- if (error)
- goto out;
-
- /* the vnode had better be a link */
- if (linkvp->v_type != VLNK) {
- error = EINVAL;
- goto out;
- }
-
- /* read the contents of the link */
- iov.iov_len = CFS_FRONTFILE_NAME_SIZE;
- iov.iov_base = dirname;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = iov.iov_len;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_loffset = 0;
- uio.uio_fmode = 0;
- uio.uio_extflg = UIO_COPY_CACHED;
- error = VOP_READLINK(linkvp, &uio, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: Can't read filesystem cache link");
- goto out;
- }
-
- /* convert the contents of the link to a ino64_t */
- nodeid = 0;
- pd = dirname;
- for (xx = 0; xx < (CFS_FRONTFILE_NAME_SIZE - 2); xx++) {
- nodeid <<= 4;
- c = *pd++;
- if (c <= '9')
- c -= '0';
- else if (c <= 'F')
- c = c - 'A' + 10;
- else
- c = c - 'a' + 10;
- nodeid += c;
- }
- *fsidp = nodeid;
-out:
- if (linkvp)
- VN_RELE(linkvp);
-
- return (error);
-}
-
-
-/*
- * Suspends the thread until access to the cache is granted.
- * If !SOFT then
- * waitconnected == 1 means wait until connected
- * waitconnected == 0 means wait until connected or disconnected
- * else then
- * wait until connected or disconnected
- * writing is set to 1 if writing, 0 if reading
- * Returns 0, EINTR, or ETIMEDOUT.
- */
-int
-cachefs_cd_access(fscache_t *fscp, int waitconnected, int writing)
-{
- int nosig;
- int error = 0;
- cachefscache_t *cachep;
- int waithappens = 0;
- pid_t pid;
-
- mutex_enter(&fscp->fs_cdlock);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
- for (;;) {
- /* if we have to wait */
- if (waithappens ||
- (waitconnected &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED))) {
-
- /* do not make soft mounts wait until connected */
- if ((waithappens == 0) && CFS_ISFS_SOFT(fscp)) {
- error = ETIMEDOUT;
- break;
- }
-
- /* wait for a wakeup or a signal */
- nosig = cv_wait_sig(&fscp->fs_cdwaitcv,
- &fscp->fs_cdlock);
-
- /* if we got a signal */
- if (nosig == 0) {
- error = EINTR;
- break;
- }
-
- if (waitconnected &&
- (fscp->fs_cdconnected == CFS_CD_CONNECTED))
- waitconnected = 0;
-
- /* try again to get access */
- waithappens = 0;
- continue;
- }
-
- /* if transitioning modes */
- if (fscp->fs_cdtransition) {
- waithappens = 1;
- continue;
- }
-
- /* if rolling the log */
- if (fscp->fs_cdconnected == CFS_CD_RECONNECTING) {
- pid = ttoproc(curthread)->p_pid;
- cachep = fscp->fs_cache;
-
- /* if writing or not the cachefsd */
- if (writing ||
- ((fscp->fs_cddaemonid != pid) &&
- (cachep->c_rootdaemonid != pid))) {
- waithappens = 1;
- continue;
- }
- }
-
- /* if the daemon is not running */
- if (fscp->fs_cddaemonid == 0) {
- /* if writing and not connected */
- if (writing &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- waithappens = 1;
- continue;
- }
- }
-
- /*
- * Verify don't set wait for NFSv4 (doesn't support
- * disconnected behavior).
- */
- ASSERT(!CFS_ISFS_BACKFS_NFSV4(fscp) ||
- (waithappens == 0 && waitconnected == 0));
-
- ASSERT(fscp->fs_cdrefcnt >= 0);
- fscp->fs_cdrefcnt++;
-#ifdef CFS_CD_DEBUG
- curthread->t_flag |= T_CD_HELD;
-#endif
- break;
- }
- mutex_exit(&fscp->fs_cdlock);
-
- return (error);
-}
-
-/*
- * Call to check if can have access after a cache miss has occurred.
- * Only read access is allowed, do not call this routine if want
- * to write.
- * Returns 1 if yes, 0 if no.
- */
-int
-cachefs_cd_access_miss(fscache_t *fscp)
-{
- cachefscache_t *cachep;
- pid_t pid;
-
-#ifdef CFS_CD_DEBUG
- ASSERT(curthread->t_flag & T_CD_HELD);
-#endif
-
- /* should not get called if connected */
- ASSERT(fscp->fs_cdconnected != CFS_CD_CONNECTED);
-
- /* if no back file system, then no */
- if (fscp->fs_backvfsp == NULL)
- return (0);
-
- /* if daemon is not running, then yes */
- if (fscp->fs_cddaemonid == 0) {
- return (1);
- }
-
- pid = ttoproc(curthread)->p_pid;
- cachep = fscp->fs_cache;
-
- /* if daemon is running, only daemon is allowed to have access */
- if ((fscp->fs_cddaemonid != pid) &&
- (cachep->c_rootdaemonid != pid)) {
- return (0);
- }
-
- return (1);
-}
-
-/*
- * Releases an access to the file system.
- */
-void
-cachefs_cd_release(fscache_t *fscp)
-{
- mutex_enter(&fscp->fs_cdlock);
-
-#ifdef CFS_CD_DEBUG
- ASSERT(curthread->t_flag & T_CD_HELD);
- curthread->t_flag &= ~T_CD_HELD;
-#endif
- /* decriment hold on file system */
- fscp->fs_cdrefcnt--;
- ASSERT(fscp->fs_cdrefcnt >= 0);
-
- /* Verify no connected state transitions for NFSv4 */
- ASSERT(!CFS_ISFS_BACKFS_NFSV4(fscp) || fscp->fs_cdtransition == 0);
-
- /* wake up cachefsd */
- if ((fscp->fs_cdrefcnt == 0) && fscp->fs_cdtransition)
- cv_broadcast(&fscp->fs_cdwaitcv);
-
- mutex_exit(&fscp->fs_cdlock);
-}
-
-/*
- * Called when a network timeout error has occurred.
- * If connected, switches state to disconnected.
- */
-void
-cachefs_cd_timedout(fscache_t *fscp)
-{
- int state;
-
- /* nothing to do if not snr or not connected */
- if (!CFS_ISFS_SNR(fscp) || (fscp->fs_cdconnected != CFS_CD_CONNECTED))
- return;
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
- /* Verify no state changes done for NFSv4 */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- state = CFS_FS_DISCONNECTED;
- (void) cachefs_io_stateset(fscp->fs_rootvp, &state, NULL);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_ioctl.c b/usr/src/uts/common/fs/cachefs/cachefs_ioctl.c
deleted file mode 100644
index 2a6b60a7a0..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_ioctl.c
+++ /dev/null
@@ -1,2589 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-#include <sys/vfs.h>
-#include <sys/file.h>
-#include <sys/filio.h>
-#include <sys/uio.h>
-#include <sys/buf.h>
-#include <sys/mman.h>
-#include <sys/tiuser.h>
-#include <sys/pathname.h>
-#include <sys/dirent.h>
-#include <sys/conf.h>
-#include <sys/debug.h>
-#include <sys/vmsystm.h>
-#include <sys/fcntl.h>
-#include <sys/flock.h>
-#include <sys/fbuf.h>
-#include <sys/swap.h>
-#include <sys/errno.h>
-#include <sys/sysmacros.h>
-#include <sys/disp.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/vtrace.h>
-#include <sys/mount.h>
-#include <sys/dnlc.h>
-#include <sys/stat.h>
-#include <rpc/types.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include <sys/fs/cachefs_dir.h>
-#include <sys/fs/cachefs_dlog.h>
-#include "fs/fs_subr.h"
-
-void cachefs_addhash(struct cnode *);
-
-
-/*
- * Local functions
- */
-static void sync_metadata(cnode_t *);
-static void drop_backvp(cnode_t *);
-static void allow_pendrm(cnode_t *cp);
-static int cachefs_unpack_common(vnode_t *vp);
-static int cachefs_unpackall_list(cachefscache_t *cachep,
- enum cachefs_rl_type type);
-static void cachefs_modified_fix(fscache_t *fscp);
-static void cachefs_iosetneedattrs(fscache_t *fscp, cfs_cid_t *cidp);
-
-#if (defined(_SYSCALL32_IMPL) || defined(_LP64))
-
-#define CACHEFS_DECL(type, handle) \
- type handle
-
-#define CACHEFS_TMPPTR_SET(in_addr, tmp_addr, tmp_ptr, type) \
- tmp_ptr = (type *)(tmp_addr)
-
-#define CACHEFS_FID_COPYOUT(in_fidp, out_fidp) \
- CACHEFS_FID_COPY((fid_t *)(in_fidp), (cfs_fid_t *)(out_fidp))
-
-#define CACHEFS_FID_COPYIN(in_fidp, out_fidp) \
- CACHEFS_FID_COPY((cfs_fid_t *)(in_fidp), (fid_t *)(out_fidp))
-
-#define CACHEFS_VATTR_COPYOUT(in_vattrp, out_vattrp, error) \
- if (!error) { \
- CACHEFS_VATTR_TO_CFS_VATTR_COPY((vattr_t *)(in_vattrp), \
- (cfs_vattr_t *)(out_vattrp), error); \
- }
-
-#define CACHEFS_VATTR_COPYIN(in_vattrp, out_vattrp) \
- CACHEFS_CFS_VATTR_TO_VATTR_COPY((cfs_vattr_t *)(in_vattrp), \
- (vattr_t *)(out_vattrp))
-
-#else /* not _SYSCALL32_IMPL || _LP64 */
-
-#define CACHEFS_DECL(type, handle)
-
-#define CACHEFS_TMPPTR_SET(in_addr, tmp_addr, tmp_ptr, type) \
- tmp_ptr = (type *)(in_addr)
-
-#define CACHEFS_FID_COPYOUT(in_fidp, out_fidp)
-
-#define CACHEFS_FID_COPYIN(in_fidp, out_fidp)
-
-#define CACHEFS_VATTR_COPYOUT(in_vattrp, out_vattrp, error)
-
-#define CACHEFS_VATTR_COPYIN(in_vattrp, out_vattrp)
-
-#endif /* _SYSCALL32_IMPL || _LP64 */
-
-/*
- * Conjure up a credential from the partial credential stored in
- * a file. This is bogus and cachefs should really be fixed, but
- * this maintains maximum compatibility.
- * dl_cred *cr points to a basic credential followed directly by a buffer that
- * takes a number of groups.
- */
-
-static cred_t *
-conj_cred(dl_cred_t *cr)
-{
- cred_t *newcr = crget();
-
- (void) crsetresuid(newcr, cr->cr_ruid, cr->cr_uid, cr->cr_suid);
- (void) crsetresgid(newcr, cr->cr_rgid, cr->cr_gid, cr->cr_sgid);
-
- (void) crsetgroups(newcr, MIN(NGROUPS_MAX_DEFAULT, cr->cr_ngroups),
- cr->cr_groups);
-
- return (newcr);
-}
-/*
- * Pack a file in the cache
- * dvp is the directory the file resides in.
- * name is the name of the file.
- * Returns 0 or an error if could not perform the operation.
- */
-int
-cachefs_pack(struct vnode *dvp, char *name, cred_t *cr)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(dvp));
- int error = 0;
- int connected = 0;
- vnode_t *vp;
-
- /*
- * Return if NFSv4 is the backfs (no caching).
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- goto out;
- }
-
- for (;;) {
- /* get access to the file system */
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
-
- /* lookup the file name */
- error = cachefs_lookup_common(dvp, name, &vp, NULL, 0, NULL,
- cr);
- if (error == 0) {
- error = cachefs_pack_common(vp, cr);
- VN_RELE(vp);
- }
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- } else {
- cachefs_cd_release(fscp);
- connected = 1;
- continue;
- }
- }
- cachefs_cd_release(fscp);
- break;
- }
-
-out:
- return (error);
-}
-/*
- * Packs the file belonging to the passed in vnode.
- */
-int
-cachefs_pack_common(vnode_t *vp, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- offset_t off;
- caddr_t buf;
- int buflen;
- rl_entry_t rl_ent;
- u_offset_t cnode_size;
-
- rw_enter(&cp->c_rwlock, RW_WRITER);
- mutex_enter(&cp->c_statelock);
-
- /* done if cannot write to cache */
- if ((cp->c_filegrp->fg_flags & CFS_FG_WRITE) == 0) {
- error = EROFS;
- goto out;
- }
-
- /* done if not usable */
- if (cp->c_flags & (CN_STALE | CN_DESTROY)) {
- error = ESTALE;
- goto out;
- }
-
- /* make sure up to date */
- error = CFSOP_CHECK_COBJECT(fscp, cp, C_BACK_CHECK, cr);
- if (error)
- goto out;
-
- /* make it cachable */
- cp->c_flags &= ~CN_NOCACHE;
-
- /* get a metadata slot if we do not have one yet */
- if (cp->c_flags & CN_ALLOC_PENDING) {
- if (cp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(cp->c_filegrp);
- }
- error = filegrp_create_metadata(cp->c_filegrp,
- &cp->c_metadata, &cp->c_id);
- if (error)
- goto out;
- cp->c_flags &= ~CN_ALLOC_PENDING;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* cache the ACL if necessary */
- if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
- (cachefs_vtype_aclok(vp)) &&
- ((cp->c_metadata.md_flags & MD_ACL) == 0)) {
- error = cachefs_cacheacl(cp, NULL);
- if (error != 0)
- goto out;
- }
-
- /* directory */
- if (vp->v_type == VDIR) {
- if (cp->c_metadata.md_flags & MD_POPULATED)
- goto out;
-
- if (error = cachefs_dir_fill(cp, cr))
- goto out;
- }
-
- /* regular file */
- else if (vp->v_type == VREG) {
- if (cp->c_metadata.md_flags & MD_POPULATED)
- goto out;
-
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
- if (cp->c_frontvp == NULL) {
- error = cachefs_getfrontfile(cp);
- if (error)
- goto out;
- }
- /* populate the file */
- off = (offset_t)0;
- cnode_size = cp->c_attr.va_size;
- while (off < cnode_size) {
- if (!cachefs_check_allocmap(cp, off)) {
- u_offset_t popoff;
- size_t popsize;
-
- cachefs_cluster_allocmap(off, &popoff,
- &popsize, (size_t)DEF_POP_SIZE, cp);
- if (popsize != 0) {
- error = cachefs_populate(cp, popoff,
- popsize, cp->c_frontvp,
- cp->c_backvp, cp->c_size, cr);
- if (error)
- goto out;
- else
- cp->c_flags |= (CN_UPDATED |
- CN_NEED_FRONT_SYNC |
- CN_POPULATION_PENDING);
- popsize = popsize - (off - popoff);
- }
- }
- off += PAGESIZE;
- }
- }
-
- /* symbolic link */
- else if (vp->v_type == VLNK) {
- if (cp->c_metadata.md_flags & (MD_POPULATED | MD_FASTSYMLNK))
- goto out;
-
- /* get the sym link contents from the back fs */
- error = cachefs_readlink_back(cp, cr, &buf, &buflen);
- if (error)
- goto out;
-
- /* try to cache the sym link */
- error = cachefs_stuffsymlink(cp, buf, buflen);
- cachefs_kmem_free(buf, MAXPATHLEN);
- }
-
- /* assume that all other types fit in the attributes */
-
-out:
- /* get the rl slot if needed */
- if ((error == 0) && (cp->c_metadata.md_rlno == 0)) {
- rl_ent.rl_fileno = cp->c_id.cid_fileno;
- rl_ent.rl_local = (cp->c_id.cid_flags & CFS_CID_LOCAL) ? 1 : 0;
- rl_ent.rl_fsid = fscp->fs_cfsid;
- rl_ent.rl_attrc = 0;
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
- error = cachefs_rl_alloc(fscp->fs_cache, &rl_ent,
- &cp->c_metadata.md_rlno);
- if (error == 0)
- error = filegrp_ffhold(cp->c_filegrp);
- }
-
- /* mark the file as packed */
- if (error == 0) {
- /* modified takes precedence over packed */
- if (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED) {
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_PACKED, cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_PACKED;
- }
- cp->c_metadata.md_flags |= MD_PACKED;
- cp->c_flags |= CN_UPDATED;
- }
-
- mutex_exit(&cp->c_statelock);
- rw_exit(&cp->c_rwlock);
-
- return (error);
-}
-
-/*
- * Unpack a file from the cache
- * dvp is the directory the file resides in.
- * name is the name of the file.
- * Returns 0 or an error if could not perform the operation.
- */
-int
-cachefs_unpack(struct vnode *dvp, char *name, cred_t *cr)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(dvp));
- int error = 0;
- int connected = 0;
- vnode_t *vp;
-
- /* Return error if NFSv4 is the backfs (no caching) */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- goto out;
- }
-
- for (;;) {
- /* get access to the file system */
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
-
- /* lookup the file name */
- error = cachefs_lookup_common(dvp, name, &vp, NULL, 0, NULL,
- cr);
- if (error == 0) {
- error = cachefs_unpack_common(vp);
- VN_RELE(vp);
- }
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- } else {
- cachefs_cd_release(fscp);
- connected = 1;
- continue;
- }
- }
- cachefs_cd_release(fscp);
- break;
- }
-out:
- return (error);
-}
-
-/*
- * Unpacks the file belonging to the passed in vnode.
- */
-static int
-cachefs_unpack_common(vnode_t *vp)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
-
- mutex_enter(&cp->c_statelock);
-
- /* nothing to do if not packed */
- if ((cp->c_metadata.md_flags & MD_PACKED) == 0)
- goto out;
-
- /* nothing to do if cannot modify cache */
- if ((cp->c_filegrp->fg_flags & CFS_FG_WRITE) == 0) {
- error = EROFS;
- goto out;
- }
-
- /* mark file as no longer packed */
- ASSERT(cp->c_metadata.md_rlno);
- cp->c_metadata.md_flags &= ~MD_PACKED;
- cp->c_flags |= CN_UPDATED;
-
- /* done if file has been modified */
- if (cp->c_metadata.md_rltype == CACHEFS_RL_MODIFIED)
- goto out;
-
- /* if there is no front file */
- if ((cp->c_metadata.md_flags & MD_FILE) == 0) {
- /* nuke front file resources */
- filegrp_ffrele(cp->c_filegrp);
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_FREE, cp->c_metadata.md_rlno, 0);
- cp->c_metadata.md_rlno = 0;
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
- }
-
- /* else move the front file to the active list */
- else {
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_ACTIVE, cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_ACTIVE;
- }
-
-out:
- mutex_exit(&cp->c_statelock);
- return (error);
-}
-
-/*
- * Returns packing information on a file.
- * dvp is the directory the file resides in.
- * name is the name of the file.
- * *statusp is set to the status of the file
- * Returns 0 or an error if could not perform the operation.
- */
-int
-cachefs_packinfo(struct vnode *dvp, char *name, int *statusp, cred_t *cr)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(dvp));
- struct vnode *vp;
- struct cnode *cp;
- int error;
- int connected = 0;
-
- *statusp = 0;
-
- /*
- * Return if NFSv4 is the backfs (no caching).
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- goto out;
- }
-
- for (;;) {
- /* get access to the file system */
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
-
- /* lookup the file name */
- error = cachefs_lookup_common(dvp, name, &vp, NULL, 0, NULL,
- cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- } else {
- cachefs_cd_release(fscp);
- connected = 1;
- continue;
- }
- }
- if (error)
- break;
- cp = VTOC(vp);
-
- mutex_enter(&cp->c_statelock);
- if (cp->c_metadata.md_flags & MD_PACKED)
- *statusp |= CACHEFS_PACKED_FILE;
- if (cp->c_metadata.md_flags & (MD_POPULATED | MD_FASTSYMLNK))
- *statusp |= CACHEFS_PACKED_DATA;
- else if ((vp->v_type != VREG) &&
- (vp->v_type != VDIR) &&
- (vp->v_type != VLNK))
- *statusp |= CACHEFS_PACKED_DATA;
- else if (cp->c_size == 0)
- *statusp |= CACHEFS_PACKED_DATA;
- if (cp->c_flags & CN_NOCACHE)
- *statusp |= CACHEFS_PACKED_NOCACHE;
- mutex_exit(&cp->c_statelock);
-
- VN_RELE(vp);
- cachefs_cd_release(fscp);
- break;
- }
-
-out:
- return (error);
-}
-
-/*
- * Finds all packed files in the cache and unpacks them.
- */
-int
-cachefs_unpackall(vnode_t *vp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cachefscache_t *cachep = fscp->fs_cache;
- int error;
-
- /*
- * Return if NFSv4 is the backfs (no caching).
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- goto out;
- }
-
- error = cachefs_unpackall_list(cachep, CACHEFS_RL_PACKED);
- if (error)
- goto out;
- error = cachefs_unpackall_list(cachep, CACHEFS_RL_PACKED_PENDING);
-out:
- return (error);
-}
-
-/*
- * Finds all packed files on the specified list and unpacks them.
- */
-static int
-cachefs_unpackall_list(cachefscache_t *cachep, enum cachefs_rl_type type)
-{
- fscache_t *fscp = NULL;
- cnode_t *cp;
- int error = 0;
- rl_entry_t rl_ent;
- cfs_cid_t cid;
-
- rl_ent.rl_current = type;
- for (;;) {
- /* get the next entry on the specified resource list */
- error = cachefs_rlent_data(cachep, &rl_ent, NULL);
- if (error) {
- error = 0;
- break;
- }
-
- /* if the fscp we have does not match */
- if ((fscp == NULL) || (fscp->fs_cfsid != rl_ent.rl_fsid)) {
- if (fscp) {
- cachefs_cd_release(fscp);
- fscache_rele(fscp);
- fscp = NULL;
- }
-
- /* get the file system cache object for this fsid */
- mutex_enter(&cachep->c_fslistlock);
- fscp = fscache_list_find(cachep, rl_ent.rl_fsid);
- if (fscp == NULL) {
- fscp = fscache_create(cachep);
- error = fscache_activate(fscp, rl_ent.rl_fsid,
- NULL, NULL, 0);
- if (error) {
- cmn_err(CE_WARN,
- "cachefs: cache error, run fsck\n");
- fscache_destroy(fscp);
- fscp = NULL;
- mutex_exit(&cachep->c_fslistlock);
- break;
- }
- fscache_list_add(cachep, fscp);
- }
- fscache_hold(fscp);
- mutex_exit(&cachep->c_fslistlock);
-
- /* get access to the file system */
- error = cachefs_cd_access(fscp, 0, 0);
- if (error) {
- fscache_rele(fscp);
- fscp = NULL;
- break;
- }
- }
-
- /* get the cnode for the file */
- cid.cid_fileno = rl_ent.rl_fileno;
- cid.cid_flags = rl_ent.rl_local ? CFS_CID_LOCAL : 0;
- error = cachefs_cnode_make(&cid, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_IOCTL)
- printf("cachefs: cul: could not find %llu\n",
- (u_longlong_t)cid.cid_fileno);
- delay(5*hz);
-#endif
- continue;
- }
-
- /* unpack the file */
- (void) cachefs_unpack_common(CTOV(cp));
- VN_RELE(CTOV(cp));
- }
-
- /* free up allocated resources */
- if (fscp) {
- cachefs_cd_release(fscp);
- fscache_rele(fscp);
- }
- return (error);
-}
-
-/*
- * Identifies this process as the cachefsd.
- * Stays this way until close is done.
- */
-int
-/*ARGSUSED*/
-cachefs_io_daemonid(vnode_t *vp, void *dinp, void *doutp)
-{
- int error = 0;
-
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cachefscache_t *cachep = fscp->fs_cache;
-
- mutex_enter(&fscp->fs_cdlock);
-
- /* can only do this on the root of the file system */
- if (vp != fscp->fs_rootvp)
- error = ENOENT;
-
- /* else if there already is a daemon running */
- else if (fscp->fs_cddaemonid)
- error = EBUSY;
-
- /* else use the pid to identify the daemon */
- else {
- fscp->fs_cddaemonid = ttoproc(curthread)->p_pid;
- cv_broadcast(&fscp->fs_cdwaitcv);
- }
-
- mutex_exit(&fscp->fs_cdlock);
-
- if (error == 0) {
- /* the daemon that takes care of root is special */
- if (fscp->fs_flags & CFS_FS_ROOTFS) {
- mutex_enter(&cachep->c_contentslock);
- ASSERT(cachep->c_rootdaemonid == 0);
- cachep->c_rootdaemonid = fscp->fs_cddaemonid;
- mutex_exit(&cachep->c_contentslock);
- }
- }
- return (error);
-}
-
-/*
- * Returns the current state in doutp
- */
-int
-/*ARGSUSED*/
-cachefs_io_stateget(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int *statep = (int *)doutp;
- int state;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- mutex_enter(&fscp->fs_cdlock);
- switch (fscp->fs_cdconnected) {
- case CFS_CD_CONNECTED:
- state = CFS_FS_CONNECTED;
- break;
- case CFS_CD_DISCONNECTED:
- state = CFS_FS_DISCONNECTED;
- break;
- case CFS_CD_RECONNECTING:
- state = CFS_FS_RECONNECTING;
- break;
- default:
- ASSERT(0);
- break;
- }
- mutex_exit(&fscp->fs_cdlock);
-
- *statep = state;
- return (0);
-}
-
-/*
- * Sets the state of the file system.
- */
-int
-/*ARGSUSED*/
-cachefs_io_stateset(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- int nosig = 1;
- int state = *(int *)dinp;
-
- /*
- * State should not be changeable and always be connected if
- * NFSv4 is in use.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* wait until the file system is quiet */
- mutex_enter(&fscp->fs_cdlock);
- if (fscp->fs_cdtransition == 1) {
- /* if someone is already changing the state */
- mutex_exit(&fscp->fs_cdlock);
- return (0);
- }
- fscp->fs_cdtransition = 1;
- while (nosig && (fscp->fs_cdrefcnt != 0)) {
- nosig = cv_wait_sig(&fscp->fs_cdwaitcv, &fscp->fs_cdlock);
- }
- if (!nosig) {
- fscp->fs_cdtransition = 0;
- cv_broadcast(&fscp->fs_cdwaitcv);
- mutex_exit(&fscp->fs_cdlock);
- return (EINTR);
- }
- mutex_exit(&fscp->fs_cdlock);
-
- switch (state) {
- case CFS_FS_CONNECTED:
- /* done if already in this state */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- break;
-
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cdconnected = CFS_CD_CONNECTED;
- mutex_exit(&fscp->fs_cdlock);
-
- /* fix up modified files */
- cachefs_modified_fix(fscp);
-
-#if 0
- if (fscp->fs_hostname != NULL)
- printf("\ncachefs:server - %s",
- fscp->fs_hostname);
- if (fscp->fs_mntpt != NULL)
- printf("\ncachefs:mount point - %s",
- fscp->fs_mntpt);
- if (fscp->fs_backfsname != NULL)
- printf("\ncachefs:back filesystem - %s",
- fscp->fs_backfsname);
- printf("\nok\n");
-#else
- if (fscp->fs_hostname && fscp->fs_backfsname)
- printf("cachefs: %s:%s ok\n",
- fscp->fs_hostname, fscp->fs_backfsname);
- else
- printf("cachefs: server ok\n");
-#endif
-
- /* allow deletion of renamed open files to proceed */
- cachefs_cnode_traverse(fscp, allow_pendrm);
- break;
-
- case CFS_FS_DISCONNECTED:
- /* done if already in this state */
- if (fscp->fs_cdconnected == CFS_CD_DISCONNECTED)
- break;
-
- /* drop all back vps */
- cachefs_cnode_traverse(fscp, drop_backvp);
-
-
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cdconnected = CFS_CD_DISCONNECTED;
- mutex_exit(&fscp->fs_cdlock);
-
-#if 0
- if (fscp->fs_hostname != NULL)
- printf("\ncachefs:server - %s",
- fscp->fs_hostname);
- if (fscp->fs_mntpt != NULL)
- printf("\ncachefs:mount point - %s",
- fscp->fs_mntpt);
- if (fscp->fs_backfsname != NULL)
- printf("\ncachefs:back filesystem - %s",
- fscp->fs_backfsname);
- printf("\nnot responding still trying\n");
-#else
- if (fscp->fs_hostname && fscp->fs_backfsname)
- printf("cachefs: %s:%s not responding still trying\n",
- fscp->fs_hostname, fscp->fs_backfsname);
- else
- printf("cachefs: server not responding still trying\n");
-#endif
- break;
-
- case CFS_FS_RECONNECTING:
- /* done if already in this state */
- if (fscp->fs_cdconnected == CFS_CD_RECONNECTING)
- break;
-
- /*
- * Before we enter disconnected state we sync all metadata,
- * this allows us to read metadata directly in subsequent
- * calls so we don't need to allocate cnodes when
- * we just need metadata information.
- */
- /* XXX bob: need to eliminate this */
- cachefs_cnode_traverse(fscp, sync_metadata);
-
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cdconnected = CFS_CD_RECONNECTING;
- mutex_exit(&fscp->fs_cdlock);
-
- /* no longer need dlog active */
- cachefs_dlog_teardown(fscp);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cdtransition = 0;
- cv_broadcast(&fscp->fs_cdwaitcv);
- mutex_exit(&fscp->fs_cdlock);
- return (error);
-}
-
-/*
- * Blocks until the file system switches
- * out of the connected state.
- */
-int
-/*ARGSUSED*/
-cachefs_io_xwait(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int nosig = 1;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not used when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- mutex_enter(&fscp->fs_cdlock);
- while (nosig &&
- (fscp->fs_cdconnected == CFS_CD_CONNECTED)) {
- nosig = cv_wait_sig(&fscp->fs_cdwaitcv, &fscp->fs_cdlock);
- }
- mutex_exit(&fscp->fs_cdlock);
- if (!nosig)
- return (EINTR);
-
- return (0);
-}
-
-#define RL_HEAD(cachep, type) \
- (&(cachep->c_rlinfo.rl_items[CACHEFS_RL_INDEX(type)]))
-
-/*
- * Returns some statistics about the cache.
- */
-#define CFS_STAT_FACTOR (MAXBSIZE / 1024)
-int
-/*ARGSUSED*/
-cachefs_io_getstats(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cachefscache_t *cachep = fscp->fs_cache;
- struct statvfs64 sb;
- fsblkcnt64_t avail = 0;
- fsblkcnt64_t blocks;
- int error;
- cachefsio_getstats_t *gsp = (cachefsio_getstats_t *)doutp;
-
- /* determine number of blocks available to the cache */
- error = VFS_STATVFS(cachep->c_dirvp->v_vfsp, &sb);
- if (error == 0) {
- blocks = (fsblkcnt64_t)(cachep->c_label.cl_maxblks -
- cachep->c_usage.cu_blksused);
- if ((longlong_t)blocks < (longlong_t)0)
- blocks = (fsblkcnt64_t)0;
- avail = (sb.f_bfree * sb.f_frsize) / MAXBSIZE;
- if (blocks < avail)
- avail = blocks;
- }
-
- gsp->gs_total = cachep->c_usage.cu_blksused * CFS_STAT_FACTOR;
- gsp->gs_gc = RL_HEAD(cachep, CACHEFS_RL_GC)->rli_blkcnt *
- CFS_STAT_FACTOR;
- gsp->gs_active = RL_HEAD(cachep, CACHEFS_RL_ACTIVE)->rli_blkcnt *
- CFS_STAT_FACTOR;
- gsp->gs_packed = RL_HEAD(cachep, CACHEFS_RL_PACKED)->rli_blkcnt *
- CFS_STAT_FACTOR;
- gsp->gs_free = (long)(avail * CFS_STAT_FACTOR);
- gsp->gs_gctime = cachep->c_rlinfo.rl_gctime;
- return (0);
-}
-
-/*
- * This looks to see if the specified file exists in the cache.
- * 0 is returned if it exists
- * ENOENT is returned if it doesn't exist.
- */
-int
-/*ARGSUSED*/
-cachefs_io_exists(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cnode_t *cp = NULL;
- int error;
- cfs_cid_t *cidp = (cfs_cid_t *)dinp;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* find the cnode of the file */
- error = cachefs_cnode_make(cidp, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error)
- return (ENOENT);
-
- if ((cp->c_flags & (CN_DESTROY | CN_NOCACHE)) ||
- !(cp->c_metadata.md_flags & (MD_POPULATED | MD_FASTSYMLNK)))
- error = ENOENT;
-
- VN_RELE(CTOV(cp));
- return (error);
-
-}
-
-/*
- * Moves the specified file to the lost+found directory for the
- * cached file system.
- * Invalidates cached data and attributes.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_lostfound(vnode_t *vp, void *dinp, void *doutp)
-{
- int error;
- cnode_t *cp = NULL;
- fscache_t *fscp;
- cachefscache_t *cachep;
- cachefsio_lostfound_arg_t *lfp;
- cachefsio_lostfound_return_t *rp;
-
- lfp = (cachefsio_lostfound_arg_t *)dinp;
- rp = (cachefsio_lostfound_return_t *)doutp;
-
- fscp = C_TO_FSCACHE(VTOC(vp));
- cachep = fscp->fs_cache;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* find the cnode of the file */
- error = cachefs_cnode_make(&lfp->lf_cid, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error) {
- error = ENOENT;
- goto out;
- }
-
- mutex_enter(&cp->c_statelock);
-
- /* must be regular file and modified */
- if ((cp->c_attr.va_type != VREG) ||
- (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED)) {
- mutex_exit(&cp->c_statelock);
- error = EINVAL;
- goto out;
- }
-
- /* move to lost+found */
- error = cachefs_cnode_lostfound(cp, lfp->lf_name);
- mutex_exit(&cp->c_statelock);
-
- if (error == 0)
- (void) strcpy(rp->lf_name, lfp->lf_name);
-out:
- if (cp)
- VN_RELE(CTOV(cp));
-
- return (error);
-}
-
-/*
- * Given a cid, returns info about the file in the cache.
- */
-int
-cachefs_io_getinfo(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- struct cnode *dcp = NULL;
- struct cnode *cp = NULL;
- struct vattr va;
- u_offset_t blockoff = 0;
- struct fbuf *fbp;
- int offset = 0;
- int error = 0;
- cfs_cid_t *fcidp;
- cachefsio_getinfo_t *infop;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- fcidp = (cfs_cid_t *)dinp;
- infop = (cachefsio_getinfo_t *)doutp;
-
- /* find the cnode of the file */
- error = cachefs_cnode_make(fcidp, fscp, NULL, NULL, NULL,
- kcred, 0, &cp);
- if (error) {
- error = ENOENT;
- goto out;
- }
-
- infop->gi_cid = *fcidp;
- infop->gi_modified = (cp->c_metadata.md_rltype == CACHEFS_RL_MODIFIED);
- CACHEFS_VATTR_TO_CFS_VATTR_COPY(&cp->c_attr, &infop->gi_attr, error);
- infop->gi_pcid = cp->c_metadata.md_parent;
- infop->gi_name[0] = '\0';
- infop->gi_seq = cp->c_metadata.md_seq;
- if (error || (cp->c_metadata.md_parent.cid_fileno == 0))
- goto out;
-
- /* try to get the cnode of the parent dir */
- error = cachefs_cnode_make(&cp->c_metadata.md_parent, fscp,
- NULL, NULL, NULL, kcred, 0, &dcp);
- if (error) {
- error = 0;
- goto out;
- }
-
- /* make sure a directory and populated */
- if ((((dcp->c_flags & CN_ASYNC_POPULATE) == 0) ||
- ((dcp->c_metadata.md_flags & MD_POPULATED) == 0)) &&
- (CTOV(dcp)->v_type == VDIR)) {
- error = 0;
- goto out;
- }
-
- /* get the front file */
- if (dcp->c_frontvp == NULL) {
- mutex_enter(&dcp->c_statelock);
- error = cachefs_getfrontfile(dcp);
- mutex_exit(&dcp->c_statelock);
- if (error) {
- error = 0;
- goto out;
- }
-
- /* make sure frontvp is still populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = 0;
- goto out;
- }
- }
-
- /* Get the length of the directory */
- va.va_mask = AT_SIZE;
- error = VOP_GETATTR(dcp->c_frontvp, &va, 0, kcred, NULL);
- if (error) {
- error = 0;
- goto out;
- }
-
- /* XXX bob: change this to use cachfs_dir_read */
- /* We have found the parent, now we open the dir and look for file */
- while (blockoff < va.va_size) {
- offset = 0;
- error = fbread(dcp->c_frontvp, (offset_t)blockoff, MAXBSIZE,
- S_OTHER, &fbp);
- if (error)
- goto out;
- while (offset < MAXBSIZE && (blockoff + offset) < va.va_size) {
- struct c_dirent *dep;
- dep = (struct c_dirent *)((uintptr_t)fbp->fb_addr +
- offset);
- if ((dep->d_flag & CDE_VALID) &&
- (bcmp(&dep->d_id, &infop->gi_cid,
- sizeof (cfs_cid_t)) == 0)) {
- /* found the name */
- (void) strcpy(infop->gi_name, dep->d_name);
- fbrelse(fbp, S_OTHER);
- goto out;
- }
- offset += dep->d_length;
- }
- fbrelse(fbp, S_OTHER);
- fbp = NULL;
- blockoff += MAXBSIZE;
-
- }
-out:
- if (cp)
- VN_RELE(CTOV(cp));
- if (dcp)
- VN_RELE(CTOV(dcp));
- return (error);
-}
-
-/*
- * Given a file number, this functions returns the fid
- * for the back file system.
- * Returns ENOENT if file does not exist.
- * Returns ENOMSG if fid is not valid, ie: local file.
- */
-int
-cachefs_io_cidtofid(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cnode_t *cp = NULL;
- int error;
- cfs_cid_t *cidp = (cfs_cid_t *)dinp;
- cfs_fid_t *fidp = (cfs_fid_t *)doutp;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* get the cnode for the file */
- error = cachefs_cnode_make(cidp, fscp, NULL, NULL, NULL, kcred, 0, &cp);
- if (error)
- goto out;
-
- /* if local file, fid is a local fid and is not valid */
- if (cp->c_id.cid_flags & CFS_CID_LOCAL) {
- error = ENOMSG;
- goto out;
- }
-
- /* copy out the fid */
- CACHEFS_FID_COPY(&cp->c_cookie, fidp);
-
-out:
- if (cp)
- VN_RELE(CTOV(cp));
- return (error);
-}
-
-/*
- * This performs a getattr on the back file system given
- * a fid that is passed in.
- *
- * The backfid is in gafid->cg_backfid, the creds to use for
- * this operation are in gafid->cg_cred. The attributes are
- * returned in gafid->cg_attr
- *
- * the error returned is 0 if successful, nozero if not
- */
-int
-cachefs_io_getattrfid(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *backvp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- cred_t *cr;
- cachefsio_getattrfid_t *gafid;
- fid_t *tmpfidp;
- vattr_t *tmpvap;
- cfs_vattr_t *attrp;
- CACHEFS_DECL(fid_t, tmpfid);
- CACHEFS_DECL(vattr_t, va);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- gafid = (cachefsio_getattrfid_t *)dinp;
- attrp = (cfs_vattr_t *)doutp;
-
- /* Get a vnode for the back file */
- CACHEFS_TMPPTR_SET(&gafid->cg_backfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&gafid->cg_backfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &backvp, tmpfidp);
- if (error)
- return (error);
-
- cr = conj_cred(&gafid->cg_cred);
- CACHEFS_TMPPTR_SET(attrp, &va, tmpvap, vattr_t);
- tmpvap->va_mask = AT_ALL;
- error = VOP_GETATTR(backvp, tmpvap, 0, cr, NULL);
- CACHEFS_VATTR_COPYOUT(tmpvap, attrp, error);
- crfree(cr);
-
- /* VFS_VGET performs a VN_HOLD on the vp */
- VN_RELE(backvp);
-
- return (error);
-}
-
-
-/*
- * This performs a getattr on the back file system. Instead of
- * passing the fid to perform the gettr on we are given the
- * parent directory fid and a name.
- */
-int
-cachefs_io_getattrname(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *pbackvp = NULL;
- vnode_t *cbackvp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- cred_t *cr;
- fid_t *tmpfidp;
- vattr_t *tmpvap;
- cachefsio_getattrname_arg_t *gap;
- cachefsio_getattrname_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
- CACHEFS_DECL(vattr_t, va);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- gap = (cachefsio_getattrname_arg_t *)dinp;
- retp = (cachefsio_getattrname_return_t *)doutp;
-
- /* Get a vnode for the parent directory */
- CACHEFS_TMPPTR_SET(&gap->cg_dir, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&gap->cg_dir, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &pbackvp, tmpfidp);
- if (error)
- return (error);
-
- /* lookup the file name */
- cr = conj_cred(&gap->cg_cred);
- error = VOP_LOOKUP(pbackvp, gap->cg_name, &cbackvp,
- (struct pathname *)NULL, 0, (vnode_t *)NULL, cr, NULL, NULL, NULL);
- if (error) {
- crfree(cr);
- VN_RELE(pbackvp);
- return (error);
- }
-
- CACHEFS_TMPPTR_SET(&retp->cg_attr, &va, tmpvap, vattr_t);
- tmpvap->va_mask = AT_ALL;
- error = VOP_GETATTR(cbackvp, tmpvap, 0, cr, NULL);
- CACHEFS_VATTR_COPYOUT(tmpvap, &retp->cg_attr, error);
- if (!error) {
- CACHEFS_TMPPTR_SET(&retp->cg_fid, &tmpfid, tmpfidp, fid_t);
- tmpfidp->fid_len = MAXFIDSZ;
- error = VOP_FID(cbackvp, tmpfidp, NULL);
- CACHEFS_FID_COPYOUT(tmpfidp, &retp->cg_fid);
- }
-
- crfree(cr);
- VN_RELE(cbackvp);
- VN_RELE(pbackvp);
- return (error);
-}
-
-/*
- * This will return the fid of the root of this mount point.
- */
-int
-/*ARGSUSED*/
-cachefs_io_rootfid(vnode_t *vp, void *dinp, void *doutp)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- cfs_fid_t *rootfid = (cfs_fid_t *)doutp;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- CACHEFS_FID_COPY(&VTOC(fscp->fs_rootvp)->c_metadata.md_cookie, rootfid);
- return (0);
-}
-
-/*
- * Pushes the data associated with a file back to the file server.
- */
-int
-cachefs_io_pushback(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *backvp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- caddr_t buffer = NULL;
- int error = 0;
- cnode_t *cp;
- size_t amt;
- u_offset_t size;
- vattr_t va;
- offset_t off;
- cred_t *cr = NULL;
- fid_t *tmpfidp;
- cachefsio_pushback_arg_t *pbp;
- cachefsio_pushback_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- pbp = (cachefsio_pushback_arg_t *)dinp;
- retp = (cachefsio_pushback_return_t *)doutp;
-
- cr = conj_cred(&pbp->pb_cred);
-
- /* get the backvp to push to */
- CACHEFS_TMPPTR_SET(&pbp->pb_fid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&pbp->pb_fid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &backvp, tmpfidp);
- if (error) {
- backvp = NULL;
- goto out;
- }
-
- /* Get the cnode for the file we are to push back */
- error = cachefs_cnode_make(&pbp->pb_cid, fscp,
- NULL, NULL, NULL, cr, 0, &cp);
- if (error) {
- goto out;
- }
-
- /* must be a regular file */
- if (cp->c_attr.va_type != VREG) {
- error = EINVAL;
- goto out;
- }
-
- mutex_enter(&cp->c_statelock);
-
- /* get the front file */
- if (cp->c_frontvp == NULL) {
- error = cachefs_getfrontfile(cp);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
- }
-
- /* better be populated */
- if ((cp->c_metadata.md_flags & MD_POPULATED) == 0) {
- mutex_exit(&cp->c_statelock);
- error = EINVAL;
- goto out;
- }
-
- /* do open so NFS gets correct creds on writes */
- error = VOP_OPEN(&backvp, FWRITE, cr, NULL);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- buffer = cachefs_kmem_alloc(MAXBSIZE, KM_SLEEP);
-
- /* Read the data from the cache and write it to the server */
- /* XXX why not use segmapio? */
- off = 0;
- for (size = cp->c_size; size != 0; size -= amt) {
- if (size > MAXBSIZE)
- amt = MAXBSIZE;
- else
- amt = size;
-
- /* read a block of data from the front file */
- error = vn_rdwr(UIO_READ, cp->c_frontvp, buffer,
- amt, off, UIO_SYSSPACE, 0, RLIM_INFINITY, cr, 0);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- /* write the block of data to the back file */
- error = vn_rdwr(UIO_WRITE, backvp, buffer, amt, off,
- UIO_SYSSPACE, 0, RLIM_INFINITY, cr, 0);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
- off += amt;
- }
-
- error = VOP_FSYNC(backvp, FSYNC, cr, NULL);
- if (error == 0)
- error = VOP_CLOSE(backvp, FWRITE, 1, (offset_t)0, cr, NULL);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- cp->c_metadata.md_flags |= MD_PUSHDONE;
- cp->c_metadata.md_flags &= ~MD_PUTPAGE;
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-
- /*
- * if we have successfully stored the data, we need the
- * new ctime and mtimes.
- */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(backvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->pb_ctime, error);
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_mtime, &retp->pb_mtime, error);
-
-out:
- if (buffer)
- cachefs_kmem_free(buffer, MAXBSIZE);
- if (cp)
- VN_RELE(CTOV(cp));
- if (backvp)
- VN_RELE(backvp);
- if (cr)
- crfree(cr);
- return (error);
-}
-
-/*
- * Create a file on the back file system.
- */
-int
-cachefs_io_create(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- vnode_t *cvp = NULL;
- cnode_t *cp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- vattr_t va, *tmpvap;
- int error = 0;
- cred_t *cr = NULL;
- fid_t *tmpfidp;
- cachefsio_create_arg_t *crp;
- cachefsio_create_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- crp = (cachefsio_create_arg_t *)dinp;
- retp = (cachefsio_create_return_t *)doutp;
-
- /* get a vnode for the parent directory */
- CACHEFS_TMPPTR_SET(&crp->cr_backfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&crp->cr_backfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, tmpfidp);
- if (error)
- goto out;
-
- cr = conj_cred(&crp->cr_cred);
-
- /* do the create */
- CACHEFS_TMPPTR_SET(&crp->cr_va, &va, tmpvap, vattr_t);
- CACHEFS_VATTR_COPYIN(&crp->cr_va, tmpvap);
- error = VOP_CREATE(dvp, crp->cr_name, tmpvap,
- crp->cr_exclusive, crp->cr_mode, &cvp, cr, 0, NULL, NULL);
- if (error)
- goto out;
-
- /* get the fid of the file */
- CACHEFS_TMPPTR_SET(&retp->cr_newfid, &tmpfid, tmpfidp, fid_t);
- tmpfidp->fid_len = MAXFIDSZ;
- error = VOP_FID(cvp, tmpfidp, NULL);
- if (error)
- goto out;
- CACHEFS_FID_COPYOUT(tmpfidp, &retp->cr_newfid);
-
- /* get attributes for the file */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->cr_ctime, error);
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_mtime, &retp->cr_mtime, error);
- if (error)
- goto out;
-
- /* update the cnode for this file with the new info */
- error = cachefs_cnode_make(&crp->cr_cid, fscp,
- NULL, NULL, NULL, cr, 0, &cp);
- if (error) {
- error = 0;
- goto out;
- }
-
- mutex_enter(&cp->c_statelock);
- ASSERT(cp->c_id.cid_flags & CFS_CID_LOCAL);
- cp->c_attr.va_nodeid = va.va_nodeid;
- cp->c_metadata.md_flags |= MD_CREATEDONE;
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_metadata.md_cookie = *tmpfidp;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-
-out:
- if (cr)
- crfree(cr);
- if (dvp)
- VN_RELE(dvp);
- if (cvp)
- VN_RELE(cvp);
- if (cp)
- VN_RELE(CTOV(cp));
- return (error);
-}
-
-/*
- * Remove a file on the back file system.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_remove(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- vnode_t *cvp;
- cred_t *cr = NULL;
- vattr_t va;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error;
- fid_t child_fid, *child_fidp;
- cachefsio_remove_t *rmp = (cachefsio_remove_t *)dinp;
- cfs_timestruc_t *ctimep = (cfs_timestruc_t *)doutp;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* Get a vnode for the directory */
- CACHEFS_TMPPTR_SET(&rmp->rm_fid, &child_fid, child_fidp, fid_t);
- CACHEFS_FID_COPYIN(&rmp->rm_fid, child_fidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, child_fidp);
- if (error) {
- dvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&rmp->rm_cred);
-
- /* if the caller wants the ctime after the remove */
- if (ctimep) {
- error = VOP_LOOKUP(dvp, rmp->rm_name, &cvp, NULL, 0, NULL, cr,
- NULL, NULL, NULL);
- if (error == 0) {
- child_fid.fid_len = MAXFIDSZ;
- error = VOP_FID(cvp, &child_fid, NULL);
- VN_RELE(cvp);
- }
- if (error)
- goto out;
- }
-
- /* do the remove */
- error = VOP_REMOVE(dvp, rmp->rm_name, cr, NULL, 0);
- if (error)
- goto out;
-
- /* get the new ctime if requested */
- if (ctimep) {
- error = VFS_VGET(fscp->fs_backvfsp, &cvp, &child_fid);
- if (error == 0) {
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error == 0) {
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime,
- ctimep, error);
- }
- VN_RELE(cvp);
- }
- cachefs_iosetneedattrs(fscp, &rmp->rm_cid);
- }
-
-out:
- if (cr)
- crfree(cr);
- if (dvp)
- VN_RELE(dvp);
- return (error);
-}
-
-/*
- * Perform a link on the back file system.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_link(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- vnode_t *lvp = NULL;
- vattr_t va;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- cred_t *cr = NULL;
- fid_t *tmpfidp;
- cachefsio_link_t *linkp = (cachefsio_link_t *)dinp;
- cfs_timestruc_t *ctimep = (cfs_timestruc_t *)doutp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* Get a vnode parent directory */
- CACHEFS_TMPPTR_SET(&linkp->ln_dirfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&linkp->ln_dirfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, tmpfidp);
- if (error) {
- dvp = NULL;
- goto out;
- }
-
- /* Get a vnode file to link to */
- CACHEFS_TMPPTR_SET(&linkp->ln_filefid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&linkp->ln_filefid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &lvp, tmpfidp);
- if (error) {
- lvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&linkp->ln_cred);
-
- /* do the link */
- error = VOP_LINK(dvp, lvp, linkp->ln_name, cr, NULL, 0);
- if (error)
- goto out;
-
- /* get the ctime */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(lvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, ctimep, error);
- if (error)
- goto out;
-
- cachefs_iosetneedattrs(fscp, &linkp->ln_cid);
-out:
- if (cr)
- crfree(cr);
- if (dvp)
- VN_RELE(dvp);
- if (lvp)
- VN_RELE(lvp);
- return (error);
-}
-
-/*
- * Rename the file on the back file system.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_rename(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *odvp = NULL;
- vnode_t *ndvp = NULL;
- cred_t *cr = NULL;
- vnode_t *cvp = NULL;
- vattr_t va;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- fid_t child_fid, *child_fidp;
- cachefsio_rename_arg_t *rnp;
- cachefsio_rename_return_t *retp;
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- rnp = (cachefsio_rename_arg_t *)dinp;
- retp = (cachefsio_rename_return_t *)doutp;
-
- /* Get vnode of old parent directory */
- CACHEFS_TMPPTR_SET(&rnp->rn_olddir, &child_fid, child_fidp, fid_t);
- CACHEFS_FID_COPYIN(&rnp->rn_olddir, child_fidp);
- error = VFS_VGET(fscp->fs_backvfsp, &odvp, child_fidp);
- if (error) {
- odvp = NULL;
- goto out;
- }
-
- /* Get vnode of new parent directory */
- CACHEFS_TMPPTR_SET(&rnp->rn_newdir, &child_fid, child_fidp, fid_t);
- CACHEFS_FID_COPYIN(&rnp->rn_newdir, child_fidp);
- error = VFS_VGET(fscp->fs_backvfsp, &ndvp, child_fidp);
- if (error) {
- ndvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&rnp->rn_cred);
-
- /* if the caller wants the ctime of the target after deletion */
- if (rnp->rn_del_getctime) {
- error = VOP_LOOKUP(ndvp, rnp->rn_newname, &cvp, NULL, 0,
- NULL, cr, NULL, NULL, NULL);
- if (error) {
- cvp = NULL; /* paranoia */
- goto out;
- }
-
- child_fid.fid_len = MAXFIDSZ;
- error = VOP_FID(cvp, &child_fid, NULL);
- if (error)
- goto out;
- VN_RELE(cvp);
- cvp = NULL;
- }
-
- /* do the rename */
- error = VOP_RENAME(odvp, rnp->rn_oldname, ndvp, rnp->rn_newname, cr,
- NULL, 0);
- if (error)
- goto out;
-
- /* get the new ctime on the renamed file */
- error = VOP_LOOKUP(ndvp, rnp->rn_newname, &cvp, NULL, 0, NULL, cr,
- NULL, NULL, NULL);
- if (error)
- goto out;
-
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->rn_ctime, error);
- VN_RELE(cvp);
- cvp = NULL;
- if (error)
- goto out;
-
- cachefs_iosetneedattrs(fscp, &rnp->rn_cid);
-
- /* get the new ctime if requested of the deleted target */
- if (rnp->rn_del_getctime) {
- error = VFS_VGET(fscp->fs_backvfsp, &cvp, &child_fid);
- if (error) {
- cvp = NULL;
- goto out;
- }
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->rn_del_ctime,
- error);
- VN_RELE(cvp);
- cvp = NULL;
- if (error)
- goto out;
- cachefs_iosetneedattrs(fscp, &rnp->rn_del_cid);
- }
-
-out:
- if (cr)
- crfree(cr);
- if (cvp)
- VN_RELE(cvp);
- if (odvp)
- VN_RELE(odvp);
- if (ndvp)
- VN_RELE(ndvp);
- return (error);
-}
-
-/*
- * Make a directory on the backfs.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_mkdir(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- vnode_t *cvp = NULL;
- cnode_t *cp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error = 0;
- cred_t *cr = NULL;
- fid_t *tmpfidp;
- vattr_t va, *tmpvap;
- cachefsio_mkdir_t *mdirp = (cachefsio_mkdir_t *)dinp;
- cfs_fid_t *fidp = (cfs_fid_t *)doutp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* Get vnode of parent directory */
- CACHEFS_TMPPTR_SET(&mdirp->md_dirfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&mdirp->md_dirfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, tmpfidp);
- if (error) {
- dvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&mdirp->md_cred);
-
- /* make the directory */
- CACHEFS_TMPPTR_SET(&mdirp->md_vattr, &va, tmpvap, vattr_t);
- CACHEFS_VATTR_COPYIN(&mdirp->md_vattr, tmpvap);
- error = VOP_MKDIR(dvp, mdirp->md_name, tmpvap, &cvp, cr, NULL, 0, NULL);
- if (error) {
- if (error != EEXIST)
- goto out;
-
- /* if the directory already exists, then use it */
- error = VOP_LOOKUP(dvp, mdirp->md_name, &cvp,
- NULL, 0, NULL, cr, NULL, NULL, NULL);
- if (error) {
- cvp = NULL;
- goto out;
- }
- if (cvp->v_type != VDIR) {
- error = EINVAL;
- goto out;
- }
- }
-
- /* get the fid of the directory */
- CACHEFS_TMPPTR_SET(fidp, &tmpfid, tmpfidp, fid_t);
- tmpfidp->fid_len = MAXFIDSZ;
- error = VOP_FID(cvp, tmpfidp, NULL);
- if (error)
- goto out;
- CACHEFS_FID_COPYOUT(tmpfidp, fidp);
-
- /* get attributes of the directory */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error)
- goto out;
-
- /* update the cnode for this dir with the new fid */
- error = cachefs_cnode_make(&mdirp->md_cid, fscp,
- NULL, NULL, NULL, cr, 0, &cp);
- if (error) {
- error = 0;
- goto out;
- }
- mutex_enter(&cp->c_statelock);
- ASSERT(cp->c_id.cid_flags & CFS_CID_LOCAL);
- cp->c_metadata.md_cookie = *tmpfidp;
- cp->c_metadata.md_flags |= MD_CREATEDONE;
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_attr.va_nodeid = va.va_nodeid;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-out:
- if (cr)
- crfree(cr);
- if (dvp)
- VN_RELE(dvp);
- if (cvp)
- VN_RELE(cvp);
- if (cp)
- VN_RELE(CTOV(cp));
- return (error);
-}
-
-/*
- * Perform a rmdir on the back file system.
- * Returns 0 or an error if could not perform operation.
- */
-int
-/*ARGSUSED*/
-cachefs_io_rmdir(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- int error;
- cred_t *cr;
- fid_t *tmpfidp;
- cachefsio_rmdir_t *rdp = (cachefsio_rmdir_t *)dinp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* Get a vnode for the back file */
- CACHEFS_TMPPTR_SET(&rdp->rd_dirfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&rdp->rd_dirfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, tmpfidp);
- if (error) {
- dvp = NULL;
- return (error);
- }
-
- cr = conj_cred(&rdp->rd_cred);
- error = VOP_RMDIR(dvp, rdp->rd_name, dvp, cr, NULL, 0);
- crfree(cr);
-
- VN_RELE(dvp);
- return (error);
-}
-
-/*
- * create a symlink on the back file system
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_symlink(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *dvp = NULL;
- vnode_t *svp = NULL;
- cnode_t *cp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- fid_t *tmpfidp;
- vattr_t va, *tmpvap;
- int error = 0;
- cred_t *cr = NULL;
- cachefsio_symlink_arg_t *symp;
- cachefsio_symlink_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- symp = (cachefsio_symlink_arg_t *)dinp;
- retp = (cachefsio_symlink_return_t *)doutp;
-
- /* get a vnode for the back directory */
- CACHEFS_TMPPTR_SET(&symp->sy_dirfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&symp->sy_dirfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &dvp, tmpfidp);
- if (error) {
- dvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&symp->sy_cred);
-
- /* create the symlink */
- CACHEFS_TMPPTR_SET(&symp->sy_vattr, &va, tmpvap, vattr_t);
- CACHEFS_VATTR_COPYIN(&symp->sy_vattr, tmpvap);
- error = VOP_SYMLINK(dvp, symp->sy_name, tmpvap,
- symp->sy_link, cr, NULL, 0);
- if (error)
- goto out;
-
- /* get the vnode for the symlink */
- error = VOP_LOOKUP(dvp, symp->sy_name, &svp, NULL, 0, NULL, cr,
- NULL, NULL, NULL);
- if (error)
- goto out;
-
- /* get the attributes of the symlink */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(svp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->sy_ctime, error);
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_mtime, &retp->sy_mtime, error);
- if (error)
- goto out;
-
- /* get the fid */
- CACHEFS_TMPPTR_SET(&retp->sy_newfid, &tmpfid, tmpfidp, fid_t);
- tmpfidp->fid_len = MAXFIDSZ;
- error = VOP_FID(svp, tmpfidp, NULL);
- if (error)
- goto out;
- CACHEFS_FID_COPYOUT(tmpfidp, &retp->sy_newfid);
-
- /* update the cnode for this file with the new info */
- error = cachefs_cnode_make(&symp->sy_cid, fscp,
- NULL, NULL, NULL, cr, 0, &cp);
- if (error) {
- error = 0;
- goto out;
- }
- mutex_enter(&cp->c_statelock);
- ASSERT(cp->c_id.cid_flags & CFS_CID_LOCAL);
- cp->c_metadata.md_cookie = *tmpfidp;
- cp->c_metadata.md_flags |= MD_CREATEDONE;
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_attr.va_nodeid = va.va_nodeid;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-
-out:
- if (cr)
- crfree(cr);
- if (dvp)
- VN_RELE(dvp);
- if (svp)
- VN_RELE(svp);
- if (cp)
- VN_RELE(CTOV(cp));
- return (error);
-}
-
-/*
- * Perform setattr on the back file system.
- * Returns 0 or an error if could not perform operation.
- */
-int
-cachefs_io_setattr(vnode_t *vp, void *dinp, void *doutp)
-{
- vnode_t *cvp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- fid_t *tmpfidp;
- vattr_t va, *tmpvap;
- int error = 0;
- cred_t *cr = NULL;
- cachefsio_setattr_arg_t *sap;
- cachefsio_setattr_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- sap = (cachefsio_setattr_arg_t *)dinp;
- retp = (cachefsio_setattr_return_t *)doutp;
-
- /* get a vnode for the back directory */
- CACHEFS_TMPPTR_SET(&sap->sa_backfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&sap->sa_backfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &cvp, tmpfidp);
- if (error) {
- cvp = NULL;
- goto out;
- }
-
- cr = conj_cred(&sap->sa_cred);
-
- /* perform the setattr */
- CACHEFS_TMPPTR_SET(&sap->sa_vattr, &va, tmpvap, vattr_t);
- CACHEFS_VATTR_COPYIN(&sap->sa_vattr, tmpvap);
- error = VOP_SETATTR(cvp, tmpvap, 0, cr, NULL);
- if (error)
- goto out;
-
- /* get the new ctime and mtime */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(cvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->sa_ctime, error);
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_mtime, &retp->sa_mtime, error);
- if (error)
- goto out;
-
- cachefs_iosetneedattrs(fscp, &sap->sa_cid);
-out:
- if (cr)
- crfree(cr);
- if (cvp)
- VN_RELE(cvp);
- return (error);
-}
-
-int
-cachefs_io_setsecattr(vnode_t *vp, void *dinp, void *doutp)
-{
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
- vnode_t *tvp = NULL;
- vsecattr_t vsec;
- vattr_t va;
- cred_t *cr = NULL;
- fid_t *tmpfidp;
- cachefsio_setsecattr_arg_t *ssap;
- cachefsio_setsecattr_return_t *retp;
- CACHEFS_DECL(fid_t, tmpfid);
-
- /*
- * Only called in support of disconnectable operation, so assert
- * that this is not called when NFSv4 is the backfilesytem.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- ssap = (cachefsio_setsecattr_arg_t *)dinp;
- retp = (cachefsio_setsecattr_return_t *)doutp;
-
- /* get vnode of back file to do VOP_SETSECATTR to */
- CACHEFS_TMPPTR_SET(&ssap->sc_backfid, &tmpfid, tmpfidp, fid_t);
- CACHEFS_FID_COPYIN(&ssap->sc_backfid, tmpfidp);
- error = VFS_VGET(fscp->fs_backvfsp, &tvp, tmpfidp);
- if (error != 0) {
- tvp = NULL;
- goto out;
- }
-
- /* get the creds */
- cr = conj_cred(&ssap->sc_cred);
-
- /* form the vsecattr_t */
- vsec.vsa_mask = ssap->sc_mask;
- vsec.vsa_aclcnt = ssap->sc_aclcnt;
- vsec.vsa_dfaclcnt = ssap->sc_dfaclcnt;
- vsec.vsa_aclentp = ssap->sc_acl;
- vsec.vsa_dfaclentp = ssap->sc_acl + ssap->sc_aclcnt;
-
- /* set the ACL */
- (void) VOP_RWLOCK(tvp, V_WRITELOCK_TRUE, NULL);
- error = VOP_SETSECATTR(tvp, &vsec, 0, cr, NULL);
- VOP_RWUNLOCK(tvp, V_WRITELOCK_TRUE, NULL);
- if (error != 0)
- goto out;
-
- /* get the new ctime and mtime */
- va.va_mask = AT_ALL;
- error = VOP_GETATTR(tvp, &va, 0, cr, NULL);
- if (error)
- goto out;
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_ctime, &retp->sc_ctime, error);
- CACHEFS_TS_TO_CFS_TS_COPY(&va.va_mtime, &retp->sc_mtime, error);
- if (error)
- goto out;
-
- cachefs_iosetneedattrs(fscp, &ssap->sc_cid);
-out:
-
- if (cr != NULL)
- crfree(cr);
- if (tvp != NULL)
- VN_RELE(tvp);
-
- return (error);
-}
-
-static void
-sync_metadata(cnode_t *cp)
-{
- if (cp->c_flags & (CN_STALE | CN_DESTROY))
- return;
- (void) cachefs_sync_metadata(cp);
-}
-
-static void
-drop_backvp(cnode_t *cp)
-{
- if (cp->c_backvp) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- /* dump any pages, may be a dirty one */
- (void) VOP_PUTPAGE(cp->c_backvp, (offset_t)0, 0,
- B_INVAL | B_TRUNC, kcred, NULL);
- }
- mutex_exit(&cp->c_statelock);
- }
-}
-
-static void
-allow_pendrm(cnode_t *cp)
-{
- if (cp->c_flags & CN_PENDRM) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_flags & CN_PENDRM) {
- cp->c_flags &= ~CN_PENDRM;
- VN_RELE(CTOV(cp));
- }
- mutex_exit(&cp->c_statelock);
- }
-}
-
-static void
-cachefs_modified_fix(fscache_t *fscp)
-{
- cnode_t *cp;
- int error = 0;
- rl_entry_t rl_ent;
- cfs_cid_t cid;
- cachefscache_t *cachep = fscp->fs_cache;
- enum cachefs_rl_type type;
- cachefs_metadata_t *mdp;
- int timedout = 0;
- struct vattr va;
-
- /* XXX just return if fs is in error ro mode */
-
- /* lock out other users of the MF list */
- mutex_enter(&cachep->c_mflock);
-
- /* move the modified entries for this file system to the MF list */
- cachefs_move_modified_to_mf(cachep, fscp);
-
- rl_ent.rl_current = CACHEFS_RL_MF;
- for (;;) {
- /* get the next entry on the MF list */
- error = cachefs_rlent_data(cachep, &rl_ent, NULL);
- if (error) {
- error = 0;
- break;
- }
- ASSERT(fscp->fs_cfsid == rl_ent.rl_fsid);
-
- /* get the cnode for the file */
- cid.cid_fileno = rl_ent.rl_fileno;
- cid.cid_flags = rl_ent.rl_local ? CFS_CID_LOCAL : 0;
- error = cachefs_cnode_make(&cid, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_IOCTL)
- printf("cachefs: mf: could not find %llu\n",
- (u_longlong_t)cid.cid_fileno);
- delay(5*hz);
-#endif
- /* XXX this will loop forever, maybe put fs in */
- /* ro mode */
- continue;
- }
-
- mutex_enter(&cp->c_statelock);
-
- mdp = &cp->c_metadata;
-
- /* if a regular file that has not been pushed */
- if ((cp->c_attr.va_type == VREG) &&
- (((mdp->md_flags & (MD_PUSHDONE | MD_PUTPAGE)) ==
- MD_PUTPAGE))) {
- /* move the file to lost+found */
- error = cachefs_cnode_lostfound(cp, NULL);
- if (error) {
- /* XXX put fs in ro mode */
- /* XXX need to drain MF list */
- panic("lostfound failed %d", error);
- }
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- continue;
- }
-
- /* if a local file */
- if (cp->c_id.cid_flags & CFS_CID_LOCAL) {
- /* if the file was not created */
- if ((cp->c_metadata.md_flags & MD_CREATEDONE) == 0) {
- /* do not allow cnode to be used */
- cachefs_cnode_stale(cp);
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- continue;
- }
-
- /* save the local fileno for later getattrs */
- mdp->md_localfileno = cp->c_id.cid_fileno;
- mutex_exit(&cp->c_statelock);
-
- /* register the mapping from old to new fileno */
- mutex_enter(&fscp->fs_fslock);
- cachefs_inum_register(fscp, cp->c_attr.va_nodeid,
- mdp->md_localfileno);
- cachefs_inum_register(fscp, mdp->md_localfileno, 0);
- mutex_exit(&fscp->fs_fslock);
-
- /* move to new location in the cache */
- cachefs_cnode_move(cp);
- mutex_enter(&cp->c_statelock);
- }
-
- /* else if a modified file that needs to have its mode fixed */
- else if ((cp->c_metadata.md_flags & MD_FILE) &&
- (cp->c_attr.va_type == VREG)) {
-
- if (cp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(cp);
- if (cp->c_frontvp) {
- /* mark file as no longer modified */
- va.va_mode = 0666;
- va.va_mask = AT_MODE;
- error = VOP_SETATTR(cp->c_frontvp, &va,
- 0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN,
- "Cannot change ff mode.\n");
- }
- }
- }
-
-
- /* if there is a rl entry, put it on the correct list */
- if (mdp->md_rlno) {
- if (mdp->md_flags & MD_PACKED) {
- if ((mdp->md_flags & MD_POPULATED) ||
- ((mdp->md_flags & MD_FILE) == 0))
- type = CACHEFS_RL_PACKED;
- else
- type = CACHEFS_RL_PACKED_PENDING;
- cachefs_rlent_moveto(fscp->fs_cache, type,
- mdp->md_rlno, mdp->md_frontblks);
- mdp->md_rltype = type;
- } else if (mdp->md_flags & MD_FILE) {
- type = CACHEFS_RL_ACTIVE;
- cachefs_rlent_moveto(fscp->fs_cache, type,
- mdp->md_rlno, mdp->md_frontblks);
- mdp->md_rltype = type;
- } else {
- type = CACHEFS_RL_FREE;
- cachefs_rlent_moveto(fscp->fs_cache, type,
- mdp->md_rlno, 0);
- filegrp_ffrele(cp->c_filegrp);
- mdp->md_rlno = 0;
- mdp->md_rltype = CACHEFS_RL_NONE;
- }
- }
- mdp->md_flags &= ~(MD_CREATEDONE | MD_PUTPAGE |
- MD_PUSHDONE | MD_MAPPING);
-
- /* if a directory, populate it */
- if (CTOV(cp)->v_type == VDIR) {
- /* XXX hack for now */
- mdp->md_flags |= MD_INVALREADDIR;
- dnlc_purge_vp(CTOV(cp));
-
- mdp->md_flags |= MD_NEEDATTRS;
- }
-
- if (!timedout) {
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, kcred);
- if (CFS_TIMEOUT(fscp, error))
- timedout = 1;
- else if ((error == 0) &&
- ((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0)) {
- if (cachefs_vtype_aclok(CTOV(cp)) &&
- ((cp->c_flags & CN_NOCACHE) == 0))
- (void) cachefs_cacheacl(cp, NULL);
- }
- }
-
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
- VN_RELE(CTOV(cp));
- }
- mutex_exit(&cachep->c_mflock);
-}
-
-void
-cachefs_inum_register(fscache_t *fscp, ino64_t real, ino64_t fake)
-{
- cachefs_inum_trans_t *tbl;
- int toff, thop;
- int i;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- /*
- * first, see if an empty slot exists.
- */
-
- for (i = 0; i < fscp->fs_inum_size; i++)
- if (fscp->fs_inum_trans[i].cit_real == 0)
- break;
-
- /*
- * if there are no empty slots, try to grow the table.
- */
-
- if (i >= fscp->fs_inum_size) {
- cachefs_inum_trans_t *oldtbl;
- int oldsize, newsize = 0;
-
- /*
- * try to fetch a new table size that's bigger than
- * our current size
- */
-
- for (i = 0; cachefs_hash_sizes[i] != 0; i++)
- if (cachefs_hash_sizes[i] > fscp->fs_inum_size) {
- newsize = cachefs_hash_sizes[i];
- break;
- }
-
- /*
- * if we're out of larger twin-primes, give up. thus,
- * the inode numbers in some directory entries might
- * change at reconnect, and disagree with what stat()
- * says. this isn't worth panicing over, but it does
- * merit a warning message.
- */
- if (newsize == 0) {
- /* only print hash table warning once */
- if ((fscp->fs_flags & CFS_FS_HASHPRINT) == 0) {
- cmn_err(CE_WARN,
- "cachefs: inode hash table full\n");
- fscp->fs_flags |= CFS_FS_HASHPRINT;
- }
- return;
- }
-
- /* set up this fscp with a new hash table */
-
- oldtbl = fscp->fs_inum_trans;
- oldsize = fscp->fs_inum_size;
- fscp->fs_inum_size = newsize;
- fscp->fs_inum_trans = (cachefs_inum_trans_t *)
- cachefs_kmem_zalloc(sizeof (cachefs_inum_trans_t) * newsize,
- KM_SLEEP);
-
- /*
- * re-insert all of the old values. this will never
- * go more than one level into recursion-land.
- */
-
- for (i = 0; i < oldsize; i++) {
- tbl = oldtbl + i;
- if (tbl->cit_real != 0) {
- cachefs_inum_register(fscp, tbl->cit_real,
- tbl->cit_fake);
- } else {
- ASSERT(0);
- }
- }
-
- if (oldsize > 0)
- cachefs_kmem_free(oldtbl, oldsize *
- sizeof (cachefs_inum_trans_t));
- }
-
- /*
- * compute values for the hash table. see ken rosen's
- * `elementary number theory and its applications' for one
- * description of double hashing.
- */
-
- toff = (int)(real % fscp->fs_inum_size);
- thop = (int)(real % (fscp->fs_inum_size - 2)) + 1;
-
- /*
- * since we know the hash table isn't full when we get here,
- * this loop shouldn't terminate except via the `break'.
- */
-
- for (i = 0; i < fscp->fs_inum_size; i++) {
- tbl = fscp->fs_inum_trans + toff;
- if ((tbl->cit_real == 0) || (tbl->cit_real == real)) {
- tbl->cit_real = real;
- tbl->cit_fake = fake;
- break;
- }
-
- toff += thop;
- toff %= fscp->fs_inum_size;
- }
- ASSERT(i < fscp->fs_inum_size);
-}
-
-/*
- * given an inode number, map it to the inode number that should be
- * put in a directory entry before its copied out.
- *
- * don't call this function unless there is a fscp->fs_inum_trans
- * table that has real entries in it!
- */
-
-ino64_t
-cachefs_inum_real2fake(fscache_t *fscp, ino64_t real)
-{
- cachefs_inum_trans_t *tbl;
- ino64_t rc = real;
- int toff, thop;
- int i;
-
- ASSERT(fscp->fs_inum_size > 0);
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- toff = (int)(real % fscp->fs_inum_size);
- thop = (int)(real % (fscp->fs_inum_size - 2)) + 1;
-
- for (i = 0; i < fscp->fs_inum_size; i++) {
- tbl = fscp->fs_inum_trans + toff;
-
- if (tbl->cit_real == 0) {
- break;
- } else if (tbl->cit_real == real) {
- rc = tbl->cit_fake;
- break;
- }
-
- toff += thop;
- toff %= fscp->fs_inum_size;
- }
-
- return (rc);
-}
-
-/*
- * Passed a cid, finds the cnode and sets the MD_NEEDATTRS bit
- * in the metadata.
- */
-static void
-cachefs_iosetneedattrs(fscache_t *fscp, cfs_cid_t *cidp)
-{
- int error;
- cnode_t *cp;
-
- error = cachefs_cnode_make(cidp, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error)
- return;
-
- mutex_enter(&cp->c_statelock);
- cp->c_metadata.md_flags |= MD_NEEDATTRS;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-
- VN_RELE(CTOV(cp));
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_log.c b/usr/src/uts/common/fs/cachefs/cachefs_log.c
deleted file mode 100644
index 76a6453ba6..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_log.c
+++ /dev/null
@@ -1,1739 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/errno.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/user.h>
-#include <sys/stat.h>
-#include <sys/kstat.h>
-#include <sys/time.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/file.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <sys/mode.h>
-#include <sys/pathname.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <sys/sysmacros.h>
-
-/*
- * ino64_t is a unsigned long on LP64 and unsigned long long on ILP32,
- * the compiler emits many warnings when calling xdr_u_longlong_t with an
- * unsigned long pointer on LP64 even though it's safe.
- */
-#define xdr_ino64(xdrs, p) xdr_u_longlong_t((xdrs), (u_longlong_t *)(p))
-
-/*
- * cfs_time_t is an int in both LP64 and ILP32. To avoid compiler warnings
- * define its xdr here explicitly
- */
-#define xdr_cfs_time_t(xdrs, p) xdr_int((xdrs), (int *)(p))
-
-#define CACHEFS_LOG_MAX_BUFFERED 65536
-#define CACHEFS_LOG_LOWATER 8192
-#define CACHEFS_LOG_ENCODE_SIZE 4096
-
-#if (defined(_SYSCALL32_IMPL) || defined(_LP64))
-
-#define OUT_IF_TIME_OVERFLOW(cachep, time) \
- if (TIME_OVERFLOW(time)) { \
- cachefs_log_error(cachep, EOVERFLOW, 1); \
- goto out; \
- }
-
-#define RET_IF_TIME_OVERFLOW(cachep, time) \
- if (TIME_OVERFLOW(time)) { \
- cachefs_log_error(cachep, EOVERFLOW, 1); \
- return; \
- }
-
-#else /* not (_SYSCALL32_IMPL || _LP64) */
-
-#define OUT_IF_TIME_OVERFLOW(cachep, time)
-
-#define RET_IF_TIME_OVERFLOW(cachep, time)
-
-#endif /* (_SYSCALL32_IMPL || _LP64) */
-
-typedef struct cachefs_log_work_list {
- void *data;
- size_t size;
- xdrproc_t translate;
- struct cachefs_log_work_list *next;
-} *cachefs_log_work_list_t;
-
-/* forward declarations of static functions */
-static void cachefs_log_enqueue(cachefscache_t *, void *, int, xdrproc_t);
-static int cachefs_log_save_lc(cachefscache_t *);
-static int cachefs_log_write_header(struct vnode *, cachefscache_t *, int);
-
-static bool_t cachefs_xdr_logfile_header(XDR *,
- struct cachefs_log_logfile_header *);
-static bool_t cachefs_xdr_mount(XDR *, struct cachefs_log_mount_record *);
-static bool_t cachefs_xdr_umount(XDR *, struct cachefs_log_umount_record *);
-static bool_t cachefs_xdr_getpage(XDR *, struct cachefs_log_getpage_record *);
-static bool_t cachefs_xdr_readdir(XDR *, struct cachefs_log_readdir_record *);
-static bool_t cachefs_xdr_readlink(XDR *,
- struct cachefs_log_readlink_record *);
-static bool_t cachefs_xdr_remove(XDR *, struct cachefs_log_remove_record *);
-static bool_t cachefs_xdr_rmdir(XDR *, struct cachefs_log_rmdir_record *);
-static bool_t cachefs_xdr_truncate(XDR *,
- struct cachefs_log_truncate_record *);
-static bool_t cachefs_xdr_putpage(XDR *, struct cachefs_log_putpage_record *);
-static bool_t cachefs_xdr_create(XDR *, struct cachefs_log_create_record *);
-static bool_t cachefs_xdr_mkdir(XDR *, struct cachefs_log_mkdir_record *);
-static bool_t cachefs_xdr_rename(XDR *, struct cachefs_log_rename_record *);
-static bool_t cachefs_xdr_symlink(XDR *, struct cachefs_log_symlink_record *);
-static bool_t cachefs_xdr_populate(XDR *,
- struct cachefs_log_populate_record *);
-static bool_t cachefs_xdr_csymlink(XDR *,
- struct cachefs_log_csymlink_record *);
-static bool_t cachefs_xdr_filldir(XDR *,
- struct cachefs_log_filldir_record *);
-static bool_t cachefs_xdr_mdcreate(XDR *,
- struct cachefs_log_mdcreate_record *);
-static bool_t cachefs_xdr_gpfront(XDR *,
- struct cachefs_log_gpfront_record *);
-static bool_t cachefs_xdr_rfdir(XDR *,
- struct cachefs_log_rfdir_record *);
-static bool_t cachefs_xdr_ualloc(XDR *,
- struct cachefs_log_ualloc_record *);
-static bool_t cachefs_xdr_calloc(XDR *,
- struct cachefs_log_calloc_record *);
-static bool_t cachefs_xdr_nocache(XDR *,
- struct cachefs_log_nocache_record *);
-
-
-extern time_t time;
-
-/*
- * cachefs_log_kstat_snapshot(kstat_t *ksp, void *buf, int rw)
- *
- * called from /dev/kstat or somesuch.
- *
- */
-
-int
-cachefs_log_kstat_snapshot(kstat_t *ksp, void *buf, int rw)
-{
- cachefs_log_control_t *lc = (cachefs_log_control_t *)ksp->ks_data;
- cachefs_log_control_t *buflc = (cachefs_log_control_t *)buf;
- cachefscache_t *cachep = (cachefscache_t *)(uintptr_t)lc->lc_cachep;
- cachefs_log_cookie_t *cl = cachep->c_log;
- int error = 0;
-
- ASSERT(MUTEX_HELD(&cachep->c_log_mutex));
-
- /* if they just want to read the kstat, get that out of the way. */
- if (rw != KSTAT_WRITE) {
- bcopy(lc, buflc, sizeof (*lc));
- return (0);
- }
-
- /* make sure they're passing us a valid control cookie */
- if ((buflc->lc_cachep != lc->lc_cachep) ||
- (buflc->lc_magic != CACHEFS_LOG_MAGIC))
- return (EIO);
-
- /*
- * if logging is currently off
- * o insist that we're being handed a logfile path
- * o set cl, and give our cachep its value
- *
- * after that, if something goes wrong, we must call
- * cachefs_log_error to clear cachep->c_log.
- */
- if (cl == NULL) {
- if (buflc->lc_path[0] == '\0')
- return (EIO);
- cl = cachep->c_log = cachefs_log_create_cookie(lc);
- if (cl == NULL) {
- cachefs_log_error(cachep, ENOMEM, 0);
- return (EIO);
- }
- }
-
- /*
- * if we're being handed an empty logpath, then they must be
- * turning off logging; also, logging must have been turned on
- * before, or else the previous paragraph would have caught
- * it.
- */
- if (buflc->lc_path[0] == '\0') {
- cachefs_log_process_queue(cachep, 0);
- cachep->c_log = NULL;
- cachefs_log_destroy_cookie(cl);
- bzero(lc, sizeof (*lc));
- lc->lc_magic = CACHEFS_LOG_MAGIC;
- lc->lc_cachep = (uint64_t)(uintptr_t)cachep;
- (void) VOP_REMOVE(cachep->c_dirvp, LOG_STATUS_NAME, kcred, NULL,
- 0);
- return (0);
- }
-
- /*
- * if we get here, we know that we're being handed a valid log
- * control cookie, and that a path is set. try to open the
- * log file, even if it's the same path, because they might
- * have removed the old log file out from under us. if it
- * really is the same file, no harm done.
- */
- if ((error = cachefs_log_logfile_open(cachep, buflc->lc_path)) != 0) {
- cachefs_log_error(cachep, error, 0);
- return (EIO);
- }
-
- /*
- * if we get here, we have a valid logfile open. we don't do
- * anything here with the bitmap of what's being logged, other
- * than copy it. we're home free!
- */
- bcopy(buflc, lc, sizeof (*lc));
- if ((error = cachefs_log_save_lc(cachep)) != 0) {
- cachefs_log_error(cachep, error, 0);
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-cachefs_log_save_lc(cachefscache_t *cachep)
-{
- cachefs_log_control_t *lc = (cachefs_log_control_t *)cachep->c_log_ctl;
- struct vnode *savevp;
- struct vattr attr;
- int error = 0;
-
- if (lc == NULL)
- return (EINVAL);
-
- attr.va_mode = S_IFREG | 0666;
- attr.va_uid = 0;
- attr.va_gid = 0;
- attr.va_type = VREG;
- attr.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
-
- if (((error = VOP_LOOKUP(cachep->c_dirvp, LOG_STATUS_NAME, &savevp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL)) != 0) &&
- ((error = VOP_CREATE(cachep->c_dirvp, LOG_STATUS_NAME, &attr, EXCL,
- 0600, &savevp, kcred, 0, NULL, NULL)) != 0))
- return (error);
- ASSERT(savevp != NULL);
- if (savevp == NULL)
- return (ENOENT);
-
- error = vn_rdwr(UIO_WRITE, savevp,
- (caddr_t)lc, sizeof (*lc),
- 0LL, UIO_SYSSPACE, FSYNC, (rlim64_t)RLIM_INFINITY, kcred, NULL);
-
- VN_RELE(savevp);
-
- return (error);
-}
-
-/*
- * cachefs_log_cookie_t *cachefs_log_create_cookie(void *)
- *
- * creates and initializes the cookie, which lives in cachep. called
- * from either a kstat write which turns on logging, or from
- * initializing cachep when a log-info-file exists.
- */
-
-cachefs_log_cookie_t *
-cachefs_log_create_cookie(cachefs_log_control_t *lc)
-{
- cachefs_log_cookie_t *rc;
-
- rc = cachefs_kmem_zalloc(sizeof (*rc), KM_NOSLEEP);
- if (rc == NULL)
- return (NULL);
-
- rc->cl_magic = CACHEFS_LOG_MAGIC;
- rc->cl_logctl = lc;
-
- return (rc);
-}
-
-/*
- * void cachefs_log_destroy_cookie(cachefs_log_cookie_t *)
- *
- * destroys the log cookie. called from cachefs_log_error, or from
- * destroying the cachep.
- *
- */
-
-void
-cachefs_log_destroy_cookie(cachefs_log_cookie_t *cl)
-{
- cachefs_log_work_list_t node, oldnode;
-
- if (cl == NULL)
- return;
-
- ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
-
- cl->cl_magic++;
- node = cl->cl_head;
- while (node != NULL) {
- cachefs_kmem_free(node->data, node->size);
- oldnode = node;
- node = node->next;
- cachefs_kmem_free(oldnode, sizeof (*oldnode));
- }
- if (cl->cl_logvp != NULL)
- VN_RELE(cl->cl_logvp);
- cachefs_kmem_free(cl, sizeof (*cl));
-}
-
-/*
- * int cachefs_log_logfile_open(cachefscache_t *, char *)
- *
- * opens the logfile, and stores the path string if its successful.
- *
- * returns an errno if one occurred.
- *
- */
-
-int
-cachefs_log_logfile_open(cachefscache_t *cachep, char *path)
-{
- cachefs_log_cookie_t *cl = cachep->c_log;
- struct vnode *newvp = NULL;
- int error = 0;
- int i;
-
- ASSERT(MUTEX_HELD(&cachep->c_log_mutex));
- ASSERT(cl != NULL);
- ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
-
- /* lookup the pathname -- it must already exist! */
- error = lookupname(path, UIO_SYSSPACE, FOLLOW, NULL, &newvp);
- if (error)
- goto out;
- ASSERT(newvp != NULL);
- if (newvp == NULL) {
- error = ENOENT; /* XXX this shouldn't happen (yeah right) */
- goto out;
- }
-
- /* easy out if we just re-opened the same logfile */
- if (cl->cl_logvp == newvp) {
- VN_RELE(newvp);
- goto out;
- }
-
- /* XXX we may change this to allow named pipes */
- if (newvp->v_type != VREG) {
- error = EINVAL;
- goto out;
- }
- if (vn_matchops(newvp, cachefs_getvnodeops())) {
- error = EINVAL;
- goto out;
- }
-
- /* write out the header */
- error = cachefs_log_write_header(newvp, cachep, 0);
- if (error)
- goto out;
-
- /* if we get here, we successfully opened the log. */
- if (cl->cl_logvp != NULL)
- VN_RELE(cl->cl_logvp);
- cl->cl_logvp = newvp;
-
- /*
- * `fake' a mount entry for each mounted cachefs filesystem.
- * this is overkill, but it's easiest and most foolproof way
- * to do things here. the user-level consumers of the logfile
- * have to expect extraneous mount entries and deal with it
- * correctly.
- */
- mutex_exit(&cachep->c_log_mutex);
- for (i = 0; i < cachefs_kstat_key_n; i++) {
- cachefs_kstat_key_t *k;
- struct vfs *vfsp;
- struct fscache *fscp;
-
- k = cachefs_kstat_key + i;
- if (! k->ks_mounted)
- continue;
-
- vfsp = (struct vfs *)(uintptr_t)k->ks_vfsp;
- fscp = VFS_TO_FSCACHE(vfsp);
- cachefs_log_mount(cachep, 0, vfsp, fscp,
- (char *)(uintptr_t)k->ks_mountpoint, UIO_SYSSPACE,
- (char *)(uintptr_t)k->ks_cacheid);
- }
- mutex_enter(&cachep->c_log_mutex);
-
-out:
- if ((error != 0) && (newvp != NULL))
- VN_RELE(newvp);
- return (error);
-}
-
-/*
- * called when an error occurred during logging. send the error to
- * syslog, invalidate the logfile, and stop logging.
- */
-
-void
-cachefs_log_error(cachefscache_t *cachep, int error, int getlock)
-{
- cachefs_log_cookie_t *cl = cachep->c_log;
- cachefs_log_control_t *lc = cachep->c_log_ctl;
- int writable = 0;
-
- ASSERT((getlock) || (MUTEX_HELD(&cachep->c_log_mutex)));
-
- if (getlock)
- mutex_enter(&cachep->c_log_mutex);
-
- if ((cachep->c_flags & (CACHE_NOCACHE | CACHE_NOFILL)) == 0)
- writable = 1;
-
- cmn_err(CE_WARN, "cachefs logging: error %d\n", error);
-
- if ((writable) && (cl != NULL) && (cl->cl_logvp != NULL))
- (void) cachefs_log_write_header(cl->cl_logvp, cachep, error);
-
- cachep->c_log = NULL;
- if (cl != NULL)
- cachefs_log_destroy_cookie(cl);
- bzero(lc, sizeof (cachefs_log_control_t));
- lc->lc_magic = CACHEFS_LOG_MAGIC;
- lc->lc_cachep = (uint64_t)(uintptr_t)cachep;
- if (writable)
- (void) VOP_REMOVE(cachep->c_dirvp, LOG_STATUS_NAME, kcred, NULL,
- 0);
-
- if (getlock)
- mutex_exit(&cachep->c_log_mutex);
-}
-
-static int
-cachefs_log_write_header(struct vnode *vp, cachefscache_t *cachep, int error)
-{
- struct cachefs_log_logfile_header header, oheader;
- char buffy[2 * sizeof (header)];
- int Errno = 0;
- struct vattr attr;
- int gotold = 0;
- XDR xdrm;
-
- attr.va_mask = AT_SIZE;
- if ((error = VOP_GETATTR(vp, &attr, 0, kcred, NULL)) != 0)
- goto out;
- if (attr.va_size != 0) {
- error = vn_rdwr(UIO_READ, vp, buffy,
- MIN(sizeof (buffy), attr.va_size),
- 0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
- if (error != 0)
- goto out;
-
- xdrm.x_ops = NULL;
- xdrmem_create(&xdrm, buffy, sizeof (buffy), XDR_DECODE);
- if ((xdrm.x_ops == NULL) ||
- (! cachefs_xdr_logfile_header(&xdrm, &oheader))) {
- if (xdrm.x_ops != NULL)
- xdr_destroy(&xdrm);
- error = EINVAL;
- goto out;
- }
- xdr_destroy(&xdrm);
- gotold = 1;
-
- if (oheader.lh_magic != CACHEFS_LOG_MAGIC) {
- error = EINVAL;
- goto out;
- }
- }
-
- xdrm.x_ops = NULL;
-
- xdrmem_create(&xdrm, buffy, sizeof (buffy), XDR_ENCODE);
-
- if (gotold) {
- header = oheader;
- } else {
- header.lh_magic = CACHEFS_LOG_MAGIC;
- header.lh_revision = CACHEFS_LOG_FILE_REV;
- header.lh_blocks = cachep->c_usage.cu_blksused;
- header.lh_files = cachep->c_usage.cu_filesused;
- header.lh_maxbsize = MAXBSIZE;
- header.lh_pagesize = PAGESIZE;
- }
-
- /* these are things that we stomp over for every header write */
- header.lh_errno = Errno;
-
- if (! cachefs_xdr_logfile_header(&xdrm, &header)) {
- error = ENOMEM;
- goto out;
- }
-
- error = vn_rdwr(UIO_WRITE, vp,
- (caddr_t)buffy, xdr_getpos(&xdrm),
- 0LL, UIO_SYSSPACE, FSYNC, (rlim64_t)RLIM_INFINITY, kcred, NULL);
- if (error)
- goto out;
-
-out:
- if (xdrm.x_ops != NULL)
- xdr_destroy(&xdrm);
- return (error);
-}
-
-/*
- * enqueues a record to be written to the logfile.
- */
-
-static void
-cachefs_log_enqueue(cachefscache_t *cachep, void *record, int size,
- xdrproc_t translate)
-{
- cachefs_log_cookie_t *cl;
- cachefs_log_work_list_t newnode, oldnode;
-
- mutex_enter(&cachep->c_log_mutex);
- cl = cachep->c_log;
-
- if (cl == NULL) { /* someone turned off logging out from under us */
- mutex_exit(&cachep->c_log_mutex);
- cachefs_kmem_free(record, size);
- return;
- }
- ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
-
- cl->cl_size += size;
- newnode = cachefs_kmem_zalloc(sizeof (*newnode), KM_NOSLEEP);
- if ((cl->cl_size > CACHEFS_LOG_MAX_BUFFERED) || (newnode == NULL)) {
- cachefs_log_error(cachep, ENOMEM, 0);
- if (newnode != NULL)
- cachefs_kmem_free(newnode, sizeof (*newnode));
- cachefs_kmem_free(record, size);
- mutex_exit(&cachep->c_log_mutex);
- return;
- }
-
- newnode->data = record;
- newnode->size = size;
- newnode->translate = translate;
- newnode->next = NULL;
-
- oldnode = (cachefs_log_work_list_t)cl->cl_tail;
- if (oldnode != NULL)
- oldnode->next = newnode;
- cl->cl_tail = newnode;
- if (cl->cl_head == NULL)
- cl->cl_head = newnode;
- mutex_exit(&cachep->c_log_mutex);
-
- if (cl->cl_size >= CACHEFS_LOG_LOWATER) {
- mutex_enter(&cachep->c_workq.wq_queue_lock);
- cachep->c_workq.wq_logwork = 1;
- cv_signal(&cachep->c_workq.wq_req_cv);
- mutex_exit(&cachep->c_workq.wq_queue_lock);
- }
-}
-
-/*
- * processes the log queue. run by an async worker thread, or via
- * cachefs_cache_sync().
- */
-
-void
-cachefs_log_process_queue(cachefscache_t *cachep, int getlock)
-{
- cachefs_log_cookie_t *cl;
- cachefs_log_work_list_t work, workhead, oldwork;
- struct vnode *logvp = NULL;
- struct uio uio;
- struct iovec iov;
- int error = 0;
- XDR xdrm;
- char *buffy = NULL;
-
- /*
- * NULL out the x_ops field of XDR. this way, if x_ops !=
- * NULL, we know that we did the xdr*_create() successfully.
- * this is documented in the xdr_create man page.
- */
-
- xdrm.x_ops = NULL;
-
- /* see if we're still logging */
- if (getlock)
- mutex_enter(&cachep->c_log_mutex);
- cl = cachep->c_log;
- if ((cl == NULL) || (cl->cl_magic != CACHEFS_LOG_MAGIC)) {
- if (getlock)
- mutex_exit(&cachep->c_log_mutex);
- return;
- }
-
- /* get the work, and let go of the mutex asap. */
- workhead = cl->cl_head;
- cl->cl_head = cl->cl_tail = NULL;
- cl->cl_size = 0;
- logvp = cl->cl_logvp;
- ASSERT(logvp != NULL);
- if (logvp == NULL) {
- if (getlock)
- mutex_exit(&cachep->c_log_mutex);
- return;
- }
- VN_HOLD(logvp);
- if (getlock)
- mutex_exit(&cachep->c_log_mutex);
-
- /* we don't use vn_rdwr() because there's no way to set FNONBLOCK */
-
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_loffset = 0; /* fake -- we do FAPPEND */
- uio.uio_segflg = (short)UIO_SYSSPACE;
- uio.uio_llimit = MAXOFFSET_T;
- uio.uio_fmode = FWRITE | FNONBLOCK;
- uio.uio_extflg = UIO_COPY_CACHED;
-
- buffy = cachefs_kmem_alloc(CACHEFS_LOG_ENCODE_SIZE, KM_SLEEP);
- xdrmem_create(&xdrm, buffy, CACHEFS_LOG_ENCODE_SIZE, XDR_ENCODE);
-
- (void) VOP_RWLOCK(logvp, V_WRITELOCK_TRUE, NULL);
- for (work = workhead; work != NULL; work = work->next) {
- if (! (work->translate)(&xdrm, work->data)) {
- VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
- error = ENOMEM;
- goto out;
- }
-
- iov.iov_base = buffy;
- iov.iov_len = uio.uio_resid = xdr_getpos(&xdrm);
- (void) xdr_setpos(&xdrm, 0);
-
- error = VOP_WRITE(logvp, &uio, FAPPEND, kcred, NULL);
-
- /* XXX future -- check for EAGAIN */
-
- if ((error) || (uio.uio_resid)) {
- if (uio.uio_resid != 0)
- error = EIO;
- VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
- goto out;
- }
- }
- VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
-
-out:
- if (xdrm.x_ops != NULL)
- xdr_destroy(&xdrm);
- if (buffy != NULL)
- cachefs_kmem_free(buffy, CACHEFS_LOG_ENCODE_SIZE);
-
- /*
- * if an error occurred, we need to free the buffers ourselves.
- * cachefs_destory_cookie() can't do it.
- */
-
- work = workhead;
- while (work != NULL) {
- cachefs_kmem_free(work->data, work->size);
- oldwork = work;
- work = work->next;
- cachefs_kmem_free(oldwork, sizeof (*oldwork));
- }
- if (logvp != NULL)
- VN_RELE(logvp);
- if (error) {
- cachefs_log_error(cachep, error, 1);
- return;
- }
-}
-
-static bool_t
-cachefs_xdr_logfile_header(XDR *xdrs, struct cachefs_log_logfile_header *h)
-{
- if ((! xdr_u_int(xdrs, &h->lh_magic)) ||
- (! xdr_u_int(xdrs, &h->lh_revision)) ||
- (! xdr_int(xdrs, &h->lh_errno)) ||
- (! xdr_u_int(xdrs, &h->lh_blocks)) ||
- (! xdr_u_int(xdrs, &h->lh_files)) ||
- (! xdr_u_int(xdrs, &h->lh_maxbsize)) ||
- (! xdr_u_int(xdrs, &h->lh_pagesize)))
- return (FALSE);
-
- return (TRUE);
-}
-
-/*
- * the routines for logging each transaction follow...
- */
-
-void
-cachefs_log_mount(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fscache_t *fscp, char *upath, enum uio_seg seg, char *cacheid)
-{
- struct cachefs_log_mount_record *record;
- char *cacheidt;
- char *path = NULL;
- size_t len;
- int len1, len2;
- int size, error;
-
- /* In Solaris 64 - if can't represent time don't bother */
- OUT_IF_TIME_OVERFLOW(cachep, time)
- if (seg == UIO_USERSPACE) {
- path = cachefs_kmem_alloc(MAXPATHLEN, KM_NOSLEEP);
- if (path == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- goto out;
- }
- if ((error = copyinstr(upath, path, MAXPATHLEN, &len)) != 0) {
- cachefs_log_error(cachep, error, 1);
- goto out;
- }
- } else {
- path = upath;
- }
-
- len1 = (path != NULL) ? strlen(path) : 0;
- len2 = (cacheid != NULL) ? strlen(cacheid) : 0;
- size = (int)sizeof (*record) + len1 + len2 -
- (int)CLPAD(cachefs_log_mount_record, path);
- record = cachefs_kmem_zalloc(size, KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- goto out;
- }
-
- record->type = CACHEFS_LOG_MOUNT;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
-
- if (fscp) {
- record->flags = fscp->fs_info.fi_mntflags;
- record->popsize = fscp->fs_info.fi_popsize;
- record->fgsize = fscp->fs_info.fi_fgsize;
- }
-
- record->pathlen = (ushort_t)len1;
- record->cacheidlen = (ushort_t)len2;
- if (path != NULL)
- (void) strcpy(record->path, path);
- cacheidt = record->path + len1 + 1;
- if (cacheid != NULL)
- (void) strcpy(cacheidt, cacheid);
-
- cachefs_log_enqueue(cachep, record, size, cachefs_xdr_mount);
-
-out:
- if ((seg == UIO_USERSPACE) && (path != NULL))
- cachefs_kmem_free(path, MAXPATHLEN);
-}
-
-static bool_t
-cachefs_xdr_mount(XDR *xdrs, struct cachefs_log_mount_record *rec)
-{
- char *path = rec->path;
- char *cacheid;
-
- cacheid = path + strlen(path) + 1;
-
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_u_int(xdrs, &rec->flags)) ||
- (! xdr_u_int(xdrs, &rec->popsize)) ||
- (! xdr_u_int(xdrs, &rec->fgsize)) ||
- (! xdr_u_short(xdrs, &rec->pathlen)) ||
- (! xdr_u_short(xdrs, &rec->cacheidlen)) ||
- (! xdr_wrapstring(xdrs, &path)) ||
- (! xdr_wrapstring(xdrs, &cacheid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_umount(cachefscache_t *cachep, int Errno, struct vfs *vfsp)
-{
- struct cachefs_log_umount_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_UMOUNT;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_umount);
-}
-
-static bool_t
-cachefs_xdr_umount(XDR *xdrs, struct cachefs_log_umount_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_getpage(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, size_t len)
-{
- struct cachefs_log_getpage_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_GETPAGE;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->offset = offset;
- record->len = (uint_t)len;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_getpage);
-}
-
-static bool_t
-cachefs_xdr_getpage(XDR *xdrs, struct cachefs_log_getpage_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_longlong_t(xdrs, &rec->offset)) ||
- (! xdr_u_int(xdrs, &rec->len)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_readdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, int eof)
-{
- struct cachefs_log_readdir_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_READDIR;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->offset = offset;
- record->eof = eof;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_readdir);
-}
-
-static bool_t
-cachefs_xdr_readdir(XDR *xdrs, struct cachefs_log_readdir_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
- (! xdr_int(xdrs, &rec->eof)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_readlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, size_t length)
-{
- struct cachefs_log_readlink_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_READLINK;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->length = (uint_t)length;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_readlink);
-}
-
-static bool_t
-cachefs_xdr_readlink(XDR *xdrs, struct cachefs_log_readlink_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_int(xdrs, &rec->length)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_remove(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid)
-{
- struct cachefs_log_remove_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_REMOVE;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_remove);
-}
-
-static bool_t
-cachefs_xdr_remove(XDR *xdrs, struct cachefs_log_remove_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_rmdir(cachefscache_t *cachep, int Errno,
- struct vfs *vfsp, fid_t *fidp, ino64_t fileno, uid_t uid)
-{
- struct cachefs_log_rmdir_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_RMDIR;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_rmdir);
-}
-
-static bool_t
-cachefs_xdr_rmdir(XDR *xdrs, struct cachefs_log_rmdir_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_truncate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t size)
-{
- struct cachefs_log_truncate_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_TRUNCATE;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->size = size;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_truncate);
-}
-
-static bool_t
-cachefs_xdr_truncate(XDR *xdrs, struct cachefs_log_truncate_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_longlong_t(xdrs, &rec->size)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_putpage(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, size_t len)
-{
- struct cachefs_log_putpage_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_PUTPAGE;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->offset = offset;
- record->len = (uint_t)len;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_putpage);
-}
-
-static bool_t
-cachefs_xdr_putpage(XDR *xdrs, struct cachefs_log_putpage_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
- (! xdr_u_int(xdrs, &rec->len)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_create(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *filefidp, ino64_t fileno, uid_t uid)
-{
- struct cachefs_log_create_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_CREATE;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (filefidp != NULL) {
- CACHEFS_FID_COPY(filefidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_create);
-}
-
-static bool_t
-cachefs_xdr_create(XDR *xdrs, struct cachefs_log_create_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_mkdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *cfidp, ino64_t fileno, uid_t uid)
-{
- struct cachefs_log_mkdir_record *record;
- int size;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- size = (int)sizeof (*record);
- record = cachefs_kmem_zalloc(size, KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_MKDIR;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (cfidp != NULL) {
- CACHEFS_FID_COPY(cfidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, size,
- cachefs_xdr_mkdir);
-}
-
-static bool_t
-cachefs_xdr_mkdir(XDR *xdrs, struct cachefs_log_mkdir_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_rename(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *gfp, ino64_t fileno, int removed, uid_t uid)
-{
- struct cachefs_log_rename_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_RENAME;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (gfp != NULL) {
- CACHEFS_FID_COPY(gfp, &record->gone);
- }
- record->fileno = fileno;
- record->removed = removed;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_rename);
-}
-
-static bool_t
-cachefs_xdr_rename(XDR *xdrs, struct cachefs_log_rename_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->gone, sizeof (rec->gone))) ||
- (! xdr_int(xdrs, &rec->removed)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-
-void
-cachefs_log_symlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, int size)
-{
- struct cachefs_log_symlink_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_SYMLINK;
- record->time = time;
-
- record->error = Errno;
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->size = size;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_symlink);
-}
-
-static bool_t
-cachefs_xdr_symlink(XDR *xdrs, struct cachefs_log_symlink_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_int(xdrs, &rec->size)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_populate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, u_offset_t off, size_t popsize)
-{
- struct cachefs_log_populate_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_POPULATE;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->off = off;
- record->size = (int)popsize;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_populate);
-}
-
-static bool_t
-cachefs_xdr_populate(XDR *xdrs, struct cachefs_log_populate_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
- (! xdr_u_int(xdrs, &rec->size)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_csymlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, int size)
-{
- struct cachefs_log_csymlink_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_CSYMLINK;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->size = size;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_csymlink);
-}
-
-static bool_t
-cachefs_xdr_csymlink(XDR *xdrs, struct cachefs_log_csymlink_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->size)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_filldir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, u_offset_t size)
-{
- struct cachefs_log_filldir_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_FILLDIR;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->size = (uint_t)size;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_filldir);
-}
-
-static bool_t
-cachefs_xdr_filldir(XDR *xdrs, struct cachefs_log_filldir_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, (uint_t *)&rec->size)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_mdcreate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uint_t count)
-{
- struct cachefs_log_mdcreate_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_MDCREATE;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->count = count;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_mdcreate);
-}
-
-static bool_t
-cachefs_xdr_mdcreate(XDR *xdrs, struct cachefs_log_mdcreate_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->count)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_gpfront(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, uint_t len)
-{
- struct cachefs_log_gpfront_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_GPFRONT;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
- record->off = offset;
- record->len = len;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_gpfront);
-}
-
-static bool_t
-cachefs_xdr_gpfront(XDR *xdrs, struct cachefs_log_gpfront_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
- (! xdr_u_int(xdrs, &rec->len)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_rfdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, uid_t uid)
-{
- struct cachefs_log_rfdir_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_RFDIR;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->uid = uid;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_rfdir);
-}
-
-static bool_t
-cachefs_xdr_rfdir(XDR *xdrs, struct cachefs_log_rfdir_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_int(xdrs, &rec->uid)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_ualloc(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, u_offset_t off, size_t len)
-{
- struct cachefs_log_ualloc_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_UALLOC;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->off = off;
- record->len = (uint_t)len;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_ualloc);
-}
-
-static bool_t
-cachefs_xdr_ualloc(XDR *xdrs, struct cachefs_log_ualloc_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
- (! xdr_u_int(xdrs, (uint_t *)&rec->len)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_calloc(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno, u_offset_t off, size_t len)
-{
- struct cachefs_log_calloc_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_CALLOC;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
- record->off = off;
- record->len = (uint_t)len;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_calloc);
-}
-
-static bool_t
-cachefs_xdr_calloc(XDR *xdrs, struct cachefs_log_calloc_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
- (! xdr_u_int(xdrs, &rec->len)))
- return (FALSE);
-
- return (TRUE);
-}
-
-void
-cachefs_log_nocache(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
- fid_t *fidp, ino64_t fileno)
-{
- struct cachefs_log_nocache_record *record;
-
- /* In Solaris 64 - if can't represent time don't bother */
- RET_IF_TIME_OVERFLOW(cachep, time)
- record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
- if (record == NULL) {
- cachefs_log_error(cachep, ENOMEM, 1);
- return;
- }
-
- record->type = CACHEFS_LOG_NOCACHE;
- record->time = time;
- record->error = Errno;
-
- record->vfsp = (uint64_t)(uintptr_t)vfsp;
- if (fidp != NULL) {
- CACHEFS_FID_COPY(fidp, &record->fid);
- }
- record->fileno = fileno;
-
- cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
- cachefs_xdr_nocache);
-
-}
-
-static bool_t
-cachefs_xdr_nocache(XDR *xdrs, struct cachefs_log_nocache_record *rec)
-{
- if ((! xdr_int(xdrs, &rec->type)) ||
- (! xdr_int(xdrs, &rec->error)) ||
- (! xdr_cfs_time_t(xdrs, &rec->time)) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
- (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
- (! xdr_ino64(xdrs, &rec->fileno)))
- return (FALSE);
-
- return (TRUE);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_module.c b/usr/src/uts/common/fs/cachefs/cachefs_module.c
deleted file mode 100644
index 12eeb2b837..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_module.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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.
- * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
- */
-
-#include <sys/errno.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <rpc/types.h>
-#include <sys/mode.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/fs/cachefs_fs.h>
-
-/*
- * This is the loadable module wrapper.
- */
-#include <sys/systm.h>
-#include <sys/modctl.h>
-#include <sys/syscall.h>
-
-extern time_t time;
-
-static int cachefs_init(int, char *);
-static void cachefs_fini();
-
-static int cachefs_unloadable = 0; /* tunable */
-static boolean_t cachefs_up = B_FALSE;
-
-uint_t cachefs_max_apop_inqueue = CACHEFS_MAX_APOP_INQUEUE;
-
-/*
- * this is a list of possible hash table sizes, for the `double
- * hashing' algorithm described in rosen's `elementary number theory
- * and its applications'. minimally, this needs to be a list of
- * increasing prime integers, terminated by a 0. ideally, they should
- * be the larger of twin primes; i.e. P and P-2 are both prime.
- */
-
-int cachefs_hash_sizes[] = {5, 2029, 4093, 8089, 16363, 32719, 0};
-
-/*
- * Module linkage information for the kernel.
- */
-
-static vfsdef_t vfs_z = {
- VFSDEF_VERSION,
- CACHEFS_BASETYPE,
- cachefs_init,
- VSW_CANREMOUNT,
- NULL
-};
-
-static struct modlfs modlfs = {
- &mod_fsops,
- "cache filesystem",
- &vfs_z
-};
-
-static struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlfs, NULL
-};
-
-int
-_init(void)
-{
- int status;
-
- status = mod_install(&modlinkage);
- if (status != 0) {
- /*
- * Could not load module, clean up the work performed
- * by cachefs_init() which was indirectly called by
- * mod_installfs() which in turn was called by mod_install().
- */
- cachefs_fini();
- }
-
- return (status);
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-int
-_fini(void)
-{
- int status;
-
- if (!cachefs_unloadable)
- return (EBUSY);
-
- if ((status = mod_remove(&modlinkage)) == 0) {
- /*
- * Module has been unloaded, now clean up
- */
- cachefs_fini();
- }
-
- return (status);
-}
-
-extern kmutex_t cachefs_cachelock; /* Cache list mutex */
-extern kmutex_t cachefs_newnum_lock;
-extern kmutex_t cachefs_kstat_key_lock;
-extern kmutex_t cachefs_rename_lock;
-extern kmutex_t cachefs_minor_lock; /* Lock for minor device map */
-extern kmutex_t cachefs_kmem_lock;
-extern kmutex_t cachefs_async_lock; /* global async work count */
-extern major_t cachefs_major;
-
-/*
- * Cache initialization routine. This routine should only be called
- * once. It performs the following tasks:
- * - Initalize all global locks
- * - Call sub-initialization routines (localize access to variables)
- */
-static int
-cachefs_init(int fstyp, char *name)
-{
- kstat_t *ksp;
- int error;
-
- ASSERT(cachefs_up == B_FALSE);
-
- error = cachefs_init_vfsops(fstyp);
- if (error != 0)
- return (error);
-
- error = cachefs_init_vnops(name);
- if (error != 0)
- return (error);
-
- mutex_init(&cachefs_cachelock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_newnum_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_kstat_key_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_kmem_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_rename_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_minor_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachefs_async_lock, NULL, MUTEX_DEFAULT, NULL);
-#ifdef CFSRLDEBUG
- mutex_init(&cachefs_rl_debug_mutex, NULL, MUTEX_DEFAULT, NULL);
-#endif /* CFSRLDEBUG */
-
- /*
- * set up kmem_cache entities
- */
-
- cachefs_cnode_cache = kmem_cache_create("cachefs_cnode_cache",
- sizeof (struct cnode), 0, NULL, NULL, NULL, NULL, NULL, 0);
- cachefs_req_cache = kmem_cache_create("cachefs_async_request",
- sizeof (struct cachefs_req), 0,
- cachefs_req_create, cachefs_req_destroy, NULL, NULL, NULL, 0);
- cachefs_fscache_cache = kmem_cache_create("cachefs_fscache",
- sizeof (fscache_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
- cachefs_filegrp_cache = kmem_cache_create("cachefs_filegrp",
- sizeof (filegrp_t), 0,
- filegrp_cache_create, filegrp_cache_destroy, NULL, NULL, NULL, 0);
- cachefs_cache_kmcache = kmem_cache_create("cachefs_cache_t",
- sizeof (cachefscache_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
-
- /*
- * set up the cachefs.0.key kstat
- */
-
- cachefs_kstat_key = NULL;
- cachefs_kstat_key_n = 0;
- ksp = kstat_create("cachefs", 0, "key", "misc", KSTAT_TYPE_RAW, 1,
- KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_VAR_SIZE);
- if (ksp != NULL) {
- ksp->ks_data = &cachefs_kstat_key;
- ksp->ks_update = cachefs_kstat_key_update;
- ksp->ks_snapshot = cachefs_kstat_key_snapshot;
- ksp->ks_lock = &cachefs_kstat_key_lock;
- kstat_install(ksp);
- }
-
- /*
- * Assign unique major number for all nfs mounts
- */
-
- if ((cachefs_major = getudev()) == -1) {
- cmn_err(CE_WARN,
- "cachefs: init: can't get unique device number");
- cachefs_major = 0;
- }
- cachefs_up = B_TRUE;
-#ifdef CFSRLDEBUG
- cachefs_dbvalid = time;
-#endif /* CFSRLDEBUG */
-
- return (0);
-}
-
-/*
- * Cache clean up routine. This routine is called if mod_install() failed
- * and we have to clean up because the module could not be installed,
- * or by _fini() when we're unloading the module.
- */
-static void
-cachefs_fini()
-{
- extern int cachefsfstyp;
- extern struct vnodeops *cachefs_vnodeops;
-
- if (cachefs_up == B_FALSE) {
- /*
- * cachefs_init() was not called on _init(),
- * nothing to deallocate.
- */
- return;
- }
-
- /*
- * Clean up cachefs.0.key kstat.
- * Currently, you can only do a
- * modunload if cachefs_unloadable is nonzero, and that's
- * pretty much just for debugging. however, if there ever
- * comes a day when cachefs is more freely unloadable
- * (e.g. the modunload daemon can do it normally), then we'll
- * have to make changes in the stats_ API. this is because a
- * stats_cookie_t holds the id # derived from here, and it
- * will all go away at modunload time. thus, the API will
- * need to somehow be more robust than is currently necessary.
- */
- kstat_delete_byname("cachefs", 0, "key");
-
- if (cachefs_kstat_key != NULL) {
- cachefs_kstat_key_t *key;
- int i;
-
- for (i = 0; i < cachefs_kstat_key_n; i++) {
- key = cachefs_kstat_key + i;
-
- cachefs_kmem_free((void *)(uintptr_t)key->ks_mountpoint,
- strlen((char *)(uintptr_t)key->ks_mountpoint) + 1);
- cachefs_kmem_free((void *)(uintptr_t)key->ks_backfs,
- strlen((char *)(uintptr_t)key->ks_backfs) + 1);
- cachefs_kmem_free((void *)(uintptr_t)key->ks_cachedir,
- strlen((char *)(uintptr_t)key->ks_cachedir) + 1);
- cachefs_kmem_free((void *)(uintptr_t)key->ks_cacheid,
- strlen((char *)(uintptr_t)key->ks_cacheid) + 1);
- }
-
- cachefs_kmem_free(cachefs_kstat_key,
- cachefs_kstat_key_n * sizeof (*cachefs_kstat_key));
- }
-
- /*
- * Clean up kmem_cache entities
- */
- kmem_cache_destroy(cachefs_cache_kmcache);
- kmem_cache_destroy(cachefs_filegrp_cache);
- kmem_cache_destroy(cachefs_fscache_cache);
- kmem_cache_destroy(cachefs_req_cache);
- kmem_cache_destroy(cachefs_cnode_cache);
-#ifdef CFSRLDEBUG
- if (cachefs_rl_debug_cache != NULL)
- kmem_cache_destroy(cachefs_rl_debug_cache);
-#endif /* CFSRLDEBUG */
-
- /*
- * Clean up the operations structures
- */
- (void) vfs_freevfsops_by_type(cachefsfstyp);
- vn_freevnodeops(cachefs_vnodeops);
-
- /*
- * Destroy mutexes
- */
-#ifdef CFSRLDEBUG
- mutex_destroy(&cachefs_rl_debug_mutex);
-#endif /* CFSRLDEBUG */
- mutex_destroy(&cachefs_async_lock);
- mutex_destroy(&cachefs_minor_lock);
- mutex_destroy(&cachefs_rename_lock);
- mutex_destroy(&cachefs_kmem_lock);
- mutex_destroy(&cachefs_kstat_key_lock);
- mutex_destroy(&cachefs_newnum_lock);
- mutex_destroy(&cachefs_cachelock);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_noopc.c b/usr/src/uts/common/fs/cachefs/cachefs_noopc.c
deleted file mode 100644
index 245025bf0a..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_noopc.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/bootconf.h>
-#include <sys/modctl.h>
-
-#include <sys/fs/cachefs_fs.h>
-
-/*ARGSUSED*/
-static int
-c_nop_init_cached_object(fscache_t *fscp, cnode_t *cp, vattr_t *vap,
- cred_t *cr)
-{
- int error;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(cr != NULL);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* NFSv4 always sets strict consistency */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /* if attributes not passed in then get them */
- if (vap == NULL) {
- /* if not connected then cannot get attrs */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- return (ETIMEDOUT);
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- return (error);
- }
-
- /* get the attributes */
- cp->c_attr.va_mask = AT_ALL;
- ASSERT(cp->c_backvp != NULL);
- error = VOP_GETATTR(cp->c_backvp, &cp->c_attr, 0, cr, NULL);
- if (error)
- return (error);
- } else {
- /* copy passed in attributes into the cnode */
- cp->c_attr = *vap;
- }
-
- cp->c_size = cp->c_attr.va_size;
- mdp->md_consttype = CFS_FS_CONST_NOCONST;
- cp->c_flags |= CN_UPDATED;
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-c_nop_check_cached_object(struct fscache *fscp, struct cnode *cp,
- int verify_what, cred_t *cr)
-{
- struct vattr attrs;
- int fail = 0, backhit = 0;
- int error = 0;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(cr);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* nothing to do if not connected */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- goto out;
-
- /* done if do not have to check */
- if (((verify_what & C_BACK_CHECK) == 0) &&
- ((mdp->md_flags & MD_NEEDATTRS) == 0))
- goto out;
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
-
- /* get the file attributes from the back fs */
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- backhit = 1;
- if (error)
- goto out;
-
- cp->c_attr = attrs;
- if (attrs.va_size > cp->c_size)
- cp->c_size = attrs.va_size;
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (backhit != 0) {
- if (fail != 0)
- fscp->fs_stats.st_fails++;
- else
- fscp->fs_stats.st_passes++;
- }
-
- return (error);
-}
-
-static void
-c_nop_modify_cached_object(struct fscache *fscp, struct cnode *cp, cred_t *cr)
-{
- struct vattr attrs;
- int error;
- nlink_t nlink;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(fscp->fs_cdconnected == CFS_CD_CONNECTED);
- ASSERT(fscp->fs_backvfsp);
-
- fscp->fs_stats.st_modifies++;
-
- /* from now on, make sure we're using the server's idea of time */
- mdp->md_flags &= ~(MD_LOCALCTIME | MD_LOCALMTIME);
- mdp->md_flags |= MD_NEEDATTRS;
-
- /* if in write-around mode, make sure file is nocached */
- if (CFS_ISFS_WRITE_AROUND(fscp)) {
- if ((cp->c_flags & CN_NOCACHE) == 0)
- cachefs_nocache(cp);
- }
-
- /* get the new attributes so we don't wait forever to get them */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- return;
- }
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error)
- return;
- nlink = cp->c_attr.va_nlink;
- cp->c_attr = attrs;
- cp->c_attr.va_nlink = nlink;
- if ((attrs.va_size > cp->c_size) || !vn_has_cached_data(CTOV(cp)))
- cp->c_size = attrs.va_size;
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_nop_invalidate_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- mdp->md_flags |= MD_NEEDATTRS;
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_nop_convert_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
- mdp->md_flags |= MD_NEEDATTRS;
- mdp->md_consttype = CFS_FS_CONST_NOCONST;
- cp->c_flags |= CN_UPDATED;
-}
-
-struct cachefsops nopcfsops = {
- c_nop_init_cached_object,
- c_nop_check_cached_object,
- c_nop_modify_cached_object,
- c_nop_invalidate_cached_object,
- c_nop_convert_cached_object
-};
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_resource.c b/usr/src/uts/common/fs/cachefs/cachefs_resource.c
deleted file mode 100644
index 7526a5f826..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_resource.c
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*
- * 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
- * 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 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/kobj.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/modctl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/callb.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-
-extern time_t time;
-
-/* forward references */
-int cachefs_rl_entry_get(cachefscache_t *, uint_t, rl_entry_t **);
-void cachefs_garbage_collect_queue(cachefscache_t *cachep);
-static time_t cachefs_gc_front_atime(cachefscache_t *cachep);
-static void cachefs_garbage_collect(cachefscache_t *cachep);
-static void cachefs_packed_pending(cachefscache_t *cachep);
-
-
-#define RL_HEAD(cachep, type) \
- (&(cachep->c_rlinfo.rl_items[CACHEFS_RL_INDEX(type)]))
-
-/*
- * This function moves an RL entry from wherever it currently is to
- * the back of the requested list.
- */
-void
-cachefs_rlent_moveto(cachefscache_t *cachep,
- enum cachefs_rl_type type, uint_t entno, size_t blks)
-{
- mutex_enter(&cachep->c_contentslock);
- cachefs_cache_dirty(cachep, 0);
- cachefs_rlent_moveto_nolock(cachep, type, entno, blks);
- mutex_exit(&cachep->c_contentslock);
-}
-
-void
-cachefs_rlent_moveto_nolock(cachefscache_t *cachep,
- enum cachefs_rl_type type, uint_t entno, size_t blks)
-{
- rl_entry_t *rl_ent;
- uint_t prev, next;
- cachefs_rl_listhead_t *lhp;
- enum cachefs_rl_type otype;
- int error;
-
- ASSERT(entno != 0);
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
- ASSERT((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
-
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error)
- return;
- next = rl_ent->rl_fwd_idx;
- prev = rl_ent->rl_bkwd_idx;
- otype = rl_ent->rl_current;
- ASSERT((CACHEFS_RL_START <= otype) && (otype <= CACHEFS_RL_END));
- rl_ent->rl_current = CACHEFS_RL_NONE;
-
- if (type == CACHEFS_RL_PACKED_PENDING) {
- /* XXX sam: is this the right place to turn this on? */
- cachep->c_flags |= CACHE_PACKED_PENDING;
- }
-
- /* remove entry from its previous list */
-
- lhp = RL_HEAD(cachep, otype);
- if ((lhp->rli_back == 0) || (lhp->rli_front == 0))
- ASSERT((lhp->rli_back == 0) && (lhp->rli_front == 0));
-
- if (lhp->rli_back == entno)
- lhp->rli_back = next;
- if (lhp->rli_front == entno)
- lhp->rli_front = prev;
- if (prev != 0) {
- error = cachefs_rl_entry_get(cachep, prev, &rl_ent);
- if (error)
- return;
- rl_ent->rl_fwd_idx = next;
- }
- if (next != 0) {
- error = cachefs_rl_entry_get(cachep, next, &rl_ent);
- if (error)
- return;
- rl_ent->rl_bkwd_idx = prev;
- }
- lhp->rli_blkcnt -= blks;
- lhp->rli_itemcnt--;
-
- /* add entry to its new list */
-
- lhp = RL_HEAD(cachep, type);
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error)
- return;
- rl_ent->rl_current = type;
- rl_ent->rl_bkwd_idx = 0;
- rl_ent->rl_fwd_idx = lhp->rli_back;
-
- if (lhp->rli_back != 0) {
- ASSERT(lhp->rli_front != 0);
- error = cachefs_rl_entry_get(cachep, lhp->rli_back, &rl_ent);
- if (error)
- return;
- rl_ent->rl_bkwd_idx = entno;
- } else {
- ASSERT(lhp->rli_front == 0);
- lhp->rli_front = entno;
- }
- lhp->rli_back = entno;
- lhp->rli_blkcnt += blks;
- lhp->rli_itemcnt++;
-}
-
-/*
- * This function verifies that an rl entry is of the `correct' type.
- * it's used for debugging (only?).
- */
-
-/*ARGSUSED*/
-void
-cachefs_rlent_verify(cachefscache_t *cachep,
- enum cachefs_rl_type type, uint_t entno)
-{
-#ifdef CFSDEBUG
- rl_entry_t *rl_ent;
- int error;
-
- ASSERT((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
-
- mutex_enter(&cachep->c_contentslock);
-
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (!error && rl_ent->rl_current != type) {
-#ifdef CFSRLDEBUG
- printf("cachefs_rldebug: type should be %x\n", type);
- cachefs_rl_debug_show(rl_ent);
- debug_enter("cachefs_rlent_verify");
-#else /* CFSRLDEBUG */
- cmn_err(CE_WARN, "rl entry %x type = %x should be %x\n",
- entno, rl_ent->rl_current, type);
-#endif /* CFSRLDEBUG */
- }
-
- mutex_exit(&cachep->c_contentslock);
-#endif /* CFSDEBUG */
-}
-
-/*
- * Returns the rl data of the front of the specified resource list.
- * Returns 0 for success, !0 if the list is empty.
- */
-int
-cachefs_rlent_data(cachefscache_t *cachep, rl_entry_t *valp, uint_t *entnop)
-{
- uint_t entno;
- rl_entry_t *rl_ent;
- int error = 0;
- cachefs_rl_listhead_t *lhp;
- enum cachefs_rl_type type;
-
- ASSERT((cachep->c_flags & CACHE_NOCACHE) == 0);
-
- if (entnop == NULL)
- entnop = &entno;
- *entnop = 0;
-
- mutex_enter(&cachep->c_contentslock);
-
- type = valp->rl_current;
- ASSERT((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
- lhp = RL_HEAD(cachep, type);
- entno = lhp->rli_front;
-
- if (*entnop == 0) {
- error = ENOENT;
- } else {
- error = cachefs_rl_entry_get(cachep, *entnop, &rl_ent);
- if (!error)
- *valp = *rl_ent;
- }
- mutex_exit(&cachep->c_contentslock);
- return (error);
-}
-
-/*
- * This function plucks a slot from the RL free list and creates an RL entry.
- */
-int
-cachefs_rl_alloc(struct cachefscache *cachep, rl_entry_t *valp, uint_t *entnop)
-{
- int error = 0;
- uint_t entno;
- rl_entry_t *rl_ent;
- cachefs_rl_listhead_t *lhp;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- mutex_enter(&cachep->c_contentslock);
-
- cachefs_cache_dirty(cachep, 0);
- lhp = RL_HEAD(cachep, CACHEFS_RL_FREE);
- entno = lhp->rli_front;
- if (entno == 0) {
- if (cachep->c_rlinfo.rl_entries >=
- cachep->c_label.cl_maxinodes) {
- error = ENOMEM;
- goto out;
- }
- entno = ++(cachep->c_rlinfo.rl_entries);
- lhp->rli_itemcnt++;
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error)
- goto out;
- rl_ent->rl_current = CACHEFS_RL_NONE;
- rl_ent->rl_fwd_idx = 0;
- rl_ent->rl_bkwd_idx = 0;
- }
-
- cachefs_rlent_moveto_nolock(cachep, CACHEFS_RL_NONE, entno, 0);
-
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error)
- goto out;
- rl_ent->rl_fsid = valp->rl_fsid;
- rl_ent->rl_fileno = valp->rl_fileno;
- rl_ent->rl_local = valp->rl_local;
- rl_ent->rl_attrc = valp->rl_attrc;
- rl_ent->rl_fsck = 0;
-out:
- mutex_exit(&cachep->c_contentslock);
- if (error == 0)
- *entnop = entno;
- return (error);
-}
-
-/*
- * Call to change a local fileno in an rl entry to a normal fileno.
- */
-void
-cachefs_rl_changefileno(cachefscache_t *cachep, uint_t entno, ino64_t fileno)
-{
- rl_entry_t *rl_ent;
- int error;
-
- mutex_enter(&cachep->c_contentslock);
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (!error) {
- ASSERT(rl_ent->rl_local);
- rl_ent->rl_local = 0;
- rl_ent->rl_fileno = fileno;
- }
- mutex_exit(&cachep->c_contentslock);
-}
-
-/*
- * Moves the files on the modified list for this file system to
- * the modified fix list.
- */
-void
-cachefs_move_modified_to_mf(cachefscache_t *cachep, fscache_t *fscp)
-{
- rl_entry_t *list_ent;
- uint_t curp, nextp;
- cachefs_rl_listhead_t *lhp;
- int error;
-
- ASSERT(MUTEX_HELD(&cachep->c_mflock));
-
- mutex_enter(&cachep->c_contentslock);
-
- lhp = RL_HEAD(cachep, CACHEFS_RL_MF);
- ASSERT(lhp->rli_front == 0);
- ASSERT(lhp->rli_back == 0);
- ASSERT(lhp->rli_itemcnt == 0);
- lhp->rli_blkcnt = 0;
-
- cachefs_cache_dirty(cachep, 0);
-
- /* walk the modified list */
- lhp = RL_HEAD(cachep, CACHEFS_RL_MODIFIED);
- for (curp = lhp->rli_front; curp != 0; curp = nextp) {
- /* get the next element */
- error = cachefs_rl_entry_get(cachep, curp, &list_ent);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- return;
- }
- nextp = list_ent->rl_bkwd_idx;
-
- /* skip if element is not in this file system */
- if (list_ent->rl_fsid != fscp->fs_cfsid)
- continue;
-
- /* move from modified list to mf list */
- cachefs_rlent_moveto_nolock(cachep, CACHEFS_RL_MF, curp, 0);
- }
- mutex_exit(&cachep->c_contentslock);
-}
-
-/*
- * Moves the contents of the active list to the rl list.
- * Leave modified files on the active list, so they are not
- * garbage collected.
- */
-void
-cachefs_rl_cleanup(cachefscache_t *cachep)
-{
- cachefs_rl_listhead_t *lhp;
- rl_entry_t *rlp;
- uint_t entno, next;
- int error;
-
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
-
- /*
- * if fsck ran, then both of these lists should be empty. the
- * only time this isn't the case is when we've done a cachefs
- * boot with a clean cache. then, the cache may have been
- * clean, but files and attrfiles were left dangling.
- *
- * when this happens, we just fix the linked lists here. this
- * means that the attrcache header and cnode metadata might
- * have incorrect information about which resource lists an
- * entity is currently on. so, we set CACHE_CHECK_RLTYPE,
- * which says cache-wide to double-check and go with whatever
- * is in the resource list at the time such an object is
- * loaded into memory.
- */
-
- lhp = RL_HEAD(cachep, CACHEFS_RL_ACTIVE);
- if (lhp->rli_itemcnt > 0) {
- cachep->c_flags |= CACHE_CHECK_RLTYPE;
- cachefs_cache_dirty(cachep, 0);
- }
- for (entno = lhp->rli_front; entno != 0; entno = next) {
- error = cachefs_rl_entry_get(cachep, entno, &rlp);
- if (error)
- return;
- next = rlp->rl_bkwd_idx;
-
- ASSERT(rlp->rl_current == CACHEFS_RL_ACTIVE);
- cachefs_rlent_moveto_nolock(cachep, CACHEFS_RL_GC, entno, 0);
- }
-
-#if 0
- lhp = RL_HEAD(cachep, CACHEFS_RL_ATTRFILE);
- if (lhp->rli_itemcnt > 0) {
- cachep->c_flags |= CACHE_CHECK_RLTYPE;
- cachefs_cache_dirty(cachep, 0);
- }
- for (entno = lhp->rli_front; entno != 0; entno = next) {
- error = cachefs_rl_entry_get(cachep, entno, &rlp);
- if (error)
- return;
- next = rlp->rl_bkwd_idx;
-
- ASSERT(rlp->rl_current == CACHEFS_RL_ATTRFILE);
- cachefs_rlent_moveto_nolock(cachep, CACHEFS_RL_GC, entno, 0);
- }
-#endif
-}
-
-int
-cachefs_allocfile(cachefscache_t *cachep)
-{
- int error = 0;
- int collect = 0;
- struct statvfs64 sb;
- fsfilcnt64_t used;
-
- (void) VFS_STATVFS(cachep->c_dirvp->v_vfsp, &sb);
- used = sb.f_files - sb.f_ffree;
-
- mutex_enter(&cachep->c_contentslock);
-
- /* if there are no more available inodes */
- if ((cachep->c_usage.cu_filesused >= cachep->c_label.cl_maxinodes) ||
- ((cachep->c_usage.cu_filesused > cachep->c_label.cl_filemin) &&
- (used > cachep->c_label.cl_filetresh))) {
- error = ENOSPC;
- if ((cachep->c_flags & CACHE_GARBAGE_COLLECT) == 0)
- collect = 1;
- }
-
- /* else if there are more available inodes */
- else {
- cachefs_cache_dirty(cachep, 0);
- cachep->c_usage.cu_filesused++;
- if (((cachep->c_flags & CACHE_GARBAGE_COLLECT) == 0) &&
- (cachep->c_usage.cu_filesused >=
- cachep->c_label.cl_filehiwat))
- collect = 1;
- }
-
- mutex_exit(&cachep->c_contentslock);
-
- if (collect)
- cachefs_garbage_collect_queue(cachep);
-
- return (error);
-}
-
-void
-cachefs_freefile(cachefscache_t *cachep)
-{
- mutex_enter(&cachep->c_contentslock);
- ASSERT(cachep->c_usage.cu_filesused > 0);
- cachefs_cache_dirty(cachep, 0);
- cachep->c_usage.cu_filesused--;
- mutex_exit(&cachep->c_contentslock);
-}
-
-/*ARGSUSED*/
-int
-cachefs_allocblocks(cachefscache_t *cachep, size_t nblks,
- enum cachefs_rl_type type)
-{
- int error = 0;
- int collect = 0;
- struct statvfs64 sb;
- size_t used;
- size_t blocks;
-
- ASSERT(type != CACHEFS_RL_FREE);
-
- (void) VFS_STATVFS(cachep->c_dirvp->v_vfsp, &sb);
- used = ((sb.f_blocks - sb.f_bfree) * sb.f_frsize) / MAXBSIZE;
-
- mutex_enter(&cachep->c_contentslock);
-
- /* if there are no more available blocks */
- blocks = cachep->c_usage.cu_blksused + nblks;
- if ((blocks >= cachep->c_label.cl_maxblks) ||
- ((blocks > cachep->c_label.cl_blockmin) &&
- (used > cachep->c_label.cl_blocktresh))) {
- error = ENOSPC;
- if ((cachep->c_flags & CACHE_GARBAGE_COLLECT) == 0)
- collect = 1;
- }
-
- /* else if there are more available blocks */
- else {
- cachefs_cache_dirty(cachep, 0);
- cachep->c_usage.cu_blksused += (uint_t)nblks;
- ASSERT((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
- RL_HEAD(cachep, type)->rli_blkcnt += nblks;
-
- if (((cachep->c_flags & CACHE_GARBAGE_COLLECT) == 0) &&
- (cachep->c_usage.cu_blksused >=
- cachep->c_label.cl_blkhiwat))
- collect = 1;
- }
-
- mutex_exit(&cachep->c_contentslock);
-
- if (collect)
- cachefs_garbage_collect_queue(cachep);
-
- return (error);
-}
-
-void
-cachefs_freeblocks(cachefscache_t *cachep, size_t nblks,
- enum cachefs_rl_type type)
-{
- mutex_enter(&cachep->c_contentslock);
- cachefs_cache_dirty(cachep, 0);
- cachep->c_usage.cu_blksused -= (uint_t)nblks;
- ASSERT(cachep->c_usage.cu_blksused >= 0);
- ASSERT((CACHEFS_RL_START <= type) && (type <= CACHEFS_RL_END));
- ASSERT(type != CACHEFS_RL_FREE);
- RL_HEAD(cachep, type)->rli_blkcnt -= nblks;
- mutex_exit(&cachep->c_contentslock);
-}
-
-int
-cachefs_victim(cachefscache_t *cachep)
-{
- uint_t entno;
- rl_entry_t *rl_ent;
- int error = 0;
- ino64_t fsid;
- cfs_cid_t cid;
- struct fscache *fscp;
- struct filegrp *fgp;
- struct cachefs_metadata md;
- struct cnode *cp;
- int isattrc;
- cachefs_rl_listhead_t *lhp;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- fscp = NULL;
- fgp = NULL;
-
- /* get the file and fsid of the first item on the rl list */
- /* XXX call rlent_data() instead */
- mutex_enter(&cachep->c_contentslock);
- lhp = RL_HEAD(cachep, CACHEFS_RL_GC);
- entno = lhp->rli_front;
- if (entno == 0) {
- mutex_exit(&cachep->c_contentslock);
- error = ENOSPC;
- goto out;
- }
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
- fsid = rl_ent->rl_fsid;
- cid.cid_fileno = rl_ent->rl_fileno;
- ASSERT(rl_ent->rl_local == 0);
- cid.cid_flags = 0;
- isattrc = rl_ent->rl_attrc;
- mutex_exit(&cachep->c_contentslock);
-
- /* get the file system cache object for this fsid */
- mutex_enter(&cachep->c_fslistlock);
- fscp = fscache_list_find(cachep, fsid);
- if (fscp == NULL) {
- fscp = fscache_create(cachep);
- error = fscache_activate(fscp, fsid, NULL, NULL, 0);
- if (error) {
- cmn_err(CE_WARN,
- "cachefs: cache corruption, run fsck\n");
- fscache_destroy(fscp);
- fscp = NULL;
- mutex_exit(&cachep->c_fslistlock);
- error = 0;
- goto out;
- }
- fscache_list_add(cachep, fscp);
- }
- fscache_hold(fscp);
- mutex_exit(&cachep->c_fslistlock);
-
- /* get the file group object for this file */
- mutex_enter(&fscp->fs_fslock);
- fgp = filegrp_list_find(fscp, &cid);
- if (fgp == NULL) {
- fgp = filegrp_create(fscp, &cid);
- filegrp_list_add(fscp, fgp);
- }
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- if (isattrc == 0) {
- cmn_err(CE_WARN,
- "cachefs: cache corruption, run fsck\n");
- delay(5*hz);
- }
- filegrp_list_remove(fscp, fgp);
- filegrp_destroy(fgp);
- error = 0;
- fgp = NULL;
- mutex_exit(&fscp->fs_fslock);
- goto out;
- }
-
- /* if we are victimizing an attrcache file */
- if (isattrc) {
- mutex_enter(&fgp->fg_mutex);
- /* if the filegrp is not writable */
- if ((fgp->fg_flags & CFS_FG_WRITE) == 0) {
- mutex_exit(&fgp->fg_mutex);
- error = EROFS;
- fgp = NULL;
- mutex_exit(&fscp->fs_fslock);
- goto out;
- }
-
- /* if the filegrp did not go active on us */
- if ((fgp->fg_count == 0) && (fgp->fg_header->ach_nffs == 0)) {
- mutex_exit(&fgp->fg_mutex);
- filegrp_list_remove(fscp, fgp);
- fgp->fg_header->ach_count = 0;
- filegrp_destroy(fgp);
- } else {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("c_victim: filegrp went active"
- " %p %llu %d %d %lld\n",
- (void *) fgp,
- (u_longlong_t)fgp->fg_id.cid_fileno,
- fgp->fg_header->ach_rlno,
- fgp->fg_count, fgp->fg_header->ach_nffs);
-#endif
- ASSERT(fgp->fg_header->ach_rl_current !=
- CACHEFS_RL_GC);
- mutex_exit(&fgp->fg_mutex);
- }
- fgp = NULL;
- error = 0;
- mutex_exit(&fscp->fs_fslock);
- goto out;
- }
- ASSERT((fgp->fg_flags & CFS_FG_ALLOC_FILE) == 0);
- filegrp_hold(fgp);
- mutex_exit(&fscp->fs_fslock);
-
- /* grab the cnode list lock */
- mutex_enter(&fgp->fg_cnodelock);
-
- /* see if a cnode exists for this file */
- (void) cachefs_cnode_find(fgp, &cid, NULL, &cp, NULL, NULL);
- if (cp) {
- VN_HOLD(CTOV(cp));
-
- /* move file from rl to active list */
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_ACTIVE, cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_ACTIVE;
- mutex_exit(&cp->c_statelock);
- mutex_exit(&fgp->fg_cnodelock);
- VN_RELE(CTOV(cp));
- error = 0;
- goto out;
- }
-
- /*
- * The cnode does not exist and since we hold the hashlock
- * it cannot be created until we are done.
- */
-
- /* see if the item is no longer on the rl list, it could happen */
- mutex_enter(&cachep->c_contentslock);
- lhp = RL_HEAD(cachep, CACHEFS_RL_GC);
- entno = lhp->rli_front;
- if (entno == 0) {
- mutex_exit(&cachep->c_contentslock);
- mutex_exit(&fgp->fg_cnodelock);
- error = ENOSPC;
- goto out;
- }
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- mutex_exit(&fgp->fg_cnodelock);
- goto out;
- }
- if ((fsid != rl_ent->rl_fsid) ||
- (cid.cid_fileno != rl_ent->rl_fileno)) {
- mutex_exit(&cachep->c_contentslock);
- mutex_exit(&fgp->fg_cnodelock);
- error = 0;
- goto out;
- }
- mutex_exit(&cachep->c_contentslock);
-
- /* Get the metadata from the attrcache file */
- ASSERT((fgp->fg_flags & CFS_FG_ALLOC_ATTR) == 0);
- error = filegrp_read_metadata(fgp, &cid, &md);
- ASSERT(error == 0);
-
- /* md.md_rltype may be incorrect, but we know file isn't active. */
- if (error) {
- /* XXX this should never happen, fix on panic */
- mutex_exit(&fgp->fg_cnodelock);
- error = 0;
- goto out;
- }
-
- /* destroy the frontfile */
- cachefs_removefrontfile(&md, &cid, fgp);
-
- /* remove the victim from the gc list */
- cachefs_rlent_moveto(fscp->fs_cache, CACHEFS_RL_FREE, entno, 0);
-
- /* destroy the metadata */
- (void) filegrp_destroy_metadata(fgp, &cid);
-
- mutex_exit(&fgp->fg_cnodelock);
- error = 0;
-out:
- if (fgp) {
- filegrp_rele(fgp);
- }
- if (fscp) {
- fscache_rele(fscp);
- }
- return (error);
-}
-
-static void
-cachefs_garbage_collect(cachefscache_t *cachep)
-{
- fsfilcnt64_t filelowat, filelowatmax, maxfiles, threshfiles;
- fsblkcnt64_t blocklowat, blocklowatmax, maxblks, threshblks;
- int error;
- struct cache_usage *cup = &cachep->c_usage;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- mutex_enter(&cachep->c_contentslock);
- ASSERT(cachep->c_flags & CACHE_GARBAGE_COLLECT);
- filelowat = cachep->c_label.cl_filelowat;
- blocklowat = cachep->c_label.cl_blklowat;
- maxblks = cachep->c_label.cl_maxblks;
- maxfiles = cachep->c_label.cl_maxinodes;
- threshblks = cachep->c_label.cl_blocktresh;
- threshfiles = cachep->c_label.cl_filetresh;
- mutex_exit(&cachep->c_contentslock);
-
- cachep->c_gc_count++;
- cachep->c_gc_time = time;
- cachep->c_gc_before = cachefs_gc_front_atime(cachep);
-
- /*
- * since we're here, we're running out of blocks or files.
- * file and block lowat are what determine how low we garbage
- * collect. in order to do any good, we should drop below
- * maxblocks, threshblocks, or the current blocks, whichever
- * is smaller (same goes for files). however, we won't go
- * below an arbitrary (small) minimum for each.
- */
-
- /* move down for maxfiles and maxblocks */
- if ((filelowatmax = (maxfiles * 7) / 10) < filelowat)
- filelowat = filelowatmax;
- if ((blocklowatmax = (maxblks * 7) / 10) < blocklowat)
- blocklowat = blocklowatmax;
-
- /* move down for threshfiles and threshblocks */
- if ((filelowatmax = (threshfiles * 7) / 10) < filelowat)
- filelowat = filelowatmax;
- if ((blocklowatmax = (threshblks * 7) / 10) < blocklowat)
- blocklowat = blocklowatmax;
-
- /* move down for current files and blocks */
- if ((filelowatmax = ((fsfilcnt64_t)cup->cu_filesused * 7) / 10) <
- filelowat)
- filelowat = filelowatmax;
- if ((blocklowatmax = ((fsblkcnt64_t)cup->cu_blksused * 7) / 10) <
- blocklowat)
- blocklowat = blocklowatmax;
-
- /* move up for an arbitrary minimum */
-#define MIN_BLKLO 640 /* 640*8192 == 5MB */
-#define MIN_FILELO 1000
- if (filelowat < MIN_FILELO)
- filelowat = MIN_FILELO;
- if (blocklowat < MIN_BLKLO)
- blocklowat = MIN_BLKLO;
-
- while (cup->cu_filesused > filelowat || cup->cu_blksused > blocklowat) {
- /* if the thread is to terminate */
- if (cachep->c_flags & CACHE_CACHEW_THREADEXIT)
- break;
-
- error = cachefs_victim(cachep);
- if (error)
- break;
- }
-
- cachep->c_gc_after = cachefs_gc_front_atime(cachep);
- CACHEFS_TIME_TO_CFS_TIME_COPY(cachep->c_gc_after,
- cachep->c_rlinfo.rl_gctime, error);
-}
-
-/*
- * traverse the packed pending list, repacking files when possible.
- */
-
-static void
-cachefs_packed_pending(cachefscache_t *cachep)
-{
- rl_entry_t rl;
- int error = 0; /* not returned -- used as placeholder */
- fscache_t *fscp = NULL;
- cfs_cid_t cid;
- cnode_t *cp;
- uint_t entno;
- int count = 0;
- cachefs_rl_listhead_t *lhp;
-
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
-
- lhp = RL_HEAD(cachep, CACHEFS_RL_PACKED_PENDING);
- count = lhp->rli_itemcnt;
-
- mutex_exit(&cachep->c_contentslock);
-
- rl.rl_current = CACHEFS_RL_PACKED_PENDING;
- while (cachefs_rlent_data(cachep, &rl, &entno) == 0) {
- if (count-- <= 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs_ppending: count exceeded\n");
-#endif /* CFSDEBUG */
- break;
- }
- if ((cachep->c_flags &
- (CACHE_PACKED_PENDING | CACHE_CACHEW_THREADEXIT)) !=
- CACHE_PACKED_PENDING) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs_ppending: early exit\n");
-#endif /* CFSDEBUG */
- break;
- }
- if (rl.rl_current != CACHEFS_RL_PACKED_PENDING) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs_ppending: gone from list\n");
-#endif /* CFSDEBUG */
- break;
- }
-
- /* if the fscp we have does not match */
- if ((fscp == NULL) || (fscp->fs_cfsid != rl.rl_fsid)) {
- if (fscp) {
- cachefs_cd_release(fscp);
- fscache_rele(fscp);
- fscp = NULL;
- }
-
- /* get the file system cache object for this fsid */
- mutex_enter(&cachep->c_fslistlock);
- fscp = fscache_list_find(cachep, rl.rl_fsid);
- if (fscp == NULL) {
-
- /*
- * uh oh, the filesystem probably
- * isn't mounted. we `move' this
- * entry onto the same list that it's
- * on, which really just moves it to
- * the back of the list. we need not
- * worry about an infinite loop, due
- * to the counter.
- */
-
- cachefs_rlent_moveto(cachep,
- CACHEFS_RL_PACKED_PENDING, entno, 0);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs_ppending: "
- "fscp find failed\n");
-#endif /* CFSDEBUG */
- continue;
- }
- fscache_hold(fscp);
- mutex_exit(&cachep->c_fslistlock);
-
- /* get access to the file system */
- error = cachefs_cd_access(fscp, 0, 0);
- if ((error) ||
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs: "
- "ppending: err %d con %d\n",
- error, fscp->fs_cdconnected);
-#endif /* CFSDEBUG */
- fscache_rele(fscp);
- fscp = NULL;
- break;
- }
- }
-
- /* get the cnode for the file */
- cid.cid_fileno = rl.rl_fileno;
- cid.cid_flags = rl.rl_local ? CFS_CID_LOCAL : 0;
- error = cachefs_cnode_make(&cid, fscp,
- NULL, NULL, NULL, kcred, 0, &cp);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs: "
- "ppending: could not find %llu\n",
- (u_longlong_t)cid.cid_fileno);
- delay(5*hz);
-#endif /* CFSDEBUG */
- break;
- }
-
- mutex_enter(&cp->c_statelock);
- if (cp->c_flags & CN_STALE) {
- /* back file went away behind our back */
- ASSERT(cp->c_metadata.md_rlno == 0);
- mutex_exit(&cp->c_statelock);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs: ppending: stale\n");
-#endif /* CFSDEBUG */
-
- VN_RELE(CTOV(cp));
- continue;
- }
- mutex_exit(&cp->c_statelock);
-
- error = cachefs_pack_common(CTOV(cp),
- (cp->c_cred) ? cp->c_cred : kcred);
- VN_RELE(CTOV(cp));
-
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_RESOURCE)
- printf("cachefs: "
- "ppending: pack_common: error = %d\n",
- error);
-#endif /* CFSDEBUG */
- break;
- }
- }
-
- if (fscp != NULL) {
- cachefs_cd_release(fscp);
- fscache_rele(fscp);
- }
-
- mutex_enter(&cachep->c_contentslock);
- if (lhp->rli_itemcnt == 0)
- cachep->c_flags &= ~CACHE_PACKED_PENDING;
-}
-
-/* seconds; interval to do ppend list */
-static time_t cachefs_ppend_time = 900;
-
-/* main routine for the cachep worker thread */
-void
-cachefs_cachep_worker_thread(cachefscache_t *cachep)
-{
- int error;
- struct flock64 fl;
- callb_cpr_t cprinfo;
- kmutex_t cpr_lock;
- clock_t wakeup;
-
- /* lock the lock file for exclusive write access */
- fl.l_type = F_WRLCK;
- fl.l_whence = 0;
- fl.l_start = (offset_t)0;
- fl.l_len = (offset_t)1024;
- fl.l_sysid = 0;
- fl.l_pid = 0;
- error = VOP_FRLOCK(cachep->c_lockvp, F_SETLK, &fl, FWRITE, (offset_t)0,
- NULL, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN,
- "cachefs: Can't lock Cache Lock File(r); Error %d\n",
- error);
- }
-
- mutex_init(&cpr_lock, NULL, MUTEX_DEFAULT, NULL);
- CALLB_CPR_INIT(&cprinfo, &cpr_lock, callb_generic_cpr, "cfs_gct");
- mutex_enter(&cpr_lock);
- mutex_enter(&cachep->c_contentslock);
-
- wakeup = (clock_t)(cachefs_ppend_time * hz);
-
- /* loop while the thread is allowed to run */
- while ((cachep->c_flags & CACHE_CACHEW_THREADEXIT) == 0) {
- /* wait for a wakeup call */
- cachep->c_flags &= ~CACHE_GARBAGE_COLLECT;
- CALLB_CPR_SAFE_BEGIN(&cprinfo);
- mutex_exit(&cpr_lock);
- (void) cv_reltimedwait(&cachep->c_cwcv,
- &cachep->c_contentslock, wakeup, TR_CLOCK_TICK);
- mutex_enter(&cpr_lock);
- CALLB_CPR_SAFE_END(&cprinfo, &cpr_lock);
-
- /* if the thread is to terminate */
- if (cachep->c_flags & CACHE_CACHEW_THREADEXIT)
- break;
-
- /* thread is running during nofill, but just to hold lock */
- if (cachep->c_flags & CACHE_NOFILL)
- continue;
-
- /* if garbage collection is to run */
- if (cachep->c_flags & CACHE_GARBAGE_COLLECT) {
- mutex_exit(&cachep->c_contentslock);
- cachefs_garbage_collect(cachep);
-
- /*
- * Prevent garbage collection from running more
- * than once every 30 seconds. This addresses
- * those cases which do not allow removing
- * an item from the rl by keeping gc from
- * being a spin loop.
- */
- delay(30*hz); /* XXX sam: still do this? */
- mutex_enter(&cachep->c_contentslock);
- }
-
- if (cachep->c_flags & CACHE_PACKED_PENDING)
- cachefs_packed_pending(cachep);
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
- }
-
- cachep->c_flags &= ~CACHE_CACHEW_THREADRUN;
- cv_broadcast(&cachep->c_cwhaltcv);
- CALLB_CPR_EXIT(&cprinfo);
- mutex_exit(&cachep->c_contentslock);
- mutex_destroy(&cpr_lock);
-
- /* unlock the lock file */
- fl.l_type = F_UNLCK;
- fl.l_whence = 0;
- fl.l_start = (offset_t)0;
- fl.l_len = (offset_t)1024;
- fl.l_sysid = 0;
- fl.l_pid = 0;
- error = VOP_FRLOCK(cachep->c_lockvp, F_SETLK, &fl, FWRITE, (offset_t)0,
- NULL, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: Can't unlock lock file\n");
- }
-
- thread_exit();
- /*NOTREACHED*/
-}
-
-/* queues up a request to run the garbage collection */
-void
-cachefs_garbage_collect_queue(cachefscache_t *cachep)
-{
- cachefs_rl_listhead_t *lhp;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE|CACHE_NOFILL)) == 0);
- mutex_enter(&cachep->c_contentslock);
-
- /* quit if there is no garbage collection thread */
- if ((cachep->c_flags & CACHE_CACHEW_THREADRUN) == 0) {
- mutex_exit(&cachep->c_contentslock);
- return;
- }
-
- /* quit if garbage collection is already in progress */
- if (cachep->c_flags & CACHE_GARBAGE_COLLECT) {
- mutex_exit(&cachep->c_contentslock);
- return;
- }
-
- /* quit if there is no garbage to collect */
- lhp = RL_HEAD(cachep, CACHEFS_RL_GC);
- if (lhp->rli_front == 0) {
- mutex_exit(&cachep->c_contentslock);
- return;
- }
-
- /* indicate garbage collecting is in progress */
- cachep->c_flags |= CACHE_GARBAGE_COLLECT;
-
- /* wake up the garbage collection thread */
- cv_signal(&cachep->c_cwcv);
-
- mutex_exit(&cachep->c_contentslock);
-}
-
-#ifdef CFSRLDEBUG
-time_t cachefs_dbvalid = 123; /* default to non-zero junk */
-struct kmem_cache *cachefs_rl_debug_cache = NULL;
-static int cachefs_rl_debug_maxcount = CACHEFS_RLDB_DEF_MAXCOUNT;
-kmutex_t cachefs_rl_debug_mutex;
-static int cachefs_rl_debug_inuse = 0;
-
-void
-cachefs_rl_debug_reclaim(void *cdrarg)
-{
- extern cachefscache_t *cachefs_cachelist;
- cachefscache_t *cachep;
- int index;
- int error;
-
- for (cachep = cachefs_cachelist; cachep != NULL;
- cachep = cachep->c_next) {
- mutex_enter(&cachep->c_contentslock);
-
- for (index = 0;
- index <= cachep->c_rlinfo.rl_entries;
- index++) {
- rl_entry_t *rlent;
-
- error = cachefs_rl_entry_get(cachep, index, &rlent);
- if (error)
- break;
- cachefs_rl_debug_destroy(rlent);
- }
-
- mutex_exit(&cachep->c_contentslock);
- }
-}
-
-void
-cachefs_rl_debug_save(rl_entry_t *rlent)
-{
- rl_debug_t *rldb, *prev, *next;
- int count = 0;
-
- mutex_enter(&cachefs_rl_debug_mutex);
- if (cachefs_rl_debug_cache == NULL)
- cachefs_rl_debug_cache =
- kmem_cache_create("cachefs_rl_debug",
- sizeof (rl_debug_t), 0,
- NULL, NULL, cachefs_rl_debug_reclaim, NULL, NULL, 0);
-
- rldb = kmem_cache_alloc(cachefs_rl_debug_cache, KM_SLEEP);
- ++cachefs_rl_debug_inuse;
-
- rldb->db_hrtime = gethrtime();
-
- rldb->db_attrc = rlent->rl_attrc;
- rldb->db_fsck = rlent->rl_fsck;
- rldb->db_fsid = rlent->rl_fsid;
- rldb->db_fileno = rlent->rl_fileno;
- rldb->db_current = rlent->rl_current;
-
- rldb->db_stackheight = getpcstack(rldb->db_stack,
- CACHEFS_RLDB_STACKSIZE);
-
- if (rlent->rl_dbvalid == cachefs_dbvalid) {
- rldb->db_next = rlent->rl_debug;
- } else {
- rldb->db_next = NULL;
- rlent->rl_dbvalid = cachefs_dbvalid;
- }
- rlent->rl_debug = rldb;
-
- prev = rldb;
- for (rldb = rldb->db_next; rldb != NULL; rldb = next) {
- next = rldb->db_next;
- if (++count >= cachefs_rl_debug_maxcount) {
- if (prev != NULL)
- prev->db_next = NULL;
- kmem_cache_free(cachefs_rl_debug_cache, rldb);
- --cachefs_rl_debug_inuse;
- prev = NULL;
- } else {
- prev = rldb;
- }
- }
- mutex_exit(&cachefs_rl_debug_mutex);
-}
-
-void
-cachefs_rl_debug_show(rl_entry_t *rlent)
-{
- rl_debug_t *rldb;
- hrtime_t now, elapse;
- timestruc_t tv;
- char *cname = NULL;
- int i;
-
- mutex_enter(&cachefs_rl_debug_mutex);
- if (rlent->rl_dbvalid != cachefs_dbvalid) {
- printf("cachefs_rldb: rl entry at %lx -- no info!\n",
- (uintptr_t)rlent);
- mutex_exit(&cachefs_rl_debug_mutex);
- return;
- }
-
- now = gethrtime();
- hrt2ts(now, &tv);
-
- printf("===== cachefs_rldb start at %ld =====\n", tv.tv_sec);
- printf("-==== i am thread id %lx ====-\n", (uintptr_t)curthread);
-
- for (rldb = rlent->rl_debug;
- rldb != NULL;
- rldb = rldb->db_next) {
- printf("----- cachefs_rldb record start -----\n");
- elapse = now - rldb->db_hrtime;
- hrt2ts(elapse, &tv);
- printf("cachefs_rldb: ago = %lds %ldus\n",
- tv.tv_sec, tv.tv_nsec / 1000);
-
- printf("cachefs_rldb: rl_attrc = %d\n", rldb->db_attrc);
- printf("cachefs_rldb: rl_fsck = %d\n", rldb->db_fsck);
- printf("cachefs_rldb: rl_fsid = %u\n", rldb->db_fsid);
- printf("cachefs_rldb: rl_fileno = %lu\n", rldb->db_fileno);
-
- switch (rldb->db_current) {
- case CACHEFS_RL_NONE:
- cname = "CACHEFS_RL_NONE";
- break;
- case CACHEFS_RL_FREE:
- cname = "CACHEFS_RL_FREE";
- break;
- case CACHEFS_RL_GC:
- cname = "CACHEFS_RL_GC";
- break;
- case CACHEFS_RL_ACTIVE:
- cname = "CACHEFS_RL_ACTIVE";
- break;
- case CACHEFS_RL_ATTRFILE:
- cname = "CACHEFS_RL_ATTRFILE";
- break;
- case CACHEFS_RL_MODIFIED:
- cname = "CACHEFS_RL_MODIFIED";
- break;
- case CACHEFS_RL_PACKED:
- cname = "CACHEFS_RL_PACKED";
- break;
- case CACHEFS_RL_PACKED_PENDING:
- cname = "CACHEFS_RL_PACKED_PENDING";
- break;
- case CACHEFS_RL_MF:
- cname = "CACHEFS_MF_GC";
- break;
- }
- if (cname != NULL) {
- printf("cachefs_rldb: state = %s\n", cname);
- } else {
- printf("cachefs_rldb: undefined state %x\n",
- rldb->db_current);
- }
-
- printf("cachefs_rldb: stack trace\n");
- for (i = 0; i < rldb->db_stackheight; i++) {
- char *sym;
- uint_t off;
-
- sym = kobj_getsymname(rldb->db_stack[i], &off);
- printf("cachefs_rldb: %s+%lx\n",
- sym ? sym : "?", off);
- delay(hz/4);
- }
-
- printf("----- cachefs_rldb record end -----\n");
- }
-
- mutex_exit(&cachefs_rl_debug_mutex);
-}
-
-void
-cachefs_rl_debug_destroy(rl_entry_t *rlent)
-{
- rl_debug_t *rldb, *next;
-
- mutex_enter(&cachefs_rl_debug_mutex);
- if (rlent->rl_dbvalid != cachefs_dbvalid) {
- rlent->rl_debug = NULL;
- mutex_exit(&cachefs_rl_debug_mutex);
- return;
- }
-
- for (rldb = rlent->rl_debug; rldb != NULL; rldb = next) {
- next = rldb->db_next;
- kmem_cache_free(cachefs_rl_debug_cache, rldb);
- --cachefs_rl_debug_inuse;
- }
-
- rlent->rl_debug = NULL;
- mutex_exit(&cachefs_rl_debug_mutex);
-}
-#endif /* CFSRLDEBUG */
-
-int
-cachefs_rl_entry_get(cachefscache_t *cachep, uint_t entno, rl_entry_t **ent)
-{
- rl_entry_t *rl_ent;
- uint_t whichwindow, winoffset;
- int error = 0;
-
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
- ASSERT(entno <= cachep->c_label.cl_maxinodes); /* strictly less? */
-#if 0
- ASSERT((cachep->c_flags & CACHE_NOFILL) == 0);
-#endif
-
- whichwindow = entno / CACHEFS_RLPMBS;
- winoffset = entno % CACHEFS_RLPMBS;
-
- if ((cachep->c_rl_entries == NULL) ||
- (cachep->c_rl_window != whichwindow)) {
- if (cachep->c_rl_entries != NULL) {
- error = vn_rdwr(UIO_WRITE, cachep->c_resfilevp,
- (caddr_t)cachep->c_rl_entries, MAXBSIZE,
- (offset_t)((cachep->c_rl_window + 1) * MAXBSIZE),
- UIO_SYSSPACE, 0, RLIM_INFINITY, kcred, NULL);
- if (error)
- return (error);
- }
- else
- cachep->c_rl_entries = (rl_entry_t *)
- cachefs_kmem_alloc(MAXBSIZE, KM_SLEEP);
-
- error = vn_rdwr(UIO_READ, cachep->c_resfilevp,
- (caddr_t)cachep->c_rl_entries, MAXBSIZE,
- (offset_t)((whichwindow + 1) * MAXBSIZE),
- UIO_SYSSPACE, 0, RLIM_INFINITY, kcred, NULL);
- if (error) {
- cachefs_kmem_free(cachep->c_rl_entries, MAXBSIZE);
- cachep->c_rl_entries = NULL;
- return (error);
- }
- cachep->c_rl_window = whichwindow;
- }
- rl_ent = &cachep->c_rl_entries[winoffset];
-
- *ent = rl_ent;
-#ifdef CFSRLDEBUG
- cachefs_rl_debug_save(rl_ent);
-#endif /* CFSRLDEBUG */
-
- return (error);
-}
-
-static time_t
-cachefs_gc_front_atime(cachefscache_t *cachep)
-{
- char namebuf[CFS_FRONTFILE_NAME_SIZE];
-
- rl_entry_t rl, *rl_ent;
- uint_t entno, fgsize;
- cfs_cid_t dircid, cid;
- struct fscache *fscp;
- cachefs_rl_listhead_t *lhp;
- int error;
-
- struct vnode *dirvp, *filevp;
- struct vattr va;
-
- int reledir = 0;
- int gotfile = 0;
- time_t rc = (time_t)0;
-
- mutex_enter(&cachep->c_contentslock);
- lhp = RL_HEAD(cachep, CACHEFS_RL_GC);
- entno = lhp->rli_front;
- if (entno == 0) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
-
- error = cachefs_rl_entry_get(cachep, entno, &rl_ent);
- if (error) {
- mutex_exit(&cachep->c_contentslock);
- goto out;
- }
- rl = *rl_ent;
- mutex_exit(&cachep->c_contentslock);
- cid.cid_fileno = rl.rl_fileno;
- ASSERT(rl.rl_local == 0);
- cid.cid_flags = 0;
- dircid.cid_flags = 0;
- mutex_enter(&cachep->c_fslistlock);
- if ((fscp = fscache_list_find(cachep, rl.rl_fsid)) == NULL) {
- mutex_exit(&cachep->c_fslistlock);
- goto out;
- }
-
- if (rl.rl_attrc) {
- make_ascii_name(&cid, namebuf);
- dirvp = fscp->fs_fsattrdir;
- } else {
- dirvp = NULL;
- fgsize = fscp->fs_info.fi_fgsize;
- dircid.cid_fileno = ((cid.cid_fileno / fgsize) * fgsize);
- make_ascii_name(&dircid, namebuf);
- if (VOP_LOOKUP(fscp->fs_fscdirvp, namebuf,
- &dirvp, (struct pathname *)NULL, 0,
- (vnode_t *)NULL, kcred, NULL, NULL, NULL) == 0) {
- make_ascii_name(&cid, namebuf);
- reledir++;
- } else {
- mutex_exit(&cachep->c_fslistlock);
- goto out;
- }
- }
- if (dirvp && VOP_LOOKUP(dirvp, namebuf, &filevp,
- (struct pathname *)NULL, 0,
- (vnode_t *)NULL, kcred, NULL, NULL, NULL) == 0) {
- gotfile = 1;
- }
- if (reledir)
- VN_RELE(dirvp);
- mutex_exit(&cachep->c_fslistlock);
-
- if (gotfile) {
- va.va_mask = AT_ATIME;
- if (VOP_GETATTR(filevp, &va, 0, kcred, NULL) == 0)
- rc = va.va_atime.tv_sec;
- VN_RELE(filevp);
- }
-
-out:
- return (rc);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_strict.c b/usr/src/uts/common/fs/cachefs/cachefs_strict.c
deleted file mode 100644
index 9a4011b459..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_strict.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <netinet/in.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/bootconf.h>
-#include <sys/modctl.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-
-#define C_CACHE_VALID(SAVED_MTIME, NEW_MTIME) \
- ((SAVED_MTIME.tv_sec == NEW_MTIME.tv_sec) && \
- (SAVED_MTIME.tv_nsec == NEW_MTIME.tv_nsec))
-
-static time_t cachefs_gettime_cached_object(struct fscache *fscp,
- struct cnode *cp, time_t mtime);
-
-static int
-c_strict_init_cached_object(fscache_t *fscp, cnode_t *cp, vattr_t *vap,
- cred_t *cr)
-{
- int error;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(cr);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* if attributes not passed in then get them */
- if (vap == NULL) {
- /* if not connected then cannot get attrs */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- return (ETIMEDOUT);
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- return (error);
- }
-
- /* get the attributes */
- cp->c_attr.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &cp->c_attr, 0, cr, NULL);
- if (error)
- return (error);
- } else {
- /* copy passed in attributes into the cnode */
- cp->c_attr = *vap;
- }
-
- /*
- * Expire time is based on the number of seconds since
- * the last change.
- * (i.e. files that changed recently are likely to change soon)
- */
- mdp->md_x_time.tv_nsec = 0;
- mdp->md_x_time.tv_sec = cachefs_gettime_cached_object(fscp, cp,
- cp->c_attr.va_mtime.tv_sec);
- mdp->md_consttype = CFS_FS_CONST_STRICT;
- cp->c_size = cp->c_attr.va_size;
- cp->c_flags |= CN_UPDATED;
-
- return (0);
-}
-
-static int
-c_strict_check_cached_object(struct fscache *fscp, struct cnode *cp,
- int verify_what, cred_t *cr)
-{
- struct vattr attrs;
- int error = 0;
- int fail = 0, backhit = 0;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_strict_check_cached_object: ENTER cp %p\n",
- (void *)cp);
-#endif
-
- ASSERT(cr);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL))
- goto out;
-
- /*
- * If backfs is NFSv4, do a getattr to update link count,
- * all other attributes are not used, and the backfs is
- * called on a getattr request.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- backhit = 1;
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error)
- goto out;
- cp->c_attr = attrs;
- goto out;
- }
-
- /* done if do not have to check and time has not expired */
- if (((verify_what & C_BACK_CHECK) == 0) &&
- (gethrestime_sec() < mdp->md_x_time.tv_sec) &&
- ((mdp->md_flags & MD_NEEDATTRS) == 0))
- goto out;
-
- /* get backvp if necessary */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
-
- /*
- * If the cnode is being populated, and we're not the populating
- * thread, then block until the pop thread completes. If we are the
- * pop thread, then we may come in here, but not to nuke the directory
- * cnode at a critical juncture.
- */
-again:
- while ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread)) {
- cv_wait(&cp->c_popcv, &cp->c_statelock);
-
- /*
- * recheck backvp and connectivity - if backvp now null,
- * something bad happened, so don't bother trying to 'get' it
- */
- if ((cp->c_backvp == NULL) ||
- (fscp->fs_cdconnected != CFS_CD_CONNECTED) ||
- (fscp->fs_backvfsp == NULL)) {
- if (cp->c_flags | CN_STALE) {
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- }
- goto out;
- }
- }
-
- /* get the file attributes from the back fs */
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- backhit = 1;
- if (error)
- goto out;
-
- /* if the mtime or size of the file has changed */
- if ((!C_CACHE_VALID(mdp->md_vattr.va_mtime, attrs.va_mtime) ||
- (cp->c_size != attrs.va_size)) &&
- ((mdp->md_flags & MD_NEEDATTRS) == 0)) {
- fail = 1;
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_INVALIDATE)
- printf("c_strict_check: invalidating %llu\n",
- (u_longlong_t)cp->c_id.cid_fileno);
-#endif
- if (vn_has_cached_data(CTOV(cp))) {
- mutex_exit(&cp->c_statelock);
- error = cachefs_putpage_common(CTOV(cp),
- (offset_t)0, 0, B_INVAL, cr);
- mutex_enter(&cp->c_statelock);
- if (CFS_TIMEOUT(fscp, error))
- goto out;
- error = 0;
- /*
- * if an async pop started while the lock was
- * dropped, go back and try again
- */
- if ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread))
- goto again;
- }
- /*
- * We should properly handle the CN_NOCACHE flag here.
- * In fact, we should remember that cachefs_inval_object()
- * forcibly sets/unsets the flag, so we should keep a
- * state of the flag over the call.
- */
- if ((cp->c_flags & CN_NOCACHE) == 0)
- cachefs_inval_object(cp);
- else {
- cachefs_inval_object(cp);
- cp->c_flags |= CN_NOCACHE;
- }
- if ((CTOV(cp))->v_type == VREG) {
- attrs.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error)
- goto out;
- }
- if (!vn_has_cached_data(CTOV(cp))) {
- cp->c_size = attrs.va_size;
- }
-#ifdef CFSDEBUG
- else {
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_strict_check: v_pages not null\n");
- }
-#endif
- }
-
- /* toss cached acl info if ctime changed */
- if (!C_CACHE_VALID(mdp->md_vattr.va_ctime, attrs.va_ctime)) {
- cachefs_purgeacl(cp);
- }
-
- cp->c_attr = attrs;
- if (attrs.va_size > cp->c_size)
- cp->c_size = attrs.va_size;
- mdp->md_x_time.tv_sec =
- cachefs_gettime_cached_object(fscp, cp, attrs.va_mtime.tv_sec);
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (backhit != 0) {
- if (fail != 0)
- fscp->fs_stats.st_fails++;
- else
- fscp->fs_stats.st_passes++;
- }
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_strict_check_cached_object: EXIT expires %lx\n",
- (long)mdp->md_x_time.tv_sec);
-#endif
- return (error);
-}
-
-static void
-c_strict_modify_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- struct vattr attrs;
- int error = 0;
- nlink_t nlink;
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(fscp->fs_cdconnected == CFS_CD_CONNECTED);
- ASSERT(fscp->fs_backvfsp);
-
- /*
- * Don't do a getattr if NFSv4, which maintains
- * its attributes (and link count) by doing a call
- * to CFSOP_CHECK_COBJECT() during vnode operations.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp))
- goto out;
-
- fscp->fs_stats.st_modifies++;
-
- /* from now on, make sure we're using the server's idea of time */
- mdp->md_flags &= ~(MD_LOCALCTIME | MD_LOCALMTIME);
- mdp->md_flags |= MD_NEEDATTRS;
-
- /* if in write-around mode, make sure file is nocached */
- if (CFS_ISFS_WRITE_AROUND(fscp)) {
- if ((cp->c_flags & CN_NOCACHE) == 0)
- cachefs_nocache(cp);
-
- /*
- * If a directory, then defer getting the new attributes
- * until requested. Might be a little bit faster this way.
- */
- if (CTOV(cp)->v_type == VDIR)
- goto out;
- }
-
- /* get the new mtime so the next call to check_cobject does not fail */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error) {
- mdp->md_vattr.va_mtime.tv_sec = 0;
- goto out;
- }
- }
-
- attrs.va_mask = AT_ALL;
- ASSERT(cp->c_backvp != NULL);
- error = VOP_GETATTR(cp->c_backvp, &attrs, 0, cr, NULL);
- if (error) {
- mdp->md_vattr.va_mtime.tv_sec = 0;
- goto out;
- }
-
- mdp->md_x_time.tv_sec =
- cachefs_gettime_cached_object(fscp, cp, attrs.va_mtime.tv_sec);
- nlink = cp->c_attr.va_nlink;
- cp->c_attr = attrs;
- cp->c_attr.va_nlink = nlink;
- if ((attrs.va_size > cp->c_size) || !vn_has_cached_data(CTOV(cp)))
- cp->c_size = attrs.va_size;
- mdp->md_flags &= ~MD_NEEDATTRS;
- cachefs_cnode_setlocalstats(cp);
-out:
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_strict_invalidate_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- mdp->md_vattr.va_mtime.tv_sec = 0;
- mdp->md_flags |= MD_NEEDATTRS;
- cp->c_flags |= CN_UPDATED;
-}
-
-/*ARGSUSED*/
-static void
-c_strict_convert_cached_object(struct fscache *fscp, struct cnode *cp,
- cred_t *cr)
-{
- cachefs_metadata_t *mdp = &cp->c_metadata;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- mdp->md_flags |= MD_NEEDATTRS;
- mdp->md_consttype = CFS_FS_CONST_STRICT;
- cp->c_flags |= CN_UPDATED;
-}
-
-/*
- * Returns the tod in secs when the consistency of the object should
- * be checked.
- */
-static time_t
-cachefs_gettime_cached_object(struct fscache *fscp, struct cnode *cp,
- time_t mtime)
-{
- time_t xsec;
- time_t acmin, acmax;
- time_t now;
-
- /*
- * Expire time is based on the number of seconds since the last change
- * (i.e. files that changed recently are likely to change soon),
- */
- if ((CTOV(cp))->v_type == VDIR) {
- acmin = fscp->fs_acdirmin;
- acmax = fscp->fs_acdirmax;
- } else {
- acmin = fscp->fs_acregmin;
- acmax = fscp->fs_acregmax;
- }
-
- now = gethrestime_sec();
- xsec = now - mtime;
- xsec = MAX(xsec, acmin);
- xsec = MIN(xsec, acmax);
- xsec += now;
- return (xsec);
-}
-
-struct cachefsops strictcfsops = {
- c_strict_init_cached_object,
- c_strict_check_cached_object,
- c_strict_modify_cached_object,
- c_strict_invalidate_cached_object,
- c_strict_convert_cached_object
-};
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_subr.c b/usr/src/uts/common/fs/cachefs/cachefs_subr.c
deleted file mode 100644
index c1ab7f0b05..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_subr.c
+++ /dev/null
@@ -1,2916 +0,0 @@
-/*
- * 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
- * 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 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/modctl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/fbuf.h>
-#include <sys/dnlc.h>
-#include <sys/callb.h>
-#include <sys/kobj.h>
-#include <sys/rwlock.h>
-
-#include <sys/vmsystm.h>
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-#include <sys/fs/cachefs_dir.h>
-
-extern struct seg *segkmap;
-caddr_t segmap_getmap();
-int segmap_release();
-
-extern struct cnode *cachefs_freeback;
-extern struct cnode *cachefs_freefront;
-extern cachefscache_t *cachefs_cachelist;
-
-#ifdef CFSDEBUG
-int cachefsdebug = 0;
-#endif
-
-int cachefs_max_threads = CFS_MAX_THREADS;
-ino64_t cachefs_check_fileno = 0;
-struct kmem_cache *cachefs_cache_kmcache = NULL;
-struct kmem_cache *cachefs_req_cache = NULL;
-
-static int
-cachefs_async_populate_reg(struct cachefs_populate_req *, cred_t *,
- vnode_t *, vnode_t *);
-
-/*
- * Cache routines
- */
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_create
- *
- * Description:
- * Creates a cachefscache_t object and initializes it to
- * be NOCACHE and NOFILL mode.
- * Arguments:
- * Returns:
- * Returns a pointer to the created object or NULL if
- * threads could not be created.
- * Preconditions:
- */
-
-cachefscache_t *
-cachefs_cache_create(void)
-{
- cachefscache_t *cachep;
- struct cachefs_req *rp;
-
- /* allocate zeroed memory for the object */
- cachep = kmem_cache_alloc(cachefs_cache_kmcache, KM_SLEEP);
-
- bzero(cachep, sizeof (*cachep));
-
- cv_init(&cachep->c_cwcv, NULL, CV_DEFAULT, NULL);
- cv_init(&cachep->c_cwhaltcv, NULL, CV_DEFAULT, NULL);
- mutex_init(&cachep->c_contentslock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachep->c_fslistlock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&cachep->c_log_mutex, NULL, MUTEX_DEFAULT, NULL);
-
- /* set up the work queue and get the sync thread created */
- cachefs_workq_init(&cachep->c_workq);
- cachep->c_workq.wq_keepone = 1;
- cachep->c_workq.wq_cachep = cachep;
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- rp->cfs_cmd = CFS_NOOP;
- rp->cfs_cr = kcred;
- rp->cfs_req_u.cu_fs_sync.cf_cachep = cachep;
- crhold(rp->cfs_cr);
- cachefs_addqueue(rp, &cachep->c_workq);
- cachep->c_flags |= CACHE_NOCACHE | CACHE_NOFILL | CACHE_ALLOC_PENDING;
-
- return (cachep);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_destroy
- *
- * Description:
- * Destroys the cachefscache_t object.
- * Arguments:
- * cachep the cachefscache_t object to destroy
- * Returns:
- * Preconditions:
- * precond(cachep)
- */
-
-void
-cachefs_cache_destroy(cachefscache_t *cachep)
-{
- int error = 0;
-#ifdef CFSRLDEBUG
- uint_t index;
-#endif /* CFSRLDEBUG */
- clock_t wakeup = (60 * hz);
-
- /* stop async threads */
- while (cachep->c_workq.wq_thread_count > 0)
- (void) cachefs_async_halt(&cachep->c_workq, 1);
-
- /* kill off the cachep worker thread */
- mutex_enter(&cachep->c_contentslock);
- while (cachep->c_flags & CACHE_CACHEW_THREADRUN) {
- cachep->c_flags |= CACHE_CACHEW_THREADEXIT;
- cv_signal(&cachep->c_cwcv);
- (void) cv_reltimedwait(&cachep->c_cwhaltcv,
- &cachep->c_contentslock, wakeup, TR_CLOCK_TICK);
- }
-
- if ((cachep->c_flags & CACHE_ALLOC_PENDING) == 0) {
- cachep->c_usage.cu_flags &= ~CUSAGE_ACTIVE;
- (void) cachefs_cache_rssync(cachep);
- }
- mutex_exit(&cachep->c_contentslock);
-
- /* if there is a cache */
- if ((cachep->c_flags & CACHE_NOCACHE) == 0) {
- if ((cachep->c_flags & CACHE_NOFILL) == 0) {
-#ifdef CFSRLDEBUG
- /* blow away dangling rl debugging info */
- mutex_enter(&cachep->c_contentslock);
- for (index = 0;
- index <= cachep->c_rlinfo.rl_entries;
- index++) {
- rl_entry_t *rlent;
-
- error = cachefs_rl_entry_get(cachep, index,
- rlent);
- /*
- * Since we are destroying the cache,
- * better to ignore and proceed
- */
- if (error)
- break;
- cachefs_rl_debug_destroy(rlent);
- }
- mutex_exit(&cachep->c_contentslock);
-#endif /* CFSRLDEBUG */
-
- /* sync the cache */
- if (!error)
- cachefs_cache_sync(cachep);
- } else {
- /* get rid of any unused fscache objects */
- mutex_enter(&cachep->c_fslistlock);
- fscache_list_gc(cachep);
- mutex_exit(&cachep->c_fslistlock);
- }
- ASSERT(cachep->c_fslist == NULL);
-
- VN_RELE(cachep->c_resfilevp);
- VN_RELE(cachep->c_dirvp);
- VN_RELE(cachep->c_lockvp);
- VN_RELE(cachep->c_lostfoundvp);
- }
-
- if (cachep->c_log_ctl != NULL)
- cachefs_kmem_free(cachep->c_log_ctl,
- sizeof (cachefs_log_control_t));
- if (cachep->c_log != NULL)
- cachefs_log_destroy_cookie(cachep->c_log);
-
- cv_destroy(&cachep->c_cwcv);
- cv_destroy(&cachep->c_cwhaltcv);
- mutex_destroy(&cachep->c_contentslock);
- mutex_destroy(&cachep->c_fslistlock);
- mutex_destroy(&cachep->c_log_mutex);
-
- kmem_cache_free(cachefs_cache_kmcache, cachep);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_active_ro
- *
- * Description:
- * Activates the cachefscache_t object for a read-only file system.
- * Arguments:
- * cachep the cachefscache_t object to activate
- * cdvp the vnode of the cache directory
- * Returns:
- * Returns 0 for success, !0 if there is a problem with the cache.
- * Preconditions:
- * precond(cachep)
- * precond(cdvp)
- * precond(cachep->c_flags & CACHE_NOCACHE)
- */
-
-int
-cachefs_cache_activate_ro(cachefscache_t *cachep, vnode_t *cdvp)
-{
- cachefs_log_control_t *lc;
- vnode_t *labelvp = NULL;
- vnode_t *rifvp = NULL;
- vnode_t *lockvp = NULL;
- vnode_t *statevp = NULL;
- vnode_t *lostfoundvp = NULL;
- struct vattr *attrp = NULL;
- int error;
-
- ASSERT(cachep->c_flags & CACHE_NOCACHE);
- mutex_enter(&cachep->c_contentslock);
-
- attrp = cachefs_kmem_alloc(sizeof (struct vattr), KM_SLEEP);
-
- /* get the mode bits of the cache directory */
- attrp->va_mask = AT_ALL;
- error = VOP_GETATTR(cdvp, attrp, 0, kcred, NULL);
- if (error)
- goto out;
-
- /* ensure the mode bits are 000 to keep out casual users */
- if (attrp->va_mode & S_IAMB) {
- cmn_err(CE_WARN, "cachefs: Cache Directory Mode must be 000\n");
- error = EPERM;
- goto out;
- }
-
- /* Get the lock file */
- error = VOP_LOOKUP(cdvp, CACHEFS_LOCK_FILE, &lockvp, NULL, 0, NULL,
- kcred, NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_a: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- /* Get the label file */
- error = VOP_LOOKUP(cdvp, CACHELABEL_NAME, &labelvp, NULL, 0, NULL,
- kcred, NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_b: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- /* read in the label */
- error = vn_rdwr(UIO_READ, labelvp, (caddr_t)&cachep->c_label,
- sizeof (struct cache_label), 0LL, UIO_SYSSPACE,
- 0, (rlim64_t)0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_c: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- /* Verify that we can handle the version this cache was created under */
- if (cachep->c_label.cl_cfsversion != CFSVERSION) {
- cmn_err(CE_WARN, "cachefs: Invalid Cache Version, run fsck\n");
- error = EINVAL;
- goto out;
- }
-
- /* Open the resource file */
- error = VOP_LOOKUP(cdvp, RESOURCE_NAME, &rifvp, NULL, 0, NULL, kcred,
- NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_d: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- /* Read the usage struct for this cache */
- error = vn_rdwr(UIO_READ, rifvp, (caddr_t)&cachep->c_usage,
- sizeof (struct cache_usage), 0LL, UIO_SYSSPACE, 0,
- (rlim64_t)0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_e: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- if (cachep->c_usage.cu_flags & CUSAGE_ACTIVE) {
- cmn_err(CE_WARN, "cachefs: cache not clean. Run fsck\n");
- /* ENOSPC is what UFS uses for clean flag check */
- error = ENOSPC;
- goto out;
- }
-
- /* Read the rlinfo for this cache */
- error = vn_rdwr(UIO_READ, rifvp, (caddr_t)&cachep->c_rlinfo,
- sizeof (cachefs_rl_info_t), (offset_t)sizeof (struct cache_usage),
- UIO_SYSSPACE, 0, 0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_f: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- /* Open the lost+found directory */
- error = VOP_LOOKUP(cdvp, CACHEFS_LOSTFOUND_NAME, &lostfoundvp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: activate_g: cache corruption"
- " run fsck.\n");
- goto out;
- }
-
- VN_HOLD(rifvp);
- VN_HOLD(cdvp);
- VN_HOLD(lockvp);
- VN_HOLD(lostfoundvp);
- cachep->c_resfilevp = rifvp;
- cachep->c_dirvp = cdvp;
- cachep->c_lockvp = lockvp;
- cachep->c_lostfoundvp = lostfoundvp;
-
- /* get the cachep worker thread created */
- cachep->c_flags |= CACHE_CACHEW_THREADRUN;
- (void) thread_create(NULL, 0, cachefs_cachep_worker_thread,
- cachep, 0, &p0, TS_RUN, minclsyspri);
-
- /* allocate the `logging control' field */
- mutex_enter(&cachep->c_log_mutex);
- cachep->c_log_ctl =
- cachefs_kmem_zalloc(sizeof (cachefs_log_control_t), KM_SLEEP);
- lc = (cachefs_log_control_t *)cachep->c_log_ctl;
-
- /* if the LOG_STATUS_NAME file exists, read it in and set up logging */
- error = VOP_LOOKUP(cachep->c_dirvp, LOG_STATUS_NAME, &statevp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if (error == 0) {
- int vnrw_error;
-
- vnrw_error = vn_rdwr(UIO_READ, statevp, (caddr_t)lc,
- sizeof (*lc), 0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY,
- kcred, NULL);
- VN_RELE(statevp);
-
- if (vnrw_error == 0) {
- if ((cachep->c_log = cachefs_log_create_cookie(lc))
- == NULL)
- cachefs_log_error(cachep, ENOMEM, 0);
- else if ((lc->lc_magic != CACHEFS_LOG_MAGIC) ||
- (lc->lc_path[0] != '/') ||
- (cachefs_log_logfile_open(cachep,
- lc->lc_path) != 0))
- cachefs_log_error(cachep, EINVAL, 0);
- }
- } else {
- error = 0;
- }
- lc->lc_magic = CACHEFS_LOG_MAGIC;
- lc->lc_cachep = (uint64_t)(uintptr_t)cachep;
- mutex_exit(&cachep->c_log_mutex);
-
-out:
- if (error == 0) {
- cachep->c_flags &= ~(CACHE_NOCACHE | CACHE_ALLOC_PENDING);
- }
- if (attrp)
- cachefs_kmem_free(attrp, sizeof (struct vattr));
- if (labelvp != NULL)
- VN_RELE(labelvp);
- if (rifvp != NULL)
- VN_RELE(rifvp);
- if (lockvp)
- VN_RELE(lockvp);
- if (lostfoundvp)
- VN_RELE(lostfoundvp);
-
- mutex_exit(&cachep->c_contentslock);
- return (error);
-}
-
-int
-cachefs_stop_cache(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- filegrp_t *fgp;
- int i;
- int error = 0;
- clock_t wakeup = (60 * hz);
-
- /* XXX verify lock-ordering for this function */
-
- mutex_enter(&cachep->c_contentslock);
-
- /*
- * no work if we're already in nocache mode. hopefully this
- * will be the usual case.
- */
-
- if (cachep->c_flags & CACHE_NOCACHE) {
- mutex_exit(&cachep->c_contentslock);
- return (0);
- }
-
- if ((cachep->c_flags & CACHE_NOFILL) == 0) {
- mutex_exit(&cachep->c_contentslock);
- return (EINVAL);
- }
-
- mutex_exit(&cachep->c_contentslock);
-
- /* We are already not caching if nfsv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- return (0);
- }
-
-#ifdef CFSDEBUG
- mutex_enter(&cachep->c_fslistlock);
- ASSERT(fscp == cachep->c_fslist);
- ASSERT(fscp->fs_next == NULL);
- mutex_exit(&cachep->c_fslistlock);
-
- printf("cachefs_stop_cache: resetting CACHE_NOCACHE\n");
-#endif
-
- /* XXX should i worry about disconnected during boot? */
- error = cachefs_cd_access(fscp, 1, 1);
- if (error)
- goto out;
-
- error = cachefs_async_halt(&fscp->fs_workq, 1);
- ASSERT(error == 0);
- error = cachefs_async_halt(&cachep->c_workq, 1);
- ASSERT(error == 0);
- /* sigh -- best to keep going if async_halt failed. */
- error = 0;
-
- /* XXX current order: cnode, fgp, fscp, cache. okay? */
-
- cachefs_cnode_traverse(fscp, cachefs_cnode_disable_caching);
-
- for (i = 0; i < CFS_FS_FGP_BUCKET_SIZE; i++) {
- for (fgp = fscp->fs_filegrp[i]; fgp != NULL;
- fgp = fgp->fg_next) {
- mutex_enter(&fgp->fg_mutex);
-
- ASSERT((fgp->fg_flags &
- (CFS_FG_WRITE | CFS_FG_UPDATED)) == 0);
- fgp->fg_flags |=
- CFS_FG_ALLOC_FILE |
- CFS_FG_ALLOC_ATTR;
- fgp->fg_flags &= ~CFS_FG_READ;
-
- if (fgp->fg_dirvp) {
- fgp->fg_flags |= CFS_FG_ALLOC_FILE;
- VN_RELE(fgp->fg_dirvp);
- fgp->fg_dirvp = NULL;
- }
- if (fgp->fg_attrvp) {
- fgp->fg_flags |= CFS_FG_ALLOC_ATTR;
- VN_RELE(fgp->fg_attrvp);
- fgp->fg_attrvp = NULL;
- }
-
- mutex_exit(&fgp->fg_mutex);
- }
- }
-
- mutex_enter(&fscp->fs_fslock);
- ASSERT((fscp->fs_flags & (CFS_FS_WRITE)) == 0);
- fscp->fs_flags &= ~(CFS_FS_READ | CFS_FS_DIRTYINFO);
-
- if (fscp->fs_fscdirvp) {
- VN_RELE(fscp->fs_fscdirvp);
- fscp->fs_fscdirvp = NULL;
- }
- if (fscp->fs_fsattrdir) {
- VN_RELE(fscp->fs_fsattrdir);
- fscp->fs_fsattrdir = NULL;
- }
- if (fscp->fs_infovp) {
- VN_RELE(fscp->fs_infovp);
- fscp->fs_infovp = NULL;
- }
- /* XXX dlog stuff? */
-
- mutex_exit(&fscp->fs_fslock);
-
- /*
- * release resources grabbed in cachefs_cache_activate_ro
- */
-
- mutex_enter(&cachep->c_contentslock);
-
- /* kill off the cachep worker thread */
- while (cachep->c_flags & CACHE_CACHEW_THREADRUN) {
- cachep->c_flags |= CACHE_CACHEW_THREADEXIT;
- cv_signal(&cachep->c_cwcv);
- (void) cv_reltimedwait(&cachep->c_cwhaltcv,
- &cachep->c_contentslock, wakeup, TR_CLOCK_TICK);
- }
-
- if (cachep->c_resfilevp) {
- VN_RELE(cachep->c_resfilevp);
- cachep->c_resfilevp = NULL;
- }
- if (cachep->c_dirvp) {
- VN_RELE(cachep->c_dirvp);
- cachep->c_dirvp = NULL;
- }
- if (cachep->c_lockvp) {
- VN_RELE(cachep->c_lockvp);
- cachep->c_lockvp = NULL;
- }
- if (cachep->c_lostfoundvp) {
- VN_RELE(cachep->c_lostfoundvp);
- cachep->c_lostfoundvp = NULL;
- }
-
- mutex_enter(&cachep->c_log_mutex);
- if (cachep->c_log_ctl) {
- cachefs_kmem_free(cachep->c_log_ctl,
- sizeof (cachefs_log_control_t));
- cachep->c_log_ctl = NULL;
- }
- if (cachep->c_log) {
- cachefs_log_destroy_cookie(cachep->c_log);
- cachep->c_log = NULL;
- }
- mutex_exit(&cachep->c_log_mutex);
-
- /* XXX do what mountroot_init does when ! foundcache */
-
- cachep->c_flags |= CACHE_NOCACHE;
- mutex_exit(&cachep->c_contentslock);
-
- /* XXX should i release this here? */
- cachefs_cd_release(fscp);
-
-out:
-
- return (error);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_active_rw
- *
- * Description:
- * Activates the cachefscache_t object for a read-write file system.
- * Arguments:
- * cachep the cachefscache_t object to activate
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond((cachep->c_flags & CACHE_NOCACHE) == 0)
- * precond(cachep->c_flags & CACHE_NOFILL)
- */
-
-void
-cachefs_cache_activate_rw(cachefscache_t *cachep)
-{
- cachefs_rl_listhead_t *lhp;
-
- ASSERT((cachep->c_flags & CACHE_NOCACHE) == 0);
- ASSERT(cachep->c_flags & CACHE_NOFILL);
-
- mutex_enter(&cachep->c_contentslock);
- cachep->c_flags &= ~CACHE_NOFILL;
-
- /* move the active list to the rl list */
- cachefs_rl_cleanup(cachep);
-
- lhp = &cachep->c_rlinfo.rl_items[
- CACHEFS_RL_INDEX(CACHEFS_RL_PACKED_PENDING)];
- if (lhp->rli_itemcnt != 0)
- cachep->c_flags |= CACHE_PACKED_PENDING;
- cachefs_cache_dirty(cachep, 0);
- mutex_exit(&cachep->c_contentslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_dirty
- *
- * Description:
- * Marks the cache as dirty (active).
- * Arguments:
- * cachep the cachefscache_t to mark as dirty
- * lockit 1 means grab contents lock, 0 means caller grabbed it
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(cache is in rw mode)
- */
-
-void
-cachefs_cache_dirty(struct cachefscache *cachep, int lockit)
-{
- int error;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE | CACHE_NOFILL)) == 0);
-
- if (lockit) {
- mutex_enter(&cachep->c_contentslock);
- } else {
- ASSERT(MUTEX_HELD(&cachep->c_contentslock));
- }
- if (cachep->c_flags & CACHE_DIRTY) {
- ASSERT(cachep->c_usage.cu_flags & CUSAGE_ACTIVE);
- } else {
- /*
- * turn on the "cache active" (dirty) flag and write it
- * synchronously to disk
- */
- cachep->c_flags |= CACHE_DIRTY;
- cachep->c_usage.cu_flags |= CUSAGE_ACTIVE;
- if (error = vn_rdwr(UIO_WRITE, cachep->c_resfilevp,
- (caddr_t)&cachep->c_usage, sizeof (struct cache_usage),
- 0LL, UIO_SYSSPACE, FSYNC, (rlim64_t)RLIM_INFINITY,
- kcred, NULL)) {
- cmn_err(CE_WARN,
- "cachefs: clean flag write error: %d\n", error);
- }
- }
-
- if (lockit)
- mutex_exit(&cachep->c_contentslock);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_rssync
- *
- * Description:
- * Syncs out the resource file for the cachefscache_t object.
- * Arguments:
- * cachep the cachefscache_t object to operate on
- * Returns:
- * Returns 0 for success, !0 on an error writing data.
- * Preconditions:
- * precond(cachep)
- * precond(cache is in rw mode)
- */
-
-int
-cachefs_cache_rssync(struct cachefscache *cachep)
-{
- int error;
-
- ASSERT((cachep->c_flags & (CACHE_NOCACHE | CACHE_NOFILL |
- CACHE_ALLOC_PENDING)) == 0);
-
- if (cachep->c_rl_entries != NULL) {
- error = vn_rdwr(UIO_WRITE, cachep->c_resfilevp,
- (caddr_t)cachep->c_rl_entries, MAXBSIZE,
- (offset_t)((cachep->c_rl_window + 1) * MAXBSIZE),
- UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
- if (error)
- cmn_err(CE_WARN,
- "cachefs: Can't Write rl entries Info\n");
- cachefs_kmem_free(cachep->c_rl_entries, MAXBSIZE);
- cachep->c_rl_entries = NULL;
- }
-
- /* write the usage struct for this cache */
- error = vn_rdwr(UIO_WRITE, cachep->c_resfilevp,
- (caddr_t)&cachep->c_usage, sizeof (struct cache_usage),
- 0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: Can't Write Cache Usage Info\n");
- }
-
- /* write the rlinfo for this cache */
- error = vn_rdwr(UIO_WRITE, cachep->c_resfilevp,
- (caddr_t)&cachep->c_rlinfo, sizeof (cachefs_rl_info_t),
- (offset_t)sizeof (struct cache_usage), UIO_SYSSPACE,
- 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: Can't Write Cache RL Info\n");
- }
- error = VOP_FSYNC(cachep->c_resfilevp, FSYNC, kcred, NULL);
- return (error);
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_sync
- *
- * Description:
- * Sync a cache which includes all of its fscaches.
- * Arguments:
- * cachep the cachefscache_t object to sync
- * Returns:
- * Preconditions:
- * precond(cachep)
- * precond(cache is in rw mode)
- */
-
-void
-cachefs_cache_sync(struct cachefscache *cachep)
-{
- struct fscache *fscp;
- struct fscache **syncfsc;
- int nfscs, fscidx;
- int try;
- int done;
-
- if (cachep->c_flags & (CACHE_NOCACHE | CACHE_NOFILL))
- return;
-
- done = 0;
- for (try = 0; (try < 2) && !done; try++) {
-
- nfscs = 0;
-
- /*
- * here we turn off the cache-wide DIRTY flag. If it's still
- * off when the sync completes we can write the clean flag to
- * disk telling fsck it has no work to do.
- */
-#ifdef CFSCLEANFLAG
- mutex_enter(&cachep->c_contentslock);
- cachep->c_flags &= ~CACHE_DIRTY;
- mutex_exit(&cachep->c_contentslock);
-#endif /* CFSCLEANFLAG */
-
- cachefs_log_process_queue(cachep, 1);
-
- mutex_enter(&cachep->c_fslistlock);
- syncfsc = cachefs_kmem_alloc(
- cachep->c_refcnt * sizeof (struct fscache *), KM_SLEEP);
- for (fscp = cachep->c_fslist; fscp; fscp = fscp->fs_next) {
- fscache_hold(fscp);
- ASSERT(nfscs < cachep->c_refcnt);
- syncfsc[nfscs++] = fscp;
- }
- ASSERT(nfscs == cachep->c_refcnt);
- mutex_exit(&cachep->c_fslistlock);
- for (fscidx = 0; fscidx < nfscs; fscidx++) {
- fscp = syncfsc[fscidx];
- fscache_sync(fscp);
- fscache_rele(fscp);
- }
-
- /* get rid of any unused fscache objects */
- mutex_enter(&cachep->c_fslistlock);
- fscache_list_gc(cachep);
- mutex_exit(&cachep->c_fslistlock);
-
- /*
- * here we check the cache-wide DIRTY flag.
- * If it's off,
- * we can write the clean flag to disk.
- */
-#ifdef CFSCLEANFLAG
- mutex_enter(&cachep->c_contentslock);
- if ((cachep->c_flags & CACHE_DIRTY) == 0) {
- if (cachep->c_usage.cu_flags & CUSAGE_ACTIVE) {
- cachep->c_usage.cu_flags &= ~CUSAGE_ACTIVE;
- if (cachefs_cache_rssync(cachep) == 0) {
- done = 1;
- } else {
- cachep->c_usage.cu_flags |=
- CUSAGE_ACTIVE;
- }
- } else {
- done = 1;
- }
- }
- mutex_exit(&cachep->c_contentslock);
-#else /* CFSCLEANFLAG */
- mutex_enter(&cachep->c_contentslock);
- (void) cachefs_cache_rssync(cachep);
- mutex_exit(&cachep->c_contentslock);
- done = 1;
-#endif /* CFSCLEANFLAG */
- cachefs_kmem_free(syncfsc, nfscs * sizeof (struct fscache *));
- }
-}
-
-/*
- * ------------------------------------------------------------------
- *
- * cachefs_cache_unique
- *
- * Description:
- * Arguments:
- * Returns:
- * Returns a unique number.
- * Preconditions:
- * precond(cachep)
- */
-
-uint_t
-cachefs_cache_unique(cachefscache_t *cachep)
-{
- uint_t unique = 0;
- int error = 0;
-
- mutex_enter(&cachep->c_contentslock);
- if (cachep->c_usage.cu_flags & CUSAGE_NEED_ADJUST ||
- ++(cachep->c_unique) == 0) {
- cachep->c_usage.cu_unique++;
-
- if (cachep->c_unique == 0)
- cachep->c_unique = 1;
- cachep->c_flags &= ~CUSAGE_NEED_ADJUST;
- error = cachefs_cache_rssync(cachep);
- }
- if (error == 0)
- unique = (cachep->c_usage.cu_unique << 16) + cachep->c_unique;
- mutex_exit(&cachep->c_contentslock);
- return (unique);
-}
-
-/*
- * Called from c_getfrontfile. Shouldn't be called from anywhere else !
- */
-static int
-cachefs_createfrontfile(cnode_t *cp, struct filegrp *fgp)
-{
- char name[CFS_FRONTFILE_NAME_SIZE];
- struct vattr *attrp = NULL;
- int error = 0;
- int mode;
- int alloc = 0;
- int freefile = 0;
- int ffrele = 0;
- int rlfree = 0;
- rl_entry_t rl_ent;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("c_createfrontfile: ENTER cp %p fgp %p\n",
- (void *)cp, (void *)fgp);
-#endif
-
- ASSERT(cp->c_frontvp == NULL);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- /* quit if we cannot write to the filegrp */
- if ((fgp->fg_flags & CFS_FG_WRITE) == 0) {
- error = ENOENT;
- goto out;
- }
-
- /* find or create the filegrp attrcache file if necessary */
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- error = filegrp_allocattr(fgp);
- if (error)
- goto out;
- }
-
- make_ascii_name(&cp->c_id, name);
-
- /* set up attributes for the front file we want to create */
- attrp = cachefs_kmem_zalloc(sizeof (struct vattr), KM_SLEEP);
- alloc++;
- attrp->va_mode = S_IFREG | 0666;
- mode = 0666;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VREG;
- attrp->va_size = 0;
- attrp->va_mask = AT_SIZE | AT_TYPE | AT_MODE | AT_UID | AT_GID;
-
- /* get a file from the resource counts */
- error = cachefs_allocfile(fgp->fg_fscp->fs_cache);
- if (error) {
- error = EINVAL;
- goto out;
- }
- freefile++;
-
- /* create the metadata slot if necessary */
- if (cp->c_flags & CN_ALLOC_PENDING) {
- error = filegrp_create_metadata(fgp, &cp->c_metadata,
- &cp->c_id);
- if (error) {
- error = EINVAL;
- goto out;
- }
- cp->c_flags &= ~CN_ALLOC_PENDING;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* get an rl entry if necessary */
- if (cp->c_metadata.md_rlno == 0) {
- rl_ent.rl_fileno = cp->c_id.cid_fileno;
- rl_ent.rl_local = (cp->c_id.cid_flags & CFS_CID_LOCAL) ? 1 : 0;
- rl_ent.rl_fsid = fgp->fg_fscp->fs_cfsid;
- rl_ent.rl_attrc = 0;
- error = cachefs_rl_alloc(fgp->fg_fscp->fs_cache, &rl_ent,
- &cp->c_metadata.md_rlno);
- if (error)
- goto out;
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ACTIVE, cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_ACTIVE;
- rlfree++;
- cp->c_flags |= CN_UPDATED; /* XXX sam: do we need this? */
-
- /* increment number of front files */
- error = filegrp_ffhold(fgp);
- if (error) {
- error = EINVAL;
- goto out;
- }
- ffrele++;
- }
-
- if (cp->c_flags & CN_ASYNC_POP_WORKING) {
- /* lookup the already created front file */
- error = VOP_LOOKUP(fgp->fg_dirvp, name, &cp->c_frontvp,
- NULL, 0, NULL, kcred, NULL, NULL, NULL);
- } else {
- /* create the front file */
- error = VOP_CREATE(fgp->fg_dirvp, name, attrp, EXCL, mode,
- &cp->c_frontvp, kcred, 0, NULL, NULL);
- }
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("c_createfrontfile: Can't create cached object"
- " error %u, fileno %llx\n", error,
- (u_longlong_t)cp->c_id.cid_fileno);
-#endif
- goto out;
- }
-
- /* get a copy of the fid of the front file */
- cp->c_metadata.md_fid.fid_len = MAXFIDSZ;
- error = VOP_FID(cp->c_frontvp, &cp->c_metadata.md_fid, NULL);
- if (error) {
- /*
- * If we get back ENOSPC then the fid we passed in was too
- * small. For now we don't do anything and map to EINVAL.
- */
- if (error == ENOSPC) {
- error = EINVAL;
- }
- goto out;
- }
-
- dnlc_purge_vp(cp->c_frontvp);
-
- cp->c_metadata.md_flags |= MD_FILE;
- cp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
-
-out:
- if (error) {
- if (cp->c_frontvp) {
- VN_RELE(cp->c_frontvp);
- (void) VOP_REMOVE(fgp->fg_dirvp, name, kcred, NULL, 0);
- cp->c_frontvp = NULL;
- }
- if (ffrele)
- filegrp_ffrele(fgp);
- if (freefile)
- cachefs_freefile(fgp->fg_fscp->fs_cache);
- if (rlfree) {
-#ifdef CFSDEBUG
- cachefs_rlent_verify(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_ACTIVE, cp->c_metadata.md_rlno);
-#endif /* CFSDEBUG */
- cachefs_rlent_moveto(fgp->fg_fscp->fs_cache,
- CACHEFS_RL_FREE, cp->c_metadata.md_rlno, 0);
- cp->c_metadata.md_rlno = 0;
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
- }
- cachefs_nocache(cp);
- }
- if (alloc)
- cachefs_kmem_free(attrp, sizeof (struct vattr));
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("c_createfrontfile: EXIT error = %d name %s\n", error,
- name);
-#endif
- return (error);
-}
-
-/*
- * Releases resources associated with the front file.
- * Only call this routine if a ffhold has been done.
- * Its okay to call this routine if the front file does not exist.
- * Note: this routine is used even if there is no front file.
- */
-void
-cachefs_removefrontfile(cachefs_metadata_t *mdp, cfs_cid_t *cidp,
- filegrp_t *fgp)
-{
- int error, enoent;
- char name[CFS_FRONTFILE_NAME_SIZE + 2];
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
-
- enoent = 0;
- if (mdp->md_flags & MD_FILE) {
- if (fgp->fg_dirvp == NULL) {
- cmn_err(CE_WARN, "cachefs: remove error, run fsck\n");
- return;
- }
- make_ascii_name(cidp, name);
- error = VOP_REMOVE(fgp->fg_dirvp, name, kcred, NULL, 0);
- if (error == ENOENT)
- enoent = 1;
- if ((error) && (error != ENOENT)) {
- cmn_err(CE_WARN, "UFS remove error %s %d, run fsck\n",
- name, error);
- }
- if (mdp->md_flags & MD_ACLDIR) {
- (void) strcat(name, ".d");
- error = VOP_RMDIR(fgp->fg_dirvp, name, fgp->fg_dirvp,
- kcred, NULL, 0);
- if ((error) && (error != ENOENT)) {
- cmn_err(CE_WARN, "frontfs rmdir error %s %d"
- "; run fsck\n", name, error);
- }
- }
- mdp->md_flags &= ~(MD_FILE | MD_POPULATED | MD_ACL | MD_ACLDIR);
- bzero(&mdp->md_allocinfo, mdp->md_allocents *
- sizeof (struct cachefs_allocmap));
- cachefs_freefile(fgp->fg_fscp->fs_cache);
- }
-
- /*
- * Clear packed bit, fastsymlinks and special files
- * do not have a front file.
- */
- mdp->md_flags &= ~MD_PACKED;
-
- /* XXX either rename routine or move this to caller */
- if (enoent == 0)
- filegrp_ffrele(fgp);
-
- if (mdp->md_frontblks) {
- cachefs_freeblocks(fgp->fg_fscp->fs_cache, mdp->md_frontblks,
- mdp->md_rltype);
- mdp->md_frontblks = 0;
- }
-}
-
-/*
- * This is the interface to the rest of CFS. This takes a cnode, and returns
- * the frontvp (stuffs it in the cnode). This creates an attrcache slot and
- * and frontfile if necessary.
- */
-
-int
-cachefs_getfrontfile(cnode_t *cp)
-{
- struct filegrp *fgp = cp->c_filegrp;
- int error;
- struct vattr va;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("c_getfrontfile: ENTER cp %p\n", (void *)cp);
-#endif
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fgp->fg_fscp) == 0);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /*
- * Now we check to see if there is a front file for this entry.
- * If there is, we get the vnode for it and stick it in the cnode.
- * Otherwise, we create a front file, get the vnode for it and stick
- * it in the cnode.
- */
- if (cp->c_flags & CN_STALE) {
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- goto out;
- }
-
- /*
- * If the cnode is being populated, and we're not the populating
- * thread, then block until the pop thread completes. If we are the
- * pop thread, then we may come in here, but not to nuke the directory
- * cnode at a critical juncture. If we return from a cv_wait and the
- * cnode is now stale, don't bother trying to get the front file.
- */
- while ((cp->c_flags & CN_ASYNC_POP_WORKING) &&
- (cp->c_popthrp != curthread)) {
- cv_wait(&cp->c_popcv, &cp->c_statelock);
- if (cp->c_flags & CN_STALE) {
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- goto out;
- }
- }
-
- if ((cp->c_metadata.md_flags & MD_FILE) == 0) {
-#ifdef CFSDEBUG
- if (cp->c_frontvp != NULL)
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("c_getfrontfile: !MD_FILE and frontvp "
- "not null cp %p\n", (void *)cp);
-#endif
- if (CTOV(cp)->v_type == VDIR)
- ASSERT((cp->c_metadata.md_flags & MD_POPULATED) == 0);
- error = cachefs_createfrontfile(cp, fgp);
- if (error)
- goto out;
- } else {
- /*
- * A front file exists, all we need to do is to grab the fid,
- * do a VFS_VGET() on the fid, stuff the vnode in the cnode,
- * and return.
- */
- if (fgp->fg_dirvp == NULL) {
- cmn_err(CE_WARN, "cachefs: gff0: corrupted file system"
- " run fsck\n");
- cachefs_inval_object(cp);
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- goto out;
- }
- error = VFS_VGET(fgp->fg_dirvp->v_vfsp, &cp->c_frontvp,
- &cp->c_metadata.md_fid);
- if (error || (cp->c_frontvp == NULL)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("cachefs: "
- "gff1: front file system error %d\n",
- error);
-#endif /* CFSDEBUG */
- cachefs_inval_object(cp);
- cp->c_flags |= CN_NOCACHE;
- error = ESTALE;
- goto out;
- }
-
- /* don't need to check timestamps if need_front_sync is set */
- if (cp->c_flags & CN_NEED_FRONT_SYNC) {
- error = 0;
- goto out;
- }
-
- /* don't need to check empty directories */
- if (CTOV(cp)->v_type == VDIR &&
- ((cp->c_metadata.md_flags & MD_POPULATED) == 0)) {
- error = 0;
- goto out;
- }
-
- /* get modify time of the front file */
- va.va_mask = AT_MTIME;
- error = VOP_GETATTR(cp->c_frontvp, &va, 0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN, "cachefs: gff2: front file"
- " system error %d", error);
- cachefs_inval_object(cp);
- error = (cp->c_flags & CN_NOCACHE) ? ESTALE : 0;
- goto out;
- }
-
- /* compare with modify time stored in metadata */
- if (bcmp(&va.va_mtime, &cp->c_metadata.md_timestamp,
- sizeof (timestruc_t)) != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_GENERAL | CFSDEBUG_INVALIDATE) {
- long sec, nsec;
- sec = cp->c_metadata.md_timestamp.tv_sec;
- nsec = cp->c_metadata.md_timestamp.tv_nsec;
- printf("c_getfrontfile: timestamps don't"
- " match fileno %lld va %lx %lx"
- " meta %lx %lx\n",
- (u_longlong_t)cp->c_id.cid_fileno,
- va.va_mtime.tv_sec,
- va.va_mtime.tv_nsec, sec, nsec);
- }
-#endif
- cachefs_inval_object(cp);
- error = (cp->c_flags & CN_NOCACHE) ? ESTALE : 0;
- }
- }
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("c_getfrontfile: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-void
-cachefs_inval_object(cnode_t *cp)
-{
- cachefscache_t *cachep = C_TO_FSCACHE(cp)->fs_cache;
- struct filegrp *fgp = cp->c_filegrp;
- int error;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(cp)) == 0);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT((cp->c_flags & CN_ASYNC_POP_WORKING) == 0 ||
- cp->c_popthrp == curthread);
-#if 0
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("c_inval_object: ENTER cp %p\n", (void *)cp);
- if (cp->c_flags & (CN_ASYNC_POPULATE | CN_ASYNC_POP_WORKING))
- debug_enter("inval object during async pop");
-#endif
- cp->c_flags |= CN_NOCACHE;
-
- /* if we cannot modify the cache */
- if (C_TO_FSCACHE(cp)->fs_cache->c_flags &
- (CACHE_NOFILL | CACHE_NOCACHE)) {
- goto out;
- }
-
- /* if there is a front file */
- if (cp->c_metadata.md_flags & MD_FILE) {
- if (fgp->fg_dirvp == NULL)
- goto out;
-
- /* get the front file vp if necessary */
- if (cp->c_frontvp == NULL) {
-
- error = VFS_VGET(fgp->fg_dirvp->v_vfsp, &cp->c_frontvp,
- &cp->c_metadata.md_fid);
- if (error || (cp->c_frontvp == NULL)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("cachefs: "
- "io: front file error %d\n", error);
-#endif /* CFSDEBUG */
- goto out;
- }
- }
-
- /* truncate the file to zero size */
- error = cachefs_frontfile_size(cp, 0);
- if (error)
- goto out;
- cp->c_flags &= ~CN_NOCACHE;
-
- /* if a directory, v_type is zero if called from initcnode */
- if (cp->c_attr.va_type == VDIR) {
- if (cp->c_usage < CFS_DIRCACHE_COST) {
- cp->c_invals++;
- if (cp->c_invals > CFS_DIRCACHE_INVAL) {
- cp->c_invals = 0;
- }
- } else
- cp->c_invals = 0;
- cp->c_usage = 0;
- }
- } else {
- cp->c_flags &= ~CN_NOCACHE;
- }
-
-out:
- if ((cp->c_metadata.md_flags & MD_PACKED) &&
- (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED) &&
- ((cachep->c_flags & CACHE_NOFILL) == 0)) {
- ASSERT(cp->c_metadata.md_rlno != 0);
- if (cp->c_metadata.md_rltype != CACHEFS_RL_PACKED_PENDING) {
- cachefs_rlent_moveto(cachep,
- CACHEFS_RL_PACKED_PENDING,
- cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_PACKED_PENDING;
- /* unconditionally set CN_UPDATED below */
- }
- }
-
- cachefs_purgeacl(cp);
-
- if (cp->c_flags & CN_ASYNC_POP_WORKING)
- cp->c_flags |= CN_NOCACHE;
- cp->c_metadata.md_flags &= ~(MD_POPULATED | MD_INVALREADDIR |
- MD_FASTSYMLNK);
- cp->c_flags &= ~CN_NEED_FRONT_SYNC;
- cp->c_flags |= CN_UPDATED;
-
- /*
- * If the object invalidated is a directory, the dnlc should be purged
- * to elide all references to this (directory) vnode.
- */
- if (CTOV(cp)->v_type == VDIR)
- dnlc_purge_vp(CTOV(cp));
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("c_inval_object: EXIT\n");
-#endif
-}
-
-void
-make_ascii_name(cfs_cid_t *cidp, char *strp)
-{
- int i = sizeof (uint_t) * 4;
- u_longlong_t index;
- ino64_t name;
-
- if (cidp->cid_flags & CFS_CID_LOCAL)
- *strp++ = 'L';
- name = (ino64_t)cidp->cid_fileno;
- do {
- index = (((u_longlong_t)name) & 0xf000000000000000) >> 60;
- index &= (u_longlong_t)0xf;
- ASSERT(index < (u_longlong_t)16);
- *strp++ = "0123456789abcdef"[index];
- name <<= 4;
- } while (--i);
- *strp = '\0';
-}
-
-void
-cachefs_nocache(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("c_nocache: ENTER cp %p\n", (void *)cp);
-#endif
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- if ((cp->c_flags & CN_NOCACHE) == 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_INVALIDATE)
- printf("cachefs_nocache: invalidating %llu\n",
- (u_longlong_t)cp->c_id.cid_fileno);
-#endif
- /*
- * Here we are waiting until inactive time to do
- * the inval_object. In case we don't get to inactive
- * (because of a crash, say) we set up a timestamp mismatch
- * such that getfrontfile will blow the front file away
- * next time we try to use it.
- */
- cp->c_metadata.md_timestamp.tv_sec = 0;
- cp->c_metadata.md_timestamp.tv_nsec = 0;
- cp->c_metadata.md_flags &= ~(MD_POPULATED | MD_INVALREADDIR |
- MD_FASTSYMLNK);
- cp->c_flags &= ~CN_NEED_FRONT_SYNC;
-
- cachefs_purgeacl(cp);
-
- /*
- * It is possible we can nocache while disconnected.
- * A directory could be nocached by running out of space.
- * A regular file should only be nocached if an I/O error
- * occurs to the front fs.
- * We count on the item staying on the modified list
- * so we do not loose the cid to fid mapping for directories.
- */
-
- if ((cp->c_metadata.md_flags & MD_PACKED) &&
- (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED) &&
- ((cachep->c_flags & CACHE_NOFILL) == 0)) {
- ASSERT(cp->c_metadata.md_rlno != 0);
- if (cp->c_metadata.md_rltype !=
- CACHEFS_RL_PACKED_PENDING) {
- cachefs_rlent_moveto(cachep,
- CACHEFS_RL_PACKED_PENDING,
- cp->c_metadata.md_rlno,
- cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype =
- CACHEFS_RL_PACKED_PENDING;
- /* unconditionally set CN_UPDATED below */
- }
- }
-
- if (CTOV(cp)->v_type == VDIR)
- dnlc_purge_vp(CTOV(cp));
- cp->c_flags |= (CN_NOCACHE | CN_UPDATED);
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_NOCACHE))
- cachefs_log_nocache(cachep, 0, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("c_nocache: EXIT cp %p\n", (void *)cp);
-#endif
-}
-
-/*
- * Checks to see if the page is in the disk cache, by checking the allocmap.
- */
-int
-cachefs_check_allocmap(cnode_t *cp, u_offset_t off)
-{
- int i;
- size_t dbl_size_to_look = cp->c_attr.va_size - off;
- uint_t size_to_look;
-
- if (dbl_size_to_look > (u_offset_t)PAGESIZE)
- size_to_look = (uint_t)PAGESIZE;
- else
- /*LINTED alignment okay*/
- size_to_look = (uint_t)dbl_size_to_look;
-
- for (i = 0; i < cp->c_metadata.md_allocents; i++) {
- struct cachefs_allocmap *allocp =
- cp->c_metadata.md_allocinfo + i;
-
- if (off >= allocp->am_start_off) {
- if ((off + size_to_look) <=
- (allocp->am_start_off + allocp->am_size)) {
- struct fscache *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
-
- if (CACHEFS_LOG_LOGGING(cachep,
- CACHEFS_LOG_CALLOC))
- cachefs_log_calloc(cachep, 0,
- fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie,
- cp->c_id.cid_fileno,
- off, size_to_look);
- /*
- * Found the page in the CFS disk cache.
- */
- return (1);
- }
- } else {
- return (0);
- }
- }
- return (0);
-}
-
-/*
- * Merges adjacent allocmap entries together where possible, e.g.
- * offset=0x0, size=0x40000
- * offset=0x40000, size=0x20000 becomes just offset=0x0, size-0x90000
- * offset=0x60000, size=0x30000
- */
-
-
-void
-cachefs_coalesce_allocmap(struct cachefs_metadata *cmd)
-{
- int i, reduced = 0;
- struct cachefs_allocmap *allocp, *nallocp;
-
- nallocp = allocp = cmd->md_allocinfo;
- allocp++;
- for (i = 1; i < cmd->md_allocents; i++, allocp++) {
- if (nallocp->am_start_off + nallocp->am_size ==
- allocp->am_start_off) {
- nallocp->am_size += allocp->am_size;
- reduced++;
- } else {
- nallocp++;
- nallocp->am_start_off = allocp->am_start_off;
- nallocp->am_size = allocp->am_size;
- }
- }
- cmd->md_allocents -= reduced;
-}
-
-/*
- * Updates the allocmap to reflect a new chunk of data that has been
- * populated.
- */
-void
-cachefs_update_allocmap(cnode_t *cp, u_offset_t off, size_t size)
-{
- int i;
- struct cachefs_allocmap *allocp;
- struct fscache *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- u_offset_t saveoff;
- u_offset_t savesize;
- u_offset_t logoff = off;
- size_t logsize = size;
- u_offset_t endoff;
- u_offset_t tmpendoff;
-
- /*
- * We try to see if we can coalesce the current block into an existing
- * allocation and mark it as such.
- * If we can't do that then we make a new entry in the allocmap.
- * when we run out of allocmaps, put the cnode in NOCACHE mode.
- */
-again:
- allocp = cp->c_metadata.md_allocinfo;
- for (i = 0; i < cp->c_metadata.md_allocents; i++, allocp++) {
-
- if (off <= (allocp->am_start_off)) {
- endoff = off + size;
- if (endoff >= allocp->am_start_off) {
- tmpendoff = allocp->am_start_off +
- allocp->am_size;
- if (endoff < tmpendoff)
- endoff = tmpendoff;
- allocp->am_size = endoff - off;
- allocp->am_start_off = off;
- cachefs_coalesce_allocmap(&cp->c_metadata);
- allocp = cp->c_metadata.md_allocinfo;
- if (allocp->am_size >= cp->c_size)
- cp->c_metadata.md_flags |= MD_POPULATED;
- return;
- } else {
- saveoff = off;
- savesize = size;
- off = allocp->am_start_off;
- size = allocp->am_size;
- allocp->am_size = savesize;
- allocp->am_start_off = saveoff;
- goto again;
- }
- } else {
- endoff = allocp->am_start_off + allocp->am_size;
- if (off < endoff) {
- tmpendoff = off + size;
- if (endoff < tmpendoff)
- endoff = tmpendoff;
- allocp->am_size = endoff - allocp->am_start_off;
- cachefs_coalesce_allocmap(&cp->c_metadata);
- allocp = cp->c_metadata.md_allocinfo;
- if (allocp->am_size >= cp->c_size)
- cp->c_metadata.md_flags |= MD_POPULATED;
- return;
- }
- if (off == (allocp->am_start_off + allocp->am_size)) {
- allocp->am_size += size;
- cachefs_coalesce_allocmap(&cp->c_metadata);
- allocp = cp->c_metadata.md_allocinfo;
- if (allocp->am_size >= cp->c_size)
- cp->c_metadata.md_flags |= MD_POPULATED;
- return;
- }
- }
- }
- if (i == C_MAX_ALLOCINFO_SLOTS) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ALLOCMAP)
- printf("c_update_alloc_map: "
- "Too many allinfo entries cp %p fileno %llu %p\n",
- (void *)cp, (u_longlong_t)cp->c_id.cid_fileno,
- (void *)cp->c_metadata.md_allocinfo);
-#endif
- cachefs_nocache(cp);
- return;
- }
- allocp->am_start_off = off;
- allocp->am_size = (u_offset_t)size;
- if (allocp->am_size >= cp->c_size)
- cp->c_metadata.md_flags |= MD_POPULATED;
- cp->c_metadata.md_allocents++;
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_UALLOC))
- cachefs_log_ualloc(cachep, 0, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- logoff, logsize);
-}
-
-/*
- * CFS population function
- *
- * before async population, this function used to turn on the cnode
- * flags CN_UPDATED, CN_NEED_FRONT_SYNC, and CN_POPULATION_PENDING.
- * now, however, it's the responsibility of the caller to do this if
- * this function returns 0 (no error).
- */
-
-int
-cachefs_populate(cnode_t *cp, u_offset_t off, size_t popsize, vnode_t *frontvp,
- vnode_t *backvp, u_offset_t cpsize, cred_t *cr)
-{
- int error = 0;
- caddr_t addr;
- u_offset_t upto;
- uint_t size;
- u_offset_t from = off;
- cachefscache_t *cachep = C_TO_FSCACHE(cp)->fs_cache;
- ssize_t resid;
- struct fbuf *fbp;
- caddr_t buf = kmem_alloc(MAXBSIZE, KM_SLEEP);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_populate: ENTER cp %p off %lld\n",
- (void *)cp, off);
-#endif
-
- upto = MIN((off + popsize), cpsize);
-
- while (from < upto) {
- u_offset_t blkoff = (from & (offset_t)MAXBMASK);
- uint_t n = from - blkoff;
-
- size = upto - from;
- if (upto > (blkoff + MAXBSIZE))
- size = MAXBSIZE - n;
-
- error = fbread(backvp, (offset_t)blkoff, n + size,
- S_OTHER, &fbp);
- if (CFS_TIMEOUT(C_TO_FSCACHE(cp), error))
- goto out;
- else if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_BACK)
- printf("cachefs_populate: fbread error %d\n",
- error);
-#endif
- goto out;
- }
-
- addr = fbp->fb_addr;
- ASSERT(addr != NULL);
- ASSERT(n + size <= MAXBSIZE);
- bcopy(addr, buf, n + size);
- fbrelse(fbp, S_OTHER);
-
- if (n == 0 || cachefs_check_allocmap(cp, blkoff) == 0) {
- if (error = cachefs_allocblocks(cachep, 1,
- cp->c_metadata.md_rltype))
- goto out;
- cp->c_metadata.md_frontblks++;
- }
- resid = 0;
- error = vn_rdwr(UIO_WRITE, frontvp, buf + n, size,
- (offset_t)from, UIO_SYSSPACE, 0,
- (rlim64_t)RLIM64_INFINITY, cr, &resid);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("cachefs_populate: "
- "Got error = %d from vn_rdwr\n", error);
-#endif
- goto out;
- }
-#ifdef CFSDEBUG
- if (resid)
- CFS_DEBUG(CFSDEBUG_FRONT)
- printf("cachefs_populate: non-zero resid %ld\n",
- resid);
-#endif
- from += size;
- }
- (void) cachefs_update_allocmap(cp, off, upto - off);
-out:
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_POPULATE))
- cachefs_log_populate(cachep, error,
- C_TO_FSCACHE(cp)->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno, off,
- popsize);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_populate: EXIT cp %p error %d\n",
- (void *)cp, error);
-#endif
- kmem_free(buf, MAXBSIZE);
-
- return (error);
-}
-
-/*
- * due to compiler error we shifted cnode to the last argument slot.
- * occurred during large files project - XXX.
- */
-void
-cachefs_cluster_allocmap(u_offset_t off, u_offset_t *popoffp, size_t *popsizep,
- size_t size, struct cnode *cp)
-{
- int i;
- u_offset_t lastoff = 0;
- u_offset_t forward_diff = 0;
- u_offset_t backward_diff = 0;
-
- ASSERT(size <= C_TO_FSCACHE(cp)->fs_info.fi_popsize);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("cachefs_cluster_allocmap: off %llx, size %llx, "
- "c_size %llx\n", off, size, (longlong_t)cp->c_size);
-#endif /* CFSDEBUG */
- for (i = 0; i < cp->c_metadata.md_allocents; i++) {
- struct cachefs_allocmap *allocp =
- cp->c_metadata.md_allocinfo + i;
-
- if (allocp->am_start_off > off) {
- if ((off + size) > allocp->am_start_off) {
- forward_diff = allocp->am_start_off - off;
- backward_diff = size - forward_diff;
- if (backward_diff > off)
- backward_diff = off;
- if (lastoff > (off - backward_diff))
- backward_diff = off - lastoff;
- } else {
- forward_diff = size;
- }
- *popoffp = (off - backward_diff) & (offset_t)PAGEMASK;
- *popsizep = ((off + forward_diff) - *popoffp) &
- (offset_t)PAGEMASK;
- return;
- } else {
- lastoff = allocp->am_start_off + allocp->am_size;
- }
- }
- if ((lastoff + size) > off) {
- *popoffp = (lastoff & (offset_t)PAGEMASK);
- } else {
- *popoffp = off & (offset_t)PAGEMASK;
- }
-
- /*
- * 64bit project: popsize is the chunk size used to populate the
- * cache (default 64K). As such, 32 bit should suffice.
- */
- if ((*popoffp + size) > cp->c_size)
- *popsizep = (cp->c_size - *popoffp + PAGEOFFSET) &
- (offset_t)PAGEMASK;
- else if (size < PAGESIZE)
- *popsizep = (size + PAGEOFFSET) & (offset_t)PAGEMASK;
- else
- *popsizep = size & (offset_t)PAGEMASK;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_SUBR)
- printf("cachefs_cluster_allocmap: popoff %llx, popsize %llx\n",
- (u_longlong_t)(*popoffp), (u_longlong_t)(*popsizep));
-#endif /* CFSDEBUG */
-}
-
-/*
- * "populate" a symlink in the cache
- */
-int
-cachefs_stuffsymlink(cnode_t *cp, caddr_t buf, int buflen)
-{
- int error = 0;
- struct fscache *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- struct cachefs_metadata *mdp = &cp->c_metadata;
-
- ASSERT(RW_WRITE_HELD(&cp->c_rwlock));
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- if (CFS_ISFS_BACKFS_NFSV4(fscp))
- goto out;
-
- if (cp->c_flags & CN_NOCACHE)
- return (ENOENT);
-
- cp->c_size = (u_offset_t)buflen;
-
- /* if can create a fast sym link */
- if (buflen <= C_FSL_SIZE) {
- /* give up the front file resources */
- if (mdp->md_rlno) {
- cachefs_removefrontfile(mdp, &cp->c_id, cp->c_filegrp);
- cachefs_rlent_moveto(cachep, CACHEFS_RL_FREE,
- mdp->md_rlno, 0);
- mdp->md_rlno = 0;
- mdp->md_rltype = CACHEFS_RL_NONE;
- }
- /* put sym link contents in allocinfo in metadata */
- bzero(mdp->md_allocinfo, C_FSL_SIZE);
- bcopy(buf, mdp->md_allocinfo, buflen);
-
- mdp->md_flags |= MD_FASTSYMLNK;
- cp->c_flags &= ~CN_NEED_FRONT_SYNC;
- cp->c_flags |= CN_UPDATED;
- goto out;
- }
-
- /* else create a sym link in a front file */
- if (cp->c_frontvp == NULL)
- error = cachefs_getfrontfile(cp);
- if (error)
- goto out;
-
- /* truncate front file */
- error = cachefs_frontfile_size(cp, 0);
- mdp->md_flags &= ~(MD_FASTSYMLNK | MD_POPULATED);
- if (error)
- goto out;
-
- /* get space for the sym link */
- error = cachefs_allocblocks(cachep, 1, cp->c_metadata.md_rltype);
- if (error)
- goto out;
-
- /* write the sym link to the front file */
- error = vn_rdwr(UIO_WRITE, cp->c_frontvp, buf, buflen, 0,
- UIO_SYSSPACE, 0, RLIM_INFINITY, kcred, NULL);
- if (error) {
- cachefs_freeblocks(cachep, 1, cp->c_metadata.md_rltype);
- goto out;
- }
-
- cp->c_metadata.md_flags |= MD_POPULATED;
- cp->c_flags |= CN_NEED_FRONT_SYNC;
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_CSYMLINK))
- cachefs_log_csymlink(cachep, error, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno, buflen);
-
- return (error);
-}
-
-/*
- * Reads the full contents of the symbolic link from the back file system.
- * *bufp is set to a MAXPATHLEN buffer that must be freed when done
- * *buflenp is the length of the link
- */
-int
-cachefs_readlink_back(cnode_t *cp, cred_t *cr, caddr_t *bufp, int *buflenp)
-{
- int error;
- struct uio uio;
- struct iovec iov;
- caddr_t buf;
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- *bufp = NULL;
-
- /* get back vnode */
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- return (error);
- }
-
- /* set up for the readlink */
- bzero(&uio, sizeof (struct uio));
- bzero(&iov, sizeof (struct iovec));
- buf = cachefs_kmem_alloc(MAXPATHLEN, KM_SLEEP);
- iov.iov_base = buf;
- iov.iov_len = MAXPATHLEN;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = MAXPATHLEN;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_loffset = 0;
- uio.uio_fmode = 0;
- uio.uio_extflg = UIO_COPY_CACHED;
- uio.uio_llimit = MAXOFFSET_T;
-
- /* get the link data */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_readlink (nfsv4): cnode %p, backvp %p\n",
- cp, cp->c_backvp));
- error = VOP_READLINK(cp->c_backvp, &uio, cr, NULL);
- if (error) {
- cachefs_kmem_free(buf, MAXPATHLEN);
- } else {
- *bufp = buf;
- /*LINTED alignment okay*/
- *buflenp = MAXPATHLEN - (int)uio.uio_resid;
- }
-
- return (error);
-}
-
-int
-cachefs_getbackvp(struct fscache *fscp, struct cnode *cp)
-{
- int error = 0;
- int flag;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CHEAT | CFSDEBUG_BACK)
- printf("cachefs_getbackvp: ENTER fscp %p cp %p\n",
- (void *)fscp, (void *)cp);
-#endif
- ASSERT(cp != NULL);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(cp->c_backvp == NULL);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /*
- * If destroy is set then the last link to a file has been
- * removed. Oddly enough NFS will still return a vnode
- * for the file if the timeout has not expired.
- * This causes headaches for cachefs_push because the
- * vnode is really stale.
- * So we just short circuit the problem here.
- */
- if (cp->c_flags & CN_DESTROY)
- return (ESTALE);
-
- ASSERT(fscp->fs_backvfsp);
- if (fscp->fs_backvfsp == NULL)
- return (ETIMEDOUT);
- error = VFS_VGET(fscp->fs_backvfsp, &cp->c_backvp,
- (struct fid *)&cp->c_cookie);
- if (cp->c_backvp && cp->c_cred &&
- ((cp->c_flags & CN_NEEDOPEN) || (cp->c_attr.va_type == VREG))) {
- /*
- * XXX bob: really should pass in the correct flag,
- * fortunately nobody pays attention to it
- */
- flag = 0;
- /*
- * If NEEDOOPEN is set, then this file was opened VOP_OPEN'd
- * but the backvp was not. So, for the sake of the vnode
- * open counts used by delegation, we need to OPEN the backvp
- * with the same flags that were used for this cnode. That way
- * when the file is VOP_CLOSE'd the counts won't go negative.
- */
- if (cp->c_flags & CN_NEEDOPEN) {
- cp->c_flags &= ~CN_NEEDOPEN;
- if (cp->c_rdcnt > 0) {
- cp->c_rdcnt--;
- flag |= FREAD;
- }
- if (cp->c_wrcnt > 0) {
- cp->c_wrcnt--;
- flag |= FWRITE;
- }
- }
- error = VOP_OPEN(&cp->c_backvp, flag, cp->c_cred, NULL);
- if (error) {
- VN_RELE(cp->c_backvp);
- cp->c_backvp = NULL;
- }
- }
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_GENERAL | CFSDEBUG_BACK) {
- if (error || cp->c_backvp == NULL) {
- printf("Stale cookie cp %p fileno %llu type %d \n",
- (void *)cp, (u_longlong_t)cp->c_id.cid_fileno,
- CTOV(cp)->v_type);
- }
- }
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CHEAT | CFSDEBUG_BACK)
- printf("cachefs_getbackvp: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-int
-cachefs_getcookie(
- vnode_t *vp,
- struct fid *cookiep,
- struct vattr *attrp,
- cred_t *cr,
- uint32_t valid_fid)
-{
- int error = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CHEAT)
- printf("cachefs_getcookie: ENTER vp %p\n", (void *)vp);
-#endif
- /*
- * Get the FID only if the caller has indicated it is valid,
- * otherwise, zero the cookie.
- */
- if (valid_fid) {
- /*
- * This assumes that the cookie is a full size fid, if we go to
- * variable length fids we will need to change this.
- */
- cookiep->fid_len = MAXFIDSZ;
- error = VOP_FID(vp, cookiep, NULL);
- } else {
- bzero(cookiep, sizeof (*cookiep));
- }
-
- if (!error) {
- if (attrp) {
- ASSERT(attrp != NULL);
- attrp->va_mask = AT_ALL;
- error = VOP_GETATTR(vp, attrp, 0, cr, NULL);
- }
- } else {
- if (error == ENOSPC) {
- /*
- * This is an indication that the underlying filesystem
- * needs a bigger fid. For now just map to EINVAL.
- */
- error = EINVAL;
- }
- }
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_CHEAT)
- printf("cachefs_getcookie: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-void
-cachefs_workq_init(struct cachefs_workq *qp)
-{
- qp->wq_head = qp->wq_tail = NULL;
- qp->wq_length =
- qp->wq_thread_count =
- qp->wq_max_len =
- qp->wq_halt_request = 0;
- qp->wq_keepone = 0;
- cv_init(&qp->wq_req_cv, NULL, CV_DEFAULT, NULL);
- cv_init(&qp->wq_halt_cv, NULL, CV_DEFAULT, NULL);
- mutex_init(&qp->wq_queue_lock, NULL, MUTEX_DEFAULT, NULL);
-}
-
-/*
- * return non-zero if it's `okay' to queue more requests (policy)
- */
-
-static int cachefs_async_max = 512;
-static int cachefs_async_count = 0;
-kmutex_t cachefs_async_lock;
-
-int
-cachefs_async_okay(void)
-{
- /*
- * a value of -1 for max means to ignore freemem
- */
-
- if (cachefs_async_max == -1)
- return (1);
-
- if (freemem < minfree)
- return (0);
-
- /*
- * a value of 0 for max means no arbitrary limit (only `freemen')
- */
-
- if (cachefs_async_max == 0)
- return (1);
-
- ASSERT(cachefs_async_max > 0);
-
- /*
- * check the global count against the max.
- *
- * we don't need to grab cachefs_async_lock -- we're just
- * looking, and a little bit of `fuzz' is okay.
- */
-
- if (cachefs_async_count >= cachefs_async_max)
- return (0);
-
- return (1);
-}
-
-void
-cachefs_async_start(struct cachefs_workq *qp)
-{
- struct cachefs_req *rp;
- int left;
- callb_cpr_t cprinfo;
-
- CALLB_CPR_INIT(&cprinfo, &qp->wq_queue_lock, callb_generic_cpr, "cas");
- mutex_enter(&qp->wq_queue_lock);
- left = 1;
- for (;;) {
- /* if there are no pending requests */
- if ((qp->wq_head == NULL) && (qp->wq_logwork == 0)) {
- /* see if thread should exit */
- if (qp->wq_halt_request || (left == -1)) {
- if ((qp->wq_thread_count > 1) ||
- (qp->wq_keepone == 0))
- break;
- }
-
- /* wake up thread in async_halt if necessary */
- if (qp->wq_halt_request)
- cv_broadcast(&qp->wq_halt_cv);
-
- CALLB_CPR_SAFE_BEGIN(&cprinfo);
- /* sleep until there is something to do */
- left = cv_reltimedwait(&qp->wq_req_cv,
- &qp->wq_queue_lock, CFS_ASYNC_TIMEOUT,
- TR_CLOCK_TICK);
- CALLB_CPR_SAFE_END(&cprinfo, &qp->wq_queue_lock);
- if ((qp->wq_head == NULL) && (qp->wq_logwork == 0))
- continue;
- }
- left = 1;
-
- if (qp->wq_logwork) {
- qp->wq_logwork = 0;
- mutex_exit(&qp->wq_queue_lock);
- cachefs_log_process_queue(qp->wq_cachep, 1);
- mutex_enter(&qp->wq_queue_lock);
- continue;
- }
-
- /* remove request from the list */
- rp = qp->wq_head;
- qp->wq_head = rp->cfs_next;
- if (rp->cfs_next == NULL)
- qp->wq_tail = NULL;
-
- /* do the request */
- mutex_exit(&qp->wq_queue_lock);
- cachefs_do_req(rp);
- mutex_enter(&qp->wq_queue_lock);
-
- /* decrement count of requests */
- qp->wq_length--;
- mutex_enter(&cachefs_async_lock);
- --cachefs_async_count;
- mutex_exit(&cachefs_async_lock);
- }
- ASSERT(qp->wq_head == NULL);
- qp->wq_thread_count--;
- if (qp->wq_halt_request && qp->wq_thread_count == 0)
- cv_broadcast(&qp->wq_halt_cv);
- CALLB_CPR_EXIT(&cprinfo);
- thread_exit();
- /*NOTREACHED*/
-}
-
-/*
- * attempt to halt all the async threads associated with a given workq
- */
-int
-cachefs_async_halt(struct cachefs_workq *qp, int force)
-{
- int error = 0;
-
- mutex_enter(&qp->wq_queue_lock);
- if (force)
- qp->wq_keepone = 0;
-
- if (qp->wq_thread_count > 0) {
- qp->wq_halt_request++;
- cv_broadcast(&qp->wq_req_cv);
- (void) cv_reltimedwait(&qp->wq_halt_cv,
- &qp->wq_queue_lock, (60 * hz), TR_CLOCK_TICK);
- qp->wq_halt_request--;
- if (qp->wq_thread_count > 0) {
- if ((qp->wq_thread_count == 1) &&
- (qp->wq_length == 0) && qp->wq_keepone)
- error = EAGAIN;
- else
- error = EBUSY;
- } else {
- ASSERT(qp->wq_length == 0 && qp->wq_head == NULL);
- }
- }
- mutex_exit(&qp->wq_queue_lock);
- return (error);
-}
-
-void
-cachefs_addqueue(struct cachefs_req *rp, struct cachefs_workq *qp)
-{
- mutex_enter(&qp->wq_queue_lock);
- if (qp->wq_thread_count < cachefs_max_threads) {
- if (qp->wq_thread_count == 0 ||
- (qp->wq_length >= (qp->wq_thread_count * 2))) {
- (void) thread_create(NULL, 0, cachefs_async_start,
- qp, 0, &p0, TS_RUN, minclsyspri);
- qp->wq_thread_count++;
- }
- }
- mutex_enter(&rp->cfs_req_lock);
- if (qp->wq_tail)
- qp->wq_tail->cfs_next = rp;
- else
- qp->wq_head = rp;
- qp->wq_tail = rp;
- rp->cfs_next = NULL;
- qp->wq_length++;
- if (qp->wq_length > qp->wq_max_len)
- qp->wq_max_len = qp->wq_length;
- mutex_enter(&cachefs_async_lock);
- ++cachefs_async_count;
- mutex_exit(&cachefs_async_lock);
-
- cv_signal(&qp->wq_req_cv);
- mutex_exit(&rp->cfs_req_lock);
- mutex_exit(&qp->wq_queue_lock);
-}
-
-void
-cachefs_async_putpage(struct cachefs_putpage_req *prp, cred_t *cr)
-{
- struct cnode *cp = VTOC(prp->cp_vp);
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(cp)) == 0);
-
- (void) VOP_PUTPAGE(prp->cp_vp, prp->cp_off, prp->cp_len,
- prp->cp_flags, cr, NULL);
-
- mutex_enter(&cp->c_iomutex);
- if (--cp->c_nio == 0)
- cv_broadcast(&cp->c_iocv);
- if (prp->cp_off == 0 && prp->cp_len == 0 &&
- (cp->c_ioflags & CIO_PUTPAGES)) {
- cp->c_ioflags &= ~CIO_PUTPAGES;
- }
- mutex_exit(&cp->c_iomutex);
-}
-
-void
-cachefs_async_populate(struct cachefs_populate_req *pop, cred_t *cr)
-{
- struct cnode *cp = VTOC(pop->cpop_vp);
- struct fscache *fscp = C_TO_FSCACHE(cp);
- struct filegrp *fgp = cp->c_filegrp;
- int error = 0; /* not returned -- used as a place-holder */
- vnode_t *frontvp = NULL, *backvp = NULL;
- int havelock = 0;
- vattr_t va;
-
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- if (((cp->c_filegrp->fg_flags & CFS_FG_WRITE) == 0) ||
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- mutex_enter(&cp->c_statelock);
- cp->c_flags &= ~CN_ASYNC_POPULATE;
- mutex_exit(&cp->c_statelock);
- return; /* goto out */
- }
-
- error = cachefs_cd_access(fscp, 0, 0);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("async_pop: cd_access: err %d con %d\n",
- error, fscp->fs_cdconnected);
-#endif /* CFSDEBUG */
- mutex_enter(&cp->c_statelock);
- cp->c_flags &= ~CN_ASYNC_POPULATE;
- mutex_exit(&cp->c_statelock);
- return; /* goto out */
- }
-
- /*
- * grab the statelock for some minimal things
- */
-
- rw_enter(&cp->c_rwlock, RW_WRITER);
- mutex_enter(&cp->c_statelock);
- havelock = 1;
-
- if ((cp->c_flags & CN_ASYNC_POPULATE) == 0)
- goto out;
-
- /* there can be only one */
- ASSERT((cp->c_flags & CN_ASYNC_POP_WORKING) == 0);
- cp->c_flags |= CN_ASYNC_POP_WORKING;
- cp->c_popthrp = curthread;
-
- if (cp->c_metadata.md_flags & MD_POPULATED)
- goto out;
-
- if (cp->c_flags & CN_NOCACHE) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: nocache bit on\n");
-#endif /* CFSDEBUG */
- error = EINVAL;
- goto out;
- }
-
- if (cp->c_frontvp == NULL) {
- if ((cp->c_metadata.md_flags & MD_FILE) == 0) {
- struct cfs_cid cid = cp->c_id;
-
- mutex_exit(&cp->c_statelock);
- havelock = 0;
-
- /*
- * if frontfile doesn't exist, drop the lock
- * to do some of the file creation stuff.
- */
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- error = filegrp_allocattr(fgp);
- if (error != 0)
- goto out;
- }
- if (fgp->fg_flags & CFS_FG_ALLOC_FILE) {
- mutex_enter(&fgp->fg_mutex);
- if (fgp->fg_flags & CFS_FG_ALLOC_FILE) {
- if (fgp->fg_header->ach_nffs == 0)
- error = filegrpdir_create(fgp);
- else
- error = filegrpdir_find(fgp);
- if (error != 0) {
- mutex_exit(&fgp->fg_mutex);
- goto out;
- }
- }
- mutex_exit(&fgp->fg_mutex);
- }
-
- if (fgp->fg_dirvp != NULL) {
- char name[CFS_FRONTFILE_NAME_SIZE];
- struct vattr *attrp;
-
- attrp = cachefs_kmem_zalloc(
- sizeof (struct vattr), KM_SLEEP);
- attrp->va_mode = S_IFREG | 0666;
- attrp->va_uid = 0;
- attrp->va_gid = 0;
- attrp->va_type = VREG;
- attrp->va_size = 0;
- attrp->va_mask =
- AT_SIZE | AT_TYPE | AT_MODE |
- AT_UID | AT_GID;
-
- make_ascii_name(&cid, name);
-
- (void) VOP_CREATE(fgp->fg_dirvp, name, attrp,
- EXCL, 0666, &frontvp, kcred, 0, NULL, NULL);
-
- cachefs_kmem_free(attrp,
- sizeof (struct vattr));
- }
-
- mutex_enter(&cp->c_statelock);
- havelock = 1;
- }
- error = cachefs_getfrontfile(cp);
- ASSERT((error != 0) ||
- (frontvp == NULL) ||
- (frontvp == cp->c_frontvp));
- }
- if ((error != 0) || (cp->c_frontvp == NULL))
- goto out;
-
- if (frontvp != NULL)
- VN_RELE(frontvp);
-
- frontvp = cp->c_frontvp;
- VN_HOLD(frontvp);
-
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if ((error != 0) || (cp->c_backvp == NULL))
- goto out;
- }
- backvp = cp->c_backvp;
- VN_HOLD(backvp);
-
- switch (pop->cpop_vp->v_type) {
- case VREG:
- mutex_exit(&cp->c_statelock);
- havelock = 0;
- error = cachefs_async_populate_reg(pop, cr, backvp, frontvp);
- break;
- case VDIR:
- error = cachefs_async_populate_dir(pop, cr, backvp, frontvp);
- mutex_exit(&cp->c_statelock);
- havelock = 0;
- break;
- default:
-#ifdef CFSDEBUG
- printf("cachefs_async_populate: warning: vnode type = %d\n",
- pop->cpop_vp->v_type);
- ASSERT(0);
-#endif /* CFSDEBUG */
- error = EINVAL;
- break;
- }
-
- if (error != 0)
- goto out;
-
- error = VOP_FSYNC(frontvp, FSYNC, cr, NULL);
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: fsync\n");
-#endif /* CFSDEBUG */
- goto out;
- }
-
- /* grab the lock and finish up */
- mutex_enter(&cp->c_statelock);
- havelock = 1;
-
- /* if went nocache while lock was dropped, get out */
- if ((cp->c_flags & CN_NOCACHE) || (cp->c_frontvp == NULL)) {
- error = EINVAL;
- goto out;
- }
-
- va.va_mask = AT_MTIME;
- error = VOP_GETATTR(cp->c_frontvp, &va, 0, cr, NULL);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: getattr\n");
-#endif /* CFSDEBUG */
- goto out;
- }
- cp->c_metadata.md_timestamp = va.va_mtime;
- cp->c_metadata.md_flags |= MD_POPULATED;
- cp->c_metadata.md_flags &= ~MD_INVALREADDIR;
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (! havelock)
- mutex_enter(&cp->c_statelock);
-
- /* see if an error happened behind our backs */
- if ((error == 0) && (cp->c_flags & CN_NOCACHE)) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: "
- "nocache behind our backs\n");
-#endif /* CFSDEBUG */
- error = EINVAL;
- }
-
- cp->c_flags &= ~(CN_NEED_FRONT_SYNC | CN_POPULATION_PENDING |
- CN_ASYNC_POPULATE | CN_ASYNC_POP_WORKING);
- cp->c_popthrp = NULL;
-
- if (error != 0)
- cachefs_nocache(cp);
-
- /* unblock any threads waiting for populate to finish */
- cv_broadcast(&cp->c_popcv);
- mutex_exit(&cp->c_statelock);
- rw_exit(&cp->c_rwlock);
- cachefs_cd_release(fscp);
-
- if (backvp != NULL) {
- VN_RELE(backvp);
- }
- if (frontvp != NULL) {
- VN_RELE(frontvp);
- }
-}
-
-/*
- * only to be called from cachefs_async_populate
- */
-
-static int
-cachefs_async_populate_reg(struct cachefs_populate_req *pop, cred_t *cr,
- vnode_t *backvp, vnode_t *frontvp)
-{
- struct cnode *cp = VTOC(pop->cpop_vp);
- int error = 0;
- u_offset_t popoff;
- size_t popsize;
-
- cachefs_cluster_allocmap(pop->cpop_off, &popoff,
- &popsize, pop->cpop_size, cp);
- if (popsize == 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: popsize == 0\n");
-#endif /* CFSDEBUG */
- goto out;
- }
-
- error = cachefs_populate(cp, popoff, popsize, frontvp, backvp,
- cp->c_size, cr);
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_ASYNCPOP)
- printf("cachefs_async_populate: cachefs_populate\n");
-#endif /* CFSDEBUG */
- goto out;
- }
-
-out:
- return (error);
-}
-
-void
-cachefs_do_req(struct cachefs_req *rp)
-{
- struct cachefscache *cachep;
-
- mutex_enter(&rp->cfs_req_lock);
- switch (rp->cfs_cmd) {
- case CFS_INVALID:
- panic("cachefs_do_req: CFS_INVALID operation on queue");
- /*NOTREACHED*/
- case CFS_CACHE_SYNC:
- cachep = rp->cfs_req_u.cu_fs_sync.cf_cachep;
- cachefs_cache_sync(cachep);
- break;
- case CFS_IDLE:
- cachefs_cnode_idle(rp->cfs_req_u.cu_idle.ci_vp, rp->cfs_cr);
- break;
- case CFS_PUTPAGE:
- cachefs_async_putpage(&rp->cfs_req_u.cu_putpage, rp->cfs_cr);
- VN_RELE(rp->cfs_req_u.cu_putpage.cp_vp);
- break;
- case CFS_POPULATE:
- cachefs_async_populate(&rp->cfs_req_u.cu_populate, rp->cfs_cr);
- VN_RELE(rp->cfs_req_u.cu_populate.cpop_vp);
- break;
- case CFS_NOOP:
- break;
- default:
- panic("c_do_req: Invalid CFS async operation");
- }
- crfree(rp->cfs_cr);
- rp->cfs_cmd = CFS_INVALID;
- mutex_exit(&rp->cfs_req_lock);
- kmem_cache_free(cachefs_req_cache, rp);
-}
-
-
-
-
-ssize_t cachefs_mem_usage = 0;
-
-struct km_wrap {
- size_t kw_size;
- struct km_wrap *kw_other;
-};
-
-kmutex_t cachefs_kmem_lock;
-
-void *
-cachefs_kmem_alloc(size_t size, int flag)
-{
-#ifdef DEBUG
- caddr_t mp = NULL;
- struct km_wrap *kwp;
- size_t n = (size + (2 * sizeof (struct km_wrap)) + 7) & ~7;
-
- ASSERT(n >= (size + 8));
- mp = kmem_alloc(n, flag);
- if (mp == NULL) {
- return (NULL);
- }
- /*LINTED alignment okay*/
- kwp = (struct km_wrap *)mp;
- kwp->kw_size = n;
- /*LINTED alignment okay*/
- kwp->kw_other = (struct km_wrap *)(mp + n - sizeof (struct km_wrap));
- kwp = (struct km_wrap *)kwp->kw_other;
- kwp->kw_size = n;
- /*LINTED alignment okay*/
- kwp->kw_other = (struct km_wrap *)mp;
-
- mutex_enter(&cachefs_kmem_lock);
- ASSERT(cachefs_mem_usage >= 0);
- cachefs_mem_usage += n;
- mutex_exit(&cachefs_kmem_lock);
-
- return (mp + sizeof (struct km_wrap));
-#else /* DEBUG */
- return (kmem_alloc(size, flag));
-#endif /* DEBUG */
-}
-
-void *
-cachefs_kmem_zalloc(size_t size, int flag)
-{
-#ifdef DEBUG
- caddr_t mp = NULL;
- struct km_wrap *kwp;
- size_t n = (size + (2 * sizeof (struct km_wrap)) + 7) & ~7;
-
- ASSERT(n >= (size + 8));
- mp = kmem_zalloc(n, flag);
- if (mp == NULL) {
- return (NULL);
- }
- /*LINTED alignment okay*/
- kwp = (struct km_wrap *)mp;
- kwp->kw_size = n;
- /*LINTED alignment okay*/
- kwp->kw_other = (struct km_wrap *)(mp + n - sizeof (struct km_wrap));
- kwp = (struct km_wrap *)kwp->kw_other;
- kwp->kw_size = n;
- /*LINTED alignment okay*/
- kwp->kw_other = (struct km_wrap *)mp;
-
- mutex_enter(&cachefs_kmem_lock);
- ASSERT(cachefs_mem_usage >= 0);
- cachefs_mem_usage += n;
- mutex_exit(&cachefs_kmem_lock);
-
- return (mp + sizeof (struct km_wrap));
-#else /* DEBUG */
- return (kmem_zalloc(size, flag));
-#endif /* DEBUG */
-}
-
-void
-cachefs_kmem_free(void *mp, size_t size)
-{
-#ifdef DEBUG
- struct km_wrap *front_kwp;
- struct km_wrap *back_kwp;
- size_t n = (size + (2 * sizeof (struct km_wrap)) + 7) & ~7;
- void *p;
-
- ASSERT(n >= (size + 8));
- front_kwp = (struct km_wrap *)((uintptr_t)mp - sizeof (struct km_wrap));
- back_kwp = (struct km_wrap *)
- ((uintptr_t)front_kwp + n - sizeof (struct km_wrap));
-
- ASSERT(front_kwp->kw_other == back_kwp);
- ASSERT(front_kwp->kw_size == n);
- ASSERT(back_kwp->kw_other == front_kwp);
- ASSERT(back_kwp->kw_size == n);
-
- mutex_enter(&cachefs_kmem_lock);
- cachefs_mem_usage -= n;
- ASSERT(cachefs_mem_usage >= 0);
- mutex_exit(&cachefs_kmem_lock);
-
- p = front_kwp;
- front_kwp->kw_size = back_kwp->kw_size = 0;
- front_kwp->kw_other = back_kwp->kw_other = NULL;
- kmem_free(p, n);
-#else /* DEBUG */
- kmem_free(mp, size);
-#endif /* DEBUG */
-}
-
-char *
-cachefs_strdup(char *s)
-{
- char *rc;
-
- ASSERT(s != NULL);
-
- rc = cachefs_kmem_alloc(strlen(s) + 1, KM_SLEEP);
- (void) strcpy(rc, s);
-
- return (rc);
-}
-
-int
-cachefs_stats_kstat_snapshot(kstat_t *ksp, void *buf, int rw)
-{
- struct fscache *fscp = (struct fscache *)ksp->ks_data;
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
-
- if (rw == KSTAT_WRITE) {
- bcopy(buf, &fscp->fs_stats, sizeof (fscp->fs_stats));
- cachep->c_gc_count = fscp->fs_stats.st_gc_count;
- CACHEFS_CFS_TIME_TO_TIME_COPY(fscp->fs_stats.st_gc_time,
- cachep->c_gc_time);
- CACHEFS_CFS_TIME_TO_TIME_COPY(fscp->fs_stats.st_gc_before_atime,
- cachep->c_gc_before);
- CACHEFS_CFS_TIME_TO_TIME_COPY(fscp->fs_stats.st_gc_after_atime,
- cachep->c_gc_after);
- return (error);
- }
-
- fscp->fs_stats.st_gc_count = cachep->c_gc_count;
- CACHEFS_TIME_TO_CFS_TIME_COPY(cachep->c_gc_time,
- fscp->fs_stats.st_gc_time, error);
- CACHEFS_TIME_TO_CFS_TIME_COPY(cachep->c_gc_before,
- fscp->fs_stats.st_gc_before_atime, error);
- CACHEFS_TIME_TO_CFS_TIME_COPY(cachep->c_gc_after,
- fscp->fs_stats.st_gc_after_atime, error);
- bcopy(&fscp->fs_stats, buf, sizeof (fscp->fs_stats));
-
- return (error);
-}
-
-#ifdef DEBUG
-cachefs_debug_info_t *
-cachefs_debug_save(cachefs_debug_info_t *oldcdb, int chain,
- char *message, uint_t flags, int number, void *pointer,
- cachefscache_t *cachep, struct fscache *fscp, struct cnode *cp)
-{
- cachefs_debug_info_t *cdb;
-
- if ((chain) || (oldcdb == NULL))
- cdb = cachefs_kmem_zalloc(sizeof (*cdb), KM_SLEEP);
- else
- cdb = oldcdb;
- if (chain)
- cdb->cdb_next = oldcdb;
-
- if (message != NULL) {
- if (cdb->cdb_message != NULL)
- cachefs_kmem_free(cdb->cdb_message,
- strlen(cdb->cdb_message) + 1);
- cdb->cdb_message = cachefs_kmem_alloc(strlen(message) + 1,
- KM_SLEEP);
- (void) strcpy(cdb->cdb_message, message);
- }
- cdb->cdb_flags = flags;
- cdb->cdb_int = number;
- cdb->cdb_pointer = pointer;
-
- cdb->cdb_count++;
-
- cdb->cdb_cnode = cp;
- if (cp != NULL) {
- cdb->cdb_frontvp = cp->c_frontvp;
- cdb->cdb_backvp = cp->c_backvp;
- }
- if (fscp != NULL)
- cdb->cdb_fscp = fscp;
- else if (cp != NULL)
- cdb->cdb_fscp = C_TO_FSCACHE(cp);
- if (cachep != NULL)
- cdb->cdb_cachep = cachep;
- else if (cdb->cdb_fscp != NULL)
- cdb->cdb_cachep = cdb->cdb_fscp->fs_cache;
-
- cdb->cdb_thread = curthread;
- cdb->cdb_timestamp = gethrtime();
- cdb->cdb_depth = getpcstack(cdb->cdb_stack, CACHEFS_DEBUG_DEPTH);
-
- return (cdb);
-}
-
-void
-cachefs_debug_show(cachefs_debug_info_t *cdb)
-{
- hrtime_t now = gethrtime();
- timestruc_t ts;
- int i;
-
- while (cdb != NULL) {
- hrt2ts(now - cdb->cdb_timestamp, &ts);
- printf("cdb: %p count: %d timelapse: %ld.%9ld\n",
- (void *)cdb, cdb->cdb_count, ts.tv_sec, ts.tv_nsec);
- if (cdb->cdb_message != NULL)
- printf("message: %s", cdb->cdb_message);
- printf("flags: %x int: %d pointer: %p\n",
- cdb->cdb_flags, cdb->cdb_int, (void *)cdb->cdb_pointer);
-
- printf("cnode: %p fscp: %p cachep: %p\n",
- (void *)cdb->cdb_cnode,
- (void *)cdb->cdb_fscp, (void *)cdb->cdb_cachep);
- printf("frontvp: %p backvp: %p\n",
- (void *)cdb->cdb_frontvp, (void *)cdb->cdb_backvp);
-
- printf("thread: %p stack...\n", (void *)cdb->cdb_thread);
- for (i = 0; i < cdb->cdb_depth; i++) {
- ulong_t off;
- char *sym;
-
- sym = kobj_getsymname(cdb->cdb_stack[i], &off);
- printf("%s+%lx\n", sym ? sym : "?", off);
- }
- delay(2*hz);
- cdb = cdb->cdb_next;
- }
- debug_enter(NULL);
-}
-#endif /* DEBUG */
-
-/*
- * Changes the size of the front file.
- * Returns 0 for success or error if cannot set file size.
- * NOCACHE bit is ignored.
- * c_size is ignored.
- * statelock must be held, frontvp must be set.
- * File must be populated if setting to a size other than zero.
- */
-int
-cachefs_frontfile_size(cnode_t *cp, u_offset_t length)
-{
- cachefscache_t *cachep = C_TO_FSCACHE(cp)->fs_cache;
- vattr_t va;
- size_t nblks, blkdelta;
- int error = 0;
- int alloc = 0;
- struct cachefs_allocmap *allocp;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(cp->c_frontvp);
-
- /* if growing the file, allocate space first, we charge for holes */
- if (length) {
- ASSERT(cp->c_metadata.md_flags & MD_POPULATED);
-
- nblks = (length + MAXBSIZE - 1) / MAXBSIZE;
- if (nblks > cp->c_metadata.md_frontblks) {
- blkdelta = nblks - cp->c_metadata.md_frontblks;
- error = cachefs_allocblocks(cachep, blkdelta,
- cp->c_metadata.md_rltype);
- if (error)
- goto out;
- alloc = 1;
- }
- }
-
- /* change the size of the front file */
- va.va_mask = AT_SIZE;
- va.va_size = length;
- error = VOP_SETATTR(cp->c_frontvp, &va, 0, kcred, NULL);
- if (error)
- goto out;
-
- /* zero out the alloc map */
- bzero(&cp->c_metadata.md_allocinfo,
- cp->c_metadata.md_allocents * sizeof (struct cachefs_allocmap));
- cp->c_metadata.md_allocents = 0;
-
- if (length == 0) {
- /* free up blocks */
- if (cp->c_metadata.md_frontblks) {
- cachefs_freeblocks(cachep, cp->c_metadata.md_frontblks,
- cp->c_metadata.md_rltype);
- cp->c_metadata.md_frontblks = 0;
- }
- } else {
- /* update number of blocks if shrinking file */
- nblks = (length + MAXBSIZE - 1) / MAXBSIZE;
- if (nblks < cp->c_metadata.md_frontblks) {
- blkdelta = cp->c_metadata.md_frontblks - nblks;
- cachefs_freeblocks(cachep, blkdelta,
- cp->c_metadata.md_rltype);
- cp->c_metadata.md_frontblks = (uint_t)nblks;
- }
-
- /* fix up alloc map to reflect new size */
- allocp = cp->c_metadata.md_allocinfo;
- allocp->am_start_off = 0;
- allocp->am_size = length;
- cp->c_metadata.md_allocents = 1;
- }
- cp->c_flags |= CN_UPDATED | CN_NEED_FRONT_SYNC;
-
-out:
- if (error && alloc)
- cachefs_freeblocks(cachep, blkdelta, cp->c_metadata.md_rltype);
- return (error);
-}
-
-/*ARGSUSED*/
-int
-cachefs_req_create(void *voidp, void *cdrarg, int kmflags)
-{
- struct cachefs_req *rp = (struct cachefs_req *)voidp;
-
- /*
- * XXX don't do this! if you need this, you can't use this
- * constructor.
- */
-
- bzero(rp, sizeof (struct cachefs_req));
-
- mutex_init(&rp->cfs_req_lock, NULL, MUTEX_DEFAULT, NULL);
- return (0);
-}
-
-/*ARGSUSED*/
-void
-cachefs_req_destroy(void *voidp, void *cdrarg)
-{
- struct cachefs_req *rp = (struct cachefs_req *)voidp;
-
- mutex_destroy(&rp->cfs_req_lock);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_vfsops.c b/usr/src/uts/common/fs/cachefs/cachefs_vfsops.c
deleted file mode 100644
index 26631b3380..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_vfsops.c
+++ /dev/null
@@ -1,1342 +0,0 @@
-/*
- * 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
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/vfs.h>
-#include <sys/vfs_opreg.h>
-#include <sys/vnode.h>
-#include <sys/pathname.h>
-#include <sys/uio.h>
-#include <sys/tiuser.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <sys/debug.h>
-#include <sys/cmn_err.h>
-#include <sys/utsname.h>
-#include <sys/bootconf.h>
-#include <sys/reboot.h>
-#include <sys/modctl.h>
-#include <rpc/types.h>
-
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_log.h>
-#include <sys/mkdev.h>
-#include <sys/dnlc.h>
-#include <sys/policy.h>
-#include "fs/fs_subr.h"
-
-extern kmutex_t cachefs_kmem_lock;
-kmutex_t cachefs_kstat_key_lock;
-
-/* forward declarations */
-static int cachefs_remount(struct vfs *, struct mounta *);
-static void cachefs_delete_cachep(cachefscache_t *);
-
-#define CFS_MAPSIZE 256
-
-kmutex_t cachefs_cachelock; /* Cache list mutex */
-cachefscache_t *cachefs_cachelist = NULL; /* Cache struct list */
-
-int cachefs_mount_retries = 3;
-kmutex_t cachefs_minor_lock; /* Lock for minor device map */
-major_t cachefs_major = 0;
-minor_t cachefs_minor = 0;
-cachefs_kstat_key_t *cachefs_kstat_key = NULL;
-int cachefs_kstat_key_n = 0;
-static uint32_t cachefs_nfsv4_warnmsg = FALSE;
-
-/*
- * cachefs vfs operations.
- */
-static int cachefs_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);
-static int cachefs_unmount(vfs_t *, int, cred_t *);
-static int cachefs_root(vfs_t *, vnode_t **);
-static int cachefs_statvfs(register vfs_t *, struct statvfs64 *);
-static int cachefs_sync(vfs_t *, short, cred_t *);
-
-/*
- * Initialize the vfs structure
- */
-int cachefsfstyp;
-int cnodesize = 0;
-
-int
-cachefs_init_vfsops(int fstype)
-{
- static const fs_operation_def_t cachefs_vfsops_template[] = {
- VFSNAME_MOUNT, { .vfs_mount = cachefs_mount },
- VFSNAME_UNMOUNT, { .vfs_unmount = cachefs_unmount },
- VFSNAME_ROOT, { .vfs_root = cachefs_root },
- VFSNAME_STATVFS, { .vfs_statvfs = cachefs_statvfs },
- VFSNAME_SYNC, { .vfs_sync = cachefs_sync },
- NULL, NULL
- };
- int error;
-
- error = vfs_setfsops(fstype, cachefs_vfsops_template, NULL);
- if (error != 0)
- return (error);
-
- cachefsfstyp = fstype;
-
- return (0);
-}
-
-dev_t
-cachefs_mkmntdev(void)
-{
- dev_t cachefs_dev;
-
- mutex_enter(&cachefs_minor_lock);
- do {
- cachefs_minor = (cachefs_minor + 1) & MAXMIN32;
- cachefs_dev = makedevice(cachefs_major, cachefs_minor);
- } while (vfs_devismounted(cachefs_dev));
- mutex_exit(&cachefs_minor_lock);
-
- return (cachefs_dev);
-}
-
-/*
- * vfs operations
- */
-static int
-cachefs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
-{
- char *data = uap->dataptr;
- STRUCT_DECL(cachefs_mountargs, map);
- struct cachefsoptions *cfs_options;
- char *backfs, *cacheid, *cachedir;
- vnode_t *cachedirvp = NULL;
- vnode_t *backrootvp = NULL;
- cachefscache_t *cachep = NULL;
- fscache_t *fscp = NULL;
- cnode_t *cp;
- struct fid *cookiep = NULL;
- struct vattr *attrp = NULL;
- dev_t cachefs_dev; /* devid for this mount */
- int error = 0;
- int retries = cachefs_mount_retries;
- ino64_t fsid;
- cfs_cid_t cid;
- char *backmntpt;
- ino64_t backfileno;
- struct vfs *backvfsp;
- size_t strl;
- char tmpstr[MAXPATHLEN];
- vnode_t *tmpdirvp = NULL;
- ulong_t maxfilesizebits;
- uint32_t valid_fid;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_mount: ENTER cachefs_mntargs %p\n", data);
-#endif
-
- /*
- * Make sure we have sufficient privileges.
- */
- if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0)
- goto out;
-
- /*
- * make sure we're mounting on a directory
- */
- if (mvp->v_type != VDIR) {
- error = ENOTDIR;
- goto out;
- }
-
- /*
- * Determine the zone we're being mounted into, and make sure it's the
- * global zone.
- */
- if (getzoneid() == GLOBAL_ZONEID) {
- zone_t *mntzone;
-
- mntzone = zone_find_by_path(refstr_value(vfsp->vfs_mntpt));
- ASSERT(mntzone != NULL);
- zone_rele(mntzone);
- if (mntzone != curproc->p_zone) {
- error = EBUSY;
- goto out;
- }
- } else {
- error = EPERM;
- goto out;
- }
-
- if (uap->flags & MS_REMOUNT) {
- error = cachefs_remount(vfsp, uap);
- goto out;
- }
-
- /*
- * Assign a unique device id to the mount
- */
- cachefs_dev = cachefs_mkmntdev();
-#ifdef _LP64
- /*
- * It's not a good idea to make fsid bigger since that'll
- * have adverse effects on nfs filehandles. For now assume that
- * cachefs be used on devices that fit into dev32_t's.
- */
- if (cachefs_dev == NODEV) {
- error = EOVERFLOW;
- goto out;
- }
-#endif
-
- /*
- * Copy in the arguments
- */
- STRUCT_INIT(map, get_udatamodel());
- error = copyin(data, STRUCT_BUF(map),
- SIZEOF_STRUCT(cachefs_mountargs, DATAMODEL_NATIVE));
- if (error) {
- goto out;
- }
-
- cfs_options = (struct cachefsoptions *)STRUCT_FADDR(map, cfs_options);
- cacheid = (char *)STRUCT_FGETP(map, cfs_cacheid);
- if ((cfs_options->opt_flags &
- (CFS_WRITE_AROUND|CFS_NONSHARED|CFS_BACKFS_NFSV4)) == 0) {
- error = EINVAL;
- goto out;
- }
- if ((cfs_options->opt_popsize % MAXBSIZE) != 0) {
- error = EINVAL;
- goto out;
- }
- /*
- * Get the cache directory vp
- */
- /*LINTED 32-bit pointer casting okay*/
- cachedir = (char *)STRUCT_FGETP(map, cfs_cachedir);
- error = lookupname(cachedir, UIO_USERSPACE, FOLLOW,
- NULLVPP, &cachedirvp);
- if (error)
- goto out;
-
- /*
- * Make sure the thing we just looked up is a directory
- */
- if (cachedirvp->v_type != VDIR) {
- cmn_err(CE_WARN, "cachefs_mount: cachedir not a directory\n");
- error = EINVAL;
- goto out;
- }
-
- /*
- * Make sure the cache doesn't live in cachefs!
- */
- if (vn_matchops(cachedirvp, cachefs_getvnodeops())) {
- cmn_err(CE_WARN, "cachefs_mount: cachedir in cachefs!\n");
- error = EINVAL;
- goto out;
- }
-
- /* if the backfs is mounted */
- /*LINTED 32-bit pointer casting okay*/
- if ((backfs = STRUCT_FGETP(map, cfs_backfs)) != NULL) {
- /*
- * Get the back file system root vp
- */
- error = lookupname(backfs, UIO_USERSPACE, FOLLOW,
- NULLVPP, &backrootvp);
- if (error)
- goto out;
-
- /*
- * Make sure the thing we just looked up is a directory
- * and a root of a file system
- */
- if (backrootvp->v_type != VDIR ||
- !(backrootvp->v_flag & VROOT)) {
- cmn_err(CE_WARN,
- "cachefs_mount: backpath not a directory\n");
- error = EINVAL;
- goto out;
- }
-
- /*
- * Get the fid and attributes for the root of the
- * backfilesystem, except if NFSv4 is in use,
- * in which case we get the attributes only (the
- * (VOP_FID() operation called by cachefs_get_cookie()
- * is not supported in NFSv4).
- */
- cookiep = cachefs_kmem_alloc(sizeof (struct fid), KM_SLEEP);
- attrp = cachefs_kmem_alloc(sizeof (struct vattr), KM_SLEEP);
-
- if ((cfs_options->opt_flags & CFS_BACKFS_NFSV4)) {
- valid_fid = FALSE;
- } else {
- valid_fid = TRUE;
- }
- error = cachefs_getcookie(backrootvp, cookiep, attrp, cr,
- valid_fid);
-
- if (error)
- goto out;
-
- backmntpt = backfs;
- backfileno = attrp->va_nodeid;
- backvfsp = backrootvp->v_vfsp;
- } else {
- backmntpt = NULL;
- backfileno = 0;
- backvfsp = NULL;
- }
-
-again:
-
- /*
- * In SVR4 it's not acceptable to stack up mounts
- * unless MS_OVERLAY specified.
- */
- mutex_enter(&mvp->v_lock);
- if (((uap->flags & MS_OVERLAY) == 0) &&
- ((mvp->v_count != 1) || (mvp->v_flag & VROOT))) {
- mutex_exit(&mvp->v_lock);
- error = EBUSY;
- goto out;
- }
- mutex_exit(&mvp->v_lock);
-
- /*
- * Lock out other mounts and unmounts until we safely have
- * a mounted fscache object.
- */
- mutex_enter(&cachefs_cachelock);
-
- /*
- * Find the cache structure
- */
- for (cachep = cachefs_cachelist; cachep != NULL;
- cachep = cachep->c_next) {
- if (cachep->c_dirvp == cachedirvp)
- break;
- }
-
- /* if the cache object does not exist, then create it */
- if (cachep == NULL) {
- cachep = cachefs_cache_create();
- error = cachefs_cache_activate_ro(cachep, cachedirvp);
- if (error) {
- cachefs_cache_destroy(cachep);
- cachep = NULL;
- goto out;
- }
- if ((cfs_options->opt_flags & CFS_NOFILL) == 0)
- cachefs_cache_activate_rw(cachep);
- else
- cfs_options->opt_flags &= ~CFS_NOFILL;
-
- cachep->c_next = cachefs_cachelist;
- cachefs_cachelist = cachep;
- } else if (cfs_options->opt_flags & CFS_NOFILL) {
- cmn_err(CE_WARN,
- "CacheFS: attempt to convert nonempty cache "
- "to NOFILL mode");
- error = EINVAL;
- goto out;
- }
-
- /* get the fscache id for this name */
- error = fscache_name_to_fsid(cachep, cacheid, &fsid);
- if (error) {
- fsid = 0;
- }
-
- /* find the fscache object for this mount point or create it */
- mutex_enter(&cachep->c_fslistlock);
- fscp = fscache_list_find(cachep, fsid);
- if (fscp == NULL) {
- fscp = fscache_create(cachep);
- error = fscache_activate(fscp, fsid, cacheid,
- cfs_options, backfileno);
- if (error) {
- fscache_destroy(fscp);
- fscp = NULL;
- mutex_exit(&cachep->c_fslistlock);
- if ((error == ENOSPC) && (retries-- > 0)) {
- mutex_exit(&cachefs_cachelock);
- delay(6 * hz);
- goto again;
- }
- goto out;
- }
- fscache_list_add(cachep, fscp);
- } else {
- /* compare the options to make sure they are compatible */
- error = fscache_compare_options(fscp, cfs_options);
- if (error) {
- cmn_err(CE_WARN,
- "CacheFS: mount failed, options do not match.");
- fscp = NULL;
- mutex_exit(&cachep->c_fslistlock);
- goto out;
- }
-
- /* copy options into the fscache */
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_info.fi_mntflags = cfs_options->opt_flags;
- fscp->fs_info.fi_popsize = cfs_options->opt_popsize;
- fscp->fs_info.fi_fgsize = cfs_options->opt_fgsize;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
- mutex_exit(&fscp->fs_fslock);
- }
- fscache_hold(fscp);
-
- error = 0;
- if (fscp->fs_fscdirvp) {
- error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
- &tmpdirvp, NULL, 0, NULL, kcred, NULL, NULL, NULL);
-
- /*
- * If a log file exists and the cache is being mounted without
- * the snr (aka disconnectable) option, return an error.
- */
- if ((error == 0) &&
- !(cfs_options->opt_flags & CFS_DISCONNECTABLE)) {
- mutex_exit(&cachep->c_fslistlock);
- cmn_err(CE_WARN, "cachefs: log exists and "
- "disconnectable option not specified\n");
- error = EINVAL;
- goto out;
- }
- }
-
- /*
- * Acquire the name of the mount point
- */
- if (fscp->fs_mntpt == NULL) {
- /*
- * the string length returned by copystr includes the
- * terminating NULL character, unless a NULL string is
- * passed in, then the string length is unchanged.
- */
- strl = 0;
- tmpstr[0] = '\0';
- (void) copyinstr(uap->dir, tmpstr, MAXPATHLEN, &strl);
- if (strl > 1) {
- fscp->fs_mntpt = kmem_alloc(strl, KM_SLEEP);
- (void) strncpy(fscp->fs_mntpt, tmpstr, strl);
- }
- /*
- * else fscp->fs_mntpt is unchanged(still NULL) try again
- * next time
- */
- }
-
- /*
- * Acquire the name of the server
- */
- if (fscp->fs_hostname == NULL) {
- strl = 0;
- tmpstr[0] = '\0';
- /*LINTED 32-bit pointer casting okay*/
- (void) copyinstr((char *)STRUCT_FGETP(map, cfs_hostname),
- tmpstr, MAXPATHLEN, &strl);
- if (strl > 1) {
- fscp->fs_hostname = kmem_alloc(strl, KM_SLEEP);
- (void) strncpy(fscp->fs_hostname, tmpstr, strl);
- }
- /*
- * else fscp->fs_hostname remains unchanged (is still NULL)
- */
- }
-
- /*
- * Acquire name of the back filesystem
- */
- if (fscp->fs_backfsname == NULL) {
- strl = 0;
- tmpstr[0] = '\0';
- /*LINTED 32-bit pointer casting okay*/
- (void) copyinstr((char *)STRUCT_FGETP(map, cfs_backfsname),
- tmpstr, MAXPATHLEN, &strl);
- if (strl > 1) {
- fscp->fs_backfsname = kmem_alloc(strl, KM_SLEEP);
- (void) strncpy(fscp->fs_backfsname, tmpstr, strl);
- }
- /*
- * else fscp->fs_backfsname remains unchanged (is still NULL)
- */
- }
-
- backfileno = fscp->fs_info.fi_root;
- mutex_exit(&cachep->c_fslistlock);
-
- /* see if fscache object is already mounted, it not, make it so */
- error = fscache_mounted(fscp, vfsp, backvfsp);
- if (error) {
- /* fs cache was already mounted */
- error = EBUSY;
- goto out;
- }
-
- cachefs_kstat_mount(fscp, uap->dir, backmntpt, cachedir, cacheid);
-
- /* set nfs style time out parameters */
- fscache_acset(fscp, STRUCT_FGET(map, cfs_acregmin),
- STRUCT_FGET(map, cfs_acregmax),
- STRUCT_FGET(map, cfs_acdirmin), STRUCT_FGET(map, cfs_acdirmax));
-
- vfsp->vfs_dev = cachefs_dev;
- vfsp->vfs_data = (caddr_t)fscp;
- vfs_make_fsid(&vfsp->vfs_fsid, cachefs_dev, cachefsfstyp);
- vfsp->vfs_fstype = cachefsfstyp;
- if (backvfsp)
- vfsp->vfs_bsize = backvfsp->vfs_bsize;
- else
- vfsp->vfs_bsize = MAXBSIZE; /* XXX */
-
- /* make a cnode for the root of the file system */
- cid.cid_flags = 0;
- cid.cid_fileno = backfileno;
- error = cachefs_cnode_make(&cid, fscp, (valid_fid ? cookiep : NULL),
- attrp, backrootvp, cr, CN_ROOT, &cp);
-
- if (error) {
- cmn_err(CE_WARN, "cachefs_mount: can't create root cnode\n");
- goto out;
- }
-
- /* stick the root cnode in the fscache object */
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_rootvp = CTOV(cp);
- fscp->fs_rootvp->v_flag |= VROOT;
- fscp->fs_rootvp->v_type |= cp->c_attr.va_type;
- ASSERT(fscp->fs_rootvp->v_type == VDIR);
-
- /*
- * Get the maxfilesize bits of the back file system.
- */
-
- error = VOP_PATHCONF(backrootvp, _PC_FILESIZEBITS, &maxfilesizebits,
- kcred, NULL);
-
- if (error) {
- cmn_err(CE_WARN,
- "cachefs_mount: Can't get the FILESIZEBITS of the back root vnode \n");
- goto out;
- }
-
- fscp->fs_offmax = (1LL << (maxfilesizebits - 1)) - 1;
- mutex_exit(&fscp->fs_fslock);
-
- /* remove the unmount file if it is there */
- (void) VOP_REMOVE(fscp->fs_fscdirvp, CACHEFS_UNMNT_FILE, kcred, NULL,
- 0);
-
- /* wake up the cache worker if ANY packed pending work */
- mutex_enter(&cachep->c_contentslock);
- if (cachep->c_flags & CACHE_PACKED_PENDING)
- cv_signal(&cachep->c_cwcv);
- mutex_exit(&cachep->c_contentslock);
-
- /*
- * Warn that caching is disabled with NFSv4 first time around.
- */
- if (!cachefs_nfsv4_warnmsg && CFS_ISFS_BACKFS_NFSV4(fscp)) {
- cmn_err(CE_WARN,
- "Cachefs has detected a mount with NFSv4: caching will"
- " be disabled for this and other NFSv4 mounts\n");
- cachefs_nfsv4_warnmsg = TRUE;
- }
-
-out:
- /*
- * make a log entry, if appropriate
- */
-
- if ((cachep != NULL) &&
- CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_MOUNT))
- cachefs_log_mount(cachep, error, vfsp, fscp,
- uap->dir, UIO_USERSPACE,
- (STRUCT_BUF(map) != NULL) ? cacheid : NULL);
-
- /*
- * Cleanup our mess
- */
- if (cookiep != NULL)
- cachefs_kmem_free(cookiep, sizeof (struct fid));
- if (cachedirvp != NULL)
- VN_RELE(cachedirvp);
- if (backrootvp != NULL)
- VN_RELE(backrootvp);
- if (fscp)
- fscache_rele(fscp);
- if (attrp)
- cachefs_kmem_free(attrp, sizeof (struct vattr));
-
- if (error) {
- if (cachep) {
- int xx;
-
- /* lock the cachep's fslist */
- mutex_enter(&cachep->c_fslistlock);
-
- /*
- * gc isn't necessary for list_mounted(), but
- * we want to do it anyway.
- */
-
- fscache_list_gc(cachep);
- xx = fscache_list_mounted(cachep);
-
- mutex_exit(&cachep->c_fslistlock);
-
- /* if no more references to this cachep, punt it. */
- if (xx == 0)
- cachefs_delete_cachep(cachep);
- mutex_exit(&cachefs_cachelock);
- }
- } else {
- mutex_exit(&cachefs_cachelock);
- }
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_mount: EXIT\n");
-#endif
- return (error);
-}
-
-void
-cachefs_kstat_mount(struct fscache *fscp,
- char *umountpoint, char *ubackfs, char *ucachedir, char *cacheid)
-{
- cachefscache_t *cachep = fscp->fs_cache;
- cachefs_kstat_key_t *key;
- char *mountpoint = NULL, *backfs = NULL, *cachedir = NULL;
- size_t len;
- kstat_t *ksp;
- int i, rc;
-
- mountpoint = cachefs_kmem_alloc(MAXPATHLEN, KM_SLEEP);
- if (copyinstr(umountpoint, mountpoint, MAXPATHLEN, &len) != 0)
- goto out;
-
- cachedir = cachefs_kmem_alloc(MAXPATHLEN, KM_SLEEP);
- if (copyinstr(ucachedir, cachedir, MAXPATHLEN, &len) != 0)
- goto out;
-
- backfs = cachefs_kmem_alloc(MAXPATHLEN, KM_SLEEP);
- if (backfs) {
- if (copyinstr(ubackfs, backfs, MAXPATHLEN, &len) != 0)
- goto out;
- } else {
- (void) strcpy(backfs, "no back file system");
- }
-
- ASSERT(strlen(mountpoint) < MAXPATHLEN);
- ASSERT(strlen(backfs) < MAXPATHLEN);
- ASSERT(strlen(cachedir) < MAXPATHLEN);
-
- /* protect cachefs_kstat_key */
- mutex_enter(&cachefs_kstat_key_lock);
- /*
- * XXXX If already there, why not go straight to it?
- * We know that fscp->fs_kstat_id == i + 1
- */
- i = fscp->fs_kstat_id - 1;
- if ((i >= 0) && (i < cachefs_kstat_key_n))
- rc = 1;
- else
- rc = i = 0;
- for (; i < cachefs_kstat_key_n; i++) {
- key = cachefs_kstat_key + i;
- if (strcmp((char *)(uintptr_t)key->ks_mountpoint,
- mountpoint) == 0 &&
- strcmp((char *)(uintptr_t)key->ks_cachedir,
- cachedir) == 0 &&
- strcmp((char *)(uintptr_t)key->ks_cacheid, cacheid) == 0)
- break;
- if (rc) { /* direct key did not work - check all */
- i = -1; /* will increment to zero in loop */
- rc = 0;
- }
- }
-
- if (i >= cachefs_kstat_key_n) {
- key = cachefs_kmem_alloc((cachefs_kstat_key_n + 1) *
- sizeof (cachefs_kstat_key_t), KM_SLEEP);
- if (cachefs_kstat_key != NULL) {
- bcopy(cachefs_kstat_key, key,
- cachefs_kstat_key_n * sizeof (*key));
- cachefs_kmem_free(cachefs_kstat_key,
- cachefs_kstat_key_n * sizeof (*key));
- }
- cachefs_kstat_key = key;
- key = cachefs_kstat_key + cachefs_kstat_key_n;
- ++cachefs_kstat_key_n;
- rc = key->ks_id = cachefs_kstat_key_n; /* offset + 1 */
-
- key->ks_mountpoint = (uint64_t)(uintptr_t)
- cachefs_strdup(mountpoint);
- key->ks_backfs = (uint64_t)(uintptr_t)cachefs_strdup(backfs);
- key->ks_cachedir = (uint64_t)(uintptr_t)
- cachefs_strdup(cachedir);
- key->ks_cacheid = (uint64_t)(uintptr_t)cachefs_strdup(cacheid);
- } else
- rc = key->ks_id;
-
- mutex_enter(&fscp->fs_fslock); /* protect fscp */
-
- fscp->fs_kstat_id = rc;
-
- mutex_exit(&fscp->fs_fslock); /* finished with fscp */
- /* finished cachefs_kstat_key */
- mutex_exit(&cachefs_kstat_key_lock);
-
- key->ks_vfsp = (uint64_t)(uintptr_t)fscp->fs_cfsvfsp;
- key->ks_mounted = 1;
-
- /*
- * we must not be holding any mutex that is a ks_lock field
- * for one of the kstats when we invoke kstat_create,
- * kstat_install, and friends.
- */
- ASSERT(MUTEX_NOT_HELD(&cachefs_kstat_key_lock));
- /* really should be EVERY cachep's c_log_mutex */
- ASSERT(MUTEX_NOT_HELD(&cachep->c_log_mutex));
-
- /* cachefs.#.log */
- ksp = kstat_create("cachefs", fscp->fs_kstat_id, "log",
- "misc", KSTAT_TYPE_RAW, 1,
- KSTAT_FLAG_WRITABLE | KSTAT_FLAG_VIRTUAL);
- if (ksp != NULL) {
- ksp->ks_data = cachep->c_log_ctl;
- ksp->ks_data_size = sizeof (cachefs_log_control_t);
- ksp->ks_lock = &cachep->c_log_mutex;
- ksp->ks_snapshot = cachefs_log_kstat_snapshot;
- kstat_install(ksp);
- }
- /* cachefs.#.stats */
- ksp = kstat_create("cachefs", fscp->fs_kstat_id, "stats",
- "misc", KSTAT_TYPE_RAW, 1,
- KSTAT_FLAG_WRITABLE | KSTAT_FLAG_VIRTUAL);
- if (ksp != NULL) {
- ksp->ks_data = fscp;
- ksp->ks_data_size = sizeof (cachefs_stats_t);
- ksp->ks_snapshot = cachefs_stats_kstat_snapshot;
- kstat_install(ksp);
- }
-
-out:
- if (mountpoint != NULL)
- cachefs_kmem_free(mountpoint, MAXPATHLEN);
- if (backfs != NULL)
- cachefs_kmem_free(backfs, MAXPATHLEN);
- if (cachedir != NULL)
- cachefs_kmem_free(cachedir, MAXPATHLEN);
-}
-
-void
-cachefs_kstat_umount(int ksid)
-{
- cachefs_kstat_key_t *k = cachefs_kstat_key + (ksid - 1);
-
- ASSERT(k->ks_id == ksid);
-
- k->ks_mounted = 0;
-
- kstat_delete_byname("cachefs", ksid, "stats");
- kstat_delete_byname("cachefs", ksid, "log");
-}
-
-int
-cachefs_kstat_key_update(kstat_t *ksp, int rw)
-{
- cachefs_kstat_key_t *key = *((cachefs_kstat_key_t **)ksp->ks_data);
- cachefs_kstat_key_t *k;
- int i;
-
- if (rw == KSTAT_WRITE)
- return (EIO);
- if (key == NULL)
- return (EIO);
-
- ksp->ks_data_size = cachefs_kstat_key_n * sizeof (*key);
- for (i = 0; i < cachefs_kstat_key_n; i++) {
- k = key + i;
-
- ksp->ks_data_size +=
- strlen((char *)(uintptr_t)k->ks_mountpoint) + 1;
- ksp->ks_data_size +=
- strlen((char *)(uintptr_t)k->ks_backfs) + 1;
- ksp->ks_data_size +=
- strlen((char *)(uintptr_t)k->ks_cachedir) + 1;
- ksp->ks_data_size +=
- strlen((char *)(uintptr_t)k->ks_cacheid) + 1;
- }
-
- ksp->ks_ndata = cachefs_kstat_key_n;
-
- return (0);
-}
-
-int
-cachefs_kstat_key_snapshot(kstat_t *ksp, void *buf, int rw)
-{
- cachefs_kstat_key_t *key = *((cachefs_kstat_key_t **)ksp->ks_data);
- cachefs_kstat_key_t *k;
- caddr_t s;
- int i;
-
- if (rw == KSTAT_WRITE)
- return (EIO);
-
- if (key == NULL)
- return (0); /* paranoid */
-
- bcopy(key, buf, cachefs_kstat_key_n * sizeof (*key));
- key = buf;
- s = (caddr_t)(key + cachefs_kstat_key_n);
-
- for (i = 0; i < cachefs_kstat_key_n; i++) {
- k = key + i;
-
- (void) strcpy(s, (char *)(uintptr_t)k->ks_mountpoint);
- k->ks_mountpoint = (uint64_t)(uintptr_t)(s - (uintptr_t)buf);
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_backfs);
- k->ks_backfs = (uint64_t)(uintptr_t)(s - (uintptr_t)buf);
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_cachedir);
- k->ks_cachedir = (uint64_t)(uintptr_t)(s - (uintptr_t)buf);
- s += strlen(s) + 1;
- (void) strcpy(s, (char *)(uintptr_t)k->ks_cacheid);
- k->ks_cacheid = (uint64_t)(uintptr_t)(s - (uintptr_t)buf);
- s += strlen(s) + 1;
- }
-
- return (0);
-}
-
-extern void cachefs_inactivate();
-
-static int
-cachefs_unmount(vfs_t *vfsp, int flag, cred_t *cr)
-{
- fscache_t *fscp = VFS_TO_FSCACHE(vfsp);
- struct cachefscache *cachep = fscp->fs_cache;
- int error;
- int xx;
- vnode_t *nmvp;
- struct vattr attr;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: ENTER fscp %p\n", fscp);
-#endif
-
- if ((error = secpolicy_fs_unmount(cr, vfsp)) != 0)
- goto out;
-
- /*
- * forced unmount is not supported by this file system
- * and thus, ENOTSUP, is being returned.
- */
- if (flag & MS_FORCE) {
- error = ENOTSUP;
- goto out;
- }
- /* if a log file exists don't allow the unmount */
- if (fscp->fs_dlogfile) {
- error = EBUSY;
- goto out;
- }
-
- /*
- * wait for the cache-wide async queue to drain. Someone
- * here may be trying to sync our fscache...
- */
- while (cachefs_async_halt(&fscp->fs_cache->c_workq, 0) == EBUSY) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("unmount: waiting for cache async queue...\n");
-#endif
- }
-
- error = cachefs_async_halt(&fscp->fs_workq, 1);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: "
- "cachefs_async_halt error %d\n", error);
-#endif
- goto out;
- }
-
- /*
- * No active cnodes on this cache && rootvp refcnt == 1
- */
- mutex_enter(&fscp->fs_fslock);
- xx = fscp->fs_cnodecnt - fscp->fs_idlecnt;
- ASSERT(xx >= 1);
- if (xx > 1 || fscp->fs_rootvp->v_count != 1) {
- mutex_exit(&fscp->fs_fslock);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: busy (cnodes active %d, idle "
- "%d)\n", fscp->fs_cnodecnt, fscp->fs_idlecnt);
-#endif
- error = EBUSY;
- goto out;
- }
- mutex_exit(&fscp->fs_fslock);
-
- /* get rid of anything on the idle list */
- ASSERT(fscp->fs_idleclean == 0);
- cachefs_cnode_idleclean(fscp, 1);
- if (fscp->fs_cnodecnt > 1) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: busy (cnode count %d)\n",
- fscp->fs_cnodecnt);
-#endif
- error = EBUSY;
- goto out;
- }
-
- fscache_hold(fscp);
-
- /* get rid of the root cnode */
- if (cachefs_cnode_inactive(fscp->fs_rootvp, cr) == EBUSY) {
- fscache_rele(fscp);
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: busy (inactive failed)\n");
-#endif
- error = EBUSY;
- goto out;
- }
-
- /* create the file indicating not mounted */
- attr.va_mode = S_IFREG | 0666;
- attr.va_uid = 0;
- attr.va_gid = 0;
- attr.va_type = VREG;
- attr.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
- if (fscp->fs_fscdirvp != NULL)
- xx = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_UNMNT_FILE, &attr,
- NONEXCL, 0600, &nmvp, kcred, 0, NULL, NULL);
- else
- xx = ENOENT; /* for unmounting when NOCACHE */
- if (xx == 0) {
- VN_RELE(nmvp);
- } else {
- printf("could not create %s %d\n", CACHEFS_UNMNT_FILE, xx);
- }
-
- ASSERT(fscp->fs_cnodecnt == 0);
-
- /* sync the file system just in case */
- fscache_sync(fscp);
-
- /* lock out other unmounts and mount */
- mutex_enter(&cachefs_cachelock);
-
- /* mark the file system as not mounted */
- mutex_enter(&fscp->fs_fslock);
- fscp->fs_flags &= ~CFS_FS_MOUNTED;
- fscp->fs_rootvp = NULL;
- if (fscp->fs_kstat_id > 0)
- cachefs_kstat_umount(fscp->fs_kstat_id);
- fscp->fs_kstat_id = 0;
-
- /* drop the inum translation table */
- if (fscp->fs_inum_size > 0) {
- cachefs_kmem_free(fscp->fs_inum_trans,
- fscp->fs_inum_size * sizeof (cachefs_inum_trans_t));
- fscp->fs_inum_size = 0;
- fscp->fs_inum_trans = NULL;
- fscp->fs_flags &= ~CFS_FS_HASHPRINT;
- }
- mutex_exit(&fscp->fs_fslock);
-
- fscache_rele(fscp);
-
- /* get rid of any unused fscache objects */
- mutex_enter(&cachep->c_fslistlock);
- fscache_list_gc(cachep);
- mutex_exit(&cachep->c_fslistlock);
-
- /* get the number of mounts on this cache */
- mutex_enter(&cachep->c_fslistlock);
- xx = fscache_list_mounted(cachep);
- mutex_exit(&cachep->c_fslistlock);
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_UMOUNT))
- cachefs_log_umount(cachep, 0, vfsp);
-
- /* if no mounts left, deactivate the cache */
- if (xx == 0)
- cachefs_delete_cachep(cachep);
-
- mutex_exit(&cachefs_cachelock);
-
-out:
- if (error) {
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_UMOUNT))
- cachefs_log_umount(cachep, error, vfsp);
- }
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VFSOP)
- printf("cachefs_unmount: EXIT\n");
-#endif
- return (error);
-}
-
-/*
- * remove the cache from the list of caches
- */
-
-static void
-cachefs_delete_cachep(cachefscache_t *cachep)
-{
- struct cachefscache **cachepp;
- int found = 0;
-
- ASSERT(MUTEX_HELD(&cachefs_cachelock));
-
- for (cachepp = &cachefs_cachelist;
- *cachepp != NULL;
- cachepp = &(*cachepp)->c_next) {
- if (*cachepp == cachep) {
- *cachepp = cachep->c_next;
- found++;
- break;
- }
- }
- ASSERT(found);
-
- /* shut down the cache */
- cachefs_cache_destroy(cachep);
-}
-
-static int
-cachefs_root(vfs_t *vfsp, vnode_t **vpp)
-{
- /*LINTED alignment okay*/
- struct fscache *fscp = (struct fscache *)vfsp->vfs_data;
-
- ASSERT(fscp != NULL);
- ASSERT(fscp->fs_rootvp != NULL);
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
- *vpp = fscp->fs_rootvp;
- VN_HOLD(*vpp);
- return (0);
-}
-
-/*
- * Get file system statistics.
- */
-static int
-cachefs_statvfs(register vfs_t *vfsp, struct statvfs64 *sbp)
-{
- struct fscache *fscp = VFS_TO_FSCACHE(vfsp);
- struct cache_label *lp = &fscp->fs_cache->c_label;
- struct cache_usage *up = &fscp->fs_cache->c_usage;
- int error;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
- error = cachefs_cd_access(fscp, 0, 0);
- if (error)
- return (error);
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- /*
- * When connected return backfs stats
- */
- error = VFS_STATVFS(fscp->fs_backvfsp, sbp);
- } else {
- /*
- * Otherwise, just return the frontfs stats
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = VFS_STATVFS(fscp->fs_fscdirvp->v_vfsp, sbp);
- if (!error) {
- dev32_t d32;
-
- sbp->f_frsize = MAXBSIZE;
- sbp->f_blocks = lp->cl_maxblks;
- sbp->f_bfree = sbp->f_bavail =
- lp->cl_maxblks - up->cu_blksused;
- sbp->f_files = lp->cl_maxinodes;
- sbp->f_ffree = sbp->f_favail =
- lp->cl_maxinodes - up->cu_filesused;
- (void) cmpldev(&d32, vfsp->vfs_dev);
- sbp->f_fsid = d32;
- }
- }
- cachefs_cd_release(fscp);
- if (error)
- return (error);
-
- /*
- * Make sure fstype is CFS.
- */
- (void) strcpy(sbp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
- bzero(sbp->f_fstr, sizeof (sbp->f_fstr));
-
- return (0);
-}
-
-/*
- * queue a request to sync the given fscache
- */
-static void
-queue_sync(struct cachefscache *cachep, cred_t *cr)
-{
- struct cachefs_req *rp;
-
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- rp->cfs_cmd = CFS_CACHE_SYNC;
- rp->cfs_cr = cr;
- rp->cfs_req_u.cu_fs_sync.cf_cachep = cachep;
- crhold(rp->cfs_cr);
- cachefs_addqueue(rp, &cachep->c_workq);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_sync(vfs_t *vfsp, short flag, cred_t *cr)
-{
- struct fscache *fscp;
- struct cachefscache *cachep;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
- if (!(flag & SYNC_ATTR)) {
- /*
- * queue an async request to do the sync.
- * We always sync an entire cache (as opposed to an
- * individual fscache) so that we have an opportunity
- * to set the clean flag.
- */
- if (vfsp) {
- /*LINTED alignment okay*/
- fscp = (struct fscache *)vfsp->vfs_data;
- queue_sync(fscp->fs_cache, cr);
- } else {
- mutex_enter(&cachefs_cachelock);
- for (cachep = cachefs_cachelist; cachep != NULL;
- cachep = cachep->c_next) {
- queue_sync(cachep, cr);
- }
- mutex_exit(&cachefs_cachelock);
- }
- }
- return (0);
-}
-
-static int
-cachefs_remount(struct vfs *vfsp, struct mounta *uap)
-{
- fscache_t *fscp = VFS_TO_FSCACHE(vfsp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- STRUCT_DECL(cachefs_mountargs, map);
- struct cachefsoptions *cfs_options;
- char *backfs, *cacheid, *cachedir;
- struct vnode *cachedirvp = NULL;
- ino64_t fsid;
- vnode_t *backrootvp = NULL;
- struct vnode *tmpdirvp = NULL;
-
- STRUCT_INIT(map, get_udatamodel());
- error = copyin(uap->dataptr, STRUCT_BUF(map),
- SIZEOF_STRUCT(cachefs_mountargs, DATAMODEL_NATIVE));
- if (error)
- goto out;
-
- /*
- * get cache directory vp
- */
- cachedir = (char *)STRUCT_FGETP(map, cfs_cachedir);
- error = lookupname(cachedir, UIO_USERSPACE, FOLLOW,
- NULLVPP, &cachedirvp);
- if (error)
- goto out;
- if (cachedirvp->v_type != VDIR) {
- error = EINVAL;
- goto out;
- }
-
- error = 0;
- if (cachedirvp) {
- error = VOP_LOOKUP(cachedirvp, CACHEFS_DLOG_FILE,
- &tmpdirvp, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- }
- cfs_options = (struct cachefsoptions *)STRUCT_FADDR(map, cfs_options);
- cacheid = (char *)STRUCT_FGETP(map, cfs_cacheid);
-/* XXX not quite right */
-#if 0
- /*
- * If a log file exists and the cache is being mounted without
- * the snr (aka disconnectable) option, return an error.
- */
- if ((error == 0) &&
- !(cfs_options->opt_flags & CFS_DISCONNECTABLE)) {
- cmn_err(CE_WARN,
- "cachefs_mount: log exists and disconnectable"
- "option not specified\n");
- error = EINVAL;
- goto out;
- }
-#endif
- error = 0;
-
- /*
- * If the user is using NFSv4 and there are other options
- * specified, make sure we ignore the other options.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- cfs_options->opt_flags = CFS_BACKFS_NFSV4;
- }
-
- /* XXX need mount options "nocache" and "nofill" */
-
- /* if nocache is being turned off */
- if (cachep->c_flags & CACHE_NOCACHE) {
- error = cachefs_cache_activate_ro(cachep, cachedirvp);
- if (error)
- goto out;
- cachefs_cache_activate_rw(cachep);
-
- /* get the fsid for the fscache */
- error = fscache_name_to_fsid(cachep, cacheid, &fsid);
- if (error)
- fsid = 0;
-
- /* activate the fscache */
- mutex_enter(&cachep->c_fslistlock);
- error = fscache_enable(fscp, fsid, cacheid,
- cfs_options, fscp->fs_info.fi_root);
- mutex_exit(&cachep->c_fslistlock);
- if (error) {
- cmn_err(CE_WARN, "cachefs: cannot remount %s\n",
- cacheid);
- goto out;
- }
-
- /* enable the cache */
- cachefs_enable_caching(fscp);
- fscache_activate_rw(fscp);
- }
-
- /* else if nofill is being turn off */
- else if (cachep->c_flags & CACHE_NOFILL) {
- ASSERT(cachep->c_flags & CACHE_NOFILL);
- cachefs_cache_activate_rw(cachep);
-
- /* enable the cache */
- cachefs_enable_caching(fscp);
- fscache_activate_rw(fscp);
- }
-
- fscache_acset(fscp, STRUCT_FGET(map, cfs_acregmin),
- STRUCT_FGET(map, cfs_acregmax),
- STRUCT_FGET(map, cfs_acdirmin), STRUCT_FGET(map, cfs_acdirmax));
-
- /* if the backfs is mounted now or we have a new backfs */
- backfs = (char *)STRUCT_FGETP(map, cfs_backfs);
- if (backfs && (cfs_options->opt_flags & CFS_SLIDE)) {
- /* get the back file system root vp */
- error = lookupname(backfs, UIO_USERSPACE, FOLLOW,
- NULLVPP, &backrootvp);
- if (error)
- goto out;
-
- /*
- * Make sure the thing we just looked up is a directory
- * and a root of a file system
- */
- if (backrootvp->v_type != VDIR ||
- !(backrootvp->v_flag & VROOT)) {
- cmn_err(CE_WARN,
- "cachefs_mount: backpath not a directory\n");
- error = EINVAL;
- goto out;
- }
-
- /*
- * XXX
- * Kind of dangerous to just set this but we do
- * not have locks around usage of fs_backvfsp.
- * Hope for the best for now.
- * Probably should also spin through vnodes and fix them up.
- * Krishna - fixed c_backvp to reflect the change.
- */
- fscp->fs_backvfsp = backrootvp->v_vfsp;
- ((cnode_t *)(fscp->fs_rootvp->v_data))->c_backvp = backrootvp;
-
- /*
- * Now the root cnode structure is an owner of
- * the opened back root vnode structure; we must
- * clear the pointer to back root vnode here as
- * we don't need it since now, and the root cnode
- * structure will control the vnode
- */
- backrootvp = (vnode_t *)NULL;
- }
-
- if (fscp->fs_kstat_id > 0)
- cachefs_kstat_umount(fscp->fs_kstat_id);
- fscp->fs_kstat_id = 0;
- cachefs_kstat_mount(fscp, uap->dir, backfs, cachedir, cacheid);
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_MOUNT))
- cachefs_log_mount(cachep, error, vfsp, fscp,
- uap->dir, UIO_USERSPACE,
- (STRUCT_BUF(map) != NULL) ? cacheid : NULL);
-
-out:
- if (cachedirvp)
- VN_RELE(cachedirvp);
- if (backrootvp)
- VN_RELE(backrootvp);
- return (error);
-}
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_vnops.c b/usr/src/uts/common/fs/cachefs/cachefs_vnops.c
deleted file mode 100644
index f0417ef349..0000000000
--- a/usr/src/uts/common/fs/cachefs/cachefs_vnops.c
+++ /dev/null
@@ -1,10249 +0,0 @@
-/*
- * 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
- * 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 (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/cred.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-#include <sys/vfs.h>
-#include <sys/vfs_opreg.h>
-#include <sys/file.h>
-#include <sys/filio.h>
-#include <sys/uio.h>
-#include <sys/buf.h>
-#include <sys/mman.h>
-#include <sys/tiuser.h>
-#include <sys/pathname.h>
-#include <sys/dirent.h>
-#include <sys/conf.h>
-#include <sys/debug.h>
-#include <sys/vmsystm.h>
-#include <sys/fcntl.h>
-#include <sys/flock.h>
-#include <sys/swap.h>
-#include <sys/errno.h>
-#include <sys/sysmacros.h>
-#include <sys/disp.h>
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/vtrace.h>
-#include <sys/mount.h>
-#include <sys/bootconf.h>
-#include <sys/dnlc.h>
-#include <sys/stat.h>
-#include <sys/acl.h>
-#include <sys/policy.h>
-#include <rpc/types.h>
-
-#include <vm/hat.h>
-#include <vm/as.h>
-#include <vm/page.h>
-#include <vm/pvn.h>
-#include <vm/seg.h>
-#include <vm/seg_map.h>
-#include <vm/seg_vn.h>
-#include <vm/rm.h>
-#include <sys/fs/cachefs_fs.h>
-#include <sys/fs/cachefs_dir.h>
-#include <sys/fs/cachefs_dlog.h>
-#include <sys/fs/cachefs_ioctl.h>
-#include <sys/fs/cachefs_log.h>
-#include <fs/fs_subr.h>
-
-int cachefs_dnlc; /* use dnlc, debugging */
-
-static void cachefs_attr_setup(vattr_t *srcp, vattr_t *targp, cnode_t *cp,
- cred_t *cr);
-static void cachefs_creategid(cnode_t *dcp, cnode_t *newcp, vattr_t *vap,
- cred_t *cr);
-static void cachefs_createacl(cnode_t *dcp, cnode_t *newcp);
-static int cachefs_getaclfromcache(cnode_t *cp, vsecattr_t *vsec);
-static int cachefs_getacldirvp(cnode_t *cp);
-static void cachefs_acl2perm(cnode_t *cp, vsecattr_t *vsec);
-static int cachefs_access_local(void *cp, int mode, cred_t *cr);
-static int cachefs_acl_access(struct cnode *cp, int mode, cred_t *cr);
-static int cachefs_push_connected(vnode_t *vp, struct buf *bp, size_t iolen,
- u_offset_t iooff, cred_t *cr);
-static int cachefs_push_front(vnode_t *vp, struct buf *bp, size_t iolen,
- u_offset_t iooff, cred_t *cr);
-static int cachefs_setattr_connected(vnode_t *vp, vattr_t *vap, int flags,
- cred_t *cr, caller_context_t *ct);
-static int cachefs_setattr_disconnected(vnode_t *vp, vattr_t *vap,
- int flags, cred_t *cr, caller_context_t *ct);
-static int cachefs_access_connected(struct vnode *vp, int mode,
- int flags, cred_t *cr);
-static int cachefs_lookup_back(vnode_t *dvp, char *nm, vnode_t **vpp,
- cred_t *cr);
-static int cachefs_symlink_connected(vnode_t *dvp, char *lnm, vattr_t *tva,
- char *tnm, cred_t *cr);
-static int cachefs_symlink_disconnected(vnode_t *dvp, char *lnm,
- vattr_t *tva, char *tnm, cred_t *cr);
-static int cachefs_link_connected(vnode_t *tdvp, vnode_t *fvp, char *tnm,
- cred_t *cr);
-static int cachefs_link_disconnected(vnode_t *tdvp, vnode_t *fvp,
- char *tnm, cred_t *cr);
-static int cachefs_mkdir_connected(vnode_t *dvp, char *nm, vattr_t *vap,
- vnode_t **vpp, cred_t *cr);
-static int cachefs_mkdir_disconnected(vnode_t *dvp, char *nm, vattr_t *vap,
- vnode_t **vpp, cred_t *cr);
-static int cachefs_stickyrmchk(struct cnode *dcp, struct cnode *cp, cred_t *cr);
-static int cachefs_rmdir_connected(vnode_t *dvp, char *nm,
- vnode_t *cdir, cred_t *cr, vnode_t *vp);
-static int cachefs_rmdir_disconnected(vnode_t *dvp, char *nm,
- vnode_t *cdir, cred_t *cr, vnode_t *vp);
-static char *cachefs_newname(void);
-static int cachefs_remove_dolink(vnode_t *dvp, vnode_t *vp, char *nm,
- cred_t *cr);
-static int cachefs_rename_connected(vnode_t *odvp, char *onm,
- vnode_t *ndvp, char *nnm, cred_t *cr, vnode_t *delvp);
-static int cachefs_rename_disconnected(vnode_t *odvp, char *onm,
- vnode_t *ndvp, char *nnm, cred_t *cr, vnode_t *delvp);
-static int cachefs_readdir_connected(vnode_t *vp, uio_t *uiop, cred_t *cr,
- int *eofp);
-static int cachefs_readdir_disconnected(vnode_t *vp, uio_t *uiop,
- cred_t *cr, int *eofp);
-static int cachefs_readback_translate(cnode_t *cp, uio_t *uiop,
- cred_t *cr, int *eofp);
-
-static int cachefs_setattr_common(vnode_t *vp, vattr_t *vap, int flags,
- cred_t *cr, caller_context_t *ct);
-
-static int cachefs_open(struct vnode **, int, cred_t *,
- caller_context_t *);
-static int cachefs_close(struct vnode *, int, int, offset_t,
- cred_t *, caller_context_t *);
-static int cachefs_read(struct vnode *, struct uio *, int, cred_t *,
- caller_context_t *);
-static int cachefs_write(struct vnode *, struct uio *, int, cred_t *,
- caller_context_t *);
-static int cachefs_ioctl(struct vnode *, int, intptr_t, int, cred_t *,
- int *, caller_context_t *);
-static int cachefs_getattr(struct vnode *, struct vattr *, int,
- cred_t *, caller_context_t *);
-static int cachefs_setattr(struct vnode *, struct vattr *,
- int, cred_t *, caller_context_t *);
-static int cachefs_access(struct vnode *, int, int, cred_t *,
- caller_context_t *);
-static int cachefs_lookup(struct vnode *, char *, struct vnode **,
- struct pathname *, int, struct vnode *, cred_t *,
- caller_context_t *, int *, pathname_t *);
-static int cachefs_create(struct vnode *, char *, struct vattr *,
- enum vcexcl, int, struct vnode **, cred_t *, int,
- caller_context_t *, vsecattr_t *);
-static int cachefs_create_connected(vnode_t *dvp, char *nm,
- vattr_t *vap, enum vcexcl exclusive, int mode,
- vnode_t **vpp, cred_t *cr);
-static int cachefs_create_disconnected(vnode_t *dvp, char *nm,
- vattr_t *vap, enum vcexcl exclusive, int mode,
- vnode_t **vpp, cred_t *cr);
-static int cachefs_remove(struct vnode *, char *, cred_t *,
- caller_context_t *, int);
-static int cachefs_link(struct vnode *, struct vnode *, char *,
- cred_t *, caller_context_t *, int);
-static int cachefs_rename(struct vnode *, char *, struct vnode *,
- char *, cred_t *, caller_context_t *, int);
-static int cachefs_mkdir(struct vnode *, char *, struct
- vattr *, struct vnode **, cred_t *, caller_context_t *,
- int, vsecattr_t *);
-static int cachefs_rmdir(struct vnode *, char *, struct vnode *,
- cred_t *, caller_context_t *, int);
-static int cachefs_readdir(struct vnode *, struct uio *,
- cred_t *, int *, caller_context_t *, int);
-static int cachefs_symlink(struct vnode *, char *, struct vattr *,
- char *, cred_t *, caller_context_t *, int);
-static int cachefs_readlink(struct vnode *, struct uio *, cred_t *,
- caller_context_t *);
-static int cachefs_readlink_connected(vnode_t *vp, uio_t *uiop, cred_t *cr);
-static int cachefs_readlink_disconnected(vnode_t *vp, uio_t *uiop);
-static int cachefs_fsync(struct vnode *, int, cred_t *,
- caller_context_t *);
-static void cachefs_inactive(struct vnode *, cred_t *, caller_context_t *);
-static int cachefs_fid(struct vnode *, struct fid *, caller_context_t *);
-static int cachefs_rwlock(struct vnode *, int, caller_context_t *);
-static void cachefs_rwunlock(struct vnode *, int, caller_context_t *);
-static int cachefs_seek(struct vnode *, offset_t, offset_t *,
- caller_context_t *);
-static int cachefs_frlock(struct vnode *, int, struct flock64 *,
- int, offset_t, struct flk_callback *, cred_t *,
- caller_context_t *);
-static int cachefs_space(struct vnode *, int, struct flock64 *, int,
- offset_t, cred_t *, caller_context_t *);
-static int cachefs_realvp(struct vnode *, struct vnode **,
- caller_context_t *);
-static int cachefs_getpage(struct vnode *, offset_t, size_t, uint_t *,
- struct page *[], size_t, struct seg *, caddr_t,
- enum seg_rw, cred_t *, caller_context_t *);
-static int cachefs_getapage(struct vnode *, u_offset_t, size_t, uint_t *,
- struct page *[], size_t, struct seg *, caddr_t,
- enum seg_rw, cred_t *);
-static int cachefs_getapage_back(struct vnode *, u_offset_t, size_t,
- uint_t *, struct page *[], size_t, struct seg *, caddr_t,
- enum seg_rw, cred_t *);
-static int cachefs_putpage(struct vnode *, offset_t, size_t, int,
- cred_t *, caller_context_t *);
-static int cachefs_map(struct vnode *, offset_t, struct as *,
- caddr_t *, size_t, uchar_t, uchar_t, uint_t, cred_t *,
- caller_context_t *);
-static int cachefs_addmap(struct vnode *, offset_t, struct as *,
- caddr_t, size_t, uchar_t, uchar_t, uint_t, cred_t *,
- caller_context_t *);
-static int cachefs_delmap(struct vnode *, offset_t, struct as *,
- caddr_t, size_t, uint_t, uint_t, uint_t, cred_t *,
- caller_context_t *);
-static int cachefs_setsecattr(vnode_t *vp, vsecattr_t *vsec,
- int flag, cred_t *cr, caller_context_t *);
-static int cachefs_getsecattr(vnode_t *vp, vsecattr_t *vsec,
- int flag, cred_t *cr, caller_context_t *);
-static int cachefs_shrlock(vnode_t *, int, struct shrlock *, int,
- cred_t *, caller_context_t *);
-static int cachefs_getsecattr_connected(vnode_t *vp, vsecattr_t *vsec, int flag,
- cred_t *cr);
-static int cachefs_getsecattr_disconnected(vnode_t *vp, vsecattr_t *vsec,
- int flag, cred_t *cr);
-
-static int cachefs_dump(struct vnode *, caddr_t, offset_t, offset_t,
- caller_context_t *);
-static int cachefs_pageio(struct vnode *, page_t *,
- u_offset_t, size_t, int, cred_t *, caller_context_t *);
-static int cachefs_writepage(struct vnode *vp, caddr_t base,
- int tcount, struct uio *uiop);
-static int cachefs_pathconf(vnode_t *, int, ulong_t *, cred_t *,
- caller_context_t *);
-
-static int cachefs_read_backfs_nfsv4(vnode_t *vp, uio_t *uiop, int ioflag,
- cred_t *cr, caller_context_t *ct);
-static int cachefs_write_backfs_nfsv4(vnode_t *vp, uio_t *uiop, int ioflag,
- cred_t *cr, caller_context_t *ct);
-static int cachefs_getattr_backfs_nfsv4(vnode_t *vp, vattr_t *vap,
- int flags, cred_t *cr, caller_context_t *ct);
-static int cachefs_remove_backfs_nfsv4(vnode_t *dvp, char *nm, cred_t *cr,
- vnode_t *vp);
-static int cachefs_getpage_backfs_nfsv4(struct vnode *vp, offset_t off,
- size_t len, uint_t *protp, struct page *pl[],
- size_t plsz, struct seg *seg, caddr_t addr,
- enum seg_rw rw, cred_t *cr);
-static int cachefs_putpage_backfs_nfsv4(vnode_t *vp, offset_t off,
- size_t len, int flags, cred_t *cr);
-static int cachefs_map_backfs_nfsv4(struct vnode *vp, offset_t off,
- struct as *as, caddr_t *addrp, size_t len, uchar_t prot,
- uchar_t maxprot, uint_t flags, cred_t *cr);
-static int cachefs_space_backfs_nfsv4(struct vnode *vp, int cmd,
- struct flock64 *bfp, int flag, offset_t offset,
- cred_t *cr, caller_context_t *ct);
-
-struct vnodeops *cachefs_vnodeops;
-
-static const fs_operation_def_t cachefs_vnodeops_template[] = {
- VOPNAME_OPEN, { .vop_open = cachefs_open },
- VOPNAME_CLOSE, { .vop_close = cachefs_close },
- VOPNAME_READ, { .vop_read = cachefs_read },
- VOPNAME_WRITE, { .vop_write = cachefs_write },
- VOPNAME_IOCTL, { .vop_ioctl = cachefs_ioctl },
- VOPNAME_GETATTR, { .vop_getattr = cachefs_getattr },
- VOPNAME_SETATTR, { .vop_setattr = cachefs_setattr },
- VOPNAME_ACCESS, { .vop_access = cachefs_access },
- VOPNAME_LOOKUP, { .vop_lookup = cachefs_lookup },
- VOPNAME_CREATE, { .vop_create = cachefs_create },
- VOPNAME_REMOVE, { .vop_remove = cachefs_remove },
- VOPNAME_LINK, { .vop_link = cachefs_link },
- VOPNAME_RENAME, { .vop_rename = cachefs_rename },
- VOPNAME_MKDIR, { .vop_mkdir = cachefs_mkdir },
- VOPNAME_RMDIR, { .vop_rmdir = cachefs_rmdir },
- VOPNAME_READDIR, { .vop_readdir = cachefs_readdir },
- VOPNAME_SYMLINK, { .vop_symlink = cachefs_symlink },
- VOPNAME_READLINK, { .vop_readlink = cachefs_readlink },
- VOPNAME_FSYNC, { .vop_fsync = cachefs_fsync },
- VOPNAME_INACTIVE, { .vop_inactive = cachefs_inactive },
- VOPNAME_FID, { .vop_fid = cachefs_fid },
- VOPNAME_RWLOCK, { .vop_rwlock = cachefs_rwlock },
- VOPNAME_RWUNLOCK, { .vop_rwunlock = cachefs_rwunlock },
- VOPNAME_SEEK, { .vop_seek = cachefs_seek },
- VOPNAME_FRLOCK, { .vop_frlock = cachefs_frlock },
- VOPNAME_SPACE, { .vop_space = cachefs_space },
- VOPNAME_REALVP, { .vop_realvp = cachefs_realvp },
- VOPNAME_GETPAGE, { .vop_getpage = cachefs_getpage },
- VOPNAME_PUTPAGE, { .vop_putpage = cachefs_putpage },
- VOPNAME_MAP, { .vop_map = cachefs_map },
- VOPNAME_ADDMAP, { .vop_addmap = cachefs_addmap },
- VOPNAME_DELMAP, { .vop_delmap = cachefs_delmap },
- VOPNAME_DUMP, { .vop_dump = cachefs_dump },
- VOPNAME_PATHCONF, { .vop_pathconf = cachefs_pathconf },
- VOPNAME_PAGEIO, { .vop_pageio = cachefs_pageio },
- VOPNAME_SETSECATTR, { .vop_setsecattr = cachefs_setsecattr },
- VOPNAME_GETSECATTR, { .vop_getsecattr = cachefs_getsecattr },
- VOPNAME_SHRLOCK, { .vop_shrlock = cachefs_shrlock },
- NULL, NULL
-};
-
-/* forward declarations of statics */
-static void cachefs_modified(cnode_t *cp);
-static int cachefs_modified_alloc(cnode_t *cp);
-
-int
-cachefs_init_vnops(char *name)
-{
- return (vn_make_ops(name,
- cachefs_vnodeops_template, &cachefs_vnodeops));
-}
-
-struct vnodeops *
-cachefs_getvnodeops(void)
-{
- return (cachefs_vnodeops);
-}
-
-static int
-cachefs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
-{
- int error = 0;
- cnode_t *cp = VTOC(*vpp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0;
- int type;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_open: ENTER vpp %p flag %x\n",
- (void *)vpp, flag);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
- if ((flag & FWRITE) &&
- ((*vpp)->v_type == VDIR || (*vpp)->v_type == VLNK)) {
- error = EISDIR;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the open operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- goto out;
- held = 1;
-
- mutex_enter(&cp->c_statelock);
-
- /* grab creds if we do not have any yet */
- if (cp->c_cred == NULL) {
- crhold(cr);
- cp->c_cred = cr;
- }
- cp->c_flags |= CN_NEEDOPEN;
-
- /* if we are disconnected */
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- /* if we cannot write to the file system */
- if ((flag & FWRITE) && CFS_ISFS_WRITE_AROUND(fscp)) {
- mutex_exit(&cp->c_statelock);
- connected = 1;
- continue;
- }
- /*
- * Allow read only requests to continue
- */
- if ((flag & (FWRITE|FREAD)) == FREAD) {
- /* track the flag for opening the backvp */
- cp->c_rdcnt++;
- mutex_exit(&cp->c_statelock);
- error = 0;
- break;
- }
-
- /*
- * check credentials - if this procs
- * credentials don't match the creds in the
- * cnode disallow writing while disconnected.
- */
- if (crcmp(cp->c_cred, CRED()) != 0 &&
- secpolicy_vnode_access2(CRED(), *vpp,
- cp->c_attr.va_uid, 0, VWRITE) != 0) {
- mutex_exit(&cp->c_statelock);
- connected = 1;
- continue;
- }
- /* to get here, we know that the WRITE flag is on */
- cp->c_wrcnt++;
- if (flag & FREAD)
- cp->c_rdcnt++;
- }
-
- /* else if we are connected */
- else {
- /* if cannot use the cached copy of the file */
- if ((flag & FWRITE) && CFS_ISFS_WRITE_AROUND(fscp) &&
- ((cp->c_flags & CN_NOCACHE) == 0))
- cachefs_nocache(cp);
-
- /* pass open to the back file */
- if (cp->c_backvp) {
- cp->c_flags &= ~CN_NEEDOPEN;
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_open (nfsv4): cnode %p, "
- "backvp %p\n", cp, cp->c_backvp));
- error = VOP_OPEN(&cp->c_backvp, flag, cr, ct);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else if (error) {
- mutex_exit(&cp->c_statelock);
- break;
- }
- } else {
- /* backvp will be VOP_OPEN'd later */
- if (flag & FREAD)
- cp->c_rdcnt++;
- if (flag & FWRITE)
- cp->c_wrcnt++;
- }
-
- /*
- * Now perform a consistency check on the file.
- * If strict consistency then force a check to
- * the backfs even if the timeout has not expired
- * for close-to-open consistency.
- */
- type = 0;
- if (fscp->fs_consttype == CFS_FS_CONST_STRICT)
- type = C_BACK_CHECK;
- error = CFSOP_CHECK_COBJECT(fscp, cp, type, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- }
- }
- mutex_exit(&cp->c_statelock);
- break;
- }
- if (held)
- cachefs_cd_release(fscp);
-out:
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_open: EXIT vpp %p error %d\n",
- (void *)vpp, error);
-#endif
- return (error);
-}
-
-/* ARGSUSED */
-static int
-cachefs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
- caller_context_t *ct)
-{
- int error = 0;
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0;
- int connected = 0;
- int close_cnt = 1;
- cachefscache_t *cachep;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_close: ENTER vp %p\n", (void *)vp);
-#endif
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the close operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /*
- * File could have been passed in or inherited from the global zone, so
- * we don't want to flat out reject the request; we'll just leave things
- * the way they are and let the backfs (NFS) deal with it.
- */
- /* get rid of any local locks */
- if (CFS_ISFS_LLOCK(fscp)) {
- (void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
- }
-
- /* clean up if this is the daemon closing down */
- if ((fscp->fs_cddaemonid == ttoproc(curthread)->p_pid) &&
- ((ttoproc(curthread)->p_pid) != 0) &&
- (vp == fscp->fs_rootvp) &&
- (count == 1)) {
- mutex_enter(&fscp->fs_cdlock);
- fscp->fs_cddaemonid = 0;
- if (fscp->fs_dlogfile)
- fscp->fs_cdconnected = CFS_CD_DISCONNECTED;
- else
- fscp->fs_cdconnected = CFS_CD_CONNECTED;
- cv_broadcast(&fscp->fs_cdwaitcv);
- mutex_exit(&fscp->fs_cdlock);
- if (fscp->fs_flags & CFS_FS_ROOTFS) {
- cachep = fscp->fs_cache;
- mutex_enter(&cachep->c_contentslock);
- ASSERT(cachep->c_rootdaemonid != 0);
- cachep->c_rootdaemonid = 0;
- mutex_exit(&cachep->c_contentslock);
- }
- return (0);
- }
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- goto out;
- held = 1;
- connected = 0;
-
- /* if not the last close */
- if (count > 1) {
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED)
- goto out;
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_close (nfsv4): cnode %p, "
- "backvp %p\n", cp, cp->c_backvp));
- error = VOP_CLOSE(cp->c_backvp, flag, count,
- offset, cr, ct);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- }
- }
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- /*
- * If the file is an unlinked file, then flush the lookup
- * cache so that inactive will be called if this is
- * the last reference. It will invalidate all of the
- * cached pages, without writing them out. Writing them
- * out is not required because they will be written to a
- * file which will be immediately removed.
- */
- if (cp->c_unldvp != NULL) {
- dnlc_purge_vp(vp);
- mutex_enter(&cp->c_statelock);
- error = cp->c_error;
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
- /* always call VOP_CLOSE() for back fs vnode */
- }
-
- /* force dirty data to stable storage */
- else if ((vp->v_type == VREG) && (flag & FWRITE) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- /* clean the cachefs pages synchronously */
- error = cachefs_putpage_common(vp, (offset_t)0,
- 0, 0, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else {
- connected = 1;
- continue;
- }
- }
-
- /* if no space left in cache, wait until connected */
- if ((error == ENOSPC) &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- connected = 1;
- continue;
- }
-
- /* clear the cnode error if putpage worked */
- if ((error == 0) && cp->c_error) {
- mutex_enter(&cp->c_statelock);
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
- }
-
- /* if any other important error */
- if (cp->c_error) {
- /* get rid of the pages */
- (void) cachefs_putpage_common(vp,
- (offset_t)0, 0, B_INVAL | B_FORCE, cr);
- dnlc_purge_vp(vp);
- }
- }
-
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp &&
- (fscp->fs_cdconnected == CFS_CD_CONNECTED)) {
- error = VOP_CLOSE(cp->c_backvp, flag, close_cnt,
- offset, cr, ct);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- /* don't decrement the vnode counts again */
- close_cnt = 0;
- continue;
- }
- }
- mutex_exit(&cp->c_statelock);
- break;
- }
-
- mutex_enter(&cp->c_statelock);
- if (!error)
- error = cp->c_error;
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
-
-out:
- if (held)
- cachefs_cd_release(fscp);
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_close: EXIT vp %p\n", (void *)vp);
-#endif
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
-{
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- register u_offset_t off;
- register int mapoff;
- register caddr_t base;
- int n;
- offset_t diff;
- uint_t flags = 0;
- int error = 0;
-
-#if 0
- if (vp->v_flag & VNOCACHE)
- flags = SM_INVAL;
-#endif
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
- if (vp->v_type != VREG)
- return (EISDIR);
-
- ASSERT(RW_READ_HELD(&cp->c_rwlock));
-
- if (uiop->uio_resid == 0)
- return (0);
-
-
- if (uiop->uio_loffset < (offset_t)0)
- return (EINVAL);
-
- /*
- * Call backfilesystem to read if NFSv4, the cachefs code
- * does the read from the back filesystem asynchronously
- * which is not supported by pass-through functionality.
- */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_read_backfs_nfsv4(vp, uiop, ioflag, cr, ct);
- goto out;
- }
-
- if (MANDLOCK(vp, cp->c_attr.va_mode)) {
- error = chklock(vp, FREAD, (offset_t)uiop->uio_loffset,
- uiop->uio_resid, uiop->uio_fmode, ct);
- if (error)
- return (error);
- }
-
- /*
- * Sit in a loop and transfer (uiomove) the data in up to
- * MAXBSIZE chunks. Each chunk is mapped into the kernel's
- * address space as needed and then released.
- */
- do {
- /*
- * off Offset of current MAXBSIZE chunk
- * mapoff Offset within the current chunk
- * n Number of bytes to move from this chunk
- * base kernel address of mapped in chunk
- */
- off = uiop->uio_loffset & (offset_t)MAXBMASK;
- mapoff = uiop->uio_loffset & MAXBOFFSET;
- n = MAXBSIZE - mapoff;
- if (n > uiop->uio_resid)
- n = (uint_t)uiop->uio_resid;
-
- /* perform consistency check */
- error = cachefs_cd_access(fscp, 0, 0);
- if (error)
- break;
- mutex_enter(&cp->c_statelock);
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- diff = cp->c_size - uiop->uio_loffset;
- mutex_exit(&cp->c_statelock);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- error = 0;
- continue;
- }
- cachefs_cd_release(fscp);
-
- if (error)
- break;
-
- if (diff <= (offset_t)0)
- break;
- if (diff < (offset_t)n)
- n = diff;
-
- base = segmap_getmapflt(segkmap, vp, off, (uint_t)n, 1, S_READ);
-
- error = segmap_fault(kas.a_hat, segkmap, base, n,
- F_SOFTLOCK, S_READ);
- if (error) {
- (void) segmap_release(segkmap, base, 0);
- if (FC_CODE(error) == FC_OBJERR)
- error = FC_ERRNO(error);
- else
- error = EIO;
- break;
- }
- error = uiomove(base+mapoff, n, UIO_READ, uiop);
- (void) segmap_fault(kas.a_hat, segkmap, base, n,
- F_SOFTUNLOCK, S_READ);
- if (error == 0) {
- /*
- * if we read a whole page(s), or to eof,
- * we won't need this page(s) again soon.
- */
- if (n + mapoff == MAXBSIZE ||
- uiop->uio_loffset == cp->c_size)
- flags |= SM_DONTNEED;
- }
- (void) segmap_release(segkmap, base, flags);
- } while (error == 0 && uiop->uio_resid > 0);
-
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_read: EXIT error %d resid %ld\n", error,
- uiop->uio_resid);
-#endif
- return (error);
-}
-
-/*
- * cachefs_read_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the read (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_read_backfs_nfsv4(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation
- * is supported, the cnode backvp must exist, and cachefs
- * optional (eg., disconnectable) flags are turned off. Assert
- * these conditions for the read operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_read_backfs_nfsv4: cnode %p, "
- "backvp %p\n", cp, backvp));
-
- (void) VOP_RWLOCK(backvp, V_WRITELOCK_FALSE, ct);
- error = VOP_READ(backvp, uiop, ioflag, cr, ct);
- VOP_RWUNLOCK(backvp, V_WRITELOCK_FALSE, ct);
-
- /* Increment cache miss counter */
- fscp->fs_stats.st_misses++;
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
-{
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- u_offset_t off;
- caddr_t base;
- uint_t bsize;
- uint_t flags;
- int n, on;
- rlim64_t limit = uiop->uio_llimit;
- ssize_t resid;
- offset_t offset;
- offset_t remainder;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf(
- "cachefs_write: ENTER vp %p offset %llu count %ld cflags %x\n",
- (void *)vp, uiop->uio_loffset, uiop->uio_resid,
- cp->c_flags);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
- if (vp->v_type != VREG) {
- error = EISDIR;
- goto out;
- }
-
- ASSERT(RW_WRITE_HELD(&cp->c_rwlock));
-
- if (uiop->uio_resid == 0) {
- goto out;
- }
-
- /* Call backfilesystem to write if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_write_backfs_nfsv4(vp, uiop, ioflag, cr, ct);
- goto out2;
- }
-
- if (MANDLOCK(vp, cp->c_attr.va_mode)) {
- error = chklock(vp, FWRITE, (offset_t)uiop->uio_loffset,
- uiop->uio_resid, uiop->uio_fmode, ct);
- if (error)
- goto out;
- }
-
- if (ioflag & FAPPEND) {
- for (;;) {
- /* do consistency check to get correct file size */
- error = cachefs_cd_access(fscp, 0, 1);
- if (error)
- goto out;
- mutex_enter(&cp->c_statelock);
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- uiop->uio_loffset = cp->c_size;
- mutex_exit(&cp->c_statelock);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- cachefs_cd_timedout(fscp);
- continue;
- }
- cachefs_cd_release(fscp);
- if (error)
- goto out;
- break;
- }
- }
-
- if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T)
- limit = MAXOFFSET_T;
-
- if (uiop->uio_loffset >= limit) {
- proc_t *p = ttoproc(curthread);
-
- mutex_enter(&p->p_lock);
- (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE], p->p_rctls,
- p, RCA_UNSAFE_SIGINFO);
- mutex_exit(&p->p_lock);
- error = EFBIG;
- goto out;
- }
- if (uiop->uio_loffset > fscp->fs_offmax) {
- error = EFBIG;
- goto out;
- }
-
- if (limit > fscp->fs_offmax)
- limit = fscp->fs_offmax;
-
- if (uiop->uio_loffset < (offset_t)0) {
- error = EINVAL;
- goto out;
- }
-
- offset = uiop->uio_loffset + uiop->uio_resid;
- /*
- * Check to make sure that the process will not exceed
- * its limit on file size. It is okay to write up to
- * the limit, but not beyond. Thus, the write which
- * reaches the limit will be short and the next write
- * will return an error.
- */
- remainder = 0;
- if (offset > limit) {
- remainder = (int)(offset - (u_offset_t)limit);
- uiop->uio_resid = limit - uiop->uio_loffset;
- if (uiop->uio_resid <= 0) {
- proc_t *p = ttoproc(curthread);
-
- uiop->uio_resid += remainder;
- mutex_enter(&p->p_lock);
- (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE],
- p->p_rctls, p, RCA_UNSAFE_SIGINFO);
- mutex_exit(&p->p_lock);
- error = EFBIG;
- goto out;
- }
- }
-
- resid = uiop->uio_resid;
- offset = uiop->uio_loffset;
- bsize = vp->v_vfsp->vfs_bsize;
-
- /* loop around and do the write in MAXBSIZE chunks */
- do {
- /* mapping offset */
- off = uiop->uio_loffset & (offset_t)MAXBMASK;
- on = uiop->uio_loffset & MAXBOFFSET; /* Rel. offset */
- n = MAXBSIZE - on;
- if (n > uiop->uio_resid)
- n = (int)uiop->uio_resid;
-
- /*
- * Touch the page and fault it in if it is not in
- * core before segmap_getmapflt can lock it. This
- * is to avoid the deadlock if the buffer is mapped
- * to the same file through mmap which we want to
- * write to.
- */
- uio_prefaultpages((long)n, uiop);
-
- base = segmap_getmap(segkmap, vp, off);
- error = cachefs_writepage(vp, (base + on), n, uiop);
- if (error == 0) {
- flags = 0;
- /*
- * Have written a whole block.Start an
- * asynchronous write and mark the buffer to
- * indicate that it won't be needed again
- * soon.
- */
- if (n + on == bsize) {
- flags = SM_WRITE |SM_ASYNC |SM_DONTNEED;
- }
-#if 0
- /* XXX need to understand this */
- if ((ioflag & (FSYNC|FDSYNC)) ||
- (cp->c_backvp && vn_has_flocks(cp->c_backvp))) {
- flags &= ~SM_ASYNC;
- flags |= SM_WRITE;
- }
-#else
- if (ioflag & (FSYNC|FDSYNC)) {
- flags &= ~SM_ASYNC;
- flags |= SM_WRITE;
- }
-#endif
- error = segmap_release(segkmap, base, flags);
- } else {
- (void) segmap_release(segkmap, base, 0);
- }
- } while (error == 0 && uiop->uio_resid > 0);
-
-out:
- if (error == EINTR && (ioflag & (FSYNC|FDSYNC))) {
- uiop->uio_resid = resid;
- uiop->uio_loffset = offset;
- } else
- uiop->uio_resid += remainder;
-
-out2:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_write: EXIT error %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_write_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the write (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_write_backfs_nfsv4(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation
- * is supported, the cnode backvp must exist, and cachefs
- * optional (eg., disconnectable) flags are turned off. Assert
- * these conditions for the read operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting the backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_write_backfs_nfsv4: cnode %p, "
- "backvp %p\n", cp, backvp));
- (void) VOP_RWLOCK(backvp, V_WRITELOCK_TRUE, ct);
- error = VOP_WRITE(backvp, uiop, ioflag, cr, ct);
- VOP_RWUNLOCK(backvp, V_WRITELOCK_TRUE, ct);
-
- return (error);
-}
-
-/*
- * see if we've charged ourselves for frontfile data at
- * the given offset. If not, allocate a block for it now.
- */
-static int
-cachefs_charge_page(struct cnode *cp, u_offset_t offset)
-{
- u_offset_t blockoff;
- int error;
- int inc;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- /*LINTED*/
- ASSERT(PAGESIZE <= MAXBSIZE);
-
- error = 0;
- blockoff = offset & (offset_t)MAXBMASK;
-
- /* get the front file if necessary so allocblocks works */
- if ((cp->c_frontvp == NULL) &&
- ((cp->c_flags & CN_NOCACHE) == 0)) {
- (void) cachefs_getfrontfile(cp);
- }
- if (cp->c_flags & CN_NOCACHE)
- return (1);
-
- if (cachefs_check_allocmap(cp, blockoff))
- return (0);
-
- for (inc = PAGESIZE; inc < MAXBSIZE; inc += PAGESIZE)
- if (cachefs_check_allocmap(cp, blockoff+inc))
- return (0);
-
- error = cachefs_allocblocks(C_TO_FSCACHE(cp)->fs_cache, 1,
- cp->c_metadata.md_rltype);
- if (error == 0) {
- cp->c_metadata.md_frontblks++;
- cp->c_flags |= CN_UPDATED;
- }
- return (error);
-}
-
-/*
- * Called only by cachefs_write to write 1 page or less of data.
- * base - base address kernel addr space
- * tcount - Total bytes to move - < MAXBSIZE
- */
-static int
-cachefs_writepage(vnode_t *vp, caddr_t base, int tcount, uio_t *uiop)
-{
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- register int n;
- register u_offset_t offset;
- int error = 0, terror;
- extern struct as kas;
- u_offset_t lastpage_off;
- int pagecreate = 0;
- int newpage;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf(
- "cachefs_writepage: ENTER vp %p offset %llu len %ld\\\n",
- (void *)vp, uiop->uio_loffset, uiop->uio_resid);
-#endif
-
- /*
- * Move bytes in PAGESIZE chunks. We must avoid spanning pages in
- * uiomove() because page faults may cause the cache to be invalidated
- * out from under us.
- */
- do {
- offset = uiop->uio_loffset;
- lastpage_off = (cp->c_size - 1) & (offset_t)PAGEMASK;
-
- /*
- * If not connected then need to make sure we have space
- * to perform the write. We could make this check
- * a little tighter by only doing it if we are growing the file.
- */
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- error = cachefs_allocblocks(fscp->fs_cache, 1,
- cp->c_metadata.md_rltype);
- if (error)
- break;
- cachefs_freeblocks(fscp->fs_cache, 1,
- cp->c_metadata.md_rltype);
- }
-
- /*
- * n is the number of bytes required to satisfy the request
- * or the number of bytes to fill out the page.
- */
- n = (int)(PAGESIZE - ((uintptr_t)base & PAGEOFFSET));
- if (n > tcount)
- n = tcount;
-
- /*
- * The number of bytes of data in the last page can not
- * be accurately be determined while page is being
- * uiomove'd to and the size of the file being updated.
- * Thus, inform threads which need to know accurately
- * how much data is in the last page of the file. They
- * will not do the i/o immediately, but will arrange for
- * the i/o to happen later when this modify operation
- * will have finished.
- *
- * in similar NFS code, this is done right before the
- * uiomove(), which is best. but here in cachefs, we
- * have two uiomove()s, so we must do it here.
- */
- ASSERT(!(cp->c_flags & CN_CMODINPROG));
- mutex_enter(&cp->c_statelock);
- cp->c_flags |= CN_CMODINPROG;
- cp->c_modaddr = (offset & (offset_t)MAXBMASK);
- mutex_exit(&cp->c_statelock);
-
- /*
- * Check to see if we can skip reading in the page
- * and just allocate the memory. We can do this
- * if we are going to rewrite the entire mapping
- * or if we are going to write to or beyond the current
- * end of file from the beginning of the mapping.
- */
- if ((offset > (lastpage_off + PAGEOFFSET)) ||
- ((cp->c_size == 0) && (offset < PAGESIZE)) ||
- ((uintptr_t)base & PAGEOFFSET) == 0 && (n == PAGESIZE ||
- ((offset + n) >= cp->c_size))) {
- pagecreate = 1;
-
- /*
- * segmap_pagecreate() returns 1 if it calls
- * page_create_va() to allocate any pages.
- */
- newpage = segmap_pagecreate(segkmap,
- (caddr_t)((uintptr_t)base & (uintptr_t)PAGEMASK),
- PAGESIZE, 0);
- /* do not zero page if we are overwriting all of it */
- if (!((((uintptr_t)base & PAGEOFFSET) == 0) &&
- (n == PAGESIZE))) {
- (void) kzero((void *)
- ((uintptr_t)base & (uintptr_t)PAGEMASK),
- PAGESIZE);
- }
- error = uiomove(base, n, UIO_WRITE, uiop);
-
- /*
- * Unlock the page allocated by page_create_va()
- * in segmap_pagecreate()
- */
- if (newpage)
- segmap_pageunlock(segkmap,
- (caddr_t)((uintptr_t)base &
- (uintptr_t)PAGEMASK),
- PAGESIZE, S_WRITE);
- } else {
- /*
- * KLUDGE ! Use segmap_fault instead of faulting and
- * using as_fault() to avoid a recursive readers lock
- * on kas.
- */
- error = segmap_fault(kas.a_hat, segkmap, (caddr_t)
- ((uintptr_t)base & (uintptr_t)PAGEMASK),
- PAGESIZE, F_SOFTLOCK, S_WRITE);
- if (error) {
- if (FC_CODE(error) == FC_OBJERR)
- error = FC_ERRNO(error);
- else
- error = EIO;
- break;
- }
- error = uiomove(base, n, UIO_WRITE, uiop);
- (void) segmap_fault(kas.a_hat, segkmap, (caddr_t)
- ((uintptr_t)base & (uintptr_t)PAGEMASK),
- PAGESIZE, F_SOFTUNLOCK, S_WRITE);
- }
- n = (int)(uiop->uio_loffset - offset); /* n = # bytes written */
- base += n;
- tcount -= n;
-
- /* get access to the file system */
- if ((terror = cachefs_cd_access(fscp, 0, 1)) != 0) {
- error = terror;
- break;
- }
-
- /*
- * cp->c_attr.va_size is the maximum number of
- * bytes known to be in the file.
- * Make sure it is at least as high as the
- * last byte we just wrote into the buffer.
- */
- mutex_enter(&cp->c_statelock);
- if (cp->c_size < uiop->uio_loffset) {
- cp->c_size = uiop->uio_loffset;
- }
- if (cp->c_size != cp->c_attr.va_size) {
- cp->c_attr.va_size = cp->c_size;
- cp->c_flags |= CN_UPDATED;
- }
- /* c_size is now correct, so we can clear modinprog */
- cp->c_flags &= ~CN_CMODINPROG;
- if (error == 0) {
- cp->c_flags |= CDIRTY;
- if (pagecreate && (cp->c_flags & CN_NOCACHE) == 0) {
- /*
- * if we're not in NOCACHE mode
- * (i.e., single-writer), we update the
- * allocmap here rather than waiting until
- * cachefspush is called. This prevents
- * getpage from clustering up pages from
- * the backfile and stomping over the changes
- * we make here.
- */
- if (cachefs_charge_page(cp, offset) == 0) {
- cachefs_update_allocmap(cp,
- offset & (offset_t)PAGEMASK,
- (size_t)PAGESIZE);
- }
-
- /* else we ran out of space */
- else {
- /* nocache file if connected */
- if (fscp->fs_cdconnected ==
- CFS_CD_CONNECTED)
- cachefs_nocache(cp);
- /*
- * If disconnected then cannot
- * nocache the file. Let it have
- * the space.
- */
- else {
- cp->c_metadata.md_frontblks++;
- cp->c_flags |= CN_UPDATED;
- cachefs_update_allocmap(cp,
- offset & (offset_t)PAGEMASK,
- (size_t)PAGESIZE);
- }
- }
- }
- }
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- } while (tcount > 0 && error == 0);
-
- if (cp->c_flags & CN_CMODINPROG) {
- /* XXX assert error != 0? FC_ERRNO() makes this more risky. */
- mutex_enter(&cp->c_statelock);
- cp->c_flags &= ~CN_CMODINPROG;
- mutex_exit(&cp->c_statelock);
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_writepage: EXIT error %d\n", error);
-#endif
-
- return (error);
-}
-
-/*
- * Pushes out pages to the back and/or front file system.
- */
-static int
-cachefs_push(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
- int flags, cred_t *cr)
-{
- struct cnode *cp = VTOC(vp);
- struct buf *bp;
- int error;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- u_offset_t iooff;
- size_t iolen;
- u_offset_t lbn;
- u_offset_t lbn_off;
- uint_t bsize;
-
- ASSERT((flags & B_ASYNC) == 0);
- ASSERT(!vn_is_readonly(vp));
- ASSERT(pp != NULL);
- ASSERT(cr != NULL);
-
- bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
- lbn = pp->p_offset / bsize;
- lbn_off = lbn * bsize;
-
- /*
- * Find a kluster that fits in one block, or in
- * one page if pages are bigger than blocks. If
- * there is less file space allocated than a whole
- * page, we'll shorten the i/o request below.
- */
-
- pp = pvn_write_kluster(vp, pp, &iooff, &iolen, lbn_off,
- roundup(bsize, PAGESIZE), flags);
-
- /*
- * The CN_CMODINPROG flag makes sure that we use a correct
- * value of c_size, below. CN_CMODINPROG is set in
- * cachefs_writepage(). When CN_CMODINPROG is set it
- * indicates that a uiomove() is in progress and the c_size
- * has not been made consistent with the new size of the
- * file. When the uiomove() completes the c_size is updated
- * and the CN_CMODINPROG flag is cleared.
- *
- * The CN_CMODINPROG flag makes sure that cachefs_push_front
- * and cachefs_push_connected see a consistent value of
- * c_size. Without this handshaking, it is possible that
- * these routines will pick up the old value of c_size before
- * the uiomove() in cachefs_writepage() completes. This will
- * result in the vn_rdwr() being too small, and data loss.
- *
- * More precisely, there is a window between the time the
- * uiomove() completes and the time the c_size is updated. If
- * a VOP_PUTPAGE() operation intervenes in this window, the
- * page will be picked up, because it is dirty; it will be
- * unlocked, unless it was pagecreate'd. When the page is
- * picked up as dirty, the dirty bit is reset
- * (pvn_getdirty()). In cachefs_push_connected(), c_size is
- * checked. This will still be the old size. Therefore, the
- * page will not be written out to the correct length, and the
- * page will be clean, so the data may disappear.
- */
- if (cp->c_flags & CN_CMODINPROG) {
- mutex_enter(&cp->c_statelock);
- if ((cp->c_flags & CN_CMODINPROG) &&
- cp->c_modaddr + MAXBSIZE > iooff &&
- cp->c_modaddr < iooff + iolen) {
- page_t *plist;
-
- /*
- * A write is in progress for this region of
- * the file. If we did not detect
- * CN_CMODINPROG here then this path through
- * cachefs_push_connected() would eventually
- * do the vn_rdwr() and may not write out all
- * of the data in the pages. We end up losing
- * data. So we decide to set the modified bit
- * on each page in the page list and mark the
- * cnode with CDIRTY. This push will be
- * restarted at some later time.
- */
-
- plist = pp;
- while (plist != NULL) {
- pp = plist;
- page_sub(&plist, pp);
- hat_setmod(pp);
- page_io_unlock(pp);
- page_unlock(pp);
- }
- cp->c_flags |= CDIRTY;
- mutex_exit(&cp->c_statelock);
- if (offp)
- *offp = iooff;
- if (lenp)
- *lenp = iolen;
- return (0);
- }
- mutex_exit(&cp->c_statelock);
- }
-
- /*
- * Set the pages up for pageout.
- */
- bp = pageio_setup(pp, iolen, CTOV(cp), B_WRITE | flags);
- if (bp == NULL) {
-
- /*
- * currently, there is no way for pageio_setup() to
- * return NULL, since it uses its own scheme for
- * kmem_alloc()ing that shouldn't return NULL, and
- * since pageio_setup() itself dereferences the thing
- * it's about to return. still, we need to be ready
- * in case this ever does start happening.
- */
-
- error = ENOMEM;
- goto writedone;
- }
- /*
- * pageio_setup should have set b_addr to 0. This
- * is correct since we want to do I/O on a page
- * boundary. bp_mapin will use this addr to calculate
- * an offset, and then set b_addr to the kernel virtual
- * address it allocated for us.
- */
- bp->b_edev = 0;
- bp->b_dev = 0;
- bp->b_lblkno = (diskaddr_t)lbtodb(iooff);
- bp_mapin(bp);
-
- iolen = cp->c_size - ldbtob(bp->b_blkno);
- if (iolen > bp->b_bcount)
- iolen = bp->b_bcount;
-
- /* if connected */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- /* write to the back file first */
- error = cachefs_push_connected(vp, bp, iolen, iooff, cr);
-
- /* write to the front file if allowed */
- if ((error == 0) && CFS_ISFS_NONSHARED(fscp) &&
- ((cp->c_flags & CN_NOCACHE) == 0)) {
- /* try to write to the front file */
- (void) cachefs_push_front(vp, bp, iolen, iooff, cr);
- }
- }
-
- /* else if disconnected */
- else {
- /* try to write to the front file */
- error = cachefs_push_front(vp, bp, iolen, iooff, cr);
- }
-
- bp_mapout(bp);
- pageio_done(bp);
-
-writedone:
-
- pvn_write_done(pp, ((error) ? B_ERROR : 0) | B_WRITE | flags);
- if (offp)
- *offp = iooff;
- if (lenp)
- *lenp = iolen;
-
- /* XXX ask bob mastors how to fix this someday */
- mutex_enter(&cp->c_statelock);
- if (error) {
- if (error == ENOSPC) {
- if ((fscp->fs_cdconnected == CFS_CD_CONNECTED) ||
- CFS_ISFS_SOFT(fscp)) {
- CFSOP_INVALIDATE_COBJECT(fscp, cp, cr);
- cp->c_error = error;
- }
- } else if ((CFS_TIMEOUT(fscp, error) == 0) &&
- (error != EINTR)) {
- CFSOP_INVALIDATE_COBJECT(fscp, cp, cr);
- cp->c_error = error;
- }
- } else if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- CFSOP_MODIFY_COBJECT(fscp, cp, cr);
- }
- mutex_exit(&cp->c_statelock);
-
- return (error);
-}
-
-/*
- * Pushes out pages to the back file system.
- */
-static int
-cachefs_push_connected(vnode_t *vp, struct buf *bp, size_t iolen,
- u_offset_t iooff, cred_t *cr)
-{
- struct cnode *cp = VTOC(vp);
- int error = 0;
- int mode = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- ssize_t resid;
- vnode_t *backvp;
-
- /* get the back file if necessary */
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
- }
- backvp = cp->c_backvp;
- VN_HOLD(backvp);
- mutex_exit(&cp->c_statelock);
-
- if (CFS_ISFS_NONSHARED(fscp) && CFS_ISFS_SNR(fscp))
- mode = FSYNC;
-
- /* write to the back file */
- error = bp->b_error = vn_rdwr(UIO_WRITE, backvp, bp->b_un.b_addr,
- iolen, iooff, UIO_SYSSPACE, mode,
- RLIM64_INFINITY, cr, &resid);
- if (error) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS | CFSDEBUG_BACK)
- printf("cachefspush: error %d cr %p\n",
- error, (void *)cr);
-#endif
- bp->b_flags |= B_ERROR;
- }
- VN_RELE(backvp);
-out:
- return (error);
-}
-
-/*
- * Pushes out pages to the front file system.
- * Called for both connected and disconnected states.
- */
-static int
-cachefs_push_front(vnode_t *vp, struct buf *bp, size_t iolen,
- u_offset_t iooff, cred_t *cr)
-{
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- ssize_t resid;
- u_offset_t popoff;
- off_t commit = 0;
- uint_t seq;
- enum cachefs_rl_type type;
- vnode_t *frontvp = NULL;
-
- mutex_enter(&cp->c_statelock);
-
- if (!CFS_ISFS_NONSHARED(fscp)) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* get the front file if necessary */
- if ((cp->c_frontvp == NULL) &&
- ((cp->c_flags & CN_NOCACHE) == 0)) {
- (void) cachefs_getfrontfile(cp);
- }
- if (cp->c_flags & CN_NOCACHE) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* if disconnected, needs to be populated and have good attributes */
- if ((fscp->fs_cdconnected != CFS_CD_CONNECTED) &&
- (((cp->c_metadata.md_flags & MD_POPULATED) == 0) ||
- (cp->c_metadata.md_flags & MD_NEEDATTRS))) {
- error = ETIMEDOUT;
- goto out;
- }
-
- for (popoff = iooff; popoff < (iooff + iolen); popoff += MAXBSIZE) {
- if (cachefs_charge_page(cp, popoff)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_nocache(cp);
- goto out;
- } else {
- error = ENOSPC;
- goto out;
- }
- }
- }
-
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- /* log the first putpage to a file */
- if ((cp->c_metadata.md_flags & MD_PUTPAGE) == 0) {
- /* uses open's creds if we have them */
- if (cp->c_cred)
- cr = cp->c_cred;
-
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- }
-
- commit = cachefs_dlog_modify(fscp, cp, cr, &seq);
- if (commit == 0) {
- /* out of space */
- error = ENOSPC;
- goto out;
- }
-
- cp->c_metadata.md_seq = seq;
- type = cp->c_metadata.md_rltype;
- cachefs_modified(cp);
- cp->c_metadata.md_flags |= MD_PUTPAGE;
- cp->c_metadata.md_flags &= ~MD_PUSHDONE;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* subsequent putpages just get a new sequence number */
- else {
- /* but only if it matters */
- if (cp->c_metadata.md_seq != fscp->fs_dlogseq) {
- seq = cachefs_dlog_seqnext(fscp);
- if (seq == 0) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_seq = seq;
- cp->c_flags |= CN_UPDATED;
- /* XXX maybe should do write_metadata here */
- }
- }
- }
-
- frontvp = cp->c_frontvp;
- VN_HOLD(frontvp);
- mutex_exit(&cp->c_statelock);
- error = bp->b_error = vn_rdwr(UIO_WRITE, frontvp,
- bp->b_un.b_addr, iolen, iooff, UIO_SYSSPACE, 0,
- RLIM64_INFINITY, kcred, &resid);
- mutex_enter(&cp->c_statelock);
- VN_RELE(frontvp);
- frontvp = NULL;
- if (error) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_nocache(cp);
- error = 0;
- goto out;
- } else {
- goto out;
- }
- }
-
- (void) cachefs_update_allocmap(cp, iooff, iolen);
- cp->c_flags |= (CN_UPDATED | CN_NEED_FRONT_SYNC |
- CN_POPULATION_PENDING);
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- gethrestime(&cp->c_metadata.md_localmtime);
- cp->c_metadata.md_flags |= MD_LOCALMTIME;
- }
-
-out:
- if (commit) {
- /* commit the log record */
- ASSERT(fscp->fs_cdconnected == CFS_CD_DISCONNECTED);
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX fix on panic */
- }
- }
-
- if (error && commit) {
- cp->c_metadata.md_flags &= ~MD_PUTPAGE;
- cachefs_rlent_moveto(fscp->fs_cache, type,
- cp->c_metadata.md_rlno, cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = type;
- cp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&cp->c_statelock);
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_dump(struct vnode *vp, caddr_t foo1, offset_t foo2, offset_t foo3,
- caller_context_t *ct)
-{
- return (ENOSYS); /* should we panic if we get here? */
-}
-
-/*ARGSUSED*/
-static int
-cachefs_ioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, cred_t *cred,
- int *rvalp, caller_context_t *ct)
-{
- int error;
- struct cnode *cp = VTOC(vp);
- struct fscache *fscp = C_TO_FSCACHE(cp);
- struct cachefscache *cachep;
- extern kmutex_t cachefs_cachelock;
- extern cachefscache_t *cachefs_cachelist;
- cachefsio_pack_t *packp;
- STRUCT_DECL(cachefsio_dcmd, dcmd);
- int inlen, outlen; /* LP64: generic int for struct in/out len */
- void *dinp, *doutp;
- int (*dcmd_routine)(vnode_t *, void *, void *);
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions which ensure
- * that only a subset of the ioctls are "truly supported"
- * for NFSv4 (these are CFSDCMD_DAEMONID and CFSDCMD_GETSTATS.
- * The packing operations are meaningless since there is
- * no caching for NFSv4, and the called functions silently
- * return if the backfilesystem is NFSv4. The daemon
- * commands except for those above are essentially used
- * for disconnectable operation support (including log
- * rolling), so in each called function, we assert that
- * NFSv4 is not in use. The _FIO* calls (except _FIOCOD)
- * are from "cfsfstype" which is not a documented
- * command. However, the command is visible in
- * /usr/lib/fs/cachefs so the commands are simply let
- * through (don't seem to impact pass-through functionality).
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- switch (cmd) {
- case CACHEFSIO_PACK:
- packp = cachefs_kmem_alloc(sizeof (cachefsio_pack_t), KM_SLEEP);
- error = xcopyin((void *)arg, packp, sizeof (cachefsio_pack_t));
- if (!error)
- error = cachefs_pack(vp, packp->p_name, cred);
- cachefs_kmem_free(packp, sizeof (cachefsio_pack_t));
- break;
-
- case CACHEFSIO_UNPACK:
- packp = cachefs_kmem_alloc(sizeof (cachefsio_pack_t), KM_SLEEP);
- error = xcopyin((void *)arg, packp, sizeof (cachefsio_pack_t));
- if (!error)
- error = cachefs_unpack(vp, packp->p_name, cred);
- cachefs_kmem_free(packp, sizeof (cachefsio_pack_t));
- break;
-
- case CACHEFSIO_PACKINFO:
- packp = cachefs_kmem_alloc(sizeof (cachefsio_pack_t), KM_SLEEP);
- error = xcopyin((void *)arg, packp, sizeof (cachefsio_pack_t));
- if (!error)
- error = cachefs_packinfo(vp, packp->p_name,
- &packp->p_status, cred);
- if (!error)
- error = xcopyout(packp, (void *)arg,
- sizeof (cachefsio_pack_t));
- cachefs_kmem_free(packp, sizeof (cachefsio_pack_t));
- break;
-
- case CACHEFSIO_UNPACKALL:
- error = cachefs_unpackall(vp);
- break;
-
- case CACHEFSIO_DCMD:
- /*
- * This is a private interface between the cachefsd and
- * this file system.
- */
-
- /* must be root to use these commands */
- if (secpolicy_fs_config(cred, vp->v_vfsp) != 0)
- return (EPERM);
-
- /* get the command packet */
- STRUCT_INIT(dcmd, flag & DATAMODEL_MASK);
- error = xcopyin((void *)arg, STRUCT_BUF(dcmd),
- SIZEOF_STRUCT(cachefsio_dcmd, DATAMODEL_NATIVE));
- if (error)
- return (error);
-
- /* copy in the data for the operation */
- dinp = NULL;
- if ((inlen = STRUCT_FGET(dcmd, d_slen)) > 0) {
- dinp = cachefs_kmem_alloc(inlen, KM_SLEEP);
- error = xcopyin(STRUCT_FGETP(dcmd, d_sdata), dinp,
- inlen);
- if (error)
- return (error);
- }
-
- /* allocate space for the result */
- doutp = NULL;
- if ((outlen = STRUCT_FGET(dcmd, d_rlen)) > 0)
- doutp = cachefs_kmem_alloc(outlen, KM_SLEEP);
-
- /*
- * Assert NFSv4 only allows the daemonid and getstats
- * daemon requests
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0 ||
- STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_DAEMONID ||
- STRUCT_FGET(dcmd, d_cmd) == CFSDCMD_GETSTATS);
-
- /* get the routine to execute */
- dcmd_routine = NULL;
- switch (STRUCT_FGET(dcmd, d_cmd)) {
- case CFSDCMD_DAEMONID:
- dcmd_routine = cachefs_io_daemonid;
- break;
- case CFSDCMD_STATEGET:
- dcmd_routine = cachefs_io_stateget;
- break;
- case CFSDCMD_STATESET:
- dcmd_routine = cachefs_io_stateset;
- break;
- case CFSDCMD_XWAIT:
- dcmd_routine = cachefs_io_xwait;
- break;
- case CFSDCMD_EXISTS:
- dcmd_routine = cachefs_io_exists;
- break;
- case CFSDCMD_LOSTFOUND:
- dcmd_routine = cachefs_io_lostfound;
- break;
- case CFSDCMD_GETINFO:
- dcmd_routine = cachefs_io_getinfo;
- break;
- case CFSDCMD_CIDTOFID:
- dcmd_routine = cachefs_io_cidtofid;
- break;
- case CFSDCMD_GETATTRFID:
- dcmd_routine = cachefs_io_getattrfid;
- break;
- case CFSDCMD_GETATTRNAME:
- dcmd_routine = cachefs_io_getattrname;
- break;
- case CFSDCMD_GETSTATS:
- dcmd_routine = cachefs_io_getstats;
- break;
- case CFSDCMD_ROOTFID:
- dcmd_routine = cachefs_io_rootfid;
- break;
- case CFSDCMD_CREATE:
- dcmd_routine = cachefs_io_create;
- break;
- case CFSDCMD_REMOVE:
- dcmd_routine = cachefs_io_remove;
- break;
- case CFSDCMD_LINK:
- dcmd_routine = cachefs_io_link;
- break;
- case CFSDCMD_RENAME:
- dcmd_routine = cachefs_io_rename;
- break;
- case CFSDCMD_MKDIR:
- dcmd_routine = cachefs_io_mkdir;
- break;
- case CFSDCMD_RMDIR:
- dcmd_routine = cachefs_io_rmdir;
- break;
- case CFSDCMD_SYMLINK:
- dcmd_routine = cachefs_io_symlink;
- break;
- case CFSDCMD_SETATTR:
- dcmd_routine = cachefs_io_setattr;
- break;
- case CFSDCMD_SETSECATTR:
- dcmd_routine = cachefs_io_setsecattr;
- break;
- case CFSDCMD_PUSHBACK:
- dcmd_routine = cachefs_io_pushback;
- break;
- default:
- error = ENOTTY;
- break;
- }
-
- /* execute the routine */
- if (dcmd_routine)
- error = (*dcmd_routine)(vp, dinp, doutp);
-
- /* copy out the result */
- if ((error == 0) && doutp)
- error = xcopyout(doutp, STRUCT_FGETP(dcmd, d_rdata),
- outlen);
-
- /* free allocated memory */
- if (dinp)
- cachefs_kmem_free(dinp, inlen);
- if (doutp)
- cachefs_kmem_free(doutp, outlen);
-
- break;
-
- case _FIOCOD:
- if (secpolicy_fs_config(cred, vp->v_vfsp) != 0) {
- error = EPERM;
- break;
- }
-
- error = EBUSY;
- if (arg) {
- /* non-zero arg means do all filesystems */
- mutex_enter(&cachefs_cachelock);
- for (cachep = cachefs_cachelist; cachep != NULL;
- cachep = cachep->c_next) {
- mutex_enter(&cachep->c_fslistlock);
- for (fscp = cachep->c_fslist;
- fscp != NULL;
- fscp = fscp->fs_next) {
- if (CFS_ISFS_CODCONST(fscp)) {
- gethrestime(&fscp->fs_cod_time);
- error = 0;
- }
- }
- mutex_exit(&cachep->c_fslistlock);
- }
- mutex_exit(&cachefs_cachelock);
- } else {
- if (CFS_ISFS_CODCONST(fscp)) {
- gethrestime(&fscp->fs_cod_time);
- error = 0;
- }
- }
- break;
-
- case _FIOSTOPCACHE:
- error = cachefs_stop_cache(cp);
- break;
-
- default:
- error = ENOTTY;
- break;
- }
-
- /* return the result */
- return (error);
-}
-
-ino64_t
-cachefs_fileno_conflict(fscache_t *fscp, ino64_t old)
-{
- ino64_t new;
-
- ASSERT(MUTEX_HELD(&fscp->fs_fslock));
-
- for (;;) {
- fscp->fs_info.fi_localfileno++;
- if (fscp->fs_info.fi_localfileno == 0)
- fscp->fs_info.fi_localfileno = 3;
- fscp->fs_flags |= CFS_FS_DIRTYINFO;
-
- new = fscp->fs_info.fi_localfileno;
- if (! cachefs_fileno_inuse(fscp, new))
- break;
- }
-
- cachefs_inum_register(fscp, old, new);
- cachefs_inum_register(fscp, new, 0);
- return (new);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
- caller_context_t *ct)
-{
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getattr: ENTER vp %p\n", (void *)vp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- /* Call backfilesystem getattr if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_getattr_backfs_nfsv4(vp, vap, flags, cr, ct);
- goto out;
- }
-
- /*
- * If it has been specified that the return value will
- * just be used as a hint, and we are only being asked
- * for size, fsid or rdevid, then return the client's
- * notion of these values without checking to make sure
- * that the attribute cache is up to date.
- * The whole point is to avoid an over the wire GETATTR
- * call.
- */
- if (flags & ATTR_HINT) {
- if (vap->va_mask ==
- (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
- if (vap->va_mask | AT_SIZE)
- vap->va_size = cp->c_size;
- /*
- * Return the FSID of the cachefs filesystem,
- * not the back filesystem
- */
- if (vap->va_mask | AT_FSID)
- vap->va_fsid = vp->v_vfsp->vfs_dev;
- if (vap->va_mask | AT_RDEV)
- vap->va_rdev = cp->c_attr.va_rdev;
- return (0);
- }
- }
-
- /*
- * Only need to flush pages if asking for the mtime
- * and if there any dirty pages.
- */
- if (vap->va_mask & AT_MTIME) {
- /*EMPTY*/
-#if 0
- /*
- * XXX bob: stolen from nfs code, need to do something similar
- */
- rp = VTOR(vp);
- if ((rp->r_flags & RDIRTY) || rp->r_iocnt > 0)
- (void) nfs3_putpage(vp, (offset_t)0, 0, 0, cr);
-#endif
- }
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- goto out;
- held = 1;
-
- /*
- * If it has been specified that the return value will
- * just be used as a hint, and we are only being asked
- * for size, fsid or rdevid, then return the client's
- * notion of these values without checking to make sure
- * that the attribute cache is up to date.
- * The whole point is to avoid an over the wire GETATTR
- * call.
- */
- if (flags & ATTR_HINT) {
- if (vap->va_mask ==
- (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
- if (vap->va_mask | AT_SIZE)
- vap->va_size = cp->c_size;
- /*
- * Return the FSID of the cachefs filesystem,
- * not the back filesystem
- */
- if (vap->va_mask | AT_FSID)
- vap->va_fsid = vp->v_vfsp->vfs_dev;
- if (vap->va_mask | AT_RDEV)
- vap->va_rdev = cp->c_attr.va_rdev;
- goto out;
- }
- }
-
- mutex_enter(&cp->c_statelock);
- if ((cp->c_metadata.md_flags & MD_NEEDATTRS) &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- mutex_exit(&cp->c_statelock);
- connected = 1;
- continue;
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- }
- if (error) {
- mutex_exit(&cp->c_statelock);
- break;
- }
-
- /* check for fileno conflict */
- if ((fscp->fs_inum_size > 0) &&
- ((cp->c_metadata.md_flags & MD_LOCALFILENO) == 0)) {
- ino64_t fakenum;
-
- mutex_exit(&cp->c_statelock);
- mutex_enter(&fscp->fs_fslock);
- fakenum = cachefs_inum_real2fake(fscp,
- cp->c_attr.va_nodeid);
- if (fakenum == 0) {
- fakenum = cachefs_fileno_conflict(fscp,
- cp->c_attr.va_nodeid);
- }
- mutex_exit(&fscp->fs_fslock);
-
- mutex_enter(&cp->c_statelock);
- cp->c_metadata.md_flags |= MD_LOCALFILENO;
- cp->c_metadata.md_localfileno = fakenum;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* copy out the attributes */
- *vap = cp->c_attr;
-
- /*
- * return the FSID of the cachefs filesystem,
- * not the back filesystem
- */
- vap->va_fsid = vp->v_vfsp->vfs_dev;
-
- /* return our idea of the size */
- if (cp->c_size > vap->va_size)
- vap->va_size = cp->c_size;
-
- /* overwrite with our version of fileno and timestamps */
- vap->va_nodeid = cp->c_metadata.md_localfileno;
- vap->va_mtime = cp->c_metadata.md_localmtime;
- vap->va_ctime = cp->c_metadata.md_localctime;
-
- mutex_exit(&cp->c_statelock);
- break;
- }
-out:
- if (held)
- cachefs_cd_release(fscp);
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getattr: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_getattr_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the getattr (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_getattr_backfs_nfsv4(vnode_t *vp, vattr_t *vap,
- int flags, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation
- * is supported, the cnode backvp must exist, and cachefs
- * optional (eg., disconnectable) flags are turned off. Assert
- * these conditions for the getattr operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_getattr_backfs_nfsv4: cnode %p,"
- " backvp %p\n", cp, backvp));
- error = VOP_GETATTR(backvp, vap, flags, cr, ct);
-
- /* Update attributes */
- cp->c_attr = *vap;
-
- /*
- * return the FSID of the cachefs filesystem,
- * not the back filesystem
- */
- vap->va_fsid = vp->v_vfsp->vfs_dev;
-
- return (error);
-}
-
-/*ARGSUSED4*/
-static int
-cachefs_setattr(
- vnode_t *vp,
- vattr_t *vap,
- int flags,
- cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error;
- int connected;
- int held = 0;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the setattr operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- connected = 0;
- for (;;) {
- /* drop hold on file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
-
- /* acquire access to the file system */
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /* perform the setattr */
- error = cachefs_setattr_common(vp, vap, flags, cr, ct);
- if (error) {
- /* if connected */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- }
-
- /* else must be disconnected */
- else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- }
- break;
- }
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
- return (error);
-}
-
-static int
-cachefs_setattr_common(
- vnode_t *vp,
- vattr_t *vap,
- int flags,
- cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- uint_t mask = vap->va_mask;
- int error = 0;
- uint_t bcnt;
-
- /* Cannot set these attributes. */
- if (mask & AT_NOSET)
- return (EINVAL);
-
- /*
- * Truncate file. Must have write permission and not be a directory.
- */
- if (mask & AT_SIZE) {
- if (vp->v_type == VDIR) {
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_TRUNCATE))
- cachefs_log_truncate(cachep, EISDIR,
- fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie,
- cp->c_id.cid_fileno,
- crgetuid(cr), vap->va_size);
- return (EISDIR);
- }
- }
-
- /*
- * Gotta deal with one special case here, where we're setting the
- * size of the file. First, we zero out part of the page after the
- * new size of the file. Then we toss (not write) all pages after
- * page in which the new offset occurs. Note that the NULL passed
- * in instead of a putapage() fn parameter is correct, since
- * no dirty pages will be found (B_TRUNC | B_INVAL).
- */
-
- rw_enter(&cp->c_rwlock, RW_WRITER);
-
- /* sync dirty pages */
- if (!CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_putpage_common(vp, (offset_t)0, 0, 0, cr);
- if (error == EINTR)
- goto out;
- }
- error = 0;
-
- /* if connected */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_setattr_connected(vp, vap, flags, cr, ct);
- }
- /* else must be disconnected */
- else {
- error = cachefs_setattr_disconnected(vp, vap, flags, cr, ct);
- }
- if (error)
- goto out;
-
- /*
- * If the file size has been changed then
- * toss whole pages beyond the end of the file and zero
- * the portion of the last page that is beyond the end of the file.
- */
- if (mask & AT_SIZE && !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- bcnt = (uint_t)(cp->c_size & PAGEOFFSET);
- if (bcnt)
- pvn_vpzero(vp, cp->c_size, PAGESIZE - bcnt);
- (void) pvn_vplist_dirty(vp, cp->c_size, cachefs_push,
- B_TRUNC | B_INVAL, cr);
- }
-
-out:
- rw_exit(&cp->c_rwlock);
-
- if ((mask & AT_SIZE) &&
- (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_TRUNCATE)))
- cachefs_log_truncate(cachep, error, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- crgetuid(cr), vap->va_size);
-
- return (error);
-}
-
-static int
-cachefs_setattr_connected(
- vnode_t *vp,
- vattr_t *vap,
- int flags,
- cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- uint_t mask = vap->va_mask;
- int error = 0;
- int setsize;
-
- mutex_enter(&cp->c_statelock);
-
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error)
- goto out;
-
- CFS_DPRINT_BACKFS_NFSV4(fscp, ("cachefs_setattr (nfsv4): cnode %p, "
- "backvp %p\n", cp, cp->c_backvp));
- error = VOP_SETATTR(cp->c_backvp, vap, flags, cr, ct);
- if (error) {
- goto out;
- }
-
- /* if the size of the file is being changed */
- if (mask & AT_SIZE) {
- cp->c_size = vap->va_size;
- error = 0;
- setsize = 0;
-
- /* see if okay to try to set the file size */
- if (((cp->c_flags & CN_NOCACHE) == 0) &&
- CFS_ISFS_NONSHARED(fscp)) {
- /* okay to set size if file is populated */
- if (cp->c_metadata.md_flags & MD_POPULATED)
- setsize = 1;
-
- /*
- * Okay to set size if front file exists and setting
- * file size to zero.
- */
- if ((cp->c_metadata.md_flags & MD_FILE) &&
- (vap->va_size == 0))
- setsize = 1;
- }
-
- /* if okay to try to set the file size */
- if (setsize) {
- error = 0;
- if (cp->c_frontvp == NULL)
- error = cachefs_getfrontfile(cp);
- if (error == 0)
- error = cachefs_frontfile_size(cp, cp->c_size);
- } else if (cp->c_metadata.md_flags & MD_FILE) {
- /* make sure file gets nocached */
- error = EEXIST;
- }
-
- /* if we have to nocache the file */
- if (error) {
- if ((cp->c_flags & CN_NOCACHE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp))
- cachefs_nocache(cp);
- error = 0;
- }
- }
-
- cp->c_flags |= CN_UPDATED;
-
- /* XXX bob: given what modify_cobject does this seems unnecessary */
- cp->c_attr.va_mask = AT_ALL;
- error = VOP_GETATTR(cp->c_backvp, &cp->c_attr, 0, cr, ct);
- if (error)
- goto out;
-
- cp->c_attr.va_size = MAX(cp->c_attr.va_size, cp->c_size);
- cp->c_size = cp->c_attr.va_size;
-
- CFSOP_MODIFY_COBJECT(fscp, cp, cr);
-out:
- mutex_exit(&cp->c_statelock);
- return (error);
-}
-
-/*
- * perform the setattr on the local file system
- */
-/*ARGSUSED4*/
-static int
-cachefs_setattr_disconnected(
- vnode_t *vp,
- vattr_t *vap,
- int flags,
- cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int mask;
- int error;
- int newfile;
- off_t commit = 0;
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- /* if we do not have good attributes */
- if (cp->c_metadata.md_flags & MD_NEEDATTRS)
- return (ETIMEDOUT);
-
- /* primary concern is to keep this routine as much like ufs_setattr */
-
- mutex_enter(&cp->c_statelock);
-
- error = secpolicy_vnode_setattr(cr, vp, vap, &cp->c_attr, flags,
- cachefs_access_local, cp);
-
- if (error)
- goto out;
-
- mask = vap->va_mask;
-
- /* if changing the size of the file */
- if (mask & AT_SIZE) {
- if (vp->v_type == VDIR) {
- error = EISDIR;
- goto out;
- }
-
- if (vp->v_type == VFIFO) {
- error = 0;
- goto out;
- }
-
- if ((vp->v_type != VREG) &&
- !((vp->v_type == VLNK) && (vap->va_size == 0))) {
- error = EINVAL;
- goto out;
- }
-
- if (vap->va_size > fscp->fs_offmax) {
- error = EFBIG;
- goto out;
- }
-
- /* if the file is not populated and we are not truncating it */
- if (((cp->c_metadata.md_flags & MD_POPULATED) == 0) &&
- (vap->va_size != 0)) {
- error = ETIMEDOUT;
- goto out;
- }
-
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- }
-
- /* log the operation */
- commit = cachefs_dlog_setattr(fscp, vap, flags, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
- cp->c_flags &= ~CN_NOCACHE;
-
- /* special case truncating fast sym links */
- if ((vp->v_type == VLNK) &&
- (cp->c_metadata.md_flags & MD_FASTSYMLNK)) {
- /* XXX how can we get here */
- /* XXX should update mtime */
- cp->c_size = 0;
- error = 0;
- goto out;
- }
-
- /* get the front file, this may create one */
- newfile = (cp->c_metadata.md_flags & MD_FILE) ? 0 : 1;
- if (cp->c_frontvp == NULL) {
- error = cachefs_getfrontfile(cp);
- if (error)
- goto out;
- }
- ASSERT(cp->c_frontvp);
- if (newfile && (cp->c_flags & CN_UPDATED)) {
- /* allocate space for the metadata */
- ASSERT((cp->c_flags & CN_ALLOC_PENDING) == 0);
- ASSERT((cp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR)
- == 0);
- error = filegrp_write_metadata(cp->c_filegrp,
- &cp->c_id, &cp->c_metadata);
- if (error)
- goto out;
- }
-
- /* change the size of the front file */
- error = cachefs_frontfile_size(cp, vap->va_size);
- if (error)
- goto out;
- cp->c_attr.va_size = cp->c_size = vap->va_size;
- gethrestime(&cp->c_metadata.md_localmtime);
- cp->c_metadata.md_flags |= MD_POPULATED | MD_LOCALMTIME;
- cachefs_modified(cp);
- cp->c_flags |= CN_UPDATED;
- }
-
- if (mask & AT_MODE) {
- /* mark as modified */
- if (cachefs_modified_alloc(cp)) {
- error = ENOSPC;
- goto out;
- }
-
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- }
-
- /* log the operation if not already logged */
- if (commit == 0) {
- commit = cachefs_dlog_setattr(fscp, vap, flags, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
- }
-
- cp->c_attr.va_mode &= S_IFMT;
- cp->c_attr.va_mode |= vap->va_mode & ~S_IFMT;
- gethrestime(&cp->c_metadata.md_localctime);
- cp->c_metadata.md_flags |= MD_LOCALCTIME;
- cp->c_flags |= CN_UPDATED;
- }
-
- if (mask & (AT_UID|AT_GID)) {
-
- /* mark as modified */
- if (cachefs_modified_alloc(cp)) {
- error = ENOSPC;
- goto out;
- }
-
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- }
-
- /* log the operation if not already logged */
- if (commit == 0) {
- commit = cachefs_dlog_setattr(fscp, vap, flags, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
- }
-
- if (mask & AT_UID)
- cp->c_attr.va_uid = vap->va_uid;
-
- if (mask & AT_GID)
- cp->c_attr.va_gid = vap->va_gid;
- gethrestime(&cp->c_metadata.md_localctime);
- cp->c_metadata.md_flags |= MD_LOCALCTIME;
- cp->c_flags |= CN_UPDATED;
- }
-
-
- if (mask & (AT_MTIME|AT_ATIME)) {
- /* mark as modified */
- if (cachefs_modified_alloc(cp)) {
- error = ENOSPC;
- goto out;
- }
-
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- }
-
- /* log the operation if not already logged */
- if (commit == 0) {
- commit = cachefs_dlog_setattr(fscp, vap, flags, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
- }
-
- if (mask & AT_MTIME) {
- cp->c_metadata.md_localmtime = vap->va_mtime;
- cp->c_metadata.md_flags |= MD_LOCALMTIME;
- }
- if (mask & AT_ATIME)
- cp->c_attr.va_atime = vap->va_atime;
- gethrestime(&cp->c_metadata.md_localctime);
- cp->c_metadata.md_flags |= MD_LOCALCTIME;
- cp->c_flags |= CN_UPDATED;
- }
-
-out:
- mutex_exit(&cp->c_statelock);
-
- /* commit the log entry */
- if (commit) {
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
- return (error);
-}
-
-/* ARGSUSED */
-static int
-cachefs_access(vnode_t *vp, int mode, int flags, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_access: ENTER vp %p\n", (void *)vp);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the access operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_access_connected(vp, mode, flags,
- cr);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- mutex_enter(&cp->c_statelock);
- error = cachefs_access_local(cp, mode, cr);
- mutex_exit(&cp->c_statelock);
- if (CFS_TIMEOUT(fscp, error)) {
- if (cachefs_cd_access_miss(fscp)) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp == NULL) {
- (void) cachefs_getbackvp(fscp,
- cp);
- }
- mutex_exit(&cp->c_statelock);
- error = cachefs_access_connected(vp,
- mode, flags, cr);
- if (!CFS_TIMEOUT(fscp, error))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
- if (held)
- cachefs_cd_release(fscp);
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_access: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-static int
-cachefs_access_connected(struct vnode *vp, int mode, int flags, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
-
- mutex_enter(&cp->c_statelock);
-
- /* Make sure the cnode attrs are valid first. */
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error)
- goto out;
-
- /* see if can do a local file system check */
- if ((fscp->fs_info.fi_mntflags & CFS_ACCESS_BACKFS) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_access_local(cp, mode, cr);
- goto out;
- }
-
- /* else do a remote file system check */
- else {
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_access (nfsv4): cnode %p, backvp %p\n",
- cp, cp->c_backvp));
- error = VOP_ACCESS(cp->c_backvp, mode, flags, cr, NULL);
-
- /*
- * even though we don't `need' the ACL to do access
- * via the backvp, we should cache it here to make our
- * behavior more reasonable if we go disconnected.
- */
-
- if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
- (cachefs_vtype_aclok(vp)) &&
- ((cp->c_flags & CN_NOCACHE) == 0) &&
- (!CFS_ISFS_BACKFS_NFSV4(fscp)) &&
- ((cp->c_metadata.md_flags & MD_ACL) == 0))
- (void) cachefs_cacheacl(cp, NULL);
- }
-out:
- /*
- * If NFS returned ESTALE, mark this cnode as stale, so that
- * the vn_open retry will read the file anew from backfs
- */
- if (error == ESTALE)
- cachefs_cnode_stale(cp);
-
- mutex_exit(&cp->c_statelock);
- return (error);
-}
-
-/*
- * CFS has a fastsymlink scheme. If the size of the link is < C_FSL_SIZE, then
- * the link is placed in the metadata itself (no front file is allocated).
- */
-/*ARGSUSED*/
-static int
-cachefs_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
-{
- int error = 0;
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- int held = 0;
- int connected = 0;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- if (vp->v_type != VLNK)
- return (EINVAL);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the readlink operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- /*
- * since readlink_connected will call stuffsymlink
- * on success, have to serialize access
- */
- if (!rw_tryenter(&cp->c_rwlock, RW_WRITER)) {
- cachefs_cd_release(fscp);
- rw_enter(&cp->c_rwlock, RW_WRITER);
- error = cachefs_cd_access(fscp, connected, 0);
- if (error) {
- held = 0;
- rw_exit(&cp->c_rwlock);
- break;
- }
- }
- error = cachefs_readlink_connected(vp, uiop, cr);
- rw_exit(&cp->c_rwlock);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_readlink_disconnected(vp, uiop);
- if (CFS_TIMEOUT(fscp, error)) {
- if (cachefs_cd_access_miss(fscp)) {
- /* as above */
- if (!rw_tryenter(&cp->c_rwlock,
- RW_WRITER)) {
- cachefs_cd_release(fscp);
- rw_enter(&cp->c_rwlock,
- RW_WRITER);
- error = cachefs_cd_access(fscp,
- connected, 0);
- if (error) {
- held = 0;
- rw_exit(&cp->c_rwlock);
- break;
- }
- }
- error = cachefs_readlink_connected(vp,
- uiop, cr);
- rw_exit(&cp->c_rwlock);
- if (!CFS_TIMEOUT(fscp, error))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_READLINK))
- cachefs_log_readlink(cachep, error, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- crgetuid(cr), cp->c_size);
-
- if (held)
- cachefs_cd_release(fscp);
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
- /*
- * The over the wire error for attempting to readlink something
- * other than a symbolic link is ENXIO. However, we need to
- * return EINVAL instead of ENXIO, so we map it here.
- */
- return (error == ENXIO ? EINVAL : error);
-}
-
-static int
-cachefs_readlink_connected(vnode_t *vp, uio_t *uiop, cred_t *cr)
-{
- int error;
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- caddr_t buf;
- int buflen;
- int readcache = 0;
-
- mutex_enter(&cp->c_statelock);
-
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error)
- goto out;
-
- /* if the sym link is cached as a fast sym link */
- if (cp->c_metadata.md_flags & MD_FASTSYMLNK) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = uiomove(cp->c_metadata.md_allocinfo,
- MIN(cp->c_size, uiop->uio_resid), UIO_READ, uiop);
-#ifdef CFSDEBUG
- readcache = 1;
- goto out;
-#else /* CFSDEBUG */
- /* XXX KLUDGE! correct for insidious 0-len symlink */
- if (cp->c_size != 0) {
- readcache = 1;
- goto out;
- }
-#endif /* CFSDEBUG */
- }
-
- /* if the sym link is cached in a front file */
- if (cp->c_metadata.md_flags & MD_POPULATED) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT(cp->c_metadata.md_flags & MD_FILE);
- if (cp->c_frontvp == NULL) {
- (void) cachefs_getfrontfile(cp);
- }
- if (cp->c_metadata.md_flags & MD_POPULATED) {
- /* read symlink data from frontfile */
- uiop->uio_offset = 0;
- (void) VOP_RWLOCK(cp->c_frontvp,
- V_WRITELOCK_FALSE, NULL);
- error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
- VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
-
- /* XXX KLUDGE! correct for insidious 0-len symlink */
- if (cp->c_size != 0) {
- readcache = 1;
- goto out;
- }
- }
- }
-
- /* get the sym link contents from the back fs */
- error = cachefs_readlink_back(cp, cr, &buf, &buflen);
- if (error)
- goto out;
-
- /* copy the contents out to the user */
- error = uiomove(buf, MIN(buflen, uiop->uio_resid), UIO_READ, uiop);
-
- /*
- * try to cache the sym link, note that its a noop if NOCACHE is set
- * or if NFSv4 pass-through is enabled.
- */
- if (cachefs_stuffsymlink(cp, buf, buflen)) {
- cachefs_nocache(cp);
- }
-
- cachefs_kmem_free(buf, MAXPATHLEN);
-
-out:
- mutex_exit(&cp->c_statelock);
- if (error == 0) {
- if (readcache)
- fscp->fs_stats.st_hits++;
- else
- fscp->fs_stats.st_misses++;
- }
- return (error);
-}
-
-static int
-cachefs_readlink_disconnected(vnode_t *vp, uio_t *uiop)
-{
- int error;
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int readcache = 0;
-
- mutex_enter(&cp->c_statelock);
-
- /* if the sym link is cached as a fast sym link */
- if (cp->c_metadata.md_flags & MD_FASTSYMLNK) {
- error = uiomove(cp->c_metadata.md_allocinfo,
- MIN(cp->c_size, uiop->uio_resid), UIO_READ, uiop);
- readcache = 1;
- goto out;
- }
-
- /* if the sym link is cached in a front file */
- if (cp->c_metadata.md_flags & MD_POPULATED) {
- ASSERT(cp->c_metadata.md_flags & MD_FILE);
- if (cp->c_frontvp == NULL) {
- (void) cachefs_getfrontfile(cp);
- }
- if (cp->c_metadata.md_flags & MD_POPULATED) {
- /* read symlink data from frontfile */
- uiop->uio_offset = 0;
- (void) VOP_RWLOCK(cp->c_frontvp,
- V_WRITELOCK_FALSE, NULL);
- error = VOP_READ(cp->c_frontvp, uiop, 0, kcred, NULL);
- VOP_RWUNLOCK(cp->c_frontvp, V_WRITELOCK_FALSE, NULL);
- readcache = 1;
- goto out;
- }
- }
- error = ETIMEDOUT;
-
-out:
- mutex_exit(&cp->c_statelock);
- if (error == 0) {
- if (readcache)
- fscp->fs_stats.st_hits++;
- else
- fscp->fs_stats.st_misses++;
- }
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_fsync: ENTER vp %p\n", (void *)vp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_backvfsp && fscp->fs_backvfsp->vfs_flag & VFS_RDONLY)
- goto out;
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the fsync operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
- connected = 0;
-
- /* if a regular file, write out the pages */
- if ((vp->v_type == VREG) && vn_has_cached_data(vp) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_putpage_common(vp, (offset_t)0,
- 0, 0, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else {
- connected = 1;
- continue;
- }
- }
-
- /* if no space left in cache, wait until connected */
- if ((error == ENOSPC) &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- connected = 1;
- continue;
- }
-
- /* clear the cnode error if putpage worked */
- if ((error == 0) && cp->c_error) {
- mutex_enter(&cp->c_statelock);
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
- }
-
- if (error)
- break;
- }
-
- /* if connected, sync the backvp */
- if ((fscp->fs_cdconnected == CFS_CD_CONNECTED) &&
- cp->c_backvp) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_fsync (nfsv4): cnode %p, "
- "backvp %p\n", cp, cp->c_backvp));
- error = VOP_FSYNC(cp->c_backvp, syncflag, cr,
- ct);
- if (CFS_TIMEOUT(fscp, error)) {
- mutex_exit(&cp->c_statelock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else if (error && (error != EINTR))
- cp->c_error = error;
- }
- mutex_exit(&cp->c_statelock);
- }
-
- /* sync the metadata and the front file to the front fs */
- if (!CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_sync_metadata(cp);
- if (error &&
- (fscp->fs_cdconnected == CFS_CD_CONNECTED))
- error = 0;
- }
- break;
- }
-
- if (error == 0)
- error = cp->c_error;
-
- if (held)
- cachefs_cd_release(fscp);
-
-out:
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_fsync: EXIT vp %p\n", (void *)vp);
-#endif
- return (error);
-}
-
-/*
- * Called from cachefs_inactive(), to make sure all the data goes out to disk.
- */
-int
-cachefs_sync_metadata(cnode_t *cp)
-{
- int error = 0;
- struct filegrp *fgp;
- struct vattr va;
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_sync_metadata: ENTER cp %p cflag %x\n",
- (void *)cp, cp->c_flags);
-#endif
-
- mutex_enter(&cp->c_statelock);
- if ((cp->c_flags & CN_UPDATED) == 0)
- goto out;
- if (cp->c_flags & (CN_STALE | CN_DESTROY))
- goto out;
- fgp = cp->c_filegrp;
- if ((fgp->fg_flags & CFS_FG_WRITE) == 0)
- goto out;
- if (CFS_ISFS_BACKFS_NFSV4(fscp))
- goto out;
-
- if (fgp->fg_flags & CFS_FG_ALLOC_ATTR) {
- mutex_exit(&cp->c_statelock);
- error = filegrp_allocattr(fgp);
- mutex_enter(&cp->c_statelock);
- if (error) {
- error = 0;
- goto out;
- }
- }
-
- if (cp->c_flags & CN_ALLOC_PENDING) {
- error = filegrp_create_metadata(fgp, &cp->c_metadata,
- &cp->c_id);
- if (error)
- goto out;
- cp->c_flags &= ~CN_ALLOC_PENDING;
- }
-
- if (cp->c_flags & CN_NEED_FRONT_SYNC) {
- if (cp->c_frontvp != NULL) {
- error = VOP_FSYNC(cp->c_frontvp, FSYNC, kcred, NULL);
- if (error) {
- cp->c_metadata.md_timestamp.tv_sec = 0;
- } else {
- va.va_mask = AT_MTIME;
- error = VOP_GETATTR(cp->c_frontvp, &va, 0,
- kcred, NULL);
- if (error)
- goto out;
- cp->c_metadata.md_timestamp = va.va_mtime;
- cp->c_flags &=
- ~(CN_NEED_FRONT_SYNC |
- CN_POPULATION_PENDING);
- }
- } else {
- cp->c_flags &=
- ~(CN_NEED_FRONT_SYNC | CN_POPULATION_PENDING);
- }
- }
-
- /*
- * XXX tony: How can CN_ALLOC_PENDING still be set??
- * XXX tony: How can CN_UPDATED not be set?????
- */
- if ((cp->c_flags & CN_ALLOC_PENDING) == 0 &&
- (cp->c_flags & CN_UPDATED)) {
- error = filegrp_write_metadata(fgp, &cp->c_id,
- &cp->c_metadata);
- if (error)
- goto out;
- }
-out:
- if (error) {
- /* XXX modified files? */
- if (cp->c_metadata.md_rlno) {
- cachefs_removefrontfile(&cp->c_metadata,
- &cp->c_id, fgp);
- cachefs_rlent_moveto(C_TO_FSCACHE(cp)->fs_cache,
- CACHEFS_RL_FREE, cp->c_metadata.md_rlno, 0);
- cp->c_metadata.md_rlno = 0;
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
- if (cp->c_frontvp) {
- VN_RELE(cp->c_frontvp);
- cp->c_frontvp = NULL;
- }
- }
- if ((cp->c_flags & CN_ALLOC_PENDING) == 0)
- (void) filegrp_destroy_metadata(fgp, &cp->c_id);
- cp->c_flags |= CN_ALLOC_PENDING;
- cachefs_nocache(cp);
- }
- /*
- * we clear the updated bit even on errors because a retry
- * will probably fail also.
- */
- cp->c_flags &= ~CN_UPDATED;
- mutex_exit(&cp->c_statelock);
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("c_sync_metadata: EXIT cp %p cflag %x\n",
- (void *)cp, cp->c_flags);
-#endif
-
- return (error);
-}
-
-/*
- * This is the vop entry point for inactivating a vnode.
- * It just queues the request for the async thread which
- * calls cachefs_inactive.
- * Because of the dnlc, it is not safe to grab most locks here.
- */
-/*ARGSUSED*/
-static void
-cachefs_inactive(struct vnode *vp, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp;
- struct cachefs_req *rp;
- fscache_t *fscp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_inactive: ENTER vp %p\n", (void *)vp);
-#endif
-
- cp = VTOC(vp);
- fscp = C_TO_FSCACHE(cp);
-
- ASSERT((cp->c_flags & CN_IDLE) == 0);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the inactive operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* vn_rele() set the v_count == 1 */
-
- cp->c_ipending = 1;
-
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- rp->cfs_cmd = CFS_IDLE;
- rp->cfs_cr = cr;
- crhold(rp->cfs_cr);
- rp->cfs_req_u.cu_idle.ci_vp = vp;
- cachefs_addqueue(rp, &(C_TO_FSCACHE(cp)->fs_workq));
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_inactive: EXIT vp %p\n", (void *)vp);
-#endif
-}
-
-/* ARGSUSED */
-static int
-cachefs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp,
- struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr,
- caller_context_t *ct, int *direntflags, pathname_t *realpnp)
-
-{
- int error = 0;
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_lookup: ENTER dvp %p nm %s\n", (void *)dvp, nm);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the lookup operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- error = cachefs_lookup_common(dvp, nm, vpp, pnp,
- flags, rdir, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- } else {
- if (cachefs_cd_access_miss(fscp)) {
- rw_enter(&dcp->c_rwlock, RW_READER);
- error = cachefs_lookup_back(dvp, nm,
- vpp, cr);
- rw_exit(&dcp->c_rwlock);
- if (!CFS_TIMEOUT(fscp, error))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
- if (held)
- cachefs_cd_release(fscp);
-
- if (error == 0 && IS_DEVVP(*vpp)) {
- struct vnode *newvp;
- newvp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
- VN_RELE(*vpp);
- if (newvp == NULL) {
- error = ENOSYS;
- } else {
- *vpp = newvp;
- }
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_lookup: EXIT error = %d\n", error);
-#endif
-
- return (error);
-}
-
-/* ARGSUSED */
-int
-cachefs_lookup_common(vnode_t *dvp, char *nm, vnode_t **vpp,
- struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr)
-{
- int error = 0;
- cnode_t *cp, *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- struct fid cookie;
- u_offset_t d_offset;
- struct cachefs_req *rp;
- cfs_cid_t cid, dircid;
- uint_t flag;
- uint_t uncached = 0;
-
- *vpp = NULL;
-
- /*
- * If lookup is for "", just return dvp. Don't need
- * to send it over the wire, look it up in the dnlc,
- * or perform any access checks.
- */
- if (*nm == '\0') {
- VN_HOLD(dvp);
- *vpp = dvp;
- return (0);
- }
-
- /* can't do lookups in non-directories */
- if (dvp->v_type != VDIR)
- return (ENOTDIR);
-
- /* perform access check, also does consistency check if connected */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_access_connected(dvp, VEXEC, 0, cr);
- } else {
- mutex_enter(&dcp->c_statelock);
- error = cachefs_access_local(dcp, VEXEC, cr);
- mutex_exit(&dcp->c_statelock);
- }
- if (error)
- return (error);
-
- /*
- * If lookup is for ".", just return dvp. Don't need
- * to send it over the wire or look it up in the dnlc,
- * just need to check access.
- */
- if (strcmp(nm, ".") == 0) {
- VN_HOLD(dvp);
- *vpp = dvp;
- return (0);
- }
-
- /* check the dnlc */
- *vpp = (vnode_t *)dnlc_lookup(dvp, nm);
- if (*vpp)
- return (0);
-
- /* read lock the dir before starting the search */
- rw_enter(&dcp->c_rwlock, RW_READER);
-
- mutex_enter(&dcp->c_statelock);
- dircid = dcp->c_id;
-
- dcp->c_usage++;
-
- /* if front file is not usable, lookup on the back fs */
- if ((dcp->c_flags & (CN_NOCACHE | CN_ASYNC_POPULATE)) ||
- CFS_ISFS_BACKFS_NFSV4(fscp) ||
- ((dcp->c_filegrp->fg_flags & CFS_FG_READ) == 0)) {
- mutex_exit(&dcp->c_statelock);
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_lookup_back(dvp, nm, vpp, cr);
- else
- error = ETIMEDOUT;
- goto out;
- }
-
- /* if the front file is not populated, try to populate it */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- if (cachefs_async_okay()) {
- /* cannot populate if cache is not writable */
- ASSERT((dcp->c_flags &
- (CN_ASYNC_POPULATE | CN_NOCACHE)) == 0);
- dcp->c_flags |= CN_ASYNC_POPULATE;
-
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- rp->cfs_cmd = CFS_POPULATE;
- rp->cfs_req_u.cu_populate.cpop_vp = dvp;
- rp->cfs_cr = cr;
-
- crhold(cr);
- VN_HOLD(dvp);
-
- cachefs_addqueue(rp, &fscp->fs_workq);
- } else if (fscp->fs_info.fi_mntflags & CFS_NOACL) {
- error = cachefs_dir_fill(dcp, cr);
- if (error != 0) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- }
- /* no populate if too many asyncs and we have to cache ACLs */
-
- mutex_exit(&dcp->c_statelock);
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_lookup_back(dvp, nm, vpp, cr);
- else
- error = ETIMEDOUT;
- goto out;
- }
-
- /* by now we have a valid cached front file that we can search */
-
- ASSERT((dcp->c_flags & CN_ASYNC_POPULATE) == 0);
- error = cachefs_dir_look(dcp, nm, &cookie, &flag,
- &d_offset, &cid);
- mutex_exit(&dcp->c_statelock);
-
- if (error) {
- /* if the entry does not have the fid, go get it */
- if (error == EINVAL) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_lookup_back(dvp, nm, vpp, cr);
- else
- error = ETIMEDOUT;
- }
-
- /* errors other than does not exist */
- else if (error != ENOENT) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_lookup_back(dvp, nm, vpp, cr);
- else
- error = ETIMEDOUT;
- }
- goto out;
- }
-
- /*
- * Else we found the entry in the cached directory.
- * Make a cnode for it.
- */
- error = cachefs_cnode_make(&cid, fscp, &cookie, NULL, NULL,
- cr, 0, &cp);
- if (error == ESTALE) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- mutex_enter(&dcp->c_statelock);
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_lookup_back(dvp, nm, vpp, cr);
- uncached = 1;
- } else
- error = ETIMEDOUT;
- } else if (error == 0) {
- *vpp = CTOV(cp);
- }
-
-out:
- if (error == 0) {
- /* put the entry in the dnlc */
- if (cachefs_dnlc)
- dnlc_enter(dvp, nm, *vpp);
-
- /* save the cid of the parent so can find the name */
- cp = VTOC(*vpp);
- if (bcmp(&cp->c_metadata.md_parent, &dircid,
- sizeof (cfs_cid_t)) != 0) {
- mutex_enter(&cp->c_statelock);
- cp->c_metadata.md_parent = dircid;
- cp->c_flags |= CN_UPDATED;
- mutex_exit(&cp->c_statelock);
- }
- }
-
- rw_exit(&dcp->c_rwlock);
- if (uncached && dcp->c_metadata.md_flags & MD_PACKED)
- (void) cachefs_pack_common(dvp, cr);
- return (error);
-}
-
-/*
- * Called from cachefs_lookup_common when the back file system needs to be
- * examined to perform the lookup.
- */
-static int
-cachefs_lookup_back(vnode_t *dvp, char *nm, vnode_t **vpp,
- cred_t *cr)
-{
- int error = 0;
- cnode_t *cp, *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- vnode_t *backvp = NULL;
- struct vattr va;
- struct fid cookie;
- cfs_cid_t cid;
- uint32_t valid_fid;
-
- mutex_enter(&dcp->c_statelock);
-
- /* do a lookup on the back FS to get the back vnode */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error)
- goto out;
- }
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_lookup (nfsv4): dcp %p, dbackvp %p, name %s\n",
- dcp, dcp->c_backvp, nm));
- error = VOP_LOOKUP(dcp->c_backvp, nm, &backvp, (struct pathname *)NULL,
- 0, (vnode_t *)NULL, cr, NULL, NULL, NULL);
- if (error)
- goto out;
- if (IS_DEVVP(backvp)) {
- struct vnode *devvp = backvp;
-
- if (VOP_REALVP(devvp, &backvp, NULL) == 0) {
- VN_HOLD(backvp);
- VN_RELE(devvp);
- }
- }
-
- /* get the fid and attrs from the back fs */
- valid_fid = (CFS_ISFS_BACKFS_NFSV4(fscp) ? FALSE : TRUE);
- error = cachefs_getcookie(backvp, &cookie, &va, cr, valid_fid);
- if (error)
- goto out;
-
- cid.cid_fileno = va.va_nodeid;
- cid.cid_flags = 0;
-
-#if 0
- /* XXX bob: this is probably no longer necessary */
- /* if the directory entry was incomplete, we can complete it now */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) &&
- ((dcp->c_flags & CN_ASYNC_POPULATE) == 0) &&
- (dcp->c_filegrp->fg_flags & CFS_FG_WRITE)) {
- cachefs_dir_modentry(dcp, d_offset, &cookie, &cid);
- }
-#endif
-
-out:
- mutex_exit(&dcp->c_statelock);
-
- /* create the cnode */
- if (error == 0) {
- error = cachefs_cnode_make(&cid, fscp,
- (valid_fid ? &cookie : NULL),
- &va, backvp, cr, 0, &cp);
- if (error == 0) {
- *vpp = CTOV(cp);
- }
- }
-
- if (backvp)
- VN_RELE(backvp);
-
- return (error);
-}
-
-/*ARGSUSED7*/
-static int
-cachefs_create(vnode_t *dvp, char *nm, vattr_t *vap,
- vcexcl_t exclusive, int mode, vnode_t **vpp, cred_t *cr, int flag,
- caller_context_t *ct, vsecattr_t *vsecp)
-
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error;
- int connected = 0;
- int held = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_create: ENTER dvp %p, nm %s\n",
- (void *)dvp, nm);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the create operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /*
- * if we are connected, perform the remote portion of the
- * create.
- */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_create_connected(dvp, nm, vap,
- exclusive, mode, vpp, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- } else if (error) {
- break;
- }
- }
-
- /* else we must be disconnected */
- else {
- error = cachefs_create_disconnected(dvp, nm, vap,
- exclusive, mode, vpp, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- } else if (error) {
- break;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_CREATE)) {
- fid_t *fidp = NULL;
- ino64_t fileno = 0;
- cnode_t *cp = NULL;
- if (error == 0)
- cp = VTOC(*vpp);
-
- if (cp != NULL) {
- fidp = &cp->c_metadata.md_cookie;
- fileno = cp->c_id.cid_fileno;
- }
- cachefs_log_create(cachep, error, fscp->fs_cfsvfsp,
- fidp, fileno, crgetuid(cr));
- }
-
- if (held)
- cachefs_cd_release(fscp);
-
- if (error == 0 && CFS_ISFS_NONSHARED(fscp))
- (void) cachefs_pack(dvp, nm, cr);
- if (error == 0 && IS_DEVVP(*vpp)) {
- struct vnode *spcvp;
-
- spcvp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
- VN_RELE(*vpp);
- if (spcvp == NULL) {
- error = ENOSYS;
- } else {
- *vpp = spcvp;
- }
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_create: EXIT error %d\n", error);
-#endif
- return (error);
-}
-
-
-static int
-cachefs_create_connected(vnode_t *dvp, char *nm, vattr_t *vap,
- enum vcexcl exclusive, int mode, vnode_t **vpp, cred_t *cr)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error;
- vnode_t *tvp = NULL;
- vnode_t *devvp;
- fid_t cookie;
- vattr_t va;
- cnode_t *ncp;
- cfs_cid_t cid;
- vnode_t *vp;
- uint32_t valid_fid;
-
- /* special case if file already exists */
- error = cachefs_lookup_common(dvp, nm, &vp, NULL, 0, NULL, cr);
- if (CFS_TIMEOUT(fscp, error))
- return (error);
- if (error == 0) {
- if (exclusive == EXCL)
- error = EEXIST;
- else if (vp->v_type == VDIR && (mode & VWRITE))
- error = EISDIR;
- else if ((error =
- cachefs_access_connected(vp, mode, 0, cr)) == 0) {
- if ((vap->va_mask & AT_SIZE) && (vp->v_type == VREG)) {
- vap->va_mask = AT_SIZE;
- error = cachefs_setattr_common(vp, vap, 0,
- cr, NULL);
- }
- }
- if (error) {
- VN_RELE(vp);
- } else
- *vpp = vp;
- return (error);
- }
-
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- mutex_enter(&dcp->c_statelock);
-
- /* consistency check the directory */
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* get the backvp if necessary */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- }
-
- /* create the file on the back fs */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_create (nfsv4): dcp %p, dbackvp %p,"
- "name %s\n", dcp, dcp->c_backvp, nm));
- error = VOP_CREATE(dcp->c_backvp, nm, vap, exclusive, mode,
- &devvp, cr, 0, NULL, NULL);
- mutex_exit(&dcp->c_statelock);
- if (error)
- goto out;
- if (VOP_REALVP(devvp, &tvp, NULL) == 0) {
- VN_HOLD(tvp);
- VN_RELE(devvp);
- } else {
- tvp = devvp;
- }
-
- /* get the fid and attrs from the back fs */
- valid_fid = (CFS_ISFS_BACKFS_NFSV4(fscp) ? FALSE : TRUE);
- error = cachefs_getcookie(tvp, &cookie, &va, cr, valid_fid);
- if (error)
- goto out;
-
- /* make the cnode */
- cid.cid_fileno = va.va_nodeid;
- cid.cid_flags = 0;
- error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
- &va, tvp, cr, 0, &ncp);
- if (error)
- goto out;
-
- *vpp = CTOV(ncp);
-
- /* enter it in the parent directory */
- mutex_enter(&dcp->c_statelock);
- if (CFS_ISFS_NONSHARED(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- /* see if entry already exists */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = cachefs_dir_look(dcp, nm, NULL, NULL, NULL, NULL);
- if (error == ENOENT) {
- /* entry, does not exist, add the new file */
- error = cachefs_dir_enter(dcp, nm, &ncp->c_cookie,
- &ncp->c_id, SM_ASYNC);
- if (error) {
- cachefs_nocache(dcp);
- error = 0;
- }
- /* XXX should this be done elsewhere, too? */
- dnlc_enter(dvp, nm, *vpp);
- } else {
- /* entry exists or some other problem */
- cachefs_nocache(dcp);
- error = 0;
- }
- }
- CFSOP_MODIFY_COBJECT(fscp, dcp, cr);
- mutex_exit(&dcp->c_statelock);
-
-out:
- rw_exit(&dcp->c_rwlock);
- if (tvp)
- VN_RELE(tvp);
-
- return (error);
-}
-
-static int
-cachefs_create_disconnected(vnode_t *dvp, char *nm, vattr_t *vap,
- enum vcexcl exclusive, int mode, vnode_t **vpp, cred_t *cr)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp;
- cnode_t *ncp = NULL;
- vnode_t *vp;
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
- struct vattr va;
- timestruc_t current_time;
- off_t commit = 0;
- fid_t cookie;
- cfs_cid_t cid;
-
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- mutex_enter(&dcp->c_statelock);
-
- /* give up if the directory is not populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- mutex_exit(&dcp->c_statelock);
- rw_exit(&dcp->c_rwlock);
- return (ETIMEDOUT);
- }
-
- /* special case if file already exists */
- error = cachefs_dir_look(dcp, nm, &cookie, NULL, NULL, &cid);
- if (error == EINVAL) {
- mutex_exit(&dcp->c_statelock);
- rw_exit(&dcp->c_rwlock);
- return (ETIMEDOUT);
- }
- if (error == 0) {
- mutex_exit(&dcp->c_statelock);
- rw_exit(&dcp->c_rwlock);
- error = cachefs_cnode_make(&cid, fscp, &cookie, NULL, NULL,
- cr, 0, &cp);
- if (error) {
- return (error);
- }
- vp = CTOV(cp);
-
- if (cp->c_metadata.md_flags & MD_NEEDATTRS)
- error = ETIMEDOUT;
- else if (exclusive == EXCL)
- error = EEXIST;
- else if (vp->v_type == VDIR && (mode & VWRITE))
- error = EISDIR;
- else {
- mutex_enter(&cp->c_statelock);
- error = cachefs_access_local(cp, mode, cr);
- mutex_exit(&cp->c_statelock);
- if (!error) {
- if ((vap->va_mask & AT_SIZE) &&
- (vp->v_type == VREG)) {
- vap->va_mask = AT_SIZE;
- error = cachefs_setattr_common(vp,
- vap, 0, cr, NULL);
- }
- }
- }
- if (error) {
- VN_RELE(vp);
- } else
- *vpp = vp;
- return (error);
- }
-
- /* give up if cannot modify the cache */
- if (CFS_ISFS_WRITE_AROUND(fscp)) {
- mutex_exit(&dcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
- }
-
- /* check access */
- if (error = cachefs_access_local(dcp, VWRITE, cr)) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* mark dir as modified */
- cachefs_modified(dcp);
- mutex_exit(&dcp->c_statelock);
-
- /* must be privileged to set sticky bit */
- if ((vap->va_mode & VSVTX) && secpolicy_vnode_stky_modify(cr) != 0)
- vap->va_mode &= ~VSVTX;
-
- /* make up a reasonable set of attributes */
- cachefs_attr_setup(vap, &va, dcp, cr);
-
- /* create the cnode */
- error = cachefs_cnode_create(fscp, &va, 0, &ncp);
- if (error)
- goto out;
-
- mutex_enter(&ncp->c_statelock);
-
- /* get the front file now instead of later */
- if (vap->va_type == VREG) {
- error = cachefs_getfrontfile(ncp);
- if (error) {
- mutex_exit(&ncp->c_statelock);
- goto out;
- }
- ASSERT(ncp->c_frontvp != NULL);
- ASSERT((ncp->c_flags & CN_ALLOC_PENDING) == 0);
- ncp->c_metadata.md_flags |= MD_POPULATED;
- } else {
- ASSERT(ncp->c_flags & CN_ALLOC_PENDING);
- if (ncp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(ncp->c_filegrp);
- }
- error = filegrp_create_metadata(ncp->c_filegrp,
- &ncp->c_metadata, &ncp->c_id);
- if (error) {
- mutex_exit(&ncp->c_statelock);
- goto out;
- }
- ncp->c_flags &= ~CN_ALLOC_PENDING;
- }
- mutex_enter(&dcp->c_statelock);
- cachefs_creategid(dcp, ncp, vap, cr);
- cachefs_createacl(dcp, ncp);
- mutex_exit(&dcp->c_statelock);
-
- /* set times on the file */
- gethrestime(&current_time);
- ncp->c_metadata.md_vattr.va_atime = current_time;
- ncp->c_metadata.md_localctime = current_time;
- ncp->c_metadata.md_localmtime = current_time;
- ncp->c_metadata.md_flags |= MD_LOCALMTIME | MD_LOCALCTIME;
-
- /* reserve space for the daemon cid mapping */
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&ncp->c_statelock);
- goto out;
- }
- ncp->c_metadata.md_flags |= MD_MAPPING;
-
- /* mark the new file as modified */
- if (cachefs_modified_alloc(ncp)) {
- mutex_exit(&ncp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- ncp->c_flags |= CN_UPDATED;
-
- /*
- * write the metadata now rather than waiting until
- * inactive so that if there's no space we can let
- * the caller know.
- */
- ASSERT((ncp->c_flags & CN_ALLOC_PENDING) == 0);
- ASSERT((ncp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) == 0);
- error = filegrp_write_metadata(ncp->c_filegrp,
- &ncp->c_id, &ncp->c_metadata);
- if (error) {
- mutex_exit(&ncp->c_statelock);
- goto out;
- }
-
- /* log the operation */
- commit = cachefs_dlog_create(fscp, dcp, nm, vap, exclusive,
- mode, ncp, 0, cr);
- if (commit == 0) {
- mutex_exit(&ncp->c_statelock);
- error = ENOSPC;
- goto out;
- }
-
- mutex_exit(&ncp->c_statelock);
-
- mutex_enter(&dcp->c_statelock);
-
- /* update parent dir times */
- dcp->c_metadata.md_localmtime = current_time;
- dcp->c_metadata.md_flags |= MD_LOCALMTIME;
- dcp->c_flags |= CN_UPDATED;
-
- /* enter new file name in the parent directory */
- if (dcp->c_metadata.md_flags & MD_POPULATED) {
- error = cachefs_dir_enter(dcp, nm, &ncp->c_cookie,
- &ncp->c_id, 0);
- if (error) {
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
- }
- dnlc_enter(dvp, nm, CTOV(ncp));
- } else {
- mutex_exit(&dcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
- }
- mutex_exit(&dcp->c_statelock);
-
-out:
- rw_exit(&dcp->c_rwlock);
-
- if (commit) {
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
- if (error) {
- /* destroy the cnode we created */
- if (ncp) {
- mutex_enter(&ncp->c_statelock);
- ncp->c_flags |= CN_DESTROY;
- mutex_exit(&ncp->c_statelock);
- VN_RELE(CTOV(ncp));
- }
- } else {
- *vpp = CTOV(ncp);
- }
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct,
- int flags)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
- size_t namlen;
- vnode_t *vp = NULL;
- int vfslock = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_remove: ENTER dvp %p name %s\n",
- (void *)dvp, nm);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE))
- ASSERT(dcp->c_flags & CN_NOCACHE);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the remove operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- if (vfslock) {
- vn_vfsunlock(vp);
- vfslock = 0;
- }
- if (vp) {
- VN_RELE(vp);
- vp = NULL;
- }
-
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /* if disconnected, do some extra error checking */
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- /* check permissions */
- mutex_enter(&dcp->c_statelock);
- error = cachefs_access_local(dcp, (VEXEC|VWRITE), cr);
- mutex_exit(&dcp->c_statelock);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- if (error)
- break;
-
- namlen = strlen(nm);
- if (namlen == 0) {
- error = EINVAL;
- break;
- }
-
- /* cannot remove . and .. */
- if (nm[0] == '.') {
- if (namlen == 1) {
- error = EINVAL;
- break;
- } else if (namlen == 2 && nm[1] == '.') {
- error = EEXIST;
- break;
- }
- }
-
- }
-
- /* get the cnode of the file to delete */
- error = cachefs_lookup_common(dvp, nm, &vp, NULL, 0, NULL, cr);
- if (error) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_REMOVE)) {
- struct fid foo;
-
- bzero(&foo, sizeof (foo));
- cachefs_log_remove(cachep, error,
- fscp->fs_cfsvfsp, &foo, 0, crgetuid(cr));
- }
- break;
- }
-
- if (vp->v_type == VDIR) {
- /* must be privileged to remove dirs with unlink() */
- if ((error = secpolicy_fs_linkdir(cr, vp->v_vfsp)) != 0)
- break;
-
- /* see ufs_dirremove for why this is done, mount race */
- if (vn_vfswlock(vp)) {
- error = EBUSY;
- break;
- }
- vfslock = 1;
- if (vn_mountedvfs(vp) != NULL) {
- error = EBUSY;
- break;
- }
- }
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_remove_connected(dvp, nm, cr, vp);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_remove_disconnected(dvp, nm, cr,
- vp);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
-#if 0
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_REMOVE))
- cachefs_log_remove(cachep, error, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- crgetuid(cr));
-#endif
-
- if (held)
- cachefs_cd_release(fscp);
-
- if (vfslock)
- vn_vfsunlock(vp);
-
- if (vp)
- VN_RELE(vp);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_remove: EXIT dvp %p\n", (void *)dvp);
-#endif
-
- return (error);
-}
-
-int
-cachefs_remove_connected(vnode_t *dvp, char *nm, cred_t *cr, vnode_t *vp)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
-
- /*
- * Acquire the rwlock (WRITER) on the directory to prevent other
- * activity on the directory.
- */
- rw_enter(&dcp->c_rwlock, RW_WRITER);
-
- /* purge dnlc of this entry so can get accurate vnode count */
- dnlc_purge_vp(vp);
-
- /*
- * If the cnode is active, make a link to the file
- * so operations on the file will continue.
- */
- if ((vp->v_type != VDIR) &&
- !((vp->v_count == 1) || ((vp->v_count == 2) && cp->c_ipending))) {
- error = cachefs_remove_dolink(dvp, vp, nm, cr);
- if (error)
- goto out;
- }
-
- /* else call backfs NFSv4 handler if NFSv4 */
- else if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_remove_backfs_nfsv4(dvp, nm, cr, vp);
- goto out;
- }
-
- /* else drop the backvp so nfs does not do rename */
- else if (cp->c_backvp) {
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp) {
- VN_RELE(cp->c_backvp);
- cp->c_backvp = NULL;
- }
- mutex_exit(&cp->c_statelock);
- }
-
- mutex_enter(&dcp->c_statelock);
-
- /* get the backvp */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- }
-
- /* check directory consistency */
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* perform the remove on the back fs */
- error = VOP_REMOVE(dcp->c_backvp, nm, cr, NULL, 0);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* the dir has been modified */
- CFSOP_MODIFY_COBJECT(fscp, dcp, cr);
-
- /* remove the entry from the populated directory */
- if (CFS_ISFS_NONSHARED(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_rmentry(dcp, nm);
- if (error) {
- cachefs_nocache(dcp);
- error = 0;
- }
- }
- mutex_exit(&dcp->c_statelock);
-
- /* fix up the file we deleted */
- mutex_enter(&cp->c_statelock);
- if (cp->c_attr.va_nlink == 1)
- cp->c_flags |= CN_DESTROY;
- else
- cp->c_flags |= CN_UPDATED;
-
- cp->c_attr.va_nlink--;
- CFSOP_MODIFY_COBJECT(fscp, cp, cr);
- mutex_exit(&cp->c_statelock);
-
-out:
- rw_exit(&dcp->c_rwlock);
- return (error);
-}
-
-/*
- * cachefs_remove_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the remove (cachefs
- * pass-through support for NFSv4).
- */
-int
-cachefs_remove_backfs_nfsv4(vnode_t *dvp, char *nm, cred_t *cr, vnode_t *vp)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp = VTOC(vp);
- vnode_t *dbackvp;
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
-
- /*
- * For NFSv4 pass-through to work, only connected operation
- * is supported, the cnode backvp must exist, and cachefs
- * optional (eg., disconnectable) flags are turned off. Assert
- * these conditions for the getattr operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Should hold the directory readwrite lock to update directory */
- ASSERT(RW_WRITE_HELD(&dcp->c_rwlock));
-
- /*
- * Update attributes for directory. Note that
- * CFSOP_CHECK_COBJECT asserts for c_statelock being
- * held, so grab it before calling the routine.
- */
- mutex_enter(&dcp->c_statelock);
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- mutex_exit(&dcp->c_statelock);
- if (error)
- goto out;
-
- /*
- * Update attributes for cp. Note that CFSOP_CHECK_COBJECT
- * asserts for c_statelock being held, so grab it before
- * calling the routine.
- */
- mutex_enter(&cp->c_statelock);
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- /*
- * Drop the backvp so nfs if the link count is 1 so that
- * nfs does not do rename. Ensure that we will destroy the cnode
- * since this cnode no longer contains the backvp. Note that we
- * maintain lock on this cnode to prevent change till the remove
- * completes, otherwise other operations will encounter an ESTALE
- * if they try to use the cnode with CN_DESTROY set (see
- * cachefs_get_backvp()), or change the state of the cnode
- * while we're removing it.
- */
- if (cp->c_attr.va_nlink == 1) {
- /*
- * The unldvp information is created for the case
- * when there is more than one reference on the
- * vnode when a remove operation is called. If the
- * remove itself was holding a reference to the
- * vnode, then a subsequent remove will remove the
- * backvp, so we need to get rid of the unldvp
- * before removing the backvp. An alternate would
- * be to simply ignore the remove and let the
- * inactivation routine do the deletion of the
- * unldvp.
- */
- if (cp->c_unldvp) {
- VN_RELE(cp->c_unldvp);
- cachefs_kmem_free(cp->c_unlname, MAXNAMELEN);
- crfree(cp->c_unlcred);
- cp->c_unldvp = NULL;
- cp->c_unlcred = NULL;
- }
- cp->c_flags |= CN_DESTROY;
- cp->c_attr.va_nlink = 0;
- VN_RELE(cp->c_backvp);
- cp->c_backvp = NULL;
- }
-
- /* perform the remove on back fs after extracting directory backvp */
- mutex_enter(&dcp->c_statelock);
- dbackvp = dcp->c_backvp;
- mutex_exit(&dcp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_remove (nfsv4): dcp %p, dbackvp %p, name %s\n",
- dcp, dbackvp, nm));
- error = VOP_REMOVE(dbackvp, nm, cr, NULL, 0);
- if (error) {
- mutex_exit(&cp->c_statelock);
- goto out;
- }
-
- /* fix up the file we deleted, if not destroying the cnode */
- if ((cp->c_flags & CN_DESTROY) == 0) {
- cp->c_attr.va_nlink--;
- cp->c_flags |= CN_UPDATED;
- }
-
- mutex_exit(&cp->c_statelock);
-
-out:
- return (error);
-}
-
-int
-cachefs_remove_disconnected(vnode_t *dvp, char *nm, cred_t *cr,
- vnode_t *vp)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
- off_t commit = 0;
- timestruc_t current_time;
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- if (cp->c_metadata.md_flags & MD_NEEDATTRS)
- return (ETIMEDOUT);
-
- /*
- * Acquire the rwlock (WRITER) on the directory to prevent other
- * activity on the directory.
- */
- rw_enter(&dcp->c_rwlock, RW_WRITER);
-
- /* dir must be populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- goto out;
- }
-
- mutex_enter(&dcp->c_statelock);
- mutex_enter(&cp->c_statelock);
-
- error = cachefs_stickyrmchk(dcp, cp, cr);
-
- mutex_exit(&cp->c_statelock);
- mutex_exit(&dcp->c_statelock);
- if (error)
- goto out;
-
- /* purge dnlc of this entry so can get accurate vnode count */
- dnlc_purge_vp(vp);
-
- /*
- * If the cnode is active, make a link to the file
- * so operations on the file will continue.
- */
- if ((vp->v_type != VDIR) &&
- !((vp->v_count == 1) || ((vp->v_count == 2) && cp->c_ipending))) {
- error = cachefs_remove_dolink(dvp, vp, nm, cr);
- if (error)
- goto out;
- }
-
- if (cp->c_attr.va_nlink > 1) {
- mutex_enter(&cp->c_statelock);
- if (cachefs_modified_alloc(cp)) {
- mutex_exit(&cp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&cp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- cp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&cp->c_statelock);
- }
-
- /* log the remove */
- commit = cachefs_dlog_remove(fscp, dcp, nm, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
-
- /* remove the file from the dir */
- mutex_enter(&dcp->c_statelock);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- mutex_exit(&dcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
-
- }
- cachefs_modified(dcp);
- error = cachefs_dir_rmentry(dcp, nm);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- goto out;
- }
-
- /* update parent dir times */
- gethrestime(&current_time);
- dcp->c_metadata.md_localctime = current_time;
- dcp->c_metadata.md_localmtime = current_time;
- dcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- dcp->c_flags |= CN_UPDATED;
- mutex_exit(&dcp->c_statelock);
-
- /* adjust file we are deleting */
- mutex_enter(&cp->c_statelock);
- cp->c_attr.va_nlink--;
- cp->c_metadata.md_localctime = current_time;
- cp->c_metadata.md_flags |= MD_LOCALCTIME;
- if (cp->c_attr.va_nlink == 0) {
- cp->c_flags |= CN_DESTROY;
- } else {
- cp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&cp->c_statelock);
-
-out:
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
-
- rw_exit(&dcp->c_rwlock);
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_link(vnode_t *tdvp, vnode_t *fvp, char *tnm, cred_t *cr,
- caller_context_t *ct, int flags)
-{
- fscache_t *fscp = VFS_TO_FSCACHE(tdvp->v_vfsp);
- cnode_t *tdcp = VTOC(tdvp);
- struct vnode *realvp;
- int error = 0;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_link: ENTER fvp %p tdvp %p tnm %s\n",
- (void *)fvp, (void *)tdvp, tnm);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE))
- ASSERT(tdcp->c_flags & CN_NOCACHE);
-
- if (VOP_REALVP(fvp, &realvp, ct) == 0) {
- fvp = realvp;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the link operation.
- */
-
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(tdcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- rw_exit(&tdcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- rw_enter(&tdcp->c_rwlock, RW_WRITER);
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_link_connected(tdvp, fvp, tnm, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- rw_exit(&tdcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_link_disconnected(tdvp, fvp, tnm,
- cr);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (held) {
- rw_exit(&tdcp->c_rwlock);
- cachefs_cd_release(fscp);
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_link: EXIT fvp %p tdvp %p tnm %s\n",
- (void *)fvp, (void *)tdvp, tnm);
-#endif
- return (error);
-}
-
-static int
-cachefs_link_connected(vnode_t *tdvp, vnode_t *fvp, char *tnm, cred_t *cr)
-{
- cnode_t *tdcp = VTOC(tdvp);
- cnode_t *fcp = VTOC(fvp);
- fscache_t *fscp = VFS_TO_FSCACHE(tdvp->v_vfsp);
- int error = 0;
- vnode_t *backvp = NULL;
-
- if (tdcp != fcp) {
- mutex_enter(&fcp->c_statelock);
-
- if (fcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, fcp);
- if (error) {
- mutex_exit(&fcp->c_statelock);
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, fcp, 0, cr);
- if (error) {
- mutex_exit(&fcp->c_statelock);
- goto out;
- }
- backvp = fcp->c_backvp;
- VN_HOLD(backvp);
- mutex_exit(&fcp->c_statelock);
- }
-
- mutex_enter(&tdcp->c_statelock);
-
- /* get backvp of target directory */
- if (tdcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, tdcp);
- if (error) {
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
- }
-
- /* consistency check target directory */
- error = CFSOP_CHECK_COBJECT(fscp, tdcp, 0, cr);
- if (error) {
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
- if (backvp == NULL) {
- backvp = tdcp->c_backvp;
- VN_HOLD(backvp);
- }
-
- /* perform the link on the back fs */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_link (nfsv4): tdcp %p, tdbackvp %p, "
- "name %s\n", tdcp, tdcp->c_backvp, tnm));
- error = VOP_LINK(tdcp->c_backvp, backvp, tnm, cr, NULL, 0);
- if (error) {
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
-
- CFSOP_MODIFY_COBJECT(fscp, tdcp, cr);
-
- /* if the dir is populated, add the new link */
- if (CFS_ISFS_NONSHARED(fscp) &&
- (tdcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_enter(tdcp, tnm, &fcp->c_cookie,
- &fcp->c_id, SM_ASYNC);
- if (error) {
- cachefs_nocache(tdcp);
- error = 0;
- }
- }
- mutex_exit(&tdcp->c_statelock);
-
- /* get the new link count on the file */
- mutex_enter(&fcp->c_statelock);
- fcp->c_flags |= CN_UPDATED;
- CFSOP_MODIFY_COBJECT(fscp, fcp, cr);
- if (fcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, fcp);
- if (error) {
- mutex_exit(&fcp->c_statelock);
- goto out;
- }
- }
-
- /* XXX bob: given what modify_cobject does this seems unnecessary */
- fcp->c_attr.va_mask = AT_ALL;
- error = VOP_GETATTR(fcp->c_backvp, &fcp->c_attr, 0, cr, NULL);
- mutex_exit(&fcp->c_statelock);
-out:
- if (backvp)
- VN_RELE(backvp);
-
- return (error);
-}
-
-static int
-cachefs_link_disconnected(vnode_t *tdvp, vnode_t *fvp, char *tnm,
- cred_t *cr)
-{
- cnode_t *tdcp = VTOC(tdvp);
- cnode_t *fcp = VTOC(fvp);
- fscache_t *fscp = VFS_TO_FSCACHE(tdvp->v_vfsp);
- int error = 0;
- timestruc_t current_time;
- off_t commit = 0;
-
- if (fvp->v_type == VDIR && secpolicy_fs_linkdir(cr, fvp->v_vfsp) != 0 ||
- fcp->c_attr.va_uid != crgetuid(cr) && secpolicy_basic_link(cr) != 0)
- return (EPERM);
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- if (fcp->c_metadata.md_flags & MD_NEEDATTRS)
- return (ETIMEDOUT);
-
- mutex_enter(&tdcp->c_statelock);
-
- /* check permissions */
- if (error = cachefs_access_local(tdcp, (VEXEC|VWRITE), cr)) {
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
-
- /* the directory front file must be populated */
- if ((tdcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
-
- /* make sure tnm does not already exist in the directory */
- error = cachefs_dir_look(tdcp, tnm, NULL, NULL, NULL, NULL);
- if (error == ENOTDIR) {
- error = ETIMEDOUT;
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
- if (error != ENOENT) {
- error = EEXIST;
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
-
- mutex_enter(&fcp->c_statelock);
-
- /* create a mapping for the file if necessary */
- if ((fcp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&fcp->c_statelock);
- mutex_exit(&tdcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- fcp->c_metadata.md_flags |= MD_MAPPING;
- fcp->c_flags |= CN_UPDATED;
- }
-
- /* mark file as modified */
- if (cachefs_modified_alloc(fcp)) {
- mutex_exit(&fcp->c_statelock);
- mutex_exit(&tdcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- mutex_exit(&fcp->c_statelock);
-
- /* log the operation */
- commit = cachefs_dlog_link(fscp, tdcp, tnm, fcp, cr);
- if (commit == 0) {
- mutex_exit(&tdcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
-
- gethrestime(&current_time);
-
- /* make the new link */
- cachefs_modified(tdcp);
- error = cachefs_dir_enter(tdcp, tnm, &fcp->c_cookie,
- &fcp->c_id, SM_ASYNC);
- if (error) {
- error = 0;
- mutex_exit(&tdcp->c_statelock);
- goto out;
- }
-
- /* Update mtime/ctime of parent dir */
- tdcp->c_metadata.md_localmtime = current_time;
- tdcp->c_metadata.md_localctime = current_time;
- tdcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- tdcp->c_flags |= CN_UPDATED;
- mutex_exit(&tdcp->c_statelock);
-
- /* update the file we linked to */
- mutex_enter(&fcp->c_statelock);
- fcp->c_attr.va_nlink++;
- fcp->c_metadata.md_localctime = current_time;
- fcp->c_metadata.md_flags |= MD_LOCALCTIME;
- fcp->c_flags |= CN_UPDATED;
- mutex_exit(&fcp->c_statelock);
-
-out:
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
-
- return (error);
-}
-
-/*
- * Serialize all renames in CFS, to avoid deadlocks - We have to hold two
- * cnodes atomically.
- */
-kmutex_t cachefs_rename_lock;
-
-/*ARGSUSED*/
-static int
-cachefs_rename(vnode_t *odvp, char *onm, vnode_t *ndvp,
- char *nnm, cred_t *cr, caller_context_t *ct, int flags)
-{
- fscache_t *fscp = C_TO_FSCACHE(VTOC(odvp));
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
- vnode_t *delvp = NULL;
- vnode_t *tvp = NULL;
- int vfslock = 0;
- struct vnode *realvp;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- if (VOP_REALVP(ndvp, &realvp, ct) == 0)
- ndvp = realvp;
-
- /*
- * if the fs NOFILL or NOCACHE flags are on, then the old and new
- * directory cnodes better indicate NOCACHE mode as well.
- */
- ASSERT(
- (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE)) == 0 ||
- ((VTOC(odvp)->c_flags & CN_NOCACHE) &&
- (VTOC(ndvp)->c_flags & CN_NOCACHE)));
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the rename operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(VTOC(odvp));
- CFS_BACKFS_NFSV4_ASSERT_CNODE(VTOC(ndvp));
-
- for (;;) {
- if (vfslock) {
- vn_vfsunlock(delvp);
- vfslock = 0;
- }
- if (delvp) {
- VN_RELE(delvp);
- delvp = NULL;
- }
-
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop for NFSv4 connected support */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /* sanity check */
- if ((odvp->v_type != VDIR) || (ndvp->v_type != VDIR)) {
- error = EINVAL;
- break;
- }
-
- /* cannot rename from or to . or .. */
- if (strcmp(onm, ".") == 0 || strcmp(onm, "..") == 0 ||
- strcmp(nnm, ".") == 0 || strcmp(nnm, "..") == 0) {
- error = EINVAL;
- break;
- }
-
- if (odvp != ndvp) {
- /*
- * if moving a directory, its notion
- * of ".." will change
- */
- error = cachefs_lookup_common(odvp, onm, &tvp,
- NULL, 0, NULL, cr);
- if (error == 0) {
- ASSERT(tvp != NULL);
- if (tvp->v_type == VDIR) {
- cnode_t *cp = VTOC(tvp);
-
- dnlc_remove(tvp, "..");
-
- mutex_enter(&cp->c_statelock);
- CFSOP_MODIFY_COBJECT(fscp, cp, cr);
- mutex_exit(&cp->c_statelock);
- }
- } else {
- tvp = NULL;
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
- }
-
- /* get the cnode if file being deleted */
- error = cachefs_lookup_common(ndvp, nnm, &delvp, NULL, 0,
- NULL, cr);
- if (error) {
- delvp = NULL;
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- if (error != ENOENT)
- break;
- }
-
- if (delvp && delvp->v_type == VDIR) {
- /* see ufs_dirremove for why this is done, mount race */
- if (vn_vfswlock(delvp)) {
- error = EBUSY;
- break;
- }
- vfslock = 1;
- if (vn_mountedvfs(delvp) != NULL) {
- error = EBUSY;
- break;
- }
- }
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_rename_connected(odvp, onm,
- ndvp, nnm, cr, delvp);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_rename_disconnected(odvp, onm,
- ndvp, nnm, cr, delvp);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_RENAME)) {
- struct fid gone;
-
- bzero(&gone, sizeof (gone));
- gone.fid_len = MAXFIDSZ;
- if (delvp != NULL)
- (void) VOP_FID(delvp, &gone, ct);
-
- cachefs_log_rename(cachep, error, fscp->fs_cfsvfsp,
- &gone, 0, (delvp != NULL), crgetuid(cr));
- }
-
- if (held)
- cachefs_cd_release(fscp);
-
- if (vfslock)
- vn_vfsunlock(delvp);
-
- if (delvp)
- VN_RELE(delvp);
- if (tvp)
- VN_RELE(tvp);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
- return (error);
-}
-
-static int
-cachefs_rename_connected(vnode_t *odvp, char *onm, vnode_t *ndvp,
- char *nnm, cred_t *cr, vnode_t *delvp)
-{
- cnode_t *odcp = VTOC(odvp);
- cnode_t *ndcp = VTOC(ndvp);
- vnode_t *revp = NULL;
- cnode_t *recp;
- cnode_t *delcp;
- fscache_t *fscp = C_TO_FSCACHE(odcp);
- int error = 0;
- struct fid cookie;
- struct fid *cookiep;
- cfs_cid_t cid;
- int gotdirent;
-
- /* find the file we are renaming */
- error = cachefs_lookup_common(odvp, onm, &revp, NULL, 0, NULL, cr);
- if (error)
- return (error);
- recp = VTOC(revp);
-
- /*
- * To avoid deadlock, we acquire this global rename lock before
- * we try to get the locks for the source and target directories.
- */
- mutex_enter(&cachefs_rename_lock);
- rw_enter(&odcp->c_rwlock, RW_WRITER);
- if (odcp != ndcp) {
- rw_enter(&ndcp->c_rwlock, RW_WRITER);
- }
- mutex_exit(&cachefs_rename_lock);
-
- ASSERT((odcp->c_flags & CN_ASYNC_POP_WORKING) == 0);
- ASSERT((ndcp->c_flags & CN_ASYNC_POP_WORKING) == 0);
-
- mutex_enter(&odcp->c_statelock);
- if (odcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, odcp);
- if (error) {
- mutex_exit(&odcp->c_statelock);
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, odcp, 0, cr);
- if (error) {
- mutex_exit(&odcp->c_statelock);
- goto out;
- }
- mutex_exit(&odcp->c_statelock);
-
- if (odcp != ndcp) {
- mutex_enter(&ndcp->c_statelock);
- if (ndcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, ndcp);
- if (error) {
- mutex_exit(&ndcp->c_statelock);
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, ndcp, 0, cr);
- if (error) {
- mutex_exit(&ndcp->c_statelock);
- goto out;
- }
- mutex_exit(&ndcp->c_statelock);
- }
-
- /* if a file is being deleted because of this rename */
- if (delvp) {
- /* if src and dest file are same */
- if (delvp == revp) {
- error = 0;
- goto out;
- }
-
- /*
- * If the cnode is active, make a link to the file
- * so operations on the file will continue.
- */
- dnlc_purge_vp(delvp);
- delcp = VTOC(delvp);
- if ((delvp->v_type != VDIR) &&
- !((delvp->v_count == 1) ||
- ((delvp->v_count == 2) && delcp->c_ipending))) {
- error = cachefs_remove_dolink(ndvp, delvp, nnm, cr);
- if (error)
- goto out;
- }
- }
-
- /* do the rename on the back fs */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_rename (nfsv4): odcp %p, odbackvp %p, "
- " ndcp %p, ndbackvp %p, onm %s, nnm %s\n",
- odcp, odcp->c_backvp, ndcp, ndcp->c_backvp, onm, nnm));
- error = VOP_RENAME(odcp->c_backvp, onm, ndcp->c_backvp, nnm, cr, NULL,
- 0);
- if (error)
- goto out;
-
- /* purge mappings to file in the old directory */
- dnlc_purge_vp(odvp);
-
- /* purge mappings in the new dir if we deleted a file */
- if (delvp && (odvp != ndvp))
- dnlc_purge_vp(ndvp);
-
- /* update the file we just deleted */
- if (delvp) {
- mutex_enter(&delcp->c_statelock);
- if (delcp->c_attr.va_nlink == 1) {
- delcp->c_flags |= CN_DESTROY;
- } else {
- delcp->c_flags |= CN_UPDATED;
- }
- delcp->c_attr.va_nlink--;
- CFSOP_MODIFY_COBJECT(fscp, delcp, cr);
- mutex_exit(&delcp->c_statelock);
- }
-
- /* find the entry in the old directory */
- mutex_enter(&odcp->c_statelock);
- gotdirent = 0;
- cookiep = NULL;
- if (CFS_ISFS_NONSHARED(fscp) &&
- (odcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_look(odcp, onm, &cookie,
- NULL, NULL, &cid);
- if (error == 0 || error == EINVAL) {
- gotdirent = 1;
- if (error == 0)
- cookiep = &cookie;
- } else {
- cachefs_inval_object(odcp);
- }
- }
- error = 0;
-
- /* remove the directory entry from the old directory */
- if (gotdirent) {
- error = cachefs_dir_rmentry(odcp, onm);
- if (error) {
- cachefs_nocache(odcp);
- error = 0;
- }
- }
- CFSOP_MODIFY_COBJECT(fscp, odcp, cr);
- mutex_exit(&odcp->c_statelock);
-
- /* install the directory entry in the new directory */
- mutex_enter(&ndcp->c_statelock);
- if (CFS_ISFS_NONSHARED(fscp) &&
- (ndcp->c_metadata.md_flags & MD_POPULATED)) {
- error = 1;
- if (gotdirent) {
- ASSERT(cid.cid_fileno != 0);
- error = 0;
- if (delvp) {
- error = cachefs_dir_rmentry(ndcp, nnm);
- }
- if (error == 0) {
- error = cachefs_dir_enter(ndcp, nnm, cookiep,
- &cid, SM_ASYNC);
- }
- }
- if (error) {
- cachefs_nocache(ndcp);
- error = 0;
- }
- }
- if (odcp != ndcp)
- CFSOP_MODIFY_COBJECT(fscp, ndcp, cr);
- mutex_exit(&ndcp->c_statelock);
-
- /* ctime of renamed file has changed */
- mutex_enter(&recp->c_statelock);
- CFSOP_MODIFY_COBJECT(fscp, recp, cr);
- mutex_exit(&recp->c_statelock);
-
-out:
- if (odcp != ndcp)
- rw_exit(&ndcp->c_rwlock);
- rw_exit(&odcp->c_rwlock);
-
- VN_RELE(revp);
-
- return (error);
-}
-
-static int
-cachefs_rename_disconnected(vnode_t *odvp, char *onm, vnode_t *ndvp,
- char *nnm, cred_t *cr, vnode_t *delvp)
-{
- cnode_t *odcp = VTOC(odvp);
- cnode_t *ndcp = VTOC(ndvp);
- cnode_t *delcp = NULL;
- vnode_t *revp = NULL;
- cnode_t *recp;
- fscache_t *fscp = C_TO_FSCACHE(odcp);
- int error = 0;
- struct fid cookie;
- struct fid *cookiep;
- cfs_cid_t cid;
- off_t commit = 0;
- timestruc_t current_time;
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- /* find the file we are renaming */
- error = cachefs_lookup_common(odvp, onm, &revp, NULL, 0, NULL, cr);
- if (error)
- return (error);
- recp = VTOC(revp);
-
- /*
- * To avoid deadlock, we acquire this global rename lock before
- * we try to get the locks for the source and target directories.
- */
- mutex_enter(&cachefs_rename_lock);
- rw_enter(&odcp->c_rwlock, RW_WRITER);
- if (odcp != ndcp) {
- rw_enter(&ndcp->c_rwlock, RW_WRITER);
- }
- mutex_exit(&cachefs_rename_lock);
-
- if (recp->c_metadata.md_flags & MD_NEEDATTRS) {
- error = ETIMEDOUT;
- goto out;
- }
-
- if ((recp->c_metadata.md_flags & MD_MAPPING) == 0) {
- mutex_enter(&recp->c_statelock);
- if ((recp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&recp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- recp->c_metadata.md_flags |= MD_MAPPING;
- recp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&recp->c_statelock);
- }
-
- /* check permissions */
- /* XXX clean up this mutex junk sometime */
- mutex_enter(&odcp->c_statelock);
- error = cachefs_access_local(odcp, (VEXEC|VWRITE), cr);
- mutex_exit(&odcp->c_statelock);
- if (error != 0)
- goto out;
- mutex_enter(&ndcp->c_statelock);
- error = cachefs_access_local(ndcp, (VEXEC|VWRITE), cr);
- mutex_exit(&ndcp->c_statelock);
- if (error != 0)
- goto out;
- mutex_enter(&odcp->c_statelock);
- error = cachefs_stickyrmchk(odcp, recp, cr);
- mutex_exit(&odcp->c_statelock);
- if (error != 0)
- goto out;
-
- /* dirs must be populated */
- if (((odcp->c_metadata.md_flags & MD_POPULATED) == 0) ||
- ((ndcp->c_metadata.md_flags & MD_POPULATED) == 0)) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* for now do not allow moving dirs because could cause cycles */
- if ((((revp->v_type == VDIR) && (odvp != ndvp))) ||
- (revp == odvp)) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* if a file is being deleted because of this rename */
- if (delvp) {
- delcp = VTOC(delvp);
-
- /* if src and dest file are the same */
- if (delvp == revp) {
- error = 0;
- goto out;
- }
-
- if (delcp->c_metadata.md_flags & MD_NEEDATTRS) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* if there are hard links to this file */
- if (delcp->c_attr.va_nlink > 1) {
- mutex_enter(&delcp->c_statelock);
- if (cachefs_modified_alloc(delcp)) {
- mutex_exit(&delcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
-
- if ((delcp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&delcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
- delcp->c_metadata.md_flags |= MD_MAPPING;
- delcp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&delcp->c_statelock);
- }
-
- /* make sure we can delete file */
- mutex_enter(&ndcp->c_statelock);
- error = cachefs_stickyrmchk(ndcp, delcp, cr);
- mutex_exit(&ndcp->c_statelock);
- if (error != 0)
- goto out;
-
- /*
- * If the cnode is active, make a link to the file
- * so operations on the file will continue.
- */
- dnlc_purge_vp(delvp);
- if ((delvp->v_type != VDIR) &&
- !((delvp->v_count == 1) ||
- ((delvp->v_count == 2) && delcp->c_ipending))) {
- error = cachefs_remove_dolink(ndvp, delvp, nnm, cr);
- if (error)
- goto out;
- }
- }
-
- /* purge mappings to file in the old directory */
- dnlc_purge_vp(odvp);
-
- /* purge mappings in the new dir if we deleted a file */
- if (delvp && (odvp != ndvp))
- dnlc_purge_vp(ndvp);
-
- /* find the entry in the old directory */
- mutex_enter(&odcp->c_statelock);
- if ((odcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- mutex_exit(&odcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
- }
- cookiep = NULL;
- error = cachefs_dir_look(odcp, onm, &cookie, NULL, NULL, &cid);
- if (error == 0 || error == EINVAL) {
- if (error == 0)
- cookiep = &cookie;
- } else {
- mutex_exit(&odcp->c_statelock);
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- goto out;
- }
- error = 0;
-
- /* write the log entry */
- commit = cachefs_dlog_rename(fscp, odcp, onm, ndcp, nnm, cr,
- recp, delcp);
- if (commit == 0) {
- mutex_exit(&odcp->c_statelock);
- error = ENOSPC;
- goto out;
- }
-
- /* remove the directory entry from the old directory */
- cachefs_modified(odcp);
- error = cachefs_dir_rmentry(odcp, onm);
- if (error) {
- mutex_exit(&odcp->c_statelock);
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- goto out;
- }
- mutex_exit(&odcp->c_statelock);
-
- /* install the directory entry in the new directory */
- mutex_enter(&ndcp->c_statelock);
- error = ENOTDIR;
- if (ndcp->c_metadata.md_flags & MD_POPULATED) {
- ASSERT(cid.cid_fileno != 0);
- cachefs_modified(ndcp);
- error = 0;
- if (delvp) {
- error = cachefs_dir_rmentry(ndcp, nnm);
- }
- if (error == 0) {
- error = cachefs_dir_enter(ndcp, nnm, cookiep,
- &cid, SM_ASYNC);
- }
- }
- if (error) {
- cachefs_nocache(ndcp);
- mutex_exit(&ndcp->c_statelock);
- mutex_enter(&odcp->c_statelock);
- cachefs_nocache(odcp);
- mutex_exit(&odcp->c_statelock);
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- goto out;
- }
- mutex_exit(&ndcp->c_statelock);
-
- gethrestime(&current_time);
-
- /* update the file we just deleted */
- if (delvp) {
- mutex_enter(&delcp->c_statelock);
- delcp->c_attr.va_nlink--;
- delcp->c_metadata.md_localctime = current_time;
- delcp->c_metadata.md_flags |= MD_LOCALCTIME;
- if (delcp->c_attr.va_nlink == 0) {
- delcp->c_flags |= CN_DESTROY;
- } else {
- delcp->c_flags |= CN_UPDATED;
- }
- mutex_exit(&delcp->c_statelock);
- }
-
- /* update the file we renamed */
- mutex_enter(&recp->c_statelock);
- recp->c_metadata.md_localctime = current_time;
- recp->c_metadata.md_flags |= MD_LOCALCTIME;
- recp->c_flags |= CN_UPDATED;
- mutex_exit(&recp->c_statelock);
-
- /* update the source directory */
- mutex_enter(&odcp->c_statelock);
- odcp->c_metadata.md_localctime = current_time;
- odcp->c_metadata.md_localmtime = current_time;
- odcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- odcp->c_flags |= CN_UPDATED;
- mutex_exit(&odcp->c_statelock);
-
- /* update the destination directory */
- if (odcp != ndcp) {
- mutex_enter(&ndcp->c_statelock);
- ndcp->c_metadata.md_localctime = current_time;
- ndcp->c_metadata.md_localmtime = current_time;
- ndcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- ndcp->c_flags |= CN_UPDATED;
- mutex_exit(&ndcp->c_statelock);
- }
-
-out:
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
-
- if (odcp != ndcp)
- rw_exit(&ndcp->c_rwlock);
- rw_exit(&odcp->c_rwlock);
-
- VN_RELE(revp);
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_mkdir(vnode_t *dvp, char *nm, vattr_t *vap, vnode_t **vpp,
- cred_t *cr, caller_context_t *ct, int flags, vsecattr_t *vsecp)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_mkdir: ENTER dvp %p\n", (void *)dvp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE))
- ASSERT(dcp->c_flags & CN_NOCACHE);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the mkdir operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_mkdir_connected(dvp, nm, vap,
- vpp, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_mkdir_disconnected(dvp, nm, vap,
- vpp, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_MKDIR)) {
- fid_t *fidp = NULL;
- ino64_t fileno = 0;
- cnode_t *cp = NULL;
- if (error == 0)
- cp = VTOC(*vpp);
-
- if (cp != NULL) {
- fidp = &cp->c_metadata.md_cookie;
- fileno = cp->c_id.cid_fileno;
- }
-
- cachefs_log_mkdir(cachep, error, fscp->fs_cfsvfsp,
- fidp, fileno, crgetuid(cr));
- }
-
- if (held) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- }
- if (error == 0 && CFS_ISFS_NONSHARED(fscp))
- (void) cachefs_pack(dvp, nm, cr);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_mkdir: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-static int
-cachefs_mkdir_connected(vnode_t *dvp, char *nm, vattr_t *vap,
- vnode_t **vpp, cred_t *cr)
-{
- cnode_t *newcp = NULL, *dcp = VTOC(dvp);
- struct vnode *vp = NULL;
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- struct fid cookie;
- struct vattr attr;
- cfs_cid_t cid, dircid;
- uint32_t valid_fid;
-
- if (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE))
- ASSERT(dcp->c_flags & CN_NOCACHE);
-
- mutex_enter(&dcp->c_statelock);
-
- /* get backvp of dir */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- }
-
- /* consistency check the directory */
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- dircid = dcp->c_id;
-
- /* make the dir on the back fs */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_mkdir (nfsv4): dcp %p, dbackvp %p, "
- "name %s\n", dcp, dcp->c_backvp, nm));
- error = VOP_MKDIR(dcp->c_backvp, nm, vap, &vp, cr, NULL, 0, NULL);
- mutex_exit(&dcp->c_statelock);
- if (error) {
- goto out;
- }
-
- /* get the cookie and make the cnode */
- attr.va_mask = AT_ALL;
- valid_fid = (CFS_ISFS_BACKFS_NFSV4(fscp) ? FALSE : TRUE);
- error = cachefs_getcookie(vp, &cookie, &attr, cr, valid_fid);
- if (error) {
- goto out;
- }
- cid.cid_flags = 0;
- cid.cid_fileno = attr.va_nodeid;
- error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
- &attr, vp, cr, 0, &newcp);
- if (error) {
- goto out;
- }
- ASSERT(CTOV(newcp)->v_type == VDIR);
- *vpp = CTOV(newcp);
-
- /* if the dir is populated, add the new entry */
- mutex_enter(&dcp->c_statelock);
- if (CFS_ISFS_NONSHARED(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_enter(dcp, nm, &cookie, &newcp->c_id,
- SM_ASYNC);
- if (error) {
- cachefs_nocache(dcp);
- error = 0;
- }
- }
- dcp->c_attr.va_nlink++;
- dcp->c_flags |= CN_UPDATED;
- CFSOP_MODIFY_COBJECT(fscp, dcp, cr);
- mutex_exit(&dcp->c_statelock);
-
- /* XXX bob: should we do a filldir here? or just add . and .. */
- /* maybe should kick off an async filldir so caller does not wait */
-
- /* put the entry in the dnlc */
- if (cachefs_dnlc)
- dnlc_enter(dvp, nm, *vpp);
-
- /* save the fileno of the parent so can find the name */
- if (bcmp(&newcp->c_metadata.md_parent, &dircid,
- sizeof (cfs_cid_t)) != 0) {
- mutex_enter(&newcp->c_statelock);
- newcp->c_metadata.md_parent = dircid;
- newcp->c_flags |= CN_UPDATED;
- mutex_exit(&newcp->c_statelock);
- }
-out:
- if (vp)
- VN_RELE(vp);
-
- return (error);
-}
-
-static int
-cachefs_mkdir_disconnected(vnode_t *dvp, char *nm, vattr_t *vap,
- vnode_t **vpp, cred_t *cr)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error;
- cnode_t *newcp = NULL;
- struct vattr va;
- timestruc_t current_time;
- off_t commit = 0;
- char *s;
- int namlen;
-
- /* don't allow '/' characters in pathname component */
- for (s = nm, namlen = 0; *s; s++, namlen++)
- if (*s == '/')
- return (EACCES);
- if (namlen == 0)
- return (EINVAL);
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- mutex_enter(&dcp->c_statelock);
-
- /* check permissions */
- if (error = cachefs_access_local(dcp, (VEXEC|VWRITE), cr)) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* the directory front file must be populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* make sure nm does not already exist in the directory */
- error = cachefs_dir_look(dcp, nm, NULL, NULL, NULL, NULL);
- if (error == ENOTDIR) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- if (error != ENOENT) {
- error = EEXIST;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* make up a reasonable set of attributes */
- cachefs_attr_setup(vap, &va, dcp, cr);
- va.va_type = VDIR;
- va.va_mode |= S_IFDIR;
- va.va_nlink = 2;
-
- mutex_exit(&dcp->c_statelock);
-
- /* create the cnode */
- error = cachefs_cnode_create(fscp, &va, 0, &newcp);
- if (error)
- goto out;
-
- mutex_enter(&newcp->c_statelock);
-
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- goto out;
- }
-
- cachefs_creategid(dcp, newcp, vap, cr);
- mutex_enter(&dcp->c_statelock);
- cachefs_createacl(dcp, newcp);
- mutex_exit(&dcp->c_statelock);
- gethrestime(&current_time);
- newcp->c_metadata.md_vattr.va_atime = current_time;
- newcp->c_metadata.md_localctime = current_time;
- newcp->c_metadata.md_localmtime = current_time;
- newcp->c_metadata.md_flags |= MD_MAPPING | MD_LOCALMTIME |
- MD_LOCALCTIME;
- newcp->c_flags |= CN_UPDATED;
-
- /* make a front file for the new directory, add . and .. */
- error = cachefs_dir_new(dcp, newcp);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- goto out;
- }
- cachefs_modified(newcp);
-
- /*
- * write the metadata now rather than waiting until
- * inactive so that if there's no space we can let
- * the caller know.
- */
- ASSERT(newcp->c_frontvp);
- ASSERT((newcp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) == 0);
- ASSERT((newcp->c_flags & CN_ALLOC_PENDING) == 0);
- error = filegrp_write_metadata(newcp->c_filegrp,
- &newcp->c_id, &newcp->c_metadata);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- goto out;
- }
- mutex_exit(&newcp->c_statelock);
-
- /* log the operation */
- commit = cachefs_dlog_mkdir(fscp, dcp, newcp, nm, &va, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
-
- mutex_enter(&dcp->c_statelock);
-
- /* make sure directory is still populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- mutex_exit(&dcp->c_statelock);
- error = ETIMEDOUT;
- goto out;
- }
- cachefs_modified(dcp);
-
- /* enter the new file in the directory */
- error = cachefs_dir_enter(dcp, nm, &newcp->c_metadata.md_cookie,
- &newcp->c_id, SM_ASYNC);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* update parent dir times */
- dcp->c_metadata.md_localctime = current_time;
- dcp->c_metadata.md_localmtime = current_time;
- dcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- dcp->c_attr.va_nlink++;
- dcp->c_flags |= CN_UPDATED;
- mutex_exit(&dcp->c_statelock);
-
-out:
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
- if (error) {
- if (newcp) {
- mutex_enter(&newcp->c_statelock);
- newcp->c_flags |= CN_DESTROY;
- mutex_exit(&newcp->c_statelock);
- VN_RELE(CTOV(newcp));
- }
- } else {
- *vpp = CTOV(newcp);
- }
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr,
- caller_context_t *ct, int flags)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
- size_t namlen;
- vnode_t *vp = NULL;
- int vfslock = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_rmdir: ENTER vp %p\n", (void *)dvp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_cache->c_flags & (CACHE_NOFILL | CACHE_NOCACHE))
- ASSERT(dcp->c_flags & CN_NOCACHE);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the rmdir operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- if (vfslock) {
- vn_vfsunlock(vp);
- vfslock = 0;
- }
- if (vp) {
- VN_RELE(vp);
- vp = NULL;
- }
-
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /* if disconnected, do some extra error checking */
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- /* check permissions */
- mutex_enter(&dcp->c_statelock);
- error = cachefs_access_local(dcp, (VEXEC|VWRITE), cr);
- mutex_exit(&dcp->c_statelock);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- if (error)
- break;
-
- namlen = strlen(nm);
- if (namlen == 0) {
- error = EINVAL;
- break;
- }
-
- /* cannot remove . and .. */
- if (nm[0] == '.') {
- if (namlen == 1) {
- error = EINVAL;
- break;
- } else if (namlen == 2 && nm[1] == '.') {
- error = EEXIST;
- break;
- }
- }
-
- }
-
- /* get the cnode of the dir to remove */
- error = cachefs_lookup_common(dvp, nm, &vp, NULL, 0, NULL, cr);
- if (error) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- /* must be a dir */
- if (vp->v_type != VDIR) {
- error = ENOTDIR;
- break;
- }
-
- /* must not be current dir */
- if (VOP_CMP(vp, cdir, ct)) {
- error = EINVAL;
- break;
- }
-
- /* see ufs_dirremove for why this is done, mount race */
- if (vn_vfswlock(vp)) {
- error = EBUSY;
- break;
- }
- vfslock = 1;
- if (vn_mountedvfs(vp) != NULL) {
- error = EBUSY;
- break;
- }
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_rmdir_connected(dvp, nm, cdir,
- cr, vp);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_rmdir_disconnected(dvp, nm, cdir,
- cr, vp);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_RMDIR)) {
- ino64_t fileno = 0;
- fid_t *fidp = NULL;
- cnode_t *cp = NULL;
- if (vp)
- cp = VTOC(vp);
-
- if (cp != NULL) {
- fidp = &cp->c_metadata.md_cookie;
- fileno = cp->c_id.cid_fileno;
- }
-
- cachefs_log_rmdir(cachep, error, fscp->fs_cfsvfsp,
- fidp, fileno, crgetuid(cr));
- }
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-
- if (vfslock)
- vn_vfsunlock(vp);
-
- if (vp)
- VN_RELE(vp);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_rmdir: EXIT error = %d\n", error);
-#endif
-
- return (error);
-}
-
-static int
-cachefs_rmdir_connected(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr,
- vnode_t *vp)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp = VTOC(vp);
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(dcp);
-
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- mutex_enter(&dcp->c_statelock);
- mutex_enter(&cp->c_statelock);
-
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error)
- goto out;
-
- /* rmdir on the back fs */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_rmdir (nfsv4): dcp %p, dbackvp %p, "
- "name %s\n", dcp, dcp->c_backvp, nm));
- error = VOP_RMDIR(dcp->c_backvp, nm, cdir, cr, NULL, 0);
- if (error)
- goto out;
-
- /* if the dir is populated, remove the entry from it */
- if (CFS_ISFS_NONSHARED(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_rmentry(dcp, nm);
- if (error) {
- cachefs_nocache(dcp);
- error = 0;
- }
- }
-
- /*
- * *if* the (hard) link count goes to 0, then we set the CDESTROY
- * flag on the cnode. The cached object will then be destroyed
- * at inactive time where the chickens come home to roost :-)
- * The link cnt for directories is bumped down by 2 'cause the "."
- * entry has to be elided too ! The link cnt for the parent goes down
- * by 1 (because of "..").
- */
- cp->c_attr.va_nlink -= 2;
- dcp->c_attr.va_nlink--;
- if (cp->c_attr.va_nlink == 0) {
- cp->c_flags |= CN_DESTROY;
- } else {
- cp->c_flags |= CN_UPDATED;
- }
- dcp->c_flags |= CN_UPDATED;
-
- dnlc_purge_vp(vp);
- CFSOP_MODIFY_COBJECT(fscp, dcp, cr);
-
-out:
- mutex_exit(&cp->c_statelock);
- mutex_exit(&dcp->c_statelock);
- rw_exit(&dcp->c_rwlock);
-
- return (error);
-}
-
-static int
-/*ARGSUSED*/
-cachefs_rmdir_disconnected(vnode_t *dvp, char *nm, vnode_t *cdir,
- cred_t *cr, vnode_t *vp)
-{
- cnode_t *dcp = VTOC(dvp);
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
- off_t commit = 0;
- timestruc_t current_time;
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- mutex_enter(&dcp->c_statelock);
- mutex_enter(&cp->c_statelock);
-
- /* both directories must be populated */
- if (((dcp->c_metadata.md_flags & MD_POPULATED) == 0) ||
- ((cp->c_metadata.md_flags & MD_POPULATED) == 0)) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* if sticky bit set on the dir, more access checks to perform */
- if (error = cachefs_stickyrmchk(dcp, cp, cr)) {
- goto out;
- }
-
- /* make sure dir is empty */
- if (cp->c_attr.va_nlink > 2) {
- error = cachefs_dir_empty(cp);
- if (error) {
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- goto out;
- }
- cachefs_modified(cp);
- }
- cachefs_modified(dcp);
-
- /* log the operation */
- commit = cachefs_dlog_rmdir(fscp, dcp, nm, cp, cr);
- if (commit == 0) {
- error = ENOSPC;
- goto out;
- }
-
- /* remove name from parent dir */
- error = cachefs_dir_rmentry(dcp, nm);
- if (error == ENOTDIR) {
- error = ETIMEDOUT;
- goto out;
- }
- if (error)
- goto out;
-
- gethrestime(&current_time);
-
- /* update deleted dir values */
- cp->c_attr.va_nlink -= 2;
- if (cp->c_attr.va_nlink == 0)
- cp->c_flags |= CN_DESTROY;
- else {
- cp->c_metadata.md_localctime = current_time;
- cp->c_metadata.md_flags |= MD_LOCALCTIME;
- cp->c_flags |= CN_UPDATED;
- }
-
- /* update parent values */
- dcp->c_metadata.md_localctime = current_time;
- dcp->c_metadata.md_localmtime = current_time;
- dcp->c_metadata.md_flags |= MD_LOCALCTIME | MD_LOCALMTIME;
- dcp->c_attr.va_nlink--;
- dcp->c_flags |= CN_UPDATED;
-
-out:
- mutex_exit(&cp->c_statelock);
- mutex_exit(&dcp->c_statelock);
- rw_exit(&dcp->c_rwlock);
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- dnlc_purge_vp(vp);
- }
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_symlink(vnode_t *dvp, char *lnm, vattr_t *tva,
- char *tnm, cred_t *cr, caller_context_t *ct, int flags)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_symlink: ENTER dvp %p lnm %s tnm %s\n",
- (void *)dvp, lnm, tnm);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_cache->c_flags & CACHE_NOCACHE)
- ASSERT(dcp->c_flags & CN_NOCACHE);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the symlink operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- rw_enter(&dcp->c_rwlock, RW_WRITER);
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_symlink_connected(dvp, lnm, tva,
- tnm, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_symlink_disconnected(dvp, lnm, tva,
- tnm, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_SYMLINK))
- cachefs_log_symlink(cachep, error, fscp->fs_cfsvfsp,
- &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno,
- crgetuid(cr), (uint_t)strlen(tnm));
-
- if (held) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_symlink: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-static int
-cachefs_symlink_connected(vnode_t *dvp, char *lnm, vattr_t *tva,
- char *tnm, cred_t *cr)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error = 0;
- vnode_t *backvp = NULL;
- cnode_t *newcp = NULL;
- struct vattr va;
- struct fid cookie;
- cfs_cid_t cid;
- uint32_t valid_fid;
-
- mutex_enter(&dcp->c_statelock);
-
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error) {
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_symlink (nfsv4): dcp %p, dbackvp %p, "
- "lnm %s, tnm %s\n", dcp, dcp->c_backvp, lnm, tnm));
- error = VOP_SYMLINK(dcp->c_backvp, lnm, tva, tnm, cr, NULL, 0);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- if ((dcp->c_filegrp->fg_flags & CFS_FG_WRITE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- CFSOP_MODIFY_COBJECT(fscp, dcp, cr);
-
- /* lookup the symlink we just created and get its fid and attrs */
- (void) VOP_LOOKUP(dcp->c_backvp, lnm, &backvp, NULL, 0, NULL, cr,
- NULL, NULL, NULL);
- if (backvp == NULL) {
- if (CFS_ISFS_BACKFS_NFSV4(fscp) == 0)
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- valid_fid = (CFS_ISFS_BACKFS_NFSV4(fscp) ? FALSE : TRUE);
- error = cachefs_getcookie(backvp, &cookie, &va, cr, valid_fid);
- if (error) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = 0;
- cachefs_nocache(dcp);
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- cid.cid_fileno = va.va_nodeid;
- cid.cid_flags = 0;
-
- /* if the dir is cached, add the symlink to it */
- if (CFS_ISFS_NONSHARED(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- error = cachefs_dir_enter(dcp, lnm, &cookie, &cid, SM_ASYNC);
- if (error) {
- cachefs_nocache(dcp);
- error = 0;
- }
- }
- mutex_exit(&dcp->c_statelock);
-
- /* make the cnode for the sym link */
- error = cachefs_cnode_make(&cid, fscp, (valid_fid ? &cookie : NULL),
- &va, backvp, cr, 0, &newcp);
- if (error) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_nocache(dcp);
- error = 0;
- goto out;
- }
-
- /* try to cache the symlink contents */
- rw_enter(&newcp->c_rwlock, RW_WRITER);
- mutex_enter(&newcp->c_statelock);
-
- /*
- * try to cache the sym link, note that its a noop if NOCACHE
- * or NFSv4 is set
- */
- error = cachefs_stuffsymlink(newcp, tnm, (int)newcp->c_size);
- if (error) {
- cachefs_nocache(newcp);
- error = 0;
- }
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
-
-out:
- if (backvp)
- VN_RELE(backvp);
- if (newcp)
- VN_RELE(CTOV(newcp));
- return (error);
-}
-
-static int
-cachefs_symlink_disconnected(vnode_t *dvp, char *lnm, vattr_t *tva,
- char *tnm, cred_t *cr)
-{
- cnode_t *dcp = VTOC(dvp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- int error;
- cnode_t *newcp = NULL;
- struct vattr va;
- timestruc_t current_time;
- off_t commit = 0;
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- mutex_enter(&dcp->c_statelock);
-
- /* check permissions */
- if (error = cachefs_access_local(dcp, (VEXEC|VWRITE), cr)) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* the directory front file must be populated */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* make sure lnm does not already exist in the directory */
- error = cachefs_dir_look(dcp, lnm, NULL, NULL, NULL, NULL);
- if (error == ENOTDIR) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- if (error != ENOENT) {
- error = EEXIST;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* make up a reasonable set of attributes */
- cachefs_attr_setup(tva, &va, dcp, cr);
- va.va_type = VLNK;
- va.va_mode |= S_IFLNK;
- va.va_size = strlen(tnm);
-
- mutex_exit(&dcp->c_statelock);
-
- /* create the cnode */
- error = cachefs_cnode_create(fscp, &va, 0, &newcp);
- if (error)
- goto out;
-
- rw_enter(&newcp->c_rwlock, RW_WRITER);
- mutex_enter(&newcp->c_statelock);
-
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- error = ENOSPC;
- goto out;
- }
-
- cachefs_creategid(dcp, newcp, tva, cr);
- mutex_enter(&dcp->c_statelock);
- cachefs_createacl(dcp, newcp);
- mutex_exit(&dcp->c_statelock);
- gethrestime(&current_time);
- newcp->c_metadata.md_vattr.va_atime = current_time;
- newcp->c_metadata.md_localctime = current_time;
- newcp->c_metadata.md_localmtime = current_time;
- newcp->c_metadata.md_flags |= MD_MAPPING | MD_LOCALMTIME |
- MD_LOCALCTIME;
- newcp->c_flags |= CN_UPDATED;
-
- /* log the operation */
- commit = cachefs_dlog_symlink(fscp, dcp, newcp, lnm, tva, tnm, cr);
- if (commit == 0) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- error = ENOSPC;
- goto out;
- }
-
- /* store the symlink contents */
- error = cachefs_stuffsymlink(newcp, tnm, (int)newcp->c_size);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- goto out;
- }
- if (cachefs_modified_alloc(newcp)) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- error = ENOSPC;
- goto out;
- }
-
- /*
- * write the metadata now rather than waiting until
- * inactive so that if there's no space we can let
- * the caller know.
- */
- if (newcp->c_flags & CN_ALLOC_PENDING) {
- if (newcp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(newcp->c_filegrp);
- }
- error = filegrp_create_metadata(newcp->c_filegrp,
- &newcp->c_metadata, &newcp->c_id);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- goto out;
- }
- newcp->c_flags &= ~CN_ALLOC_PENDING;
- }
- error = filegrp_write_metadata(newcp->c_filegrp,
- &newcp->c_id, &newcp->c_metadata);
- if (error) {
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
- goto out;
- }
- mutex_exit(&newcp->c_statelock);
- rw_exit(&newcp->c_rwlock);
-
- mutex_enter(&dcp->c_statelock);
-
- /* enter the new file in the directory */
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
- cachefs_modified(dcp);
- error = cachefs_dir_enter(dcp, lnm, &newcp->c_metadata.md_cookie,
- &newcp->c_id, SM_ASYNC);
- if (error) {
- mutex_exit(&dcp->c_statelock);
- goto out;
- }
-
- /* update parent dir times */
- dcp->c_metadata.md_localctime = current_time;
- dcp->c_metadata.md_localmtime = current_time;
- dcp->c_metadata.md_flags |= MD_LOCALMTIME | MD_LOCALCTIME;
- dcp->c_flags |= CN_UPDATED;
- mutex_exit(&dcp->c_statelock);
-
-out:
- if (commit) {
- /* commit the log entry */
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX bob: fix on panic */
- }
- }
-
- if (error) {
- if (newcp) {
- mutex_enter(&newcp->c_statelock);
- newcp->c_flags |= CN_DESTROY;
- mutex_exit(&newcp->c_statelock);
- }
- }
- if (newcp) {
- VN_RELE(CTOV(newcp));
- }
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
- caller_context_t *ct, int flags)
-{
- cnode_t *dcp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_readdir: ENTER vp %p\n", (void *)vp);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the readdir operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(dcp);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- rw_enter(&dcp->c_rwlock, RW_READER);
- held = 1;
-
- /* quit if link count of zero (posix) */
- if (dcp->c_attr.va_nlink == 0) {
- if (eofp)
- *eofp = 1;
- error = 0;
- break;
- }
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_readdir_connected(vp, uiop, cr,
- eofp);
- if (CFS_TIMEOUT(fscp, error)) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_readdir_disconnected(vp, uiop, cr,
- eofp);
- if (CFS_TIMEOUT(fscp, error)) {
- if (cachefs_cd_access_miss(fscp)) {
- error = cachefs_readdir_connected(vp,
- uiop, cr, eofp);
- if (!CFS_TIMEOUT(fscp, error))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_READDIR))
- cachefs_log_readdir(cachep, error, fscp->fs_cfsvfsp,
- &dcp->c_metadata.md_cookie, dcp->c_id.cid_fileno,
- crgetuid(cr), uiop->uio_loffset, *eofp);
-
- if (held) {
- rw_exit(&dcp->c_rwlock);
- cachefs_cd_release(fscp);
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_readdir: EXIT error = %d\n", error);
-#endif
-
- return (error);
-}
-
-static int
-cachefs_readdir_connected(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp)
-{
- cnode_t *dcp = VTOC(vp);
- int error;
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- struct cachefs_req *rp;
-
- mutex_enter(&dcp->c_statelock);
-
- /* check directory consistency */
- error = CFSOP_CHECK_COBJECT(fscp, dcp, 0, cr);
- if (error)
- goto out;
- dcp->c_usage++;
-
- /* if dir was modified, toss old contents */
- if (dcp->c_metadata.md_flags & MD_INVALREADDIR) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_inval_object(dcp);
- }
-
- error = 0;
- if (((dcp->c_metadata.md_flags & MD_POPULATED) == 0) &&
- ((dcp->c_flags & (CN_ASYNC_POPULATE | CN_NOCACHE)) == 0) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp) &&
- (fscp->fs_cdconnected == CFS_CD_CONNECTED)) {
-
- if (cachefs_async_okay()) {
-
- /*
- * Set up asynchronous request to fill this
- * directory.
- */
-
- dcp->c_flags |= CN_ASYNC_POPULATE;
-
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- rp->cfs_cmd = CFS_POPULATE;
- rp->cfs_req_u.cu_populate.cpop_vp = vp;
- rp->cfs_cr = cr;
-
- crhold(cr);
- VN_HOLD(vp);
-
- cachefs_addqueue(rp, &fscp->fs_workq);
- } else {
- error = cachefs_dir_fill(dcp, cr);
- if (error != 0)
- cachefs_nocache(dcp);
- }
- }
-
- /* if front file is populated */
- if (((dcp->c_flags & (CN_NOCACHE | CN_ASYNC_POPULATE)) == 0) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp) &&
- (dcp->c_metadata.md_flags & MD_POPULATED)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- error = cachefs_dir_read(dcp, uiop, eofp);
- if (error == 0)
- fscp->fs_stats.st_hits++;
- }
-
- /* if front file could not be used */
- if ((error != 0) ||
- CFS_ISFS_BACKFS_NFSV4(fscp) ||
- (dcp->c_flags & (CN_NOCACHE | CN_ASYNC_POPULATE)) ||
- ((dcp->c_metadata.md_flags & MD_POPULATED) == 0)) {
-
- if (error && !(dcp->c_flags & CN_NOCACHE) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp))
- cachefs_nocache(dcp);
-
- /* get the back vp */
- if (dcp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, dcp);
- if (error)
- goto out;
- }
-
- if (fscp->fs_inum_size > 0) {
- error = cachefs_readback_translate(dcp, uiop, cr, eofp);
- } else {
- /* do the dir read from the back fs */
- (void) VOP_RWLOCK(dcp->c_backvp,
- V_WRITELOCK_FALSE, NULL);
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_readdir (nfsv4): "
- "dcp %p, dbackvp %p\n", dcp, dcp->c_backvp));
- error = VOP_READDIR(dcp->c_backvp, uiop, cr, eofp,
- NULL, 0);
- VOP_RWUNLOCK(dcp->c_backvp, V_WRITELOCK_FALSE, NULL);
- }
-
- if (error == 0)
- fscp->fs_stats.st_misses++;
- }
-
-out:
- mutex_exit(&dcp->c_statelock);
-
- return (error);
-}
-
-static int
-cachefs_readback_translate(cnode_t *cp, uio_t *uiop, cred_t *cr, int *eofp)
-{
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- caddr_t buffy = NULL;
- int buffysize = MAXBSIZE;
- caddr_t chrp, end;
- ino64_t newinum;
- struct dirent64 *de;
- uio_t uioin;
- iovec_t iov;
-
- ASSERT(cp->c_backvp != NULL);
- ASSERT(fscp->fs_inum_size > 0);
-
- if (uiop->uio_resid < buffysize)
- buffysize = (int)uiop->uio_resid;
- buffy = cachefs_kmem_alloc(buffysize, KM_SLEEP);
-
- iov.iov_base = buffy;
- iov.iov_len = buffysize;
- uioin.uio_iov = &iov;
- uioin.uio_iovcnt = 1;
- uioin.uio_segflg = UIO_SYSSPACE;
- uioin.uio_fmode = 0;
- uioin.uio_extflg = UIO_COPY_CACHED;
- uioin.uio_loffset = uiop->uio_loffset;
- uioin.uio_resid = buffysize;
-
- (void) VOP_RWLOCK(cp->c_backvp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READDIR(cp->c_backvp, &uioin, cr, eofp, NULL, 0);
- VOP_RWUNLOCK(cp->c_backvp, V_WRITELOCK_FALSE, NULL);
-
- if (error != 0)
- goto out;
-
- end = buffy + buffysize - uioin.uio_resid;
-
- mutex_exit(&cp->c_statelock);
- mutex_enter(&fscp->fs_fslock);
-
-
- for (chrp = buffy; chrp < end; chrp += de->d_reclen) {
- de = (dirent64_t *)chrp;
- newinum = cachefs_inum_real2fake(fscp, de->d_ino);
- if (newinum == 0)
- newinum = cachefs_fileno_conflict(fscp, de->d_ino);
- de->d_ino = newinum;
- }
- mutex_exit(&fscp->fs_fslock);
- mutex_enter(&cp->c_statelock);
-
- error = uiomove(buffy, end - buffy, UIO_READ, uiop);
- uiop->uio_loffset = uioin.uio_loffset;
-
-out:
-
- if (buffy != NULL)
- cachefs_kmem_free(buffy, buffysize);
-
- return (error);
-}
-
-static int
-/*ARGSUSED*/
-cachefs_readdir_disconnected(vnode_t *vp, uio_t *uiop, cred_t *cr,
- int *eofp)
-{
- cnode_t *dcp = VTOC(vp);
- int error;
-
- mutex_enter(&dcp->c_statelock);
- if ((dcp->c_metadata.md_flags & MD_POPULATED) == 0) {
- error = ETIMEDOUT;
- } else {
- error = cachefs_dir_read(dcp, uiop, eofp);
- if (error == ENOTDIR)
- error = ETIMEDOUT;
- }
- mutex_exit(&dcp->c_statelock);
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
-{
- int error = 0;
- struct cnode *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions, then bail
- * as NFSv4 doesn't support VOP_FID.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- return (ENOTSUP);
- }
-
- mutex_enter(&cp->c_statelock);
- if (fidp->fid_len < cp->c_metadata.md_cookie.fid_len) {
- fidp->fid_len = cp->c_metadata.md_cookie.fid_len;
- error = ENOSPC;
- } else {
- bcopy(cp->c_metadata.md_cookie.fid_data, fidp->fid_data,
- cp->c_metadata.md_cookie.fid_len);
- fidp->fid_len = cp->c_metadata.md_cookie.fid_len;
- }
- mutex_exit(&cp->c_statelock);
- return (error);
-}
-
-/* ARGSUSED2 */
-static int
-cachefs_rwlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
-{
- cnode_t *cp = VTOC(vp);
-
- /*
- * XXX - This is ifdef'ed out for now. The problem -
- * getdents() acquires the read version of rwlock, then we come
- * into cachefs_readdir() and that wants to acquire the write version
- * of this lock (if its going to populate the directory). This is
- * a problem, this can be solved by introducing another lock in the
- * cnode.
- */
-/* XXX */
- if (vp->v_type != VREG)
- return (-1);
- if (write_lock)
- rw_enter(&cp->c_rwlock, RW_WRITER);
- else
- rw_enter(&cp->c_rwlock, RW_READER);
- return (write_lock);
-}
-
-/* ARGSUSED */
-static void
-cachefs_rwunlock(struct vnode *vp, int write_lock, caller_context_t *ctp)
-{
- cnode_t *cp = VTOC(vp);
- if (vp->v_type != VREG)
- return;
- rw_exit(&cp->c_rwlock);
-}
-
-/* ARGSUSED */
-static int
-cachefs_seek(struct vnode *vp, offset_t ooff, offset_t *noffp,
- caller_context_t *ct)
-{
- return (0);
-}
-
-static int cachefs_lostpage = 0;
-/*
- * Return all the pages from [off..off+len] in file
- */
-/*ARGSUSED*/
-static int
-cachefs_getpage(struct vnode *vp, offset_t off, size_t len,
- uint_t *protp, struct page *pl[], size_t plsz, struct seg *seg,
- caddr_t addr, enum seg_rw rw, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- int error;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- int held = 0;
- int connected = 0;
-
-#ifdef CFSDEBUG
- u_offset_t offx = (u_offset_t)off;
-
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getpage: ENTER vp %p off %lld len %lu rw %d\n",
- (void *)vp, offx, len, rw);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (vp->v_flag & VNOMAP) {
- error = ENOSYS;
- goto out;
- }
-
- /* Call backfilesystem if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_getpage_backfs_nfsv4(vp, off, len, protp, pl,
- plsz, seg, addr, rw, cr);
- goto out;
- }
-
- /* XXX sam: make this do an async populate? */
- if (pl == NULL) {
- error = 0;
- goto out;
- }
- if (protp != NULL)
- *protp = PROT_ALL;
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- /*
- * If we are getting called as a side effect of a
- * cachefs_write()
- * operation the local file size might not be extended yet.
- * In this case we want to be able to return pages of zeroes.
- */
- if ((u_offset_t)off + len >
- ((cp->c_size + PAGEOFFSET) & (offset_t)PAGEMASK)) {
- if (seg != segkmap) {
- error = EFAULT;
- break;
- }
- }
- error = pvn_getpages(cachefs_getapage, vp, (u_offset_t)off,
- len, protp, pl, plsz, seg, addr, rw, cr);
- if (error == 0)
- break;
-
- if (((cp->c_flags & CN_NOCACHE) && (error == ENOSPC)) ||
- error == EAGAIN) {
- connected = 0;
- continue;
- }
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (CFS_TIMEOUT(fscp, error)) {
- if (cachefs_cd_access_miss(fscp)) {
- error = pvn_getpages(
- cachefs_getapage_back, vp,
- (u_offset_t)off, len, protp, pl,
- plsz, seg, addr, rw, cr);
- if (!CFS_TIMEOUT(fscp, error) &&
- (error != EAGAIN))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_GETPAGE))
- cachefs_log_getpage(cachep, error, vp->v_vfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- crgetuid(cr), off, len);
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-
-out:
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getpage: EXIT vp %p error %d\n",
- (void *)vp, error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_getpage_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the getpage (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_getpage_backfs_nfsv4(struct vnode *vp, offset_t off, size_t len,
- uint_t *protp, struct page *pl[], size_t plsz,
- struct seg *seg, caddr_t addr, enum seg_rw rw,
- cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation is
- * supported, the cnode backvp must exist, and cachefs optional
- * (eg., disconnectable) flags are turned off. Assert these
- * conditions for the getpage operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_getpage_backfs_nfsv4: cnode %p, backvp %p\n",
- cp, backvp));
- error = VOP_GETPAGE(backvp, off, len, protp, pl, plsz, seg,
- addr, rw, cr, NULL);
-
- return (error);
-}
-
-/*
- * Called from pvn_getpages to get a particular page.
- */
-/*ARGSUSED*/
-static int
-cachefs_getapage(struct vnode *vp, u_offset_t off, size_t len, uint_t *protp,
- struct page *pl[], size_t plsz, struct seg *seg, caddr_t addr,
- enum seg_rw rw, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- page_t **ppp, *pp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
- int error = 0;
- struct page **ourpl;
- struct page *ourstackpl[17]; /* see ASSERT() below for 17 */
- int index = 0;
- int downgrade;
- int have_statelock = 0;
- u_offset_t popoff;
- size_t popsize = 0;
-
- /*LINTED*/
- ASSERT(((DEF_POP_SIZE / PAGESIZE) + 1) <= 17);
-
- if (fscp->fs_info.fi_popsize > DEF_POP_SIZE)
- ourpl = cachefs_kmem_alloc(sizeof (struct page *) *
- ((fscp->fs_info.fi_popsize / PAGESIZE) + 1), KM_SLEEP);
- else
- ourpl = ourstackpl;
-
- ourpl[0] = NULL;
- off = off & (offset_t)PAGEMASK;
-again:
- /*
- * Look for the page
- */
- if (page_exists(vp, off) == 0) {
- /*
- * Need to do work to get the page.
- * Grab our lock because we are going to
- * modify the state of the cnode.
- */
- if (! have_statelock) {
- mutex_enter(&cp->c_statelock);
- have_statelock = 1;
- }
- /*
- * If we're in NOCACHE mode, we will need a backvp
- */
- if (cp->c_flags & CN_NOCACHE) {
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- error = ETIMEDOUT;
- goto out;
- }
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
- error = VOP_GETPAGE(cp->c_backvp, off,
- PAGESIZE, protp, ourpl, PAGESIZE, seg,
- addr, S_READ, cr, NULL);
- /*
- * backfs returns EFAULT when we are trying for a
- * page beyond EOF but cachefs has the knowledge that
- * it is not beyond EOF be cause cp->c_size is
- * greater then the offset requested.
- */
- if (error == EFAULT) {
- error = 0;
- pp = page_create_va(vp, off, PAGESIZE,
- PG_EXCL | PG_WAIT, seg, addr);
- if (pp == NULL)
- goto again;
- pagezero(pp, 0, PAGESIZE);
- pvn_plist_init(pp, pl, plsz, off, PAGESIZE, rw);
- goto out;
- }
- if (error)
- goto out;
- goto getpages;
- }
- /*
- * We need a front file. If we can't get it,
- * put the cnode in NOCACHE mode and try again.
- */
- if (cp->c_frontvp == NULL) {
- error = cachefs_getfrontfile(cp);
- if (error) {
- cachefs_nocache(cp);
- error = EAGAIN;
- goto out;
- }
- }
- /*
- * Check if the front file needs population.
- * If population is necessary, make sure we have a
- * backvp as well. We will get the page from the backvp.
- * bug 4152459-
- * But if the file system is in disconnected mode
- * and the file is a local file then do not check the
- * allocmap.
- */
- if (((fscp->fs_cdconnected == CFS_CD_CONNECTED) ||
- ((cp->c_metadata.md_flags & MD_LOCALFILENO) == 0)) &&
- (cachefs_check_allocmap(cp, off) == 0)) {
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- error = ETIMEDOUT;
- goto out;
- }
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
- if (cp->c_filegrp->fg_flags & CFS_FG_WRITE) {
- cachefs_cluster_allocmap(off, &popoff,
- &popsize,
- fscp->fs_info.fi_popsize, cp);
- if (popsize != 0) {
- error = cachefs_populate(cp,
- popoff, popsize,
- cp->c_frontvp, cp->c_backvp,
- cp->c_size, cr);
- if (error) {
- cachefs_nocache(cp);
- error = EAGAIN;
- goto out;
- } else {
- cp->c_flags |=
- CN_UPDATED |
- CN_NEED_FRONT_SYNC |
- CN_POPULATION_PENDING;
- }
- popsize = popsize - (off - popoff);
- } else {
- popsize = PAGESIZE;
- }
- }
- /* else XXX assert CN_NOCACHE? */
- error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
- PAGESIZE, protp, ourpl, popsize,
- seg, addr, S_READ, cr, NULL);
- if (error)
- goto out;
- fscp->fs_stats.st_misses++;
- } else {
- if (cp->c_flags & CN_POPULATION_PENDING) {
- error = VOP_FSYNC(cp->c_frontvp, FSYNC, cr,
- NULL);
- cp->c_flags &= ~CN_POPULATION_PENDING;
- if (error) {
- cachefs_nocache(cp);
- error = EAGAIN;
- goto out;
- }
- }
- /*
- * File was populated so we get the page from the
- * frontvp
- */
- error = VOP_GETPAGE(cp->c_frontvp, (offset_t)off,
- PAGESIZE, protp, ourpl, PAGESIZE, seg, addr,
- rw, cr, NULL);
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_GPFRONT))
- cachefs_log_gpfront(cachep, error,
- fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_fileno,
- crgetuid(cr), off, PAGESIZE);
- if (error) {
- cachefs_nocache(cp);
- error = EAGAIN;
- goto out;
- }
- fscp->fs_stats.st_hits++;
- }
-getpages:
- ASSERT(have_statelock);
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- downgrade = 0;
- for (ppp = ourpl; *ppp; ppp++) {
- if ((*ppp)->p_offset < off) {
- index++;
- page_unlock(*ppp);
- continue;
- }
- if (PAGE_SHARED(*ppp)) {
- if (page_tryupgrade(*ppp) == 0) {
- for (ppp = &ourpl[index]; *ppp; ppp++)
- page_unlock(*ppp);
- error = EAGAIN;
- goto out;
- }
- downgrade = 1;
- }
- ASSERT(PAGE_EXCL(*ppp));
- (void) hat_pageunload((*ppp), HAT_FORCE_PGUNLOAD);
- page_rename(*ppp, vp, (*ppp)->p_offset);
- }
- pl[0] = ourpl[index];
- pl[1] = NULL;
- if (downgrade) {
- page_downgrade(ourpl[index]);
- }
- /* Unlock the rest of the pages from the cluster */
- for (ppp = &ourpl[index+1]; *ppp; ppp++)
- page_unlock(*ppp);
- } else {
- ASSERT(! have_statelock);
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- /* XXX SE_SHARED probably isn't what we *always* want */
- if ((pp = page_lookup(vp, off, SE_SHARED)) == NULL) {
- cachefs_lostpage++;
- goto again;
- }
- pl[0] = pp;
- pl[1] = NULL;
- /* XXX increment st_hits? i don't think so, but... */
- }
-
-out:
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- if (fscp->fs_info.fi_popsize > DEF_POP_SIZE)
- cachefs_kmem_free(ourpl, sizeof (struct page *) *
- ((fscp->fs_info.fi_popsize / PAGESIZE) + 1));
- return (error);
-}
-
-/* gets a page but only from the back fs */
-/*ARGSUSED*/
-static int
-cachefs_getapage_back(struct vnode *vp, u_offset_t off, size_t len,
- uint_t *protp, struct page *pl[], size_t plsz, struct seg *seg,
- caddr_t addr, enum seg_rw rw, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- page_t **ppp, *pp = NULL;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- struct page *ourpl[17];
- int index = 0;
- int have_statelock = 0;
- int downgrade;
-
- /*
- * Grab the cnode statelock so the cnode state won't change
- * while we're in here.
- */
- ourpl[0] = NULL;
- off = off & (offset_t)PAGEMASK;
-again:
- if (page_exists(vp, off) == 0) {
- if (! have_statelock) {
- mutex_enter(&cp->c_statelock);
- have_statelock = 1;
- }
-
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
- }
- error = VOP_GETPAGE(cp->c_backvp, (offset_t)off,
- PAGESIZE, protp, ourpl, PAGESIZE, seg,
- addr, S_READ, cr, NULL);
- if (error)
- goto out;
-
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- downgrade = 0;
- for (ppp = ourpl; *ppp; ppp++) {
- if ((*ppp)->p_offset < off) {
- index++;
- page_unlock(*ppp);
- continue;
- }
- if (PAGE_SHARED(*ppp)) {
- if (page_tryupgrade(*ppp) == 0) {
- for (ppp = &ourpl[index]; *ppp; ppp++)
- page_unlock(*ppp);
- error = EAGAIN;
- goto out;
- }
- downgrade = 1;
- }
- ASSERT(PAGE_EXCL(*ppp));
- (void) hat_pageunload((*ppp), HAT_FORCE_PGUNLOAD);
- page_rename(*ppp, vp, (*ppp)->p_offset);
- }
- pl[0] = ourpl[index];
- pl[1] = NULL;
- if (downgrade) {
- page_downgrade(ourpl[index]);
- }
- /* Unlock the rest of the pages from the cluster */
- for (ppp = &ourpl[index+1]; *ppp; ppp++)
- page_unlock(*ppp);
- } else {
- ASSERT(! have_statelock);
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- if ((pp = page_lookup(vp, off, SE_SHARED)) == NULL) {
- cachefs_lostpage++;
- goto again;
- }
- pl[0] = pp;
- pl[1] = NULL;
- }
-
-out:
- if (have_statelock) {
- mutex_exit(&cp->c_statelock);
- have_statelock = 0;
- }
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0;
- int connected = 0;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- /* Call backfilesytem if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_putpage_backfs_nfsv4(vp, off, len, flags, cr);
- goto out;
- }
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- error = cachefs_putpage_common(vp, off, len, flags, cr);
- if (error == 0)
- break;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- if (NOMEMWAIT()) {
- error = 0;
- goto out;
- }
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- break;
- }
-
-out:
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
- return (error);
-}
-
-/*
- * cachefs_putpage_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the putpage (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_putpage_backfs_nfsv4(vnode_t *vp, offset_t off, size_t len, int flags,
- cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation is
- * supported, the cnode backvp must exist, and cachefs optional
- * (eg., disconnectable) flags are turned off. Assert these
- * conditions for the putpage operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_putpage_backfs_nfsv4: cnode %p, backvp %p\n",
- cp, backvp));
- error = VOP_PUTPAGE(backvp, off, len, flags, cr, NULL);
-
- return (error);
-}
-
-/*
- * Flags are composed of {B_INVAL, B_FREE, B_DONTNEED, B_FORCE}
- * If len == 0, do from off to EOF.
- *
- * The normal cases should be len == 0 & off == 0 (entire vp list),
- * len == MAXBSIZE (from segmap_release actions), and len == PAGESIZE
- * (from pageout).
- */
-
-/*ARGSUSED*/
-int
-cachefs_putpage_common(struct vnode *vp, offset_t off, size_t len,
- int flags, cred_t *cr)
-{
- struct cnode *cp = VTOC(vp);
- struct page *pp;
- size_t io_len;
- u_offset_t eoff, io_off;
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- cachefscache_t *cachep = fscp->fs_cache;
-
- if (len == 0 && (flags & B_INVAL) == 0 && vn_is_readonly(vp)) {
- return (0);
- }
- if (!vn_has_cached_data(vp) || (off >= cp->c_size &&
- (flags & B_INVAL) == 0))
- return (0);
-
- /*
- * Should never have cached data for the cachefs vnode
- * if NFSv4 is in use.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- /*
- * If this is an async putpage let a thread handle it.
- */
- if (flags & B_ASYNC) {
- struct cachefs_req *rp;
- int tflags = (flags & ~(B_ASYNC|B_DONTNEED));
-
- if (ttoproc(curthread) == proc_pageout) {
- /*
- * If this is the page daemon we
- * do the push synchronously (Dangerous!) and hope
- * we can free enough to keep running...
- */
- flags &= ~B_ASYNC;
- goto again;
- }
-
- if (! cachefs_async_okay()) {
-
- /*
- * this is somewhat like NFS's behavior. keep
- * the system from thrashing. we've seen
- * cases where async queues get out of
- * control, especially if
- * madvise(MADV_SEQUENTIAL) is done on a large
- * mmap()ed file that is read sequentially.
- */
-
- flags &= ~B_ASYNC;
- goto again;
- }
-
- /*
- * if no flags other than B_ASYNC were set,
- * we coalesce putpage requests into a single one for the
- * whole file (len = off = 0). If such a request is
- * already queued, we're done.
- *
- * If there are other flags set (e.g., B_INVAL), we don't
- * attempt to coalesce and we use the specified length and
- * offset.
- */
- rp = kmem_cache_alloc(cachefs_req_cache, KM_SLEEP);
- mutex_enter(&cp->c_iomutex);
- if ((cp->c_ioflags & CIO_PUTPAGES) == 0 || tflags != 0) {
- rp->cfs_cmd = CFS_PUTPAGE;
- rp->cfs_req_u.cu_putpage.cp_vp = vp;
- if (tflags == 0) {
- off = len = 0;
- cp->c_ioflags |= CIO_PUTPAGES;
- }
- rp->cfs_req_u.cu_putpage.cp_off = off;
- rp->cfs_req_u.cu_putpage.cp_len = (uint_t)len;
- rp->cfs_req_u.cu_putpage.cp_flags = flags & ~B_ASYNC;
- rp->cfs_cr = cr;
- crhold(rp->cfs_cr);
- VN_HOLD(vp);
- cp->c_nio++;
- cachefs_addqueue(rp, &(C_TO_FSCACHE(cp)->fs_workq));
- } else {
- kmem_cache_free(cachefs_req_cache, rp);
- }
-
- mutex_exit(&cp->c_iomutex);
- return (0);
- }
-
-
-again:
- if (len == 0) {
- /*
- * Search the entire vp list for pages >= off
- */
- error = pvn_vplist_dirty(vp, off, cachefs_push, flags, cr);
- } else {
- /*
- * Do a range from [off...off + len] looking for pages
- * to deal with.
- */
- eoff = (u_offset_t)off + len;
- for (io_off = off; io_off < eoff && io_off < cp->c_size;
- io_off += io_len) {
- /*
- * If we are not invalidating, synchronously
- * freeing or writing pages use the routine
- * page_lookup_nowait() to prevent reclaiming
- * them from the free list.
- */
- if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) {
- pp = page_lookup(vp, io_off,
- (flags & (B_INVAL | B_FREE)) ?
- SE_EXCL : SE_SHARED);
- } else {
- /* XXX this looks like dead code */
- pp = page_lookup_nowait(vp, io_off,
- (flags & B_FREE) ? SE_EXCL : SE_SHARED);
- }
-
- if (pp == NULL || pvn_getdirty(pp, flags) == 0)
- io_len = PAGESIZE;
- else {
- error = cachefs_push(vp, pp, &io_off,
- &io_len, flags, cr);
- if (error != 0)
- break;
- /*
- * "io_off" and "io_len" are returned as
- * the range of pages we actually wrote.
- * This allows us to skip ahead more quickly
- * since several pages may've been dealt
- * with by this iteration of the loop.
- */
- }
- }
- }
-
- if (error == 0 && off == 0 && (len == 0 || len >= cp->c_size)) {
- cp->c_flags &= ~CDIRTY;
- }
-
- if (CACHEFS_LOG_LOGGING(cachep, CACHEFS_LOG_PUTPAGE))
- cachefs_log_putpage(cachep, error, fscp->fs_cfsvfsp,
- &cp->c_metadata.md_cookie, cp->c_id.cid_fileno,
- crgetuid(cr), off, len);
-
- return (error);
-
-}
-
-/*ARGSUSED*/
-static int
-cachefs_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
- size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- struct segvn_crargs vn_a;
- int error;
- int held = 0;
- int writing;
- int connected = 0;
-
-#ifdef CFSDEBUG
- u_offset_t offx = (u_offset_t)off;
-
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_map: ENTER vp %p off %lld len %lu flags %d\n",
- (void *)vp, offx, len, flags);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (vp->v_flag & VNOMAP) {
- error = ENOSYS;
- goto out;
- }
- if (off < 0 || (offset_t)(off + len) < 0) {
- error = ENXIO;
- goto out;
- }
- if (vp->v_type != VREG) {
- error = ENODEV;
- goto out;
- }
-
- /*
- * Check to see if the vnode is currently marked as not cachable.
- * If so, we have to refuse the map request as this violates the
- * don't cache attribute.
- */
- if (vp->v_flag & VNOCACHE)
- return (EAGAIN);
-
-#ifdef OBSOLETE
- /*
- * If file is being locked, disallow mapping.
- */
- if (vn_has_flocks(vp)) {
- error = EAGAIN;
- goto out;
- }
-#endif
-
- /* call backfilesystem if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_map_backfs_nfsv4(vp, off, as, addrp, len, prot,
- maxprot, flags, cr);
- goto out;
- }
-
- writing = (prot & PROT_WRITE && ((flags & MAP_PRIVATE) == 0));
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, writing);
- if (error)
- break;
- held = 1;
-
- if (writing) {
- mutex_enter(&cp->c_statelock);
- if (CFS_ISFS_WRITE_AROUND(fscp)) {
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- connected = 1;
- continue;
- } else {
- cachefs_nocache(cp);
- }
- }
-
- /*
- * CN_MAPWRITE is for an optimization in cachefs_delmap.
- * If CN_MAPWRITE is not set then cachefs_delmap does
- * not need to try to push out any pages.
- * This bit gets cleared when the cnode goes inactive.
- */
- cp->c_flags |= CN_MAPWRITE;
-
- mutex_exit(&cp->c_statelock);
- }
- break;
- }
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-
- as_rangelock(as);
- error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags);
- if (error != 0) {
- as_rangeunlock(as);
- goto out;
- }
-
- /*
- * package up all the data passed in into a segvn_args struct and
- * call as_map with segvn_create function to create a new segment
- * in the address space.
- */
- vn_a.vp = vp;
- vn_a.offset = off;
- vn_a.type = flags & MAP_TYPE;
- vn_a.prot = (uchar_t)prot;
- vn_a.maxprot = (uchar_t)maxprot;
- vn_a.cred = cr;
- vn_a.amp = NULL;
- vn_a.flags = flags & ~MAP_TYPE;
- vn_a.szc = 0;
- vn_a.lgrp_mem_policy_flags = 0;
- error = as_map(as, *addrp, len, segvn_create, &vn_a);
- as_rangeunlock(as);
-out:
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_map: EXIT vp %p error %d\n", (void *)vp, error);
-#endif
- return (error);
-}
-
-/*
- * cachefs_map_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the map (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_map_backfs_nfsv4(struct vnode *vp, offset_t off, struct as *as,
- caddr_t *addrp, size_t len, uchar_t prot,
- uchar_t maxprot, uint_t flags, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation is
- * supported, the cnode backvp must exist, and cachefs optional
- * (eg., disconnectable) flags are turned off. Assert these
- * conditions for the map operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_map_backfs_nfsv4: cnode %p, backvp %p\n",
- cp, backvp));
- error = VOP_MAP(backvp, off, as, addrp, len, prot, maxprot, flags, cr,
- NULL);
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_addmap(struct vnode *vp, offset_t off, struct as *as,
- caddr_t addr, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
- cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- if (vp->v_flag & VNOMAP)
- return (ENOSYS);
-
- /*
- * Check this is not an NFSv4 filesystem, as the mapping
- * is not done on the cachefs filesystem if NFSv4 is in
- * use.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- mutex_enter(&cp->c_statelock);
- cp->c_mapcnt += btopr(len);
- mutex_exit(&cp->c_statelock);
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_delmap(struct vnode *vp, offset_t off, struct as *as,
- caddr_t addr, size_t len, uint_t prot, uint_t maxprot, uint_t flags,
- cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error;
- int connected = 0;
- int held = 0;
-
- /*
- * The file may be passed in to (or inherited into) the zone, so we
- * need to let this operation go through since it happens as part of
- * exiting.
- */
- if (vp->v_flag & VNOMAP)
- return (ENOSYS);
-
- /*
- * Check this is not an NFSv4 filesystem, as the mapping
- * is not done on the cachefs filesystem if NFSv4 is in
- * use.
- */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
-
- mutex_enter(&cp->c_statelock);
- cp->c_mapcnt -= btopr(len);
- ASSERT(cp->c_mapcnt >= 0);
- mutex_exit(&cp->c_statelock);
-
- if (cp->c_mapcnt || !vn_has_cached_data(vp) ||
- ((cp->c_flags & CN_MAPWRITE) == 0))
- return (0);
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
- connected = 0;
-
- error = cachefs_putpage_common(vp, (offset_t)0,
- (uint_t)0, 0, cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- continue;
- } else {
- connected = 1;
- continue;
- }
- }
-
- /* if no space left in cache, wait until connected */
- if ((error == ENOSPC) &&
- (fscp->fs_cdconnected != CFS_CD_CONNECTED)) {
- connected = 1;
- continue;
- }
-
- mutex_enter(&cp->c_statelock);
- if (!error)
- error = cp->c_error;
- cp->c_error = 0;
- mutex_exit(&cp->c_statelock);
- break;
- }
-
- if (held)
- cachefs_cd_release(fscp);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
- return (error);
-}
-
-/* ARGSUSED */
-static int
-cachefs_frlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
- offset_t offset, struct flk_callback *flk_cbp, cred_t *cr,
- caller_context_t *ct)
-{
- struct cnode *cp = VTOC(vp);
- int error;
- struct fscache *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int held = 0;
- int connected = 0;
-
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
-
- if ((cmd != F_GETLK) && (cmd != F_SETLK) && (cmd != F_SETLKW))
- return (EINVAL);
-
- /* Disallow locking of files that are currently mapped */
- if (((cmd == F_SETLK) || (cmd == F_SETLKW)) && (cp->c_mapcnt > 0)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- return (EAGAIN);
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the frlock operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* XXX bob: nfs does a bunch more checks than we do */
- if (CFS_ISFS_LLOCK(fscp)) {
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct));
- }
-
- for (;;) {
- /* get (or renew) access to the file system */
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- /* if not connected, quit or wait */
- if (fscp->fs_cdconnected != CFS_CD_CONNECTED) {
- connected = 1;
- continue;
- }
-
- /* nocache the file */
- if ((cp->c_flags & CN_NOCACHE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- mutex_enter(&cp->c_statelock);
- cachefs_nocache(cp);
- mutex_exit(&cp->c_statelock);
- }
-
- /*
- * XXX bob: probably should do a consistency check
- * Pass arguments unchanged if NFSv4 is the backfs.
- */
- if (bfp->l_whence == 2 && CFS_ISFS_BACKFS_NFSV4(fscp) == 0) {
- bfp->l_start += cp->c_size;
- bfp->l_whence = 0;
- }
-
- /* get the back vp */
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error) {
- mutex_exit(&cp->c_statelock);
- break;
- }
- }
- backvp = cp->c_backvp;
- VN_HOLD(backvp);
- mutex_exit(&cp->c_statelock);
-
- /*
- * make sure we can flush currently dirty pages before
- * allowing the lock
- */
- if (bfp->l_type != F_UNLCK && cmd != F_GETLK &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_putpage(
- vp, (offset_t)0, 0, B_INVAL, cr, ct);
- if (error) {
- error = ENOLCK;
- VN_RELE(backvp);
- break;
- }
- }
-
- /* do lock on the back file */
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_frlock (nfsv4): cp %p, backvp %p\n",
- cp, backvp));
- error = VOP_FRLOCK(backvp, cmd, bfp, flag, offset, NULL, cr,
- ct);
- VN_RELE(backvp);
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- break;
- }
-
- if (held) {
- cachefs_cd_release(fscp);
- }
-
- /*
- * If we are setting a lock mark the vnode VNOCACHE so the page
- * cache does not give inconsistent results on locked files shared
- * between clients. The VNOCACHE flag is never turned off as long
- * as the vnode is active because it is hard to figure out when the
- * last lock is gone.
- * XXX - what if some already has the vnode mapped in?
- * XXX bob: see nfs3_frlock, do not allow locking if vnode mapped in.
- */
- if ((error == 0) && (bfp->l_type != F_UNLCK) && (cmd != F_GETLK) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp))
- vp->v_flag |= VNOCACHE;
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
- return (error);
-}
-
-/*
- * Free storage space associated with the specified vnode. The portion
- * to be freed is specified by bfp->l_start and bfp->l_len (already
- * normalized to a "whence" of 0).
- *
- * This is an experimental facility whose continued existence is not
- * guaranteed. Currently, we only support the special case
- * of l_len == 0, meaning free to end of file.
- */
-/* ARGSUSED */
-static int
-cachefs_space(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
- offset_t offset, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error;
-
- ASSERT(vp->v_type == VREG);
- if (getzoneid() != GLOBAL_ZONEID)
- return (EPERM);
- if (cmd != F_FREESP)
- return (EINVAL);
-
- /* call backfilesystem if NFSv4 */
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_space_backfs_nfsv4(vp, cmd, bfp, flag,
- offset, cr, ct);
- goto out;
- }
-
- if ((error = convoff(vp, bfp, 0, offset)) == 0) {
- ASSERT(bfp->l_start >= 0);
- if (bfp->l_len == 0) {
- struct vattr va;
-
- va.va_size = bfp->l_start;
- va.va_mask = AT_SIZE;
- error = cachefs_setattr(vp, &va, 0, cr, ct);
- } else
- error = EINVAL;
- }
-
-out:
- return (error);
-}
-
-/*
- * cachefs_space_backfs_nfsv4
- *
- * Call NFSv4 back filesystem to handle the space (cachefs
- * pass-through support for NFSv4).
- */
-static int
-cachefs_space_backfs_nfsv4(struct vnode *vp, int cmd, struct flock64 *bfp,
- int flag, offset_t offset, cred_t *cr, caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vnode_t *backvp;
- int error;
-
- /*
- * For NFSv4 pass-through to work, only connected operation is
- * supported, the cnode backvp must exist, and cachefs optional
- * (eg., disconnectable) flags are turned off. Assert these
- * conditions for the space operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- /* Call backfs vnode op after extracting backvp */
- mutex_enter(&cp->c_statelock);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_space_backfs_nfsv4: cnode %p, backvp %p\n",
- cp, backvp));
- error = VOP_SPACE(backvp, cmd, bfp, flag, offset, cr, ct);
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_realvp(struct vnode *vp, struct vnode **vpp, caller_context_t *ct)
-{
- return (EINVAL);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_pageio(struct vnode *vp, page_t *pp, u_offset_t io_off, size_t io_len,
- int flags, cred_t *cr, caller_context_t *ct)
-{
- return (ENOSYS);
-}
-
-static int
-cachefs_setsecattr_connected(cnode_t *cp,
- vsecattr_t *vsec, int flag, cred_t *cr)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
-
- ASSERT(RW_WRITE_HELD(&cp->c_rwlock));
- ASSERT((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0);
-
- mutex_enter(&cp->c_statelock);
-
- if (cp->c_backvp == NULL) {
- error = cachefs_getbackvp(fscp, cp);
- if (error) {
- cachefs_nocache(cp);
- goto out;
- }
- }
-
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error)
- goto out;
-
- /* only owner can set acl */
- if (cp->c_metadata.md_vattr.va_uid != crgetuid(cr)) {
- error = EINVAL;
- goto out;
- }
-
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_setsecattr (nfsv4): cp %p, backvp %p",
- cp, cp->c_backvp));
- error = VOP_SETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
- if (error) {
- goto out;
- }
-
- if ((cp->c_filegrp->fg_flags & CFS_FG_WRITE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- cachefs_nocache(cp);
- goto out;
- }
-
- CFSOP_MODIFY_COBJECT(fscp, cp, cr);
-
- /* acl may have changed permissions -- handle this. */
- if (!CFS_ISFS_BACKFS_NFSV4(fscp))
- cachefs_acl2perm(cp, vsec);
-
- if ((cp->c_flags & CN_NOCACHE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_cacheacl(cp, vsec);
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_setacl: cacheacl: error %d\n",
- error);
-#endif /* CFSDEBUG */
- error = 0;
- cachefs_nocache(cp);
- }
- }
-
-out:
- mutex_exit(&cp->c_statelock);
-
- return (error);
-}
-
-static int
-cachefs_setsecattr_disconnected(cnode_t *cp,
- vsecattr_t *vsec, int flag, cred_t *cr)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- mode_t failmode = cp->c_metadata.md_vattr.va_mode;
- off_t commit = 0;
- int error = 0;
-
- ASSERT((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0);
-
- if (CFS_ISFS_WRITE_AROUND(fscp))
- return (ETIMEDOUT);
-
- mutex_enter(&cp->c_statelock);
-
- /* only owner can set acl */
- if (cp->c_metadata.md_vattr.va_uid != crgetuid(cr)) {
- error = EINVAL;
- goto out;
- }
-
- if (cp->c_metadata.md_flags & MD_NEEDATTRS) {
- error = ETIMEDOUT;
- goto out;
- }
-
- /* XXX do i need this? is this right? */
- if (cp->c_flags & CN_ALLOC_PENDING) {
- if (cp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(cp->c_filegrp);
- }
- error = filegrp_create_metadata(cp->c_filegrp,
- &cp->c_metadata, &cp->c_id);
- if (error) {
- goto out;
- }
- cp->c_flags &= ~CN_ALLOC_PENDING;
- }
-
- /* XXX is this right? */
- if ((cp->c_metadata.md_flags & MD_MAPPING) == 0) {
- error = cachefs_dlog_cidmap(fscp);
- if (error) {
- error = ENOSPC;
- goto out;
- }
- cp->c_metadata.md_flags |= MD_MAPPING;
- cp->c_flags |= CN_UPDATED;
- }
-
- commit = cachefs_dlog_setsecattr(fscp, vsec, flag, cp, cr);
- if (commit == 0)
- goto out;
-
- /* fix modes in metadata */
- cachefs_acl2perm(cp, vsec);
-
- if ((cp->c_flags & CN_NOCACHE) == 0) {
- error = cachefs_cacheacl(cp, vsec);
- if (error != 0) {
- goto out;
- }
- }
-
- /* XXX is this right? */
- if (cachefs_modified_alloc(cp)) {
- error = ENOSPC;
- goto out;
- }
-
-out:
- if (error != 0)
- cp->c_metadata.md_vattr.va_mode = failmode;
-
- mutex_exit(&cp->c_statelock);
-
- if (commit) {
- if (cachefs_dlog_commit(fscp, commit, error)) {
- /*EMPTY*/
- /* XXX fix on panic? */
- }
- }
-
- return (error);
-}
-
-/*ARGSUSED*/
-static int
-cachefs_setsecattr(vnode_t *vp, vsecattr_t *vsec, int flag, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int connected = 0;
- int held = 0;
- int error = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_setsecattr: ENTER vp %p\n", (void *)vp);
-#endif
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- if (fscp->fs_info.fi_mntflags & CFS_NOACL) {
- error = ENOSYS;
- goto out;
- }
-
- if (! cachefs_vtype_aclok(vp)) {
- error = EINVAL;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the setsecattr operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- for (;;) {
- /* drop hold on file system */
- if (held) {
- /* Won't loop with NFSv4 connected operation */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
-
- /* acquire access to the file system */
- error = cachefs_cd_access(fscp, connected, 1);
- if (error)
- break;
- held = 1;
-
- /* perform the setattr */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_setsecattr_connected(cp,
- vsec, flag, cr);
- else
- error = cachefs_setsecattr_disconnected(cp,
- vsec, flag, cr);
- if (error) {
- /* if connected */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- }
-
- /* else must be disconnected */
- else {
- if (CFS_TIMEOUT(fscp, error)) {
- connected = 1;
- continue;
- }
- }
- }
- break;
- }
-
- if (held) {
- cachefs_cd_release(fscp);
- }
- return (error);
-
-out:
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_setsecattr: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-/*
- * call this BEFORE calling cachefs_cacheacl(), as the latter will
- * sanitize the acl.
- */
-
-static void
-cachefs_acl2perm(cnode_t *cp, vsecattr_t *vsec)
-{
- aclent_t *aclp;
- int i;
-
- for (i = 0; i < vsec->vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsec->vsa_aclentp) + i;
- switch (aclp->a_type) {
- case USER_OBJ:
- cp->c_metadata.md_vattr.va_mode &= (~0700);
- cp->c_metadata.md_vattr.va_mode |= (aclp->a_perm << 6);
- break;
-
- case GROUP_OBJ:
- cp->c_metadata.md_vattr.va_mode &= (~070);
- cp->c_metadata.md_vattr.va_mode |= (aclp->a_perm << 3);
- break;
-
- case OTHER_OBJ:
- cp->c_metadata.md_vattr.va_mode &= (~07);
- cp->c_metadata.md_vattr.va_mode |= (aclp->a_perm);
- break;
-
- case CLASS_OBJ:
- cp->c_metadata.md_aclclass = aclp->a_perm;
- break;
- }
- }
-
- cp->c_flags |= CN_UPDATED;
-}
-
-static int
-cachefs_getsecattr(vnode_t *vp, vsecattr_t *vsec, int flag, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int held = 0, connected = 0;
- int error = 0;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getsecattr: ENTER vp %p\n", (void *)vp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the getsecattr operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- if (fscp->fs_info.fi_mntflags & CFS_NOACL) {
- error = fs_fab_acl(vp, vsec, flag, cr, ct);
- goto out;
- }
-
- for (;;) {
- if (held) {
- /* Won't loop with NFSv4 connected behavior */
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- cachefs_cd_release(fscp);
- held = 0;
- }
- error = cachefs_cd_access(fscp, connected, 0);
- if (error)
- break;
- held = 1;
-
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED) {
- error = cachefs_getsecattr_connected(vp, vsec, flag,
- cr);
- if (CFS_TIMEOUT(fscp, error)) {
- cachefs_cd_release(fscp);
- held = 0;
- cachefs_cd_timedout(fscp);
- connected = 0;
- continue;
- }
- } else {
- error = cachefs_getsecattr_disconnected(vp, vsec, flag,
- cr);
- if (CFS_TIMEOUT(fscp, error)) {
- if (cachefs_cd_access_miss(fscp)) {
- error = cachefs_getsecattr_connected(vp,
- vsec, flag, cr);
- if (!CFS_TIMEOUT(fscp, error))
- break;
- delay(5*hz);
- connected = 0;
- continue;
- }
- connected = 1;
- continue;
- }
- }
- break;
- }
-
-out:
- if (held)
- cachefs_cd_release(fscp);
-
-#ifdef CFS_CD_DEBUG
- ASSERT((curthread->t_flag & T_CD_HELD) == 0);
-#endif
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getsecattr: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-static int
-cachefs_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr,
- caller_context_t *ct)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error = 0;
- vnode_t *backvp;
-
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_shrlock: ENTER vp %p\n", (void *)vp);
-#endif
-
- if (getzoneid() != GLOBAL_ZONEID) {
- error = EPERM;
- goto out;
- }
-
- /*
- * Cachefs only provides pass-through support for NFSv4,
- * and all vnode operations are passed through to the
- * back file system. For NFSv4 pass-through to work, only
- * connected operation is supported, the cnode backvp must
- * exist, and cachefs optional (eg., disconnectable) flags
- * are turned off. Assert these conditions to ensure that
- * the backfilesystem is called for the shrlock operation.
- */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(cp);
-
- mutex_enter(&cp->c_statelock);
- if (cp->c_backvp == NULL)
- error = cachefs_getbackvp(fscp, cp);
- backvp = cp->c_backvp;
- mutex_exit(&cp->c_statelock);
- ASSERT((error != 0) || (backvp != NULL));
-
- if (error == 0) {
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_shrlock (nfsv4): cp %p, backvp %p",
- cp, backvp));
- error = VOP_SHRLOCK(backvp, cmd, shr, flag, cr, ct);
- }
-
-out:
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_shrlock: EXIT error = %d\n", error);
-#endif
- return (error);
-}
-
-static int
-cachefs_getsecattr_connected(vnode_t *vp, vsecattr_t *vsec, int flag,
- cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int hit = 0;
- int error = 0;
-
-
- mutex_enter(&cp->c_statelock);
- error = CFSOP_CHECK_COBJECT(fscp, cp, 0, cr);
- if (error)
- goto out;
-
- /* read from the cache if we can */
- if ((cp->c_metadata.md_flags & MD_ACL) &&
- ((cp->c_flags & CN_NOCACHE) == 0) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- ASSERT((cp->c_flags & CN_NOCACHE) == 0);
- error = cachefs_getaclfromcache(cp, vsec);
- if (error) {
- cachefs_nocache(cp);
- ASSERT((cp->c_metadata.md_flags & MD_ACL) == 0);
- error = 0;
- } else {
- hit = 1;
- goto out;
- }
- }
-
- ASSERT(error == 0);
- if (cp->c_backvp == NULL)
- error = cachefs_getbackvp(fscp, cp);
- if (error)
- goto out;
-
- CFS_DPRINT_BACKFS_NFSV4(fscp,
- ("cachefs_getsecattr (nfsv4): cp %p, backvp %p",
- cp, cp->c_backvp));
- error = VOP_GETSECATTR(cp->c_backvp, vsec, flag, cr, NULL);
- if (error)
- goto out;
-
- if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
- (cachefs_vtype_aclok(vp)) &&
- ((cp->c_flags & CN_NOCACHE) == 0) &&
- !CFS_ISFS_BACKFS_NFSV4(fscp)) {
- error = cachefs_cacheacl(cp, vsec);
- if (error) {
- error = 0;
- cachefs_nocache(cp);
- }
- }
-
-out:
- if (error == 0) {
- if (hit)
- fscp->fs_stats.st_hits++;
- else
- fscp->fs_stats.st_misses++;
- }
- mutex_exit(&cp->c_statelock);
-
- return (error);
-}
-
-static int
-/*ARGSUSED*/
-cachefs_getsecattr_disconnected(vnode_t *vp, vsecattr_t *vsec, int flag,
- cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int hit = 0;
- int error = 0;
-
-
- mutex_enter(&cp->c_statelock);
-
- /* read from the cache if we can */
- if (((cp->c_flags & CN_NOCACHE) == 0) &&
- (cp->c_metadata.md_flags & MD_ACL)) {
- error = cachefs_getaclfromcache(cp, vsec);
- if (error) {
- cachefs_nocache(cp);
- ASSERT((cp->c_metadata.md_flags & MD_ACL) == 0);
- error = 0;
- } else {
- hit = 1;
- goto out;
- }
- }
- error = ETIMEDOUT;
-
-out:
- if (error == 0) {
- if (hit)
- fscp->fs_stats.st_hits++;
- else
- fscp->fs_stats.st_misses++;
- }
- mutex_exit(&cp->c_statelock);
-
- return (error);
-}
-
-/*
- * cachefs_cacheacl() -- cache an ACL, which we do by applying it to
- * the frontfile if possible; otherwise, the adjunct directory.
- *
- * inputs:
- * cp - the cnode, with its statelock already held
- * vsecp - a pointer to a vsecattr_t you'd like us to cache as-is,
- * or NULL if you want us to do the VOP_GETSECATTR(backvp).
- *
- * returns:
- * 0 - all is well
- * nonzero - errno
- */
-
-int
-cachefs_cacheacl(cnode_t *cp, vsecattr_t *vsecp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- vsecattr_t vsec;
- aclent_t *aclp;
- int gotvsec = 0;
- int error = 0;
- vnode_t *vp = NULL;
- void *aclkeep = NULL;
- int i;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT((cp->c_flags & CN_NOCACHE) == 0);
- ASSERT(CFS_ISFS_BACKFS_NFSV4(fscp) == 0);
- ASSERT((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0);
- ASSERT(cachefs_vtype_aclok(CTOV(cp)));
-
- if (fscp->fs_info.fi_mntflags & CFS_NOACL) {
- error = ENOSYS;
- goto out;
- }
-
- if (vsecp == NULL) {
- if (cp->c_backvp == NULL)
- error = cachefs_getbackvp(fscp, cp);
- if (error != 0)
- goto out;
- vsecp = &vsec;
- bzero(&vsec, sizeof (vsec));
- vsecp->vsa_mask =
- VSA_ACL | VSA_ACLCNT | VSA_DFACL | VSA_DFACLCNT;
- error = VOP_GETSECATTR(cp->c_backvp, vsecp, 0, kcred, NULL);
- if (error != 0) {
- goto out;
- }
- gotvsec = 1;
- } else if (vsecp->vsa_mask & VSA_ACL) {
- aclkeep = vsecp->vsa_aclentp;
- vsecp->vsa_aclentp = cachefs_kmem_alloc(vsecp->vsa_aclcnt *
- sizeof (aclent_t), KM_SLEEP);
- bcopy(aclkeep, vsecp->vsa_aclentp, vsecp->vsa_aclcnt *
- sizeof (aclent_t));
- } else if ((vsecp->vsa_mask & (VSA_ACL | VSA_DFACL)) == 0) {
- /* unless there's real data, we can cache nothing. */
- return (0);
- }
-
- /*
- * prevent the ACL from chmoding our frontfile, and
- * snarf the class info
- */
-
- if ((vsecp->vsa_mask & (VSA_ACL | VSA_ACLCNT)) ==
- (VSA_ACL | VSA_ACLCNT)) {
- for (i = 0; i < vsecp->vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsecp->vsa_aclentp) + i;
- switch (aclp->a_type) {
- case CLASS_OBJ:
- cp->c_metadata.md_aclclass =
- aclp->a_perm;
- /*FALLTHROUGH*/
- case USER_OBJ:
- case GROUP_OBJ:
- case OTHER_OBJ:
- aclp->a_perm = 06;
- }
- }
- }
-
- /*
- * if the frontfile exists, then we always do the work. but,
- * if there's no frontfile, and the ACL isn't a `real' ACL,
- * then we don't want to do the work. otherwise, an `ls -l'
- * will create tons of emtpy frontfiles.
- */
-
- if (((cp->c_metadata.md_flags & MD_FILE) == 0) &&
- ((vsecp->vsa_aclcnt + vsecp->vsa_dfaclcnt)
- <= MIN_ACL_ENTRIES)) {
- cp->c_metadata.md_flags |= MD_ACL;
- cp->c_flags |= CN_UPDATED;
- goto out;
- }
-
- /*
- * if we have a default ACL, then we need a
- * real live directory in the frontfs that we
- * can apply the ACL to. if not, then we just
- * use the frontfile. we get the frontfile
- * regardless -- that way, we know the
- * directory for the frontfile exists.
- */
-
- if (vsecp->vsa_dfaclcnt > 0) {
- if (cp->c_acldirvp == NULL)
- error = cachefs_getacldirvp(cp);
- if (error != 0)
- goto out;
- vp = cp->c_acldirvp;
- } else {
- if (cp->c_frontvp == NULL)
- error = cachefs_getfrontfile(cp);
- if (error != 0)
- goto out;
- vp = cp->c_frontvp;
- }
- ASSERT(vp != NULL);
-
- (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
- error = VOP_SETSECATTR(vp, vsecp, 0, kcred, NULL);
- VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_cacheacl: setsecattr: error %d\n",
- error);
-#endif /* CFSDEBUG */
- /*
- * If there was an error, we don't want to call
- * cachefs_nocache(); so, set error to 0.
- * We will call cachefs_purgeacl(), in order to
- * clean such things as adjunct ACL directories.
- */
- cachefs_purgeacl(cp);
- error = 0;
- goto out;
- }
- if (vp == cp->c_frontvp)
- cp->c_flags |= CN_NEED_FRONT_SYNC;
-
- cp->c_metadata.md_flags |= MD_ACL;
- cp->c_flags |= CN_UPDATED;
-
-out:
- if ((error) && (fscp->fs_cdconnected == CFS_CD_CONNECTED))
- cachefs_nocache(cp);
-
- if (gotvsec) {
- if (vsec.vsa_aclcnt)
- kmem_free(vsec.vsa_aclentp,
- vsec.vsa_aclcnt * sizeof (aclent_t));
- if (vsec.vsa_dfaclcnt)
- kmem_free(vsec.vsa_dfaclentp,
- vsec.vsa_dfaclcnt * sizeof (aclent_t));
- } else if (aclkeep != NULL) {
- cachefs_kmem_free(vsecp->vsa_aclentp,
- vsecp->vsa_aclcnt * sizeof (aclent_t));
- vsecp->vsa_aclentp = aclkeep;
- }
-
- return (error);
-}
-
-void
-cachefs_purgeacl(cnode_t *cp)
-{
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- ASSERT(!CFS_ISFS_BACKFS_NFSV4(C_TO_FSCACHE(cp)));
-
- if (cp->c_acldirvp != NULL) {
- VN_RELE(cp->c_acldirvp);
- cp->c_acldirvp = NULL;
- }
-
- if (cp->c_metadata.md_flags & MD_ACLDIR) {
- char name[CFS_FRONTFILE_NAME_SIZE + 2];
-
- ASSERT(cp->c_filegrp->fg_dirvp != NULL);
- make_ascii_name(&cp->c_id, name);
- (void) strcat(name, ".d");
-
- (void) VOP_RMDIR(cp->c_filegrp->fg_dirvp, name,
- cp->c_filegrp->fg_dirvp, kcred, NULL, 0);
- }
-
- cp->c_metadata.md_flags &= ~(MD_ACL | MD_ACLDIR);
- cp->c_flags |= CN_UPDATED;
-}
-
-static int
-cachefs_getacldirvp(cnode_t *cp)
-{
- char name[CFS_FRONTFILE_NAME_SIZE + 2];
- int error = 0;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(cp->c_acldirvp == NULL);
-
- if (cp->c_frontvp == NULL)
- error = cachefs_getfrontfile(cp);
- if (error != 0)
- goto out;
-
- ASSERT(cp->c_filegrp->fg_dirvp != NULL);
- make_ascii_name(&cp->c_id, name);
- (void) strcat(name, ".d");
- error = VOP_LOOKUP(cp->c_filegrp->fg_dirvp,
- name, &cp->c_acldirvp, NULL, 0, NULL, kcred, NULL, NULL, NULL);
- if ((error != 0) && (error != ENOENT))
- goto out;
-
- if (error != 0) {
- vattr_t va;
-
- va.va_mode = S_IFDIR | 0777;
- va.va_uid = 0;
- va.va_gid = 0;
- va.va_type = VDIR;
- va.va_mask = AT_TYPE | AT_MODE |
- AT_UID | AT_GID;
- error =
- VOP_MKDIR(cp->c_filegrp->fg_dirvp,
- name, &va, &cp->c_acldirvp, kcred, NULL, 0, NULL);
- if (error != 0)
- goto out;
- }
-
- ASSERT(cp->c_acldirvp != NULL);
- cp->c_metadata.md_flags |= MD_ACLDIR;
- cp->c_flags |= CN_UPDATED;
-
-out:
- if (error != 0)
- cp->c_acldirvp = NULL;
- return (error);
-}
-
-static int
-cachefs_getaclfromcache(cnode_t *cp, vsecattr_t *vsec)
-{
- aclent_t *aclp;
- int error = 0;
- vnode_t *vp = NULL;
- int i;
-
- ASSERT(cp->c_metadata.md_flags & MD_ACL);
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(vsec->vsa_aclentp == NULL);
-
- if (cp->c_metadata.md_flags & MD_ACLDIR) {
- if (cp->c_acldirvp == NULL)
- error = cachefs_getacldirvp(cp);
- if (error != 0)
- goto out;
- vp = cp->c_acldirvp;
- } else if (cp->c_metadata.md_flags & MD_FILE) {
- if (cp->c_frontvp == NULL)
- error = cachefs_getfrontfile(cp);
- if (error != 0)
- goto out;
- vp = cp->c_frontvp;
- } else {
-
- /*
- * if we get here, then we know that MD_ACL is on,
- * meaning an ACL was successfully cached. we also
- * know that neither MD_ACLDIR nor MD_FILE are on, so
- * this has to be an entry without a `real' ACL.
- * thus, we forge whatever is necessary.
- */
-
- if (vsec->vsa_mask & VSA_ACLCNT)
- vsec->vsa_aclcnt = MIN_ACL_ENTRIES;
-
- if (vsec->vsa_mask & VSA_ACL) {
- vsec->vsa_aclentp =
- kmem_zalloc(MIN_ACL_ENTRIES *
- sizeof (aclent_t), KM_SLEEP);
- aclp = (aclent_t *)vsec->vsa_aclentp;
- aclp->a_type = USER_OBJ;
- ++aclp;
- aclp->a_type = GROUP_OBJ;
- ++aclp;
- aclp->a_type = OTHER_OBJ;
- ++aclp;
- aclp->a_type = CLASS_OBJ;
- ksort((caddr_t)vsec->vsa_aclentp, MIN_ACL_ENTRIES,
- sizeof (aclent_t), cmp2acls);
- }
-
- ASSERT(vp == NULL);
- }
-
- if (vp != NULL) {
- if ((error = VOP_GETSECATTR(vp, vsec, 0, kcred, NULL)) != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_getaclfromcache: error %d\n",
- error);
-#endif /* CFSDEBUG */
- goto out;
- }
- }
-
- if (vsec->vsa_aclentp != NULL) {
- for (i = 0; i < vsec->vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsec->vsa_aclentp) + i;
- switch (aclp->a_type) {
- case USER_OBJ:
- aclp->a_id = cp->c_metadata.md_vattr.va_uid;
- aclp->a_perm =
- cp->c_metadata.md_vattr.va_mode & 0700;
- aclp->a_perm >>= 6;
- break;
-
- case GROUP_OBJ:
- aclp->a_id = cp->c_metadata.md_vattr.va_gid;
- aclp->a_perm =
- cp->c_metadata.md_vattr.va_mode & 070;
- aclp->a_perm >>= 3;
- break;
-
- case OTHER_OBJ:
- aclp->a_perm =
- cp->c_metadata.md_vattr.va_mode & 07;
- break;
-
- case CLASS_OBJ:
- aclp->a_perm =
- cp->c_metadata.md_aclclass;
- break;
- }
- }
- }
-
-out:
-
- if (error != 0)
- cachefs_nocache(cp);
-
- return (error);
-}
-
-/*
- * Fills in targp with attribute information from srcp, cp
- * and if necessary the system.
- */
-static void
-cachefs_attr_setup(vattr_t *srcp, vattr_t *targp, cnode_t *cp, cred_t *cr)
-{
- time_t now;
-
- ASSERT((srcp->va_mask & (AT_TYPE | AT_MODE)) == (AT_TYPE | AT_MODE));
-
- /*
- * Add code to fill in the va struct. We use the fields from
- * the srcp struct if they are populated, otherwise we guess
- */
-
- targp->va_mask = 0; /* initialize all fields */
- targp->va_mode = srcp->va_mode;
- targp->va_type = srcp->va_type;
- targp->va_nlink = 1;
- targp->va_nodeid = 0;
-
- if (srcp->va_mask & AT_UID)
- targp->va_uid = srcp->va_uid;
- else
- targp->va_uid = crgetuid(cr);
-
- if (srcp->va_mask & AT_GID)
- targp->va_gid = srcp->va_gid;
- else
- targp->va_gid = crgetgid(cr);
-
- if (srcp->va_mask & AT_FSID)
- targp->va_fsid = srcp->va_fsid;
- else
- targp->va_fsid = 0; /* initialize all fields */
-
- now = gethrestime_sec();
- if (srcp->va_mask & AT_ATIME)
- targp->va_atime = srcp->va_atime;
- else
- targp->va_atime.tv_sec = now;
-
- if (srcp->va_mask & AT_MTIME)
- targp->va_mtime = srcp->va_mtime;
- else
- targp->va_mtime.tv_sec = now;
-
- if (srcp->va_mask & AT_CTIME)
- targp->va_ctime = srcp->va_ctime;
- else
- targp->va_ctime.tv_sec = now;
-
-
- if (srcp->va_mask & AT_SIZE)
- targp->va_size = srcp->va_size;
- else
- targp->va_size = 0;
-
- /*
- * the remaing fields are set by the fs and not changable.
- * we populate these entries useing the parent directory
- * values. It's a small hack, but should work.
- */
- targp->va_blksize = cp->c_metadata.md_vattr.va_blksize;
- targp->va_rdev = cp->c_metadata.md_vattr.va_rdev;
- targp->va_nblocks = cp->c_metadata.md_vattr.va_nblocks;
- targp->va_seq = 0; /* Never keep the sequence number */
-}
-
-/*
- * set the gid for a newly created file. The algorithm is as follows:
- *
- * 1) If the gid is set in the attribute list, then use it if
- * the caller is privileged, belongs to the target group, or
- * the group is the same as the parent directory.
- *
- * 2) If the parent directory's set-gid bit is clear, then use
- * the process gid
- *
- * 3) Otherwise, use the gid of the parent directory.
- *
- * Note: newcp->c_attr.va_{mode,type} must already be set before calling
- * this routine.
- */
-static void
-cachefs_creategid(cnode_t *dcp, cnode_t *newcp, vattr_t *vap, cred_t *cr)
-{
- if ((vap->va_mask & AT_GID) &&
- ((vap->va_gid == dcp->c_attr.va_gid) ||
- groupmember(vap->va_gid, cr) ||
- secpolicy_vnode_create_gid(cr) != 0)) {
- newcp->c_attr.va_gid = vap->va_gid;
- } else {
- if (dcp->c_attr.va_mode & S_ISGID)
- newcp->c_attr.va_gid = dcp->c_attr.va_gid;
- else
- newcp->c_attr.va_gid = crgetgid(cr);
- }
-
- /*
- * if we're creating a directory, and the parent directory has the
- * set-GID bit set, set it on the new directory.
- * Otherwise, if the user is neither privileged nor a member of the
- * file's new group, clear the file's set-GID bit.
- */
- if (dcp->c_attr.va_mode & S_ISGID && newcp->c_attr.va_type == VDIR) {
- newcp->c_attr.va_mode |= S_ISGID;
- } else if ((newcp->c_attr.va_mode & S_ISGID) &&
- secpolicy_vnode_setids_setgids(cr, newcp->c_attr.va_gid) != 0)
- newcp->c_attr.va_mode &= ~S_ISGID;
-}
-
-/*
- * create an acl for the newly created file. should be called right
- * after cachefs_creategid.
- */
-
-static void
-cachefs_createacl(cnode_t *dcp, cnode_t *newcp)
-{
- fscache_t *fscp = C_TO_FSCACHE(dcp);
- vsecattr_t vsec;
- int gotvsec = 0;
- int error = 0; /* placeholder */
- aclent_t *aclp;
- o_mode_t *classp = NULL;
- o_mode_t gunion = 0;
- int i;
-
- if ((fscp->fs_info.fi_mntflags & CFS_NOACL) ||
- (! cachefs_vtype_aclok(CTOV(newcp))))
- return;
-
- ASSERT(dcp->c_metadata.md_flags & MD_ACL);
- ASSERT(MUTEX_HELD(&dcp->c_statelock));
- ASSERT(MUTEX_HELD(&newcp->c_statelock));
-
- /*
- * XXX should probably not do VSA_ACL and VSA_ACLCNT, but that
- * would hit code paths that isn't hit anywhere else.
- */
-
- bzero(&vsec, sizeof (vsec));
- vsec.vsa_mask = VSA_ACL | VSA_ACLCNT | VSA_DFACL | VSA_DFACLCNT;
- error = cachefs_getaclfromcache(dcp, &vsec);
- if (error != 0)
- goto out;
- gotvsec = 1;
-
- if ((vsec.vsa_dfaclcnt > 0) && (vsec.vsa_dfaclentp != NULL)) {
- if ((vsec.vsa_aclcnt > 0) && (vsec.vsa_aclentp != NULL))
- kmem_free(vsec.vsa_aclentp,
- vsec.vsa_aclcnt * sizeof (aclent_t));
-
- vsec.vsa_aclcnt = vsec.vsa_dfaclcnt;
- vsec.vsa_aclentp = vsec.vsa_dfaclentp;
- vsec.vsa_dfaclcnt = 0;
- vsec.vsa_dfaclentp = NULL;
-
- if (newcp->c_attr.va_type == VDIR) {
- vsec.vsa_dfaclentp = kmem_alloc(vsec.vsa_aclcnt *
- sizeof (aclent_t), KM_SLEEP);
- vsec.vsa_dfaclcnt = vsec.vsa_aclcnt;
- bcopy(vsec.vsa_aclentp, vsec.vsa_dfaclentp,
- vsec.vsa_aclcnt * sizeof (aclent_t));
- }
-
- /*
- * this function should be called pretty much after
- * the rest of the file creation stuff is done. so,
- * uid, gid, etc. should be `right'. we'll go with
- * that, rather than trying to determine whether to
- * get stuff from cr or va.
- */
-
- for (i = 0; i < vsec.vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsec.vsa_aclentp) + i;
- switch (aclp->a_type) {
- case DEF_USER_OBJ:
- aclp->a_type = USER_OBJ;
- aclp->a_id = newcp->c_metadata.md_vattr.va_uid;
- aclp->a_perm =
- newcp->c_metadata.md_vattr.va_mode;
- aclp->a_perm &= 0700;
- aclp->a_perm >>= 6;
- break;
-
- case DEF_GROUP_OBJ:
- aclp->a_type = GROUP_OBJ;
- aclp->a_id = newcp->c_metadata.md_vattr.va_gid;
- aclp->a_perm =
- newcp->c_metadata.md_vattr.va_mode;
- aclp->a_perm &= 070;
- aclp->a_perm >>= 3;
- gunion |= aclp->a_perm;
- break;
-
- case DEF_OTHER_OBJ:
- aclp->a_type = OTHER_OBJ;
- aclp->a_perm =
- newcp->c_metadata.md_vattr.va_mode & 07;
- break;
-
- case DEF_CLASS_OBJ:
- aclp->a_type = CLASS_OBJ;
- classp = &(aclp->a_perm);
- break;
-
- case DEF_USER:
- aclp->a_type = USER;
- gunion |= aclp->a_perm;
- break;
-
- case DEF_GROUP:
- aclp->a_type = GROUP;
- gunion |= aclp->a_perm;
- break;
- }
- }
-
- /* XXX is this the POSIX thing to do? */
- if (classp != NULL)
- *classp &= gunion;
-
- /*
- * we don't need to log this; rather, we clear the
- * MD_ACL bit when we reconnect.
- */
-
- error = cachefs_cacheacl(newcp, &vsec);
- if (error != 0)
- goto out;
- }
-
- newcp->c_metadata.md_aclclass = 07; /* XXX check posix */
- newcp->c_metadata.md_flags |= MD_ACL;
- newcp->c_flags |= CN_UPDATED;
-
-out:
-
- if (gotvsec) {
- if ((vsec.vsa_aclcnt > 0) && (vsec.vsa_aclentp != NULL))
- kmem_free(vsec.vsa_aclentp,
- vsec.vsa_aclcnt * sizeof (aclent_t));
- if ((vsec.vsa_dfaclcnt > 0) && (vsec.vsa_dfaclentp != NULL))
- kmem_free(vsec.vsa_dfaclentp,
- vsec.vsa_dfaclcnt * sizeof (aclent_t));
- }
-}
-
-/*
- * this is translated from the UFS code for access checking.
- */
-
-static int
-cachefs_access_local(void *vcp, int mode, cred_t *cr)
-{
- cnode_t *cp = vcp;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int shift = 0;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- if (mode & VWRITE) {
- /*
- * Disallow write attempts on read-only
- * file systems, unless the file is special.
- */
- struct vnode *vp = CTOV(cp);
- if (vn_is_readonly(vp)) {
- if (!IS_DEVVP(vp)) {
- return (EROFS);
- }
- }
- }
-
- /*
- * if we need to do ACLs, do it. this works whether anyone
- * has explicitly made an ACL or not.
- */
-
- if (((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0) &&
- (cachefs_vtype_aclok(CTOV(cp))))
- return (cachefs_acl_access(cp, mode, cr));
-
- if (crgetuid(cr) != cp->c_attr.va_uid) {
- shift += 3;
- if (!groupmember(cp->c_attr.va_gid, cr))
- shift += 3;
- }
-
- return (secpolicy_vnode_access2(cr, CTOV(cp), cp->c_attr.va_uid,
- cp->c_attr.va_mode << shift, mode));
-}
-
-/*
- * This is transcribed from ufs_acl_access(). If that changes, then
- * this should, too.
- *
- * Check the cnode's ACL's to see if this mode of access is
- * allowed; return 0 if allowed, EACCES if not.
- *
- * We follow the procedure defined in Sec. 3.3.5, ACL Access
- * Check Algorithm, of the POSIX 1003.6 Draft Standard.
- */
-
-#define ACL_MODE_CHECK(M, PERM, C, I) \
- secpolicy_vnode_access2(C, CTOV(I), owner, (PERM), (M))
-
-static int
-cachefs_acl_access(struct cnode *cp, int mode, cred_t *cr)
-{
- int error = 0;
-
- fscache_t *fscp = C_TO_FSCACHE(cp);
-
- int mask = ~0;
- int ismask = 0;
-
- int gperm = 0;
- int ngroup = 0;
-
- vsecattr_t vsec;
- int gotvsec = 0;
- aclent_t *aclp;
-
- uid_t owner = cp->c_attr.va_uid;
-
- int i;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT((fscp->fs_info.fi_mntflags & CFS_NOACL) == 0);
-
- /*
- * strictly speaking, we shouldn't set VSA_DFACL and DFACLCNT,
- * but then i believe we'd be the only thing exercising those
- * code paths -- probably a bad thing.
- */
-
- bzero(&vsec, sizeof (vsec));
- vsec.vsa_mask = VSA_ACL | VSA_ACLCNT | VSA_DFACL | VSA_DFACLCNT;
-
- /* XXX KLUDGE! correct insidious 0-class problem */
- if (cp->c_metadata.md_aclclass == 0 &&
- fscp->fs_cdconnected == CFS_CD_CONNECTED)
- cachefs_purgeacl(cp);
-again:
- if (cp->c_metadata.md_flags & MD_ACL) {
- error = cachefs_getaclfromcache(cp, &vsec);
- if (error != 0) {
-#ifdef CFSDEBUG
- if (error != ETIMEDOUT)
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_acl_access():"
- "error %d from getaclfromcache()\n",
- error);
-#endif /* CFSDEBUG */
- if ((cp->c_metadata.md_flags & MD_ACL) == 0) {
- goto again;
- } else {
- goto out;
- }
- }
- } else {
- if (cp->c_backvp == NULL) {
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_getbackvp(fscp, cp);
- else
- error = ETIMEDOUT;
- }
- if (error == 0)
- error = VOP_GETSECATTR(cp->c_backvp, &vsec, 0, cr,
- NULL);
- if (error != 0) {
-#ifdef CFSDEBUG
- CFS_DEBUG(CFSDEBUG_VOPS)
- printf("cachefs_acl_access():"
- "error %d from getsecattr(backvp)\n",
- error);
-#endif /* CFSDEBUG */
- goto out;
- }
- if ((cp->c_flags & CN_NOCACHE) == 0 &&
- !CFS_ISFS_BACKFS_NFSV4(fscp))
- (void) cachefs_cacheacl(cp, &vsec);
- }
- gotvsec = 1;
-
- ASSERT(error == 0);
- for (i = 0; i < vsec.vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsec.vsa_aclentp) + i;
- switch (aclp->a_type) {
- case USER_OBJ:
- /*
- * this might look cleaner in the 2nd loop
- * below, but we do it here as an
- * optimization.
- */
-
- owner = aclp->a_id;
- if (crgetuid(cr) == owner) {
- error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
- cr, cp);
- goto out;
- }
- break;
-
- case CLASS_OBJ:
- mask = aclp->a_perm;
- ismask = 1;
- break;
- }
- }
-
- ASSERT(error == 0);
- for (i = 0; i < vsec.vsa_aclcnt; i++) {
- aclp = ((aclent_t *)vsec.vsa_aclentp) + i;
- switch (aclp->a_type) {
- case USER:
- if (crgetuid(cr) == aclp->a_id) {
- error = ACL_MODE_CHECK(mode,
- (aclp->a_perm & mask) << 6, cr, cp);
- goto out;
- }
- break;
-
- case GROUP_OBJ:
- if (groupmember(aclp->a_id, cr)) {
- ++ngroup;
- gperm |= aclp->a_perm;
- if (! ismask) {
- error = ACL_MODE_CHECK(mode,
- aclp->a_perm << 6,
- cr, cp);
- goto out;
- }
- }
- break;
-
- case GROUP:
- if (groupmember(aclp->a_id, cr)) {
- ++ngroup;
- gperm |= aclp->a_perm;
- }
- break;
-
- case OTHER_OBJ:
- if (ngroup == 0) {
- error = ACL_MODE_CHECK(mode, aclp->a_perm << 6,
- cr, cp);
- goto out;
- }
- break;
-
- default:
- break;
- }
- }
-
- ASSERT(ngroup > 0);
- error = ACL_MODE_CHECK(mode, (gperm & mask) << 6, cr, cp);
-
-out:
- if (gotvsec) {
- if (vsec.vsa_aclcnt && vsec.vsa_aclentp)
- kmem_free(vsec.vsa_aclentp,
- vsec.vsa_aclcnt * sizeof (aclent_t));
- if (vsec.vsa_dfaclcnt && vsec.vsa_dfaclentp)
- kmem_free(vsec.vsa_dfaclentp,
- vsec.vsa_dfaclcnt * sizeof (aclent_t));
- }
-
- return (error);
-}
-
-/*
- * see if permissions allow for removal of the given file from
- * the given directory.
- */
-static int
-cachefs_stickyrmchk(struct cnode *dcp, struct cnode *cp, cred_t *cr)
-{
- uid_t uid;
- /*
- * If the containing directory is sticky, the user must:
- * - own the directory, or
- * - own the file, or
- * - be able to write the file (if it's a plain file), or
- * - be sufficiently privileged.
- */
- if ((dcp->c_attr.va_mode & S_ISVTX) &&
- ((uid = crgetuid(cr)) != dcp->c_attr.va_uid) &&
- (uid != cp->c_attr.va_uid) &&
- (cp->c_attr.va_type != VREG ||
- cachefs_access_local(cp, VWRITE, cr) != 0))
- return (secpolicy_vnode_remove(cr));
-
- return (0);
-}
-
-/*
- * Returns a new name, may even be unique.
- * Stolen from nfs code.
- * Since now we will use renaming to .cfs* in place of .nfs*
- * for CacheFS. Both NFS and CacheFS will rename opened files.
- */
-static char cachefs_prefix[] = ".cfs";
-kmutex_t cachefs_newnum_lock;
-
-static char *
-cachefs_newname(void)
-{
- static uint_t newnum = 0;
- char *news;
- char *s, *p;
- uint_t id;
-
- mutex_enter(&cachefs_newnum_lock);
- if (newnum == 0) {
- newnum = gethrestime_sec() & 0xfffff;
- newnum |= 0x10000;
- }
- id = newnum++;
- mutex_exit(&cachefs_newnum_lock);
-
- news = cachefs_kmem_alloc(MAXNAMELEN, KM_SLEEP);
- s = news;
- p = cachefs_prefix;
- while (*p != '\0')
- *s++ = *p++;
- while (id != 0) {
- *s++ = "0123456789ABCDEF"[id & 0x0f];
- id >>= 4;
- }
- *s = '\0';
- return (news);
-}
-
-/*
- * Called to rename the specified file to a temporary file so
- * operations to the file after remove work.
- * Must call this routine with the dir c_rwlock held as a writer.
- */
-static int
-/*ARGSUSED*/
-cachefs_remove_dolink(vnode_t *dvp, vnode_t *vp, char *nm, cred_t *cr)
-{
- cnode_t *cp = VTOC(vp);
- char *tmpname;
- fscache_t *fscp = C_TO_FSCACHE(cp);
- int error;
-
- ASSERT(RW_WRITE_HELD(&(VTOC(dvp)->c_rwlock)));
-
- /* get the new name for the file */
- tmpname = cachefs_newname();
-
- /* do the link */
- if (fscp->fs_cdconnected == CFS_CD_CONNECTED)
- error = cachefs_link_connected(dvp, vp, tmpname, cr);
- else
- error = cachefs_link_disconnected(dvp, vp, tmpname, cr);
- if (error) {
- cachefs_kmem_free(tmpname, MAXNAMELEN);
- return (error);
- }
-
- mutex_enter(&cp->c_statelock);
- if (cp->c_unldvp) {
- VN_RELE(cp->c_unldvp);
- cachefs_kmem_free(cp->c_unlname, MAXNAMELEN);
- crfree(cp->c_unlcred);
- }
-
- VN_HOLD(dvp);
- cp->c_unldvp = dvp;
- crhold(cr);
- cp->c_unlcred = cr;
- cp->c_unlname = tmpname;
-
- /* drop the backvp so NFS does not also do a rename */
- mutex_exit(&cp->c_statelock);
-
- return (0);
-}
-
-/*
- * Marks the cnode as modified.
- */
-static void
-cachefs_modified(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- struct vattr va;
- int error;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
- ASSERT(cp->c_metadata.md_rlno);
-
- /* if not on the modify list */
- if (cp->c_metadata.md_rltype != CACHEFS_RL_MODIFIED) {
- /* put on modified list, also marks the file as modified */
- cachefs_rlent_moveto(fscp->fs_cache, CACHEFS_RL_MODIFIED,
- cp->c_metadata.md_rlno, cp->c_metadata.md_frontblks);
- cp->c_metadata.md_rltype = CACHEFS_RL_MODIFIED;
- cp->c_flags |= CN_UPDATED;
-
- /* if a modified regular file that is not local */
- if (((cp->c_id.cid_flags & CFS_CID_LOCAL) == 0) &&
- (cp->c_metadata.md_flags & MD_FILE) &&
- (cp->c_attr.va_type == VREG)) {
-
- if (cp->c_frontvp == NULL)
- (void) cachefs_getfrontfile(cp);
- if (cp->c_frontvp) {
- /* identify file so fsck knows it is modified */
- va.va_mode = 0766;
- va.va_mask = AT_MODE;
- error = VOP_SETATTR(cp->c_frontvp,
- &va, 0, kcred, NULL);
- if (error) {
- cmn_err(CE_WARN,
- "Cannot change ff mode.\n");
- }
- }
- }
- }
-}
-
-/*
- * Marks the cnode as modified.
- * Allocates a rl slot for the cnode if necessary.
- * Returns 0 for success, !0 if cannot get an rl slot.
- */
-static int
-cachefs_modified_alloc(cnode_t *cp)
-{
- fscache_t *fscp = C_TO_FSCACHE(cp);
- filegrp_t *fgp = cp->c_filegrp;
- int error;
- rl_entry_t rl_ent;
-
- ASSERT(MUTEX_HELD(&cp->c_statelock));
-
- /* get the rl slot if needed */
- if (cp->c_metadata.md_rlno == 0) {
- /* get a metadata slot if we do not have one yet */
- if (cp->c_flags & CN_ALLOC_PENDING) {
- if (cp->c_filegrp->fg_flags & CFS_FG_ALLOC_ATTR) {
- (void) filegrp_allocattr(cp->c_filegrp);
- }
- error = filegrp_create_metadata(cp->c_filegrp,
- &cp->c_metadata, &cp->c_id);
- if (error)
- return (error);
- cp->c_flags &= ~CN_ALLOC_PENDING;
- }
-
- /* get a free rl entry */
- rl_ent.rl_fileno = cp->c_id.cid_fileno;
- rl_ent.rl_local = (cp->c_id.cid_flags & CFS_CID_LOCAL) ? 1 : 0;
- rl_ent.rl_fsid = fscp->fs_cfsid;
- rl_ent.rl_attrc = 0;
- error = cachefs_rl_alloc(fscp->fs_cache, &rl_ent,
- &cp->c_metadata.md_rlno);
- if (error)
- return (error);
- cp->c_metadata.md_rltype = CACHEFS_RL_NONE;
-
- /* hold the filegrp so the attrcache file is not gc */
- error = filegrp_ffhold(fgp);
- if (error) {
- cachefs_rlent_moveto(fscp->fs_cache,
- CACHEFS_RL_FREE, cp->c_metadata.md_rlno, 0);
- cp->c_metadata.md_rlno = 0;
- return (error);
- }
- }
- cachefs_modified(cp);
- return (0);
-}
-
-int
-cachefs_vtype_aclok(vnode_t *vp)
-{
- vtype_t *vtp, oktypes[] = {VREG, VDIR, VFIFO, VNON};
-
- if (vp->v_type == VNON)
- return (0);
-
- for (vtp = oktypes; *vtp != VNON; vtp++)
- if (vp->v_type == *vtp)
- break;
-
- return (*vtp != VNON);
-}
-
-static int
-cachefs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
- caller_context_t *ct)
-{
- int error = 0;
- fscache_t *fscp = C_TO_FSCACHE(VTOC(vp));
-
- /* Assert cachefs compatibility if NFSv4 is in use */
- CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp);
- CFS_BACKFS_NFSV4_ASSERT_CNODE(VTOC(vp));
-
- if (cmd == _PC_FILESIZEBITS) {
- u_offset_t maxsize = fscp->fs_offmax;
- (*valp) = 0;
- while (maxsize != 0) {
- maxsize >>= 1;
- (*valp)++;
- }
- (*valp)++;
- } else
- error = fs_pathconf(vp, cmd, valp, cr, ct);
-
- return (error);
-}
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c
index 6e93d056df..1c19c8bfe2 100644
--- a/usr/src/uts/common/fs/vfs.c
+++ b/usr/src/uts/common/fs/vfs.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -4655,8 +4656,8 @@ getfsname(char *askfor, char *name, size_t namelen)
* convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c)
* we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic
* nfs module will map the type back to either "nfs", "nfs3", or "nfs4".
- * This is only for root filesystems, all other uses such as cachefs
- * will expect that "nfs" == NFS V2.
+ * This is only for root filesystems, all other uses will expect
+ * that "nfs" == NFS V2.
*/
static void
getrootfs(char **fstypp, char **fsmodp)
diff --git a/usr/src/uts/common/os/swapgeneric.c b/usr/src/uts/common/os/swapgeneric.c
index bfb6ccc05e..b573485353 100644
--- a/usr/src/uts/common/os/swapgeneric.c
+++ b/usr/src/uts/common/os/swapgeneric.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 1982, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -632,8 +633,8 @@ get_fstype_prop(char *fstype)
* convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c)
* we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic
* nfs module will map the type back to either "nfs", "nfs3", or "nfs4".
- * This is only for root filesystems, all other uses such as cachefs
- * will expect that "nfs" == NFS V2.
+ * This is only for root filesystems, all other uses will expect
+ * that "nfs" == NFS V2.
*
* If the filesystem isn't already loaded, vfs_getvfssw() will load
* it for us, but if (at the time we call it) modrootloaded is
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index 90618abb6e..ee396632ad 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -23,6 +23,7 @@
# Copyright 2013, Joyent, Inc. All rights reserved.
# Copyright 2013 Garrett D'Amore <garrett@damore.org>
# Copyright 2013 Saso Kiselkov. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
include $(SRC)/uts/Makefile.uts
@@ -847,13 +848,6 @@ FMIOHDRS= \
FSHDRS= \
autofs.h \
- cachefs_dir.h \
- cachefs_dlog.h \
- cachefs_filegrp.h \
- cachefs_fs.h \
- cachefs_fscache.h \
- cachefs_ioctl.h \
- cachefs_log.h \
decomp.h \
dv_node.h \
sdev_impl.h \
diff --git a/usr/src/uts/common/sys/filio.h b/usr/src/uts/common/sys/filio.h
index 7815aff505..beeac8af08 100644
--- a/usr/src/uts/common/sys/filio.h
+++ b/usr/src/uts/common/sys/filio.h
@@ -21,6 +21,7 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -88,11 +89,6 @@ extern "C" {
#define _FIOTUNE _IO('f', 77) /* tuning */
/*
- * WARNING: These 'f' ioctls are also defined in sys/fs/cachefs_fs.h
- * It currently defines 78-86.
- */
-
-/*
* Internal Logging UFS
*/
#define _FIOLOGENABLE _IO('f', 87) /* logging/ufs protocol */
diff --git a/usr/src/uts/common/sys/fs/cachefs_dir.h b/usr/src/uts/common/sys/fs/cachefs_dir.h
deleted file mode 100644
index c223b1c688..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_dir.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 2014 Garrett D'Amore <garrett@damore.org>
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_FS_CACHEFS_DIR_H
-#define _SYS_FS_CACHEFS_DIR_H
-
-#include <sys/types.h>
-#include <sys/fs/cachefs_fs.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * c_dirent is stored on disk, so it needs to be the same 32-bit vs. 64-bit.
- */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-
-struct c_dirent {
- uint_t d_length; /* entry length */
- uint_t d_flag; /* entry flags */
- cfs_cid_t d_id; /* file id */
- offset_t d_offset; /* disk offset of this entry */
- cfs_fid_t d_cookie; /* back fid */
- ushort_t d_namelen; /* name length, without null */
- char d_name[1]; /* name */
-};
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-
-#define C_DIRSIZ(dp) \
- (((dp)->d_namelen + (uint_t)sizeof (struct c_dirent) + 7) & ~7)
-
-#define CDE_SIZE(NM) \
- ((strlen(NM) + sizeof (struct c_dirent) + 7) & ~7)
-
-/*
- * Various flags stored in c_dirent flag field.
- */
-#define CDE_VALID 0x1 /* entry is valid */
-#define CDE_COMPLETE 0x2 /* entry is complete */
-
-
-#if defined(_KERNEL)
-int cachefs_dir_look(cnode_t *dcp, char *nm, fid_t *cookiep, uint_t *flagp,
- u_offset_t *d_offsetp, cfs_cid_t *cidp);
-int cachefs_dir_new(cnode_t *dcp, cnode_t *cp);
-int cachefs_dir_enter(cnode_t *dcp, char *nm, fid_t *cookiep, cfs_cid_t *cidp,
- int issync);
-int cachefs_dir_rmentry(cnode_t *dcp, char *nm);
-void cachefs_dir_modentry(cnode_t *dcp, u_offset_t offset, fid_t *cookiep,
- cfs_cid_t *cidp);
-int cachefs_dir_read(struct cnode *dcp, struct uio *uiop, int *eofp);
-int cachefs_dir_fill(cnode_t *dcp, cred_t *cr);
-int cachefs_dir_empty(cnode_t *dcp);
-int cachefs_async_populate_dir(struct cachefs_populate_req *, cred_t *,
- vnode_t *, vnode_t *);
-
-#endif /* defined(_KERNEL) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_FS_CACHEFS_DIR_H */
diff --git a/usr/src/uts/common/sys/fs/cachefs_dlog.h b/usr/src/uts/common/sys/fs/cachefs_dlog.h
deleted file mode 100644
index 3914cad114..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_dlog.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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 2014 Garrett D'Amore <garrett@damore.org>
- *
- * 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
-
-#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)
-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 */
diff --git a/usr/src/uts/common/sys/fs/cachefs_filegrp.h b/usr/src/uts/common/sys/fs/cachefs_filegrp.h
deleted file mode 100644
index 2734f71a74..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_filegrp.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 (c) 1996-1998 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _SYS_FS_CACHEFS_FILEGRP_H
-#define _SYS_FS_CACHEFS_FILEGRP_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct cachefs_metadata;
-
-/*
- * filegrp structure represents a group of front files.
- */
-struct filegrp {
- uint_t fg_flags; /* CFS_FS_* flags */
- int fg_count; /* cnodes in group */
- cfs_cid_t fg_id; /* starting id in group */
- struct fscache *fg_fscp; /* back ptr to fscache */
-
- struct cnode *fg_cnodelist; /* list of cnodes */
-
- struct filegrp *fg_next; /* pointer to next */
- struct vnode *fg_dirvp; /* filegrp directory vp */
- struct vnode *fg_attrvp; /* attrcache vp */
- struct attrcache_header *fg_header; /* Attrcache header */
- struct attrcache_index *fg_offsets; /* ptr to indexes in header */
- uchar_t *fg_alloclist; /* allocation bitmap */
-
- int fg_headersize; /* attrcache header size */
- int fg_filesize; /* size of attrcache file */
- kmutex_t fg_mutex; /* filegrp contents/ac lock */
- kmutex_t fg_cnodelock; /* cnode list lock */
-};
-typedef struct filegrp filegrp_t;
-
-extern struct kmem_cache *cachefs_filegrp_cache;
-
-/* fg_flags values */
-#define CFS_FG_NOCACHE 0x1 /* no cache mode */
-#define CFS_FG_ALLOC_ATTR 0x2 /* no attrcache file yet */
-#define CFS_FG_UPDATED 0x4 /* attrcache modified */
-#define CFS_FG_ALLOC_FILE 0x10 /* no front file dir yet */
-#define CFS_FG_RL 0x20 /* no longer used */
-#define CFS_FG_READ 0x40 /* attrcache can be read */
-#define CFS_FG_WRITE 0x80 /* attrcache can be written */
-
-int filegrp_cache_create(void *, void *, int);
-void filegrp_cache_destroy(void *, void *);
-filegrp_t *filegrp_create(struct fscache *fscp, cfs_cid_t *cidp);
-void filegrp_destroy(filegrp_t *fgp);
-int filegrp_allocattr(filegrp_t *fgp);
-int filegrpdir_create(filegrp_t *fgp);
-int filegrpdir_find(filegrp_t *fgp);
-void filegrp_hold(filegrp_t *fgp);
-void filegrp_rele(filegrp_t *fgp);
-int filegrp_ffhold(filegrp_t *fgp);
-void filegrp_ffrele(filegrp_t *fgp);
-
-int filegrp_sync(filegrp_t *fgp);
-int filegrp_read_metadata(filegrp_t *fgp, cfs_cid_t *cidp,
- struct cachefs_metadata *mdp);
-int filegrp_create_metadata(filegrp_t *fgp, struct cachefs_metadata *md,
- cfs_cid_t *cidp);
-int filegrp_write_metadata(filegrp_t *fgp, cfs_cid_t *cidp,
- struct cachefs_metadata *mdp);
-int filegrp_destroy_metadata(filegrp_t *fgp, cfs_cid_t *cidp);
-int filegrp_cid_to_slot(filegrp_t *fgp, cfs_cid_t *cidp);
-
-filegrp_t *filegrp_list_find(struct fscache *fscp, cfs_cid_t *cidp);
-void filegrp_list_add(struct fscache *fscp, filegrp_t *fgp);
-void filegrp_list_remove(struct fscache *fscp, filegrp_t *fgp);
-void filegrp_list_gc(struct fscache *fscp);
-void filegrp_list_enable_caching_ro(struct fscache *fscp);
-void filegrp_list_enable_caching_rw(struct fscache *fscp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_FS_CACHEFS_FILEGRP_H */
diff --git a/usr/src/uts/common/sys/fs/cachefs_fs.h b/usr/src/uts/common/sys/fs/cachefs_fs.h
deleted file mode 100644
index 30bc223a2b..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_fs.h
+++ /dev/null
@@ -1,1331 +0,0 @@
-/*
- * 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 2014 Garrett D'Amore <garrett@damore.org>
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_FS_CACHEFS_FS_H
-#define _SYS_FS_CACHEFS_FS_H
-
-#include <sys/vnode.h>
-#include <sys/vfs.h>
-#include <sys/types.h>
-#include <sys/types32.h>
-#include <sys/t_lock.h>
-#include <sys/thread.h>
-#include <sys/kmem.h>
-#include <sys/inttypes.h>
-#include <sys/time_impl.h>
-#include <sys/systm.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef CFSDEBUG
-#define CFSDEBUG_ALL 0xffffffff
-#define CFSDEBUG_NONE 0x0
-#define CFSDEBUG_GENERAL 0x1
-#define CFSDEBUG_SUBR 0x2
-#define CFSDEBUG_CNODE 0x4
-#define CFSDEBUG_DIR 0x8
-#define CFSDEBUG_STRICT 0x10
-#define CFSDEBUG_VOPS 0x20
-#define CFSDEBUG_VFSOP 0x40
-#define CFSDEBUG_RESOURCE 0x80
-#define CFSDEBUG_CHEAT 0x100
-#define CFSDEBUG_INVALIDATE 0x200
-#define CFSDEBUG_DLOG 0x400
-#define CFSDEBUG_FILEGRP 0x800
-#define CFSDEBUG_IOCTL 0x1000
-#define CFSDEBUG_FRONT 0x2000
-#define CFSDEBUG_BACK 0x4000
-#define CFSDEBUG_ALLOCMAP 0x8000
-#define CFSDEBUG_ASYNCPOP 0x10000
-#define CFSDEBUG_VOPS_NFSV4 0x20000
-
-#define CFSCLEANFLAG
-
-extern int cachefsdebug;
-
-#define CFS_DEBUG(N) if (cachefsdebug & (N))
-#endif /* DEBUG */
-
-#if 0
-#ifdef CFSDEBUG
- /*
- * Testing usage of cd_access and friends.
- * Note we steal an unused bit in t_flag.
- * This will certainly bite us later.
- */
-#define CFS_CD_DEBUG
-#define T_CD_HELD 0x01000
-#endif
-#endif
-
-/*
- * Note: in an RL debugging kernel, CFSVERSION is augmented by 100
- *
- * Version History:
- *
- * Beginning -- Solaris 2.3 and 2.4: 1
- *
- * In Solaris 2.5 alpha, the size of fid_t changed: 2
- *
- * In 2.6: Chart, RL pointers/idents became rl_entry: 3
- * added which RL list to attrcache header: 4
- *
- * Large Files support made version to 6.
- *
- * Sequence numbers made version to 7.
- *
- * 64-bit on-disk cache will make version 8. Not yet supported.
- */
-
-#if 0
-#define CFSRLDEBUG
-#endif
-
-#ifdef CFSRLDEBUG
-#define CFSVERSION 110
-#define CFSVERSION64 111 /* 64-bit cache - not yet used */
-#else /* CFSRLDEBUG */
-#define CFSVERSION 7
-#define CFSVERSION64 8 /* 64-bit cache - not yet used */
-#endif /* CFSRLDEBUG */
-
-/* Some default values */
-#define DEF_FILEGRP_SIZE 256
-#define DEF_POP_SIZE 0x10000 /* 64K */
-#define CACHELABEL_NAME ".cfs_label"
-#define RESOURCE_NAME ".cfs_resource"
-#define CACHEFS_FSINFO ".cfs_fsinfo"
-#define ATTRCACHE_NAME ".cfs_attrcache"
-#define CACHEFS_LOSTFOUND_NAME "lost+found"
-#define BACKMNT_NAME ".cfs_mnt_points"
-#define CACHEFS_LOCK_FILE ".cfs_lock"
-#define CACHEFS_DLOG_FILE ".cfs_dlog"
-#define CACHEFS_DMAP_FILE ".cfs_dmap"
-#define CACHEFS_MNT_FILE ".cfs_mnt"
-#define CACHEFS_UNMNT_FILE ".cfs_unmnt"
-#define LOG_STATUS_NAME ".cfs_logging"
-#define NOBACKUP_NAME ".nsr"
-#define CACHEFS_PREFIX ".cfs_"
-#define CACHEFS_PREFIX_LEN 5
-#define ROOTLINK_NAME "root"
-#define CFS_FRONTFILE_NAME_SIZE 18
-#define CACHEFS_BASETYPE "cachefs" /* used in statvfs() */
-#define CFS_MAXFREECNODES 20
-#define CACHEFSTAB "/etc/cachefstab"
-#define CACHEFS_ROOTRUN "/var/run"
-#define CACHEFS_LOCKDIR_PRE ".cachefs." /* used by mount(1M)/fsck(1M) */
-
-/*
- * The options structure is passed in as part of the mount arguments.
- * It is stored in the .options file and kept track of in the fscache
- * structure.
- */
-struct cachefsoptions {
- uint_t opt_flags; /* mount flags */
- int opt_popsize; /* cache population size */
- int opt_fgsize; /* filegrp size, default 256 */
-};
-
-typedef struct cachefscache cachefscache_t;
-
-/*
- * all the stuff needed to manage a queue of requests to be processed
- * by async threads.
- */
-struct cachefs_workq {
- struct cachefs_req *wq_head; /* head of work q */
- struct cachefs_req *wq_tail; /* tail of work q */
- int wq_length; /* # of requests on q */
- int wq_thread_count; /* # of threads */
- int wq_max_len; /* longest queue */
- int wq_halt_request; /* halt requested */
- unsigned int wq_keepone:1; /* keep one thread */
- unsigned int wq_logwork:1; /* write logfile */
- kcondvar_t wq_req_cv; /* wait on work to do */
- kcondvar_t wq_halt_cv; /* wait/signal halt */
- kmutex_t wq_queue_lock; /* protect queue */
- cachefscache_t *wq_cachep; /* sometimes NULL */
-};
-
-/*
- * cfs_cid is stored on disk, so it needs to be the same 32-bit vs. 64-bit.
- */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-
-/* identifies a file in the cache */
-struct cfs_cid {
- ino64_t cid_fileno; /* fileno */
- int cid_flags; /* flags */
-};
-typedef struct cfs_cid cfs_cid_t;
-#define CFS_CID_LOCAL 1 /* local file */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-
-/*
- * XX64 - for now redefine all time_t fields that are used by both kernel
- * and user space apps as a 32-bit quantity,
- */
-
-#if (defined(_SYSCALL32) && defined(_LP64))
-
-/*
- * The cfs_* types are used to represent on-disk data, since its size is
- * independent of the kernel memory model (in the LP64 case)
- */
-typedef time32_t cfs_time_t;
-typedef timestruc32_t cfs_timestruc_t;
-typedef vattr32_t cfs_vattr_t;
-typedef fid32_t cfs_fid_t;
-
-#define cfs_timespec timespec32
-#define cfs_vattr vattr32
-#define cfs_fid fid32
-
-/*
- * CACHEFS_DEV_COPY copies between two dev_t's. It expands or compresses
- * them based on type changes (if needed).
- */
-#define CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error) \
- if (cmpldev((dev32_t *)&(out_dev), in_dev) == 0) \
- error = EOVERFLOW;
-
-#define CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev) \
- out_dev = (dev_t)expldev(in_dev);
-
-#define TIME_OVERFLOW(tval) \
- ((tval) < TIME32_MIN || (tval) > TIME32_MAX)
-
-/* Set the referred to time value. Set error if overflow */
-#define CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error) \
- out_tval = (in_tval); \
- if (TIME_OVERFLOW(in_tval)) \
- error = EOVERFLOW;
-
-#define CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval) \
- out_tval = (in_tval);
-
-/* Set the cfs_timestruc_t with values from input timestruc_t */
-#define CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error) \
- (out_tsp)->tv_nsec = (in_tsp)->tv_nsec; \
- CACHEFS_TIME_TO_TIME32_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec, error)
-
-#define CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp) \
- (out_tsp)->tv_nsec = (in_tsp)->tv_nsec; \
- CACHEFS_TIME32_TO_TIME_COPY((in_tsp)->tv_sec, (out_tsp)->tv_sec)
-
-/* CACHEFS_FID_COPY copies between two fids */
-#define CACHEFS_FID_COPY(in_fidp, out_fidp) \
- (out_fidp)->fid_len = (in_fidp)->fid_len; \
- bcopy((in_fidp)->fid_data, (out_fidp)->fid_data, (in_fidp)->fid_len)
-
-#define CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error) \
- (out_vattrp)->va_mask = (in_vattrp)->va_mask; \
- (out_vattrp)->va_type = (in_vattrp)->va_type; \
- (out_vattrp)->va_mode = (in_vattrp)->va_mode; \
- (out_vattrp)->va_uid = (in_vattrp)->va_uid; \
- (out_vattrp)->va_gid = (in_vattrp)->va_gid; \
- CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_fsid, \
- (out_vattrp)->va_fsid, error); \
- (out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid; \
- (out_vattrp)->va_nlink = (in_vattrp)->va_nlink; \
- (out_vattrp)->va_size = (in_vattrp)->va_size; \
- CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_atime, \
- &(out_vattrp)->va_atime, error); \
- CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_mtime, \
- &(out_vattrp)->va_mtime, error); \
- CACHEFS_TS_TO_TS32_COPY(&(in_vattrp)->va_ctime, \
- &(out_vattrp)->va_ctime, error); \
- CACHEFS_DEV_TO_DEV32_COPY((in_vattrp)->va_rdev, \
- (out_vattrp)->va_rdev, error); \
- (out_vattrp)->va_blksize = (in_vattrp)->va_blksize; \
- (out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks; \
- (out_vattrp)->va_seq = 0
-
-#define CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp) \
- (out_vattrp)->va_mask = (in_vattrp)->va_mask; \
- (out_vattrp)->va_type = (in_vattrp)->va_type; \
- (out_vattrp)->va_mode = (in_vattrp)->va_mode; \
- (out_vattrp)->va_uid = (in_vattrp)->va_uid; \
- (out_vattrp)->va_gid = (in_vattrp)->va_gid; \
- CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_fsid, \
- (out_vattrp)->va_fsid); \
- (out_vattrp)->va_nodeid = (in_vattrp)->va_nodeid; \
- (out_vattrp)->va_nlink = (in_vattrp)->va_nlink; \
- (out_vattrp)->va_size = (in_vattrp)->va_size; \
- CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_atime, \
- &(out_vattrp)->va_atime); \
- CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_mtime, \
- &(out_vattrp)->va_mtime); \
- CACHEFS_TS32_TO_TS_COPY(&(in_vattrp)->va_ctime, \
- &(out_vattrp)->va_ctime); \
- CACHEFS_DEV32_TO_DEV_COPY((in_vattrp)->va_rdev, \
- (out_vattrp)->va_rdev); \
- (out_vattrp)->va_blksize = (in_vattrp)->va_blksize; \
- (out_vattrp)->va_nblocks = (in_vattrp)->va_nblocks; \
- (out_vattrp)->va_seq = 0
-
-#else /* not _SYSCALL32 && _LP64 */
-
-/*
- * The cfs_* types are used to represent on-disk data, since its size is
- * independent of the kernel memory model (in the LP64 case)
- */
-typedef time_t cfs_time_t;
-typedef timestruc_t cfs_timestruc_t;
-typedef vattr_t cfs_vattr_t;
-typedef fid_t cfs_fid_t;
-
-#define cfs_timespec timespec
-#define cfs_vattr vattr
-#define cfs_fid fid
-
-#define TIME_OVERFLOW(tval) FALSE
-
-#define CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error) \
- out_dev = (in_dev)
-
-#define CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev) \
- out_dev = (in_dev)
-
-#define CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error) \
- out_tval = (in_tval)
-
-#define CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval) \
- out_tval = (in_tval)
-
-#define CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error) \
- *(out_tsp) = *(in_tsp)
-
-#define CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp) \
- *(out_tsp) = *(in_tsp)
-
-#define CACHEFS_FID_COPY(in_fidp, out_fidp) \
- *(out_fidp) = *(in_fidp)
-
-#define CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error) \
- *(out_vattrp) = *(in_vattrp); \
- (out_vattrp)->va_seq = 0
-
-#define CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp) \
- *(out_vattrp) = *(in_vattrp); \
- (out_vattrp)->va_seq = 0
-
-#endif /* _SYSCALL32 && _LP64 */
-
-/*
- * The "cfs_*" structs below refer to the on-disk structures. Presently
- * they are 32-bit based. When they change to 64-bit, we'd have to modify the
- * macros below accordingly.
- */
-#define CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error) \
- CACHEFS_DEV_TO_DEV32_COPY(in_dev, out_dev, error)
-
-#define CACHEFS_CFS_DEV_TO_DEV_COPY(in_dev, out_dev) \
- CACHEFS_DEV32_TO_DEV_COPY(in_dev, out_dev)
-
-#define CACHEFS_TIME_TO_CFS_TIME_COPY(in_tval, out_tval, error) \
- CACHEFS_TIME_TO_TIME32_COPY(in_tval, out_tval, error)
-
-#define CACHEFS_CFS_TIME_TO_TIME_COPY(in_tval, out_tval) \
- CACHEFS_TIME32_TO_TIME_COPY(in_tval, out_tval)
-
-#define CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error) \
- CACHEFS_TS_TO_TS32_COPY(in_tsp, out_tsp, error)
-
-#define CACHEFS_CFS_TS_TO_TS_COPY(in_tsp, out_tsp) \
- CACHEFS_TS32_TO_TS_COPY(in_tsp, out_tsp)
-
-#define CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vattrp, out_vattrp, error) \
- CACHEFS_VATTR_TO_VATTR32_COPY(in_vattrp, out_vattrp, error)
-
-#define CACHEFS_CFS_VATTR_TO_VATTR_COPY(in_vattrp, out_vattrp) \
- CACHEFS_VATTR32_TO_VATTR_COPY(in_vattrp, out_vattrp)
-
-#include <sys/fs/cachefs_fscache.h>
-#include <sys/fs/cachefs_filegrp.h>
-
-/*
- * One cache_label structure per cache. Contains mainly user defined or
- * default values for cache resource management. Contents is static.
- * The value cl_maxfiles is not used any where in cachefs code. If and when
- * this is really used the cl_maxfiles should be declared as a 64bit value
- * for large file support.
- * The maxblks, blkhiwat, blklowat, blocktresh, blockmin, may need to be
- * 64bit values when we actually start supporting file systems of size
- * greater than 1 terabyte.
- */
-struct cache_label {
- int cl_cfsversion; /* cfs version number */
- int cl_maxblks; /* max blocks to be used by cache */
- int cl_blkhiwat; /* high water-mark for block usage */
- int cl_blklowat; /* low water-mark for block usage */
- int cl_maxinodes; /* max inodes to be used by cache */
- int cl_filehiwat; /* high water-mark for inode usage */
- int cl_filelowat; /* low water-mark for indoe usage */
- int cl_blocktresh; /* block max usage treshold */
- int cl_blockmin; /* block min usage treshold */
- int cl_filetresh; /* inode max usage treshold */
- int cl_filemin; /* inode min usage treshold */
- int cl_maxfiles; /* max cache file size */
-};
-
-/*
- * One cache_usage structure per cache. Keeps track of cache usage figures.
- * Contents gets updated frequently.
- */
-struct cache_usage {
- int cu_blksused; /* actual number of blocks used */
- int cu_filesused; /* actual number of files used */
- uint_t cu_flags; /* Cache state flags */
- ushort_t cu_unique; /* Fid persistent uniquifier */
-};
-
-#define CUSAGE_ACTIVE 1 /* Cache is active */
-#define CUSAGE_NEED_ADJUST 2 /* Adjust uniquifier before assigning new fid */
-
-/*
- * RL list identifiers.
- */
-enum cachefs_rl_type {
- CACHEFS_RL_NONE = 0x101,
- CACHEFS_RL_FREE,
- CACHEFS_RL_GC,
- CACHEFS_RL_ACTIVE,
- CACHEFS_RL_ATTRFILE,
- CACHEFS_RL_MODIFIED,
- CACHEFS_RL_PACKED,
- CACHEFS_RL_PACKED_PENDING,
- CACHEFS_RL_MF
-};
-#define CACHEFS_RL_START CACHEFS_RL_NONE
-#define CACHEFS_RL_END CACHEFS_RL_MF
-#define CACHEFS_RL_CNT (CACHEFS_RL_END - CACHEFS_RL_START + 1)
-#define CACHEFS_RL_INDEX(X) (X - CACHEFS_RL_START)
-
-struct cachefs_rl_listhead {
- uint_t rli_front; /* front of list */
- uint_t rli_back; /* back of list */
- int rli_blkcnt; /* number of 8k blocks */
- int rli_itemcnt; /* number of items on list */
-};
-typedef struct cachefs_rl_listhead cachefs_rl_listhead_t;
-
-/*
- * Resource List information. One per cache.
- */
-struct cachefs_rl_info {
- uint_t rl_entries; /* number of entries allocated in rl */
- cfs_time_t rl_gctime; /* time of item on front of gc list */
-
- /* heads of the various lists */
- cachefs_rl_listhead_t rl_items[CACHEFS_RL_CNT];
-};
-typedef struct cachefs_rl_info cachefs_rl_info_t;
-
-/*
- * rl_debug and rl_entry are stored on disk, so they need to be
- * the same 32-bit vs. 64-bit.
- */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-
-#ifdef CFSRLDEBUG
-/*
- * RL debugging thingy
- */
-
-#define CACHEFS_RLDB_STACKSIZE 16
-#define CACHEFS_RLDB_DEF_MAXCOUNT 5
-
-typedef struct rl_debug {
- hrtime_t db_hrtime;
-
- uint_t db_attrc: 1;
- uint_t db_fsck: 1;
- ino64_t db_fsid;
- ino64_t db_fileno;
- enum cachefs_rl_type db_current;
-
- int db_stackheight;
- pc_t db_stack[CACHEFS_RLDB_STACKSIZE];
-
- struct rl_debug *db_next;
-} rl_debug_t;
-
-extern time_t cachefs_dbvalid;
-extern struct kmem_cache *cachefs_rl_debug_cache;
-extern kmutex_t cachefs_rl_debug_mutex;
-#endif /* CFSRLDEBUG */
-
-/*
- * RL Entry type.
- */
-
-typedef struct rl_entry {
- uint_t rl_attrc: 1;
- uint_t rl_fsck: 1; /* used by fsck; true => rl_current is correct */
- uint_t rl_local: 1; /* 1 means a local file */
-
-#ifdef CFSRLDEBUG
- cfs_time_t rl_dbvalid; /* this == cachefs_dbvalid => trust rl_debug */
- rl_debug_t *rl_debug;
-#endif /* CFSRLDEBUG */
-
- ino64_t rl_fsid;
- ino64_t rl_fileno;
-
- enum cachefs_rl_type rl_current;
- uint_t rl_fwd_idx;
- uint_t rl_bkwd_idx;
-} rl_entry_t;
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-
-/*
- * rl entries per MAXBSIZE chunk. rl_entry_t's size need not divide
- * MAXBSIZE, as long as this constant is an integer (through integer
- * division) (see cachefs_rl_entry_get()).
- */
-
-#define CACHEFS_RLPMBS (MAXBSIZE / (uint_t)sizeof (rl_entry_t))
-
-/*
- * struct cache contains cache-wide information, and provides access
- * to lower level info. There is one cache structure per cache.
- */
-struct cachefscache {
- struct cachefscache *c_next; /* list of caches */
- uint_t c_flags; /* misc flags */
- struct cache_label c_label; /* cache resource info */
- struct cache_usage c_usage; /* cache usage info */
- struct cachefs_rl_info c_rlinfo; /* rl global pointers */
- struct vnode *c_resfilevp; /* resource file vp */
- uint_t c_rl_window; /* window mapped in */
- rl_entry_t *c_rl_entries; /* mapping for rl entries */
- struct vnode *c_dirvp; /* cache directory vp */
- struct vnode *c_lockvp; /* lock file vp */
- struct vnode *c_lostfoundvp; /* lost+found directory vp */
- int c_refcnt; /* active fs ref count */
- struct fscache *c_fslist; /* fscache list head */
- struct cachefs_workq c_workq; /* async work */
- kmutex_t c_contentslock; /* protect cache struct */
- kmutex_t c_fslistlock; /* protect fscache list */
- kmutex_t c_mflock; /* protect modified fixes */
- ushort_t c_unique; /* In core fid uniquifier */
- kcondvar_t c_cwcv; /* gc wait on work to do */
- kcondvar_t c_cwhaltcv; /* wait on gc thread exit */
- uint_t c_gc_count; /* garbage collection count */
- time_t c_gc_time; /* last garbage collection */
- time_t c_gc_before; /* atime of front before gc */
- time_t c_gc_after; /* atime of front after gc */
- uint_t c_apop_inqueue; /* # async pops queued */
- pid_t c_rootdaemonid; /* pid of root cachefsd */
- struct cachefs_log_cookie
- *c_log; /* in-core logging stuff */
- struct cachefs_log_control
- *c_log_ctl; /* on-disk logging stuff */
- kmutex_t c_log_mutex; /* protects c_log* */
-};
-
-extern struct kmem_cache *cachefs_cache_kmcache;
-
-#define CACHEFS_MAX_APOP_INQUEUE 50 /* default value for below */
-extern uint_t cachefs_max_apop_inqueue; /* max populations pending */
-
-/*
- * Various cache structure flags.
- */
-#define CACHE_NOCACHE 0x1 /* all cache refs go to back fs */
-#define CACHE_ALLOC_PENDING 0x4 /* Allocation pending */
-#define CACHE_NOFILL 0x8 /* No fill mode */
-#define CACHE_GARBAGE_COLLECT 0x10 /* Garbage collect in progress */
-#define CACHE_CACHEW_THREADRUN 0x20 /* Cachep worker thread is alive */
-#define CACHE_CACHEW_THREADEXIT 0x40 /* cachew thread should exit */
-#define CACHE_DIRTY 0x80
-#define CACHE_PACKED_PENDING 0x100 /* Packed pending work to do */
-#define CACHE_CHECK_RLTYPE 0x200 /* double-check with resource lists */
-
-/*
- * Values for the mount options flag, opt_flags.
- */
-/*
- * Mount options
- */
-#define CFS_WRITE_AROUND 0x01 /* write-around */
-#define CFS_NONSHARED 0x02 /* write to cache and back file */
-#define CFS_NOCONST_MODE 0x08 /* no-op consistency mode */
-#define CFS_ACCESS_BACKFS 0x10 /* pass VOP_ACCESS to backfs */
-#define CFS_CODCONST_MODE 0x80 /* cod consistency mode */
-#define CFS_DISCONNECTABLE 0x100 /* server not reponding option */
-#define CFS_SOFT 0x200 /* soft mounted */
-#define CFS_NOACL 0x400 /* ACLs are disabled in this fs */
-#define CFS_LLOCK 0x800 /* use local file/record locks */
-#define CFS_SLIDE 0x1000 /* slide backfs under cachefs */
-#define CFS_NOFILL 0x2000 /* start in nofill mode */
-#define CFS_BACKFS_NFSV4 0x4000 /* back filesystem is NFSv4 */
-
-#define MAXCOOKIE_SIZE 36
-
-#define C_BACK_CHECK 0x2
-
-/*
- * Macro to determine if this is a snr error where we should do a
- * state transition.
- */
-
-#define CFS_TIMEOUT(FSCP, ERROR) \
- (ERROR && CFS_ISFS_SNR(FSCP) && \
- (((ERROR) == ETIMEDOUT) || ((ERROR) == EIO)))
-
-/*
- * Macros to assert that cachefs fscache and cnode are in
- * sync with NFSv4. Note that NFSv4 always passes-through
- * the vnode calls directly to the backfilesystem. For
- * this to work:
- * (1) cachefs is always setup for connected operation,
- * (2) cachefs options (example disconnectable (snr), nonshared, etc)
- * are disabled, and
- * (3) the back filesystem vnode pointer always exists
- * (except after a remove operation)
- * (4) the front filesystem vnode pointer is always NULL.
- */
-#ifdef DEBUG
-#define CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp) \
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
- ASSERT((fscp)->fs_info.fi_mntflags == CFS_BACKFS_NFSV4); \
- ASSERT((fscp)->fs_cdconnected == CFS_CD_CONNECTED); \
- }
-#define CFS_BACKFS_NFSV4_ASSERT_CNODE(cp) \
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
- if (MUTEX_HELD(&cp->c_statelock)) { \
- ASSERT((cp)->c_backvp != NULL || \
- ((cp)->c_flags & CN_DESTROY) != 0); \
- ASSERT((cp)->c_frontvp == NULL); \
- } else { \
- mutex_enter(&(cp)->c_statelock); \
- ASSERT((cp)->c_backvp != NULL || \
- ((cp)->c_flags & CN_DESTROY) != 0); \
- ASSERT((cp)->c_frontvp == NULL); \
- mutex_exit(&cp->c_statelock); \
- } \
- }
-#else
-#define CFS_BACKFS_NFSV4_ASSERT_FSCACHE(fscp)
-#define CFS_BACKFS_NFSV4_ASSERT_CNODE(cp)
-#endif /* DEBUG */
-
-#ifdef CFSDEBUG
-#define CFS_DPRINT_BACKFS_NFSV4(fscp, x) \
- if (CFS_ISFS_BACKFS_NFSV4(fscp)) { \
- CFS_DEBUG(CFSDEBUG_VOPS_NFSV4) \
- printf x; \
- }
-#else
-#define CFS_DPRINT_BACKFS_NFSV4(fscp, x)
-#endif /* CFSDEBUG */
-
-/*
- * cachefs_allocmap and cfs_cachefs_metadata are stored on disk,
- * so they need to be the same 32-bit vs. 64-bit.
- */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-
-/*
- * Large file support. The start offset of the cached file can be
- * greater than 2GB and by coelescing the different chunks we may
- * end up having a chunk of siz3 > 2GB.
- */
-
-struct cachefs_allocmap {
- u_offset_t am_start_off; /* Start offset of this chunk */
- u_offset_t am_size; /* size of this chunk */
-};
-
-#define C_MAX_ALLOCINFO_SLOTS 32
-
-/*
- * CFS fastsymlinks. For symlink of size < C_FSL_SIZE, the symlink
- * is stored in the cnode allocmap array.
- */
-#define C_FSL_SIZE (sizeof (struct cachefs_allocmap) * \
- C_MAX_ALLOCINFO_SLOTS)
-
-/*
- * Structure representing a cached object in memory.
- */
-struct cachefs_metadata {
- struct vattr md_vattr; /* attributes */
- o_mode_t md_aclclass; /* CLASS_OBJ perm for ACL */
- ushort_t md_pad1; /* compiler padding */
- fid_t md_cookie; /* back fid */
- int md_flags; /* various flags */
- uint_t md_rlno; /* rl entry */
- enum cachefs_rl_type md_rltype; /* rl type */
- int md_consttype; /* type of consistency */
- fid_t md_fid; /* fid of front file */
- uint_t md_frontblks; /* # blks used in frontfs */
- uint_t md_gen; /* fid uniquifier */
- struct cfs_cid md_parent; /* id of parent */
- timestruc_t md_timestamp; /* front file timestamp */
- timestruc_t md_x_time; /* see consistency routines */
- timestruc_t md_localmtime; /* persistent local mtime */
- timestruc_t md_localctime; /* persistent local ctime */
- uint_t md_resettimes; /* when to reset local times */
- ino64_t md_localfileno; /* persistent local inum */
- uint_t md_resetfileno; /* when to reset local fileno */
- uint_t md_seq; /* seq number for putpage */
- int md_allocents; /* nbr of entries in allocmap */
- struct cachefs_allocmap md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
-};
-typedef struct cachefs_metadata cachefs_metadata_t;
-
-#if (defined(_SYSCALL32) && defined(_LP64))
-
-/*
- * fid_t is long aligned, so user fid could be only 4 byte aligned.
- * Since vnode/vfs calls require fid_t (which would be 8 byte aligned in
- * _LP64), we would have to copy the user's value (and on-disk data) in/out.
- */
-/* on-disk metadata structure - fid aligned to int, time is 32-bit */
-
-struct cfs_cachefs_metadata {
- struct cfs_vattr md_vattr; /* attributes */
- o_mode_t md_aclclass; /* CLASS_OBJ perm for ACL */
- cfs_fid_t md_cookie; /* back fid */
- int md_flags; /* various flags */
- uint_t md_rlno; /* rl entry */
- enum cachefs_rl_type md_rltype; /* rl type */
- int md_consttype; /* type of consistency */
- cfs_fid_t md_fid; /* fid of front file */
- uint_t md_frontblks; /* # blks used in frontfs */
- uint_t md_gen; /* fid uniquifier */
- struct cfs_cid md_parent; /* id of parent */
- cfs_timestruc_t md_timestamp; /* front file timestamp */
- cfs_timestruc_t md_x_time; /* see consistency routines */
- cfs_timestruc_t md_localmtime; /* persistent local mtime */
- cfs_timestruc_t md_localctime; /* persistent local ctime */
- uint_t md_resettimes; /* when to reset local times */
- ino64_t md_localfileno; /* persistent local inum */
- uint_t md_resetfileno; /* when to reset local fileno */
- uint_t md_seq; /* seq number for putpage */
- int md_allocents; /* nbr of entries in allocmap */
- struct cachefs_allocmap md_allocinfo[C_MAX_ALLOCINFO_SLOTS];
-};
-typedef struct cfs_cachefs_metadata cfs_cachefs_metadata_t;
-
-#else /* not _SYSCALL32 && _LP64 */
-
-typedef cachefs_metadata_t cfs_cachefs_metadata_t;
-
-#define cfs_cachefs_metadata cachefs_metadata
-
-#endif /* _SYSCALL32 && _LP64 */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-
-/*
- * Various flags to be stored in md_flags field of the metadata.
- */
-#define MD_CREATEDONE 0x1 /* create was done to backfs */
-#define MD_POPULATED 0x2 /* front file or dir is populated */
-#define MD_FILE 0x4 /* front file or dir exists */
-#define MD_FASTSYMLNK 0x8 /* fast symbolic link */
-#define MD_PACKED 0x10 /* file is packed */
-#define MD_INVALREADDIR 0x40 /* repopulate on readdir */
-#define MD_PUTPAGE 0x200 /* we have already logged a putpage */
-#define MD_FREE 0x400 /* not used */
-#define MD_PUSHDONE 0x800 /* set if file pushed to back fs */
-#define MD_MAPPING 0x1000 /* set if cid mapping space written */
-#define MD_ACL 0x2000 /* file has a cached acl */
-#define MD_ACLDIR 0x4000 /* front `dir' exists for holding acl */
-#define MD_LOCALMTIME 0x8000 /* do not overwrite md_localmtime */
-#define MD_LOCALCTIME 0x10000 /* do not overwrite md_localctime */
-#define MD_LOCALFILENO 0x20000 /* do not overwrite md_localfileno */
-#define MD_NEEDATTRS 0x40000 /* new attrs needed at next check */
-
-#define C_MAX_MOUNT_FSCDIRNAME 128
-/*
- * cachefs mount structure and related data
- */
-struct cachefs_mountargs {
- struct cachefsoptions cfs_options; /* consistency modes, etc. */
- char *cfs_fsid; /* CFS ID fpr file system */
- char cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
- /* CFS fscdir name */
- char *cfs_cachedir; /* path for this cache dir */
- char *cfs_backfs; /* back filesystem dir */
- uint_t cfs_acregmin; /* same as nfs values */
- uint_t cfs_acregmax;
- uint_t cfs_acdirmin;
- uint_t cfs_acdirmax;
- char *cfs_hostname; /* server name */
- char *cfs_backfsname; /* back filesystem name */
-};
-
-#ifdef _SYSCALL32
-struct cachefs_mountargs32 {
- struct cachefsoptions cfs_options; /* consistency modes, etc. */
- caddr32_t cfs_fsid; /* CFS ID fpr file system */
- char cfs_cacheid[C_MAX_MOUNT_FSCDIRNAME];
- /* CFS fscdir name */
- caddr32_t cfs_cachedir; /* path for this cache dir */
- caddr32_t cfs_backfs; /* back filesystem dir */
- uint32_t cfs_acregmin; /* same as nfs values */
- uint32_t cfs_acregmax;
- uint32_t cfs_acdirmin;
- uint32_t cfs_acdirmax;
- caddr32_t cfs_hostname; /* server name */
- caddr32_t cfs_backfsname; /* back filesystem name */
-};
-#endif /* _SYSCALL32 */
-
-/*
- * struct cachefsops - consistency modules.
- */
-struct cachefsops {
- int (*co_init_cobject)();
- int (*co_check_cobject)();
- void (*co_modify_cobject)();
- void (*co_invalidate_cobject)();
- void (*co_convert_cobject)();
-};
-
-
-
-/*
- * The attrcache file consists of a attrcache_header structure and an
- * array of attrcache_slot structures (one per front file).
- */
-
-/*
- * Attrcache file format
- *
- * Header
- * Offset array (# of entries = file group size)
- * alloc list (1 bit per entry, 0 = free) Note that the
- * file will be extended as needed
- * attrcache entries
- *
- */
-struct attrcache_header {
- uint_t ach_count; /* number of entries */
- int ach_nffs; /* number of front files */
- int ach_nblks; /* number of allocated blocks */
- uint_t ach_rlno; /* rl entry for this file */
- enum cachefs_rl_type ach_rl_current; /* which list we're on */
-};
-
-/*
- * We assume that the seek offset to metadata will never be > 2GB.
- * The filegrp size is 256 and the current calculations of the sizes
- * of the data structures show that the ach_offset value here will not
- * be > 2GB.
- */
-
-struct attrcache_index {
- uint_t ach_written:1; /* 1 if metadata written */
- uint_t ach_offset:31; /* seek offset to metadata */
-};
-
-/*
- * cnode structure, one per file.
- */
-#define c_attr c_metadata.md_vattr
-#define c_cookie c_metadata.md_cookie
-#define c_fileno c_id.cid_fileno
-
-/*
- * LOCKS: c_rwlock Read / Write serialization
- * c_statelock Protects most other fields in the cnode
- * c_popcv Condvar used to prevent routines from nuking
- * a cnode which is currently being populated.
- * Threads blocked on it will be woken when the
- * populate completes.
- * c_iocv broadcast, but never waited on - unused?
- * c_iomutex c_nio and c_ioflags
- *
- * Fields protected by other locks:
- *
- * c_next fg_cnodelock in the filegrp struct
- * c_idleback fs_idlelock in fscache struct
- * c_idlefront fs_idlelock in fscache struct
- *
- * Large File support: c_size goes to u_offset_t and the apopoff type
- * goes to offset_t.
- */
-struct cnode {
- int c_flags; /* see below */
- struct cnode *c_next; /* next cnode in fgp list */
- struct cnode *c_idleback; /* idle list back ptr */
- struct cnode *c_idlefront; /* idle list front ptr */
- struct vnode *c_frontvp; /* front vnode pointer */
- struct vnode *c_backvp; /* back vnode pointer */
- struct vnode *c_acldirvp; /* dir for storing dflt ACL */
- u_offset_t c_size; /* client view of the size */
- struct filegrp *c_filegrp; /* back pointer to filegrp */
- struct cfs_cid c_id; /* unique file number */
- int c_invals; /* # of recent dir invals */
- int c_usage; /* Usefulness of cache */
- struct vnode *c_vnode; /* pointer to vnode */
- struct cachefs_metadata c_metadata; /* cookie, ... */
- int c_error;
- kmutex_t c_statelock; /* statelock */
- krwlock_t c_rwlock; /* serialize write/setattr requests */
- kcondvar_t c_popcv; /* cnode populate cond var. */
- kthread_id_t c_popthrp; /* threadp performing pop */
- vnode_t *c_unldvp; /* dir to unlink in */
- char *c_unlname; /* name to unlink */
- cred_t *c_unlcred; /* creds for unlink */
- int c_nio; /* Number of io's pending */
- uint_t c_ioflags;
- kcondvar_t c_iocv; /* IO cond var. */
- kmutex_t c_iomutex;
- cred_t *c_cred;
- int c_ipending; /* 1 if inactive is pending */
- int c_mapcnt; /* number of mapped blocks */
- offset_t c_apopoffset; /* offset for async pop */
- uint_t c_apoplen; /* length for async pop */
- u_offset_t c_modaddr; /* writepage offset */
- int c_rdcnt; /* # of read opens for backvp */
- int c_wrcnt; /* # of write opens for backvp */
-};
-typedef struct cnode cnode_t;
-
-extern struct kmem_cache *cachefs_cnode_cache;
-
-/*
- * Directory caching parameters - First cut...
- */
-#define CFS_DIRCACHE_COST 3
-#define CFS_DIRCACHE_INVAL 3
-#define CFS_DIRCACHE_ENABLE (CFS_DIRCACHE_INVAL * CFS_DIRCACHE_COST)
-
-/*
- * Conversion macros
- */
-#define VTOC(VP) ((struct cnode *)((void *)((VP)->v_data)))
-#define CTOV(CP) ((CP)->c_vnode)
-#define VFS_TO_FSCACHE(VFSP) ((struct fscache *)((void *)((VFSP)->vfs_data)))
-#define C_TO_FSCACHE(CP) (VFS_TO_FSCACHE(CTOV(CP)->v_vfsp))
-
-/*
- * Various flags stored in the flags field of the cnode structure.
- */
-#define CN_NOCACHE 0x1 /* no-cache mode */
-#define CN_DESTROY 0x2 /* destroy when inactive */
-#define CN_ROOT 0x4 /* root of the file system */
-#define CN_IDLE 0x8 /* file is idle */
-#define CN_NEEDOPEN 0x10 /* need to open backvp */
-#define CN_UPDATED 0x40 /* Metadata was updated - needs sync */
-#define CDIRTY 0x80
-#define CN_NEED_FRONT_SYNC 0x100 /* front file needs to be sync'd */
-#define CN_ALLOC_PENDING 0x200 /* Need to alloc attr cache entry */
-#define CN_STALE 0x400 /* cnode is stale */
-#define CN_MODIFIED 0x800 /* Object has been written to */
-#define CN_POPULATION_PENDING 0x1000 /* Population data needs to be sync'd */
-#define CN_ASYNC_POPULATE 0x2000 /* async population pending */
-#define CN_ASYNC_POP_WORKING 0x4000 /* async population in progress */
-#define CN_PENDRM 0x8000 /* hold off unlink until reconnected */
-#define CN_MAPWRITE 0x100000 /* mmapped file that is being written */
-#define CN_CMODINPROG 0x200000 /* writepage() in progress */
-
-/*
- * io flags (in c_ioflag)
- */
-#define CIO_PUTPAGES 0x1 /* putpage pending: off==0, len==0 */
-
-#define CFS_MAX_THREADS 5
-#define CFS_ASYNC_TIMEOUT (60 * hz)
-
-enum cachefs_cmd {
- CFS_INVALID,
- CFS_CACHE_SYNC,
- CFS_PUTPAGE,
- CFS_IDLE,
- CFS_POPULATE,
- CFS_NOOP
-};
-
-struct cachefs_fs_sync_req {
- struct cachefscache *cf_cachep;
-};
-
-struct cachefs_idle_req {
- vnode_t *ci_vp;
-};
-
-/*
- * Large File support the offset in the vnode for putpage request
- * can now be greater than 2GB.
- */
-
-struct cachefs_putpage_req {
- vnode_t *cp_vp;
- offset_t cp_off;
- int cp_len;
- int cp_flags;
-};
-
-/*
- * Large File support the offset in the vnode for populate request
- * can now be greater than 2GB.
- */
-
-struct cachefs_populate_req {
- vnode_t *cpop_vp;
- offset_t cpop_off;
- size_t cpop_size;
-};
-
-struct cachefs_req {
- struct cachefs_req *cfs_next;
- enum cachefs_cmd cfs_cmd; /* Command to execute */
- cred_t *cfs_cr;
- union {
- struct cachefs_fs_sync_req cu_fs_sync;
- struct cachefs_idle_req cu_idle;
- struct cachefs_putpage_req cu_putpage;
- struct cachefs_populate_req cu_populate;
- } cfs_req_u;
- kmutex_t cfs_req_lock; /* Protects contents */
-};
-
-extern struct kmem_cache *cachefs_req_cache;
-
-/*
- * Large file support: We allow cachefs to understand the 64 bit inode type.
- */
-
-struct cachefs_fid {
- ushort_t cf_len;
- ino64_t cf_fileno;
- uint_t cf_gen;
-};
-#define CFS_FID_SIZE (sizeof (struct cachefs_fid) - sizeof (ushort_t))
-
-/*
- *
- * cachefs kstat stuff. each time you mount a cachefs filesystem, it
- * gets a unique number. it'll get that number again if you remount
- * the same thing. the number is unique until reboot, but it doesn't
- * survive reboots.
- *
- * each cachefs kstat uses this per-filesystem identifier. to get the
- * valid identifiers, the `cachefs.0.key' kstat has a mapping of all
- * the available filesystems. its structure, cachefs_kstat_key, is
- * below.
- *
- */
-
-typedef struct cachefs_kstat_key {
- int ks_id;
- int ks_mounted;
- uint64_t ks_vfsp;
- uint64_t ks_mountpoint;
- uint64_t ks_backfs;
- uint64_t ks_cachedir;
- uint64_t ks_cacheid;
-} cachefs_kstat_key_t;
-extern cachefs_kstat_key_t *cachefs_kstat_key;
-extern int cachefs_kstat_key_n;
-
-/*
- * cachefs debugging aid. cachefs_debug_info_t is a cookie that we
- * can keep around to see what was happening at a certain time.
- *
- * for example, if we have a deadlock on the cnode's statelock
- * (i.e. someone is not letting go of it), we can add a
- * cachefs_debug_info_t * to the cnode structure, and call
- * cachefs_debug_save() whenever we grab the lock. then, when we're
- * deadlocked, we can see what was going on when we grabbed the lock
- * in the first place, and (hopefully) why we didn't release it.
- */
-
-#define CACHEFS_DEBUG_DEPTH (16)
-typedef struct cachefs_debug_info {
- char *cdb_message; /* arbitrary message */
- uint_t cdb_flags; /* arbitrary flags */
- int cdb_int; /* arbitrary int */
- void *cdb_pointer; /* arbitrary pointer */
- uint_t cdb_count; /* how many times called */
-
- cachefscache_t *cdb_cachep; /* relevant cachep (maybe undefined) */
- struct fscache *cdb_fscp; /* relevant fscache */
- struct cnode *cdb_cnode; /* relevant cnode */
- vnode_t *cdb_frontvp; /* relevant front vnode */
- vnode_t *cdb_backvp; /* relevant back vnode */
-
- kthread_id_t cdb_thread; /* thread who called */
- hrtime_t cdb_timestamp; /* when */
- int cdb_depth; /* depth of saved stack */
- pc_t cdb_stack[CACHEFS_DEBUG_DEPTH]; /* stack trace */
- struct cachefs_debug_info *cdb_next; /* pointer to next */
-} cachefs_debug_info_t;
-
-/*
- * cachefs function prototypes
- */
-#if defined(_KERNEL)
-extern int cachefs_getcookie(vnode_t *, struct fid *, struct vattr *,
- cred_t *, uint32_t);
-cachefscache_t *cachefs_cache_create(void);
-void cachefs_cache_destroy(cachefscache_t *cachep);
-int cachefs_cache_activate_ro(cachefscache_t *cachep, vnode_t *cdvp);
-void cachefs_cache_activate_rw(cachefscache_t *cachep);
-void cachefs_cache_dirty(struct cachefscache *cachep, int lockit);
-int cachefs_cache_rssync(struct cachefscache *cachep);
-void cachefs_cache_sync(struct cachefscache *cachep);
-uint_t cachefs_cache_unique(cachefscache_t *cachep);
-void cachefs_do_req(struct cachefs_req *);
-
-/* cachefs_cnode.c */
-void cachefs_cnode_idle(struct vnode *vp, cred_t *cr);
-void cachefs_cnode_idleclean(fscache_t *fscp, int unmount);
-int cachefs_cnode_inactive(register struct vnode *vp, cred_t *cr);
-void cachefs_cnode_listadd(struct cnode *cp);
-void cachefs_cnode_listrem(struct cnode *cp);
-void cachefs_cnode_free(struct cnode *cp);
-void cachefs_cnode_cleanfreelist();
-void cachefs_cnode_idleadd(struct cnode *cp);
-void cachefs_cnode_idlerem(struct cnode *cp);
-int cachefs_cnode_find(filegrp_t *fgp, cfs_cid_t *cidp, fid_t *cookiep,
- struct cnode **cpp, struct vnode *vp, vattr_t *vap);
-int cachefs_cnode_make(cfs_cid_t *cidp, fscache_t *fscp, fid_t *cookiep,
- vattr_t *vap, vnode_t *backvp, cred_t *cr, int flag, cnode_t **cpp);
-int cachefs_cid_inuse(filegrp_t *fgp, cfs_cid_t *cidp);
-int cachefs_fileno_inuse(fscache_t *fscp, ino64_t fileno);
-int cachefs_cnode_create(fscache_t *fscp, vattr_t *vap, int flag,
- cnode_t **cpp);
-void cachefs_cnode_move(cnode_t *cp);
-int cachefs_cnode_lostfound(cnode_t *cp, char *rname);
-void cachefs_cnode_sync(cnode_t *cp);
-void cachefs_cnode_traverse(fscache_t *fscp, void (*routinep)(cnode_t *));
-void cachefs_cnode_stale(cnode_t *cp);
-void cachefs_cnode_setlocalstats(cnode_t *cp);
-void cachefs_cnode_disable_caching(cnode_t *cp);
-
-void cachefs_enable_caching(struct fscache *);
-
-/* cachefs_fscache.c */
-void fscache_destroy(fscache_t *);
-
-/* cachefs_ioctl.h */
-int cachefs_pack_common(vnode_t *vp, cred_t *cr);
-void cachefs_inum_register(fscache_t *fscp, ino64_t real, ino64_t fake);
-ino64_t cachefs_inum_real2fake(fscache_t *fscp, ino64_t real);
-
-
-/* cachefs_subr.c */
-int cachefs_sync_metadata(cnode_t *);
-int cachefs_cnode_cnt(int);
-int cachefs_getbackvp(struct fscache *, struct cnode *);
-int cachefs_getfrontfile(cnode_t *);
-void cachefs_removefrontfile(cachefs_metadata_t *mdp, cfs_cid_t *cidp,
- filegrp_t *fgp);
-void cachefs_nocache(cnode_t *);
-void cachefs_inval_object(cnode_t *);
-void make_ascii_name(cfs_cid_t *cidp, char *strp);
-int cachefs_async_halt(struct cachefs_workq *, int);
-int cachefs_async_okay(void);
-int cachefs_check_allocmap(cnode_t *cp, u_offset_t off);
-void cachefs_update_allocmap(cnode_t *, u_offset_t, size_t);
-int cachefs_cachesymlink(struct cnode *cp, cred_t *cr);
-int cachefs_stuffsymlink(cnode_t *cp, caddr_t buf, int buflen);
-int cachefs_readlink_back(cnode_t *cp, cred_t *cr, caddr_t *bufp, int *buflenp);
-/*
- * void cachefs_cluster_allocmap(struct cnode *, u_offset_t, u_offset_t *,
- * size_t *, size_t);
- */
-void cachefs_cluster_allocmap(u_offset_t, u_offset_t *, size_t *, size_t,
- struct cnode *);
-int cachefs_populate(cnode_t *, u_offset_t, size_t, vnode_t *, vnode_t *,
- u_offset_t, cred_t *);
-int cachefs_stats_kstat_snapshot(kstat_t *, void *, int);
-cachefs_debug_info_t *cachefs_debug_save(cachefs_debug_info_t *, int,
- char *, uint_t, int, void *, cachefscache_t *, struct fscache *,
- struct cnode *);
-void cachefs_debug_show(cachefs_debug_info_t *);
-uint32_t cachefs_cred_checksum(cred_t *cr);
-int cachefs_frontfile_size(cnode_t *cp, u_offset_t length);
-int cachefs_req_create(void *, void *, int);
-void cachefs_req_destroy(void *, void *);
-int cachefs_stop_cache(cnode_t *);
-
-
-/* cachefs_resource.c */
-void cachefs_rlent_moveto_nolock(cachefscache_t *cachep,
- enum cachefs_rl_type type, uint_t entno, size_t);
-void cachefs_rlent_moveto(cachefscache_t *, enum cachefs_rl_type, uint_t,
- size_t);
-void cachefs_rlent_verify(cachefscache_t *, enum cachefs_rl_type, uint_t);
-void cachefs_rl_changefileno(cachefscache_t *cachep, uint_t entno,
- ino64_t fileno);
-int cachefs_rlent_data(cachefscache_t *cachep, rl_entry_t *valp,
- uint_t *entnop);
-void cachefs_move_modified_to_mf(cachefscache_t *cachep, fscache_t *fscp);
-int cachefs_allocblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
-void cachefs_freeblocks(cachefscache_t *, size_t, enum cachefs_rl_type);
-void cachefs_freefile(cachefscache_t *);
-int cachefs_allocfile(cachefscache_t *);
-int cachefs_rl_alloc(struct cachefscache *cachep, rl_entry_t *valp,
- uint_t *entnop);
-int cachefs_rl_attrc(struct cachefscache *, int, int);
-void cachefs_cachep_worker_thread(cachefscache_t *);
-void cachefs_rl_cleanup(cachefscache_t *);
-int cachefs_rl_entry_get(cachefscache_t *, uint_t, rl_entry_t **);
-#ifdef CFSRLDEBUG
-void cachefs_rl_debug_save(rl_entry_t *);
-void cachefs_rl_debug_show(rl_entry_t *);
-void cachefs_rl_debug_destroy(rl_entry_t *);
-#endif /* CFSRLDEBUG */
-
-/* cachefs_log.c */
-int cachefs_log_kstat_snapshot(kstat_t *, void *, int);
-void cachefs_log_process_queue(cachefscache_t *, int);
-int cachefs_log_logfile_open(cachefscache_t *, char *);
-struct cachefs_log_cookie
- *cachefs_log_create_cookie(struct cachefs_log_control *);
-void cachefs_log_error(cachefscache_t *, int, int);
-void cachefs_log_destroy_cookie(struct cachefs_log_cookie *);
-
-void cachefs_log_mount(cachefscache_t *, int, struct vfs *,
- fscache_t *, char *, enum uio_seg, char *);
-void cachefs_log_umount(cachefscache_t *, int, struct vfs *);
-void cachefs_log_getpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, u_offset_t, size_t);
-void cachefs_log_readdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, u_offset_t, int);
-void cachefs_log_readlink(cachefscache_t *, int, struct vfs *,
- fid_t *, ino64_t, uid_t, size_t);
-void cachefs_log_remove(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t);
-void cachefs_log_rmdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t);
-void cachefs_log_truncate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, u_offset_t);
-void cachefs_log_putpage(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, u_offset_t, size_t);
-void cachefs_log_create(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t);
-void cachefs_log_mkdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t);
-void cachefs_log_rename(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- int, uid_t);
-void cachefs_log_symlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, int);
-void cachefs_log_populate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- u_offset_t, size_t);
-void cachefs_log_csymlink(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- int);
-void cachefs_log_filldir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- u_offset_t);
-void cachefs_log_mdcreate(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uint_t);
-void cachefs_log_gpfront(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t, u_offset_t, uint_t);
-void cachefs_log_rfdir(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- uid_t);
-void cachefs_log_ualloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- u_offset_t, size_t);
-void cachefs_log_calloc(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t,
- u_offset_t, size_t);
-void cachefs_log_nocache(cachefscache_t *, int, struct vfs *, fid_t *, ino64_t);
-
-/* cachefs_vnops.c */
-struct vnodeops *cachefs_getvnodeops(void);
-int cachefs_lookup_common(vnode_t *dvp, char *nm, vnode_t **vpp,
- struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr);
-int cachefs_putpage_common(struct vnode *vp, offset_t off,
- size_t len, int flags, cred_t *cr);
-ino64_t cachefs_fileno_conflict(fscache_t *fscp, ino64_t old);
-int cachefs_remove_connected(vnode_t *dvp, char *nm, cred_t *cr,
- vnode_t *vp);
-int cachefs_remove_disconnected(vnode_t *dvp, char *nm, cred_t *cr,
- vnode_t *vp);
-int cachefs_cacheacl(cnode_t *, vsecattr_t *);
-void cachefs_purgeacl(cnode_t *);
-int cachefs_vtype_aclok(vnode_t *);
-
-/* cachefs_vfsops.c */
-int cachefs_init_vfsops(int);
-int cachefs_init_vnops(char *);
-void cachefs_kstat_mount(struct fscache *, char *, char *, char *, char *);
-void cachefs_kstat_umount(int);
-int cachefs_kstat_key_update(kstat_t *, int);
-int cachefs_kstat_key_snapshot(kstat_t *, void *, int);
-
-extern void cachefs_workq_init(struct cachefs_workq *);
-extern void cachefs_addqueue(struct cachefs_req *, struct cachefs_workq *);
-
-
-extern void *cachefs_kmem_alloc(size_t, int);
-extern void *cachefs_kmem_zalloc(size_t, int);
-extern void cachefs_kmem_free(void *, size_t);
-extern char *cachefs_strdup(char *);
-
-#endif /* defined (_KERNEL) */
-
-
-
-#define C_RL_MAXENTS 0x4000 /* Whatever */
-
-/*
- * ioctls.
- */
-#include <sys/ioccom.h>
-#define _FIOCOD _IO('f', 78) /* consistency on demand */
-#define _FIOSTOPCACHE _IO('f', 86) /* stop using cache */
-
-#define CACHEFSIO_PACK _IO('f', 81)
-#define CACHEFSIO_UNPACK _IO('f', 82)
-#define CACHEFSIO_UNPACKALL _IO('f', 83)
-#define CACHEFSIO_PACKINFO _IO('f', 84)
-#define CACHEFSIO_DCMD _IO('f', 85)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_FS_CACHEFS_FS_H */
diff --git a/usr/src/uts/common/sys/fs/cachefs_fscache.h b/usr/src/uts/common/sys/fs/cachefs_fscache.h
deleted file mode 100644
index e2c012b2ff..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_fscache.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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_FSCACHE_H
-#define _SYS_FS_CACHEFS_FSCACHE_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CFS_FS_FGP_BUCKET_SIZE 64 /* must be a power of 2 */
-#define CFS_FS_MAXIDLE 100
-
-enum cachefs_connected {
- CFS_CD_CONNECTED = 0x801, /* connected to back fs */
- CFS_CD_DISCONNECTED, /* disconnected from back fs */
- CFS_CD_RECONNECTING /* rolling log to back fs */
-};
-
-typedef struct cachefs_stats {
- uint_t st_hits;
- uint_t st_misses;
- uint_t st_passes;
- uint_t st_fails;
- uint_t st_modifies;
- uint_t st_gc_count;
- cfs_time_t st_gc_time;
- cfs_time_t st_gc_before_atime;
- cfs_time_t st_gc_after_atime;
-} cachefs_stats_t;
-
-/* file system persistant state */
-struct cachefs_fsinfo {
- uint_t fi_mntflags; /* mount flags */
- int fi_popsize; /* cache population size */
- ino64_t fi_root; /* inode # of root of fs */
- uint_t fi_resettimes; /* when to reset local times */
- uint_t fi_resetfileno; /* when to reset local fileno */
- ino64_t fi_localfileno; /* next local fileno to use */
- int fi_fgsize; /* filegrp size, default 256 */
- uint_t fi_pad[1]; /* pad field */
-};
-typedef struct cachefs_fsinfo cachefs_fsinfo_t;
-
-/*
- * used to translate the server's idea of inode numbers into the
- * client's idea, after a reconnect, in a directory entry a la
- * readdir()
- */
-
-typedef struct cachefs_inum_trans {
- ino64_t cit_real;
- ino64_t cit_fake;
-} cachefs_inum_trans_t;
-
-extern int cachefs_hash_sizes[];
-
-/*
- * fscache structure contains per-filesystem information, both filesystem
- * cache directory information and mount-specific information.
- */
-struct fscache {
- ino64_t fs_cfsid; /* File system ID */
- int fs_flags;
- struct vnode *fs_fscdirvp; /* vp to fs cache dir */
- struct vnode *fs_fsattrdir; /* vp to attrcache dir */
- struct vnode *fs_infovp; /* vp to fsinfo file */
- struct cachefscache *fs_cache; /* back ptr to cache struct */
- cachefs_fsinfo_t fs_info; /* fs persistant state */
- struct vfs *fs_cfsvfsp; /* cfs vfsp */
- struct vfs *fs_backvfsp; /* back file system vfsp */
- struct vnode *fs_rootvp; /* root vnode ptr */
- offset_t fs_offmax; /* maximum offset if backvp */
- int fs_ref; /* ref count on fscache */
- int fs_cnodecnt; /* cnt of cnodes on fscache */
- int fs_consttype; /* type of consistency check */
- struct cachefsops *fs_cfsops; /* cfsops vector pointer */
- uint_t fs_acregmin; /* same as nfs values */
- uint_t fs_acregmax;
- uint_t fs_acdirmin;
- uint_t fs_acdirmax;
- struct fscache *fs_next; /* ptr to next fscache */
- struct cachefs_workq fs_workq; /* async thread work queue */
-
- kmutex_t fs_fslock; /* contents lock */
-
- struct vnode *fs_dlogfile; /* log file */
- off_t fs_dlogoff; /* offset into log file */
- uint_t fs_dlogseq; /* sequence number */
- struct vnode *fs_dmapfile; /* map file */
- off_t fs_dmapoff; /* offset into map file */
- off_t fs_dmapsize; /* size of map file */
- kmutex_t fs_dlock; /* protects d* variables */
-
- kmutex_t fs_idlelock; /* idle* lock */
- int fs_idlecnt; /* number of idle cnodes */
- int fs_idleclean; /* cleaning idle list */
- struct cnode *fs_idlefront; /* front of idle list */
-
- /* related to connected or disconnected (cd) */
- kmutex_t fs_cdlock; /* protects fs_cd* variables */
- kcondvar_t fs_cdwaitcv; /* signal state transitions */
- enum cachefs_connected fs_cdconnected; /* how connected to backfs */
- int fs_cdtransition; /* 1 transitioning, 0 not */
- pid_t fs_cddaemonid; /* pid of cachefsd */
- int fs_cdrefcnt; /* # threads in cachefs */
-
- struct cnode *fs_idleback; /* back of idle list */
-
- cachefs_inum_trans_t *fs_inum_trans; /* real->fake inums */
- int fs_inum_size; /* # fs_inum_trans alloced */
-
- /* list of fgps */
- struct filegrp *fs_filegrp[CFS_FS_FGP_BUCKET_SIZE];
-
- timestruc_t fs_cod_time; /* time of CoD event */
- int fs_kstat_id;
- cachefs_stats_t fs_stats;
- char *fs_mntpt;
- char *fs_hostname;
- char *fs_backfsname;
-};
-typedef struct fscache fscache_t;
-
-extern struct kmem_cache *cachefs_fscache_cache;
-
-/* valid fscache flags */
-#define CFS_FS_MOUNTED 0x01 /* fscache is mounted */
-#define CFS_FS_READ 0x02 /* fscache can be read */
-#define CFS_FS_WRITE 0x04 /* fscache can be written */
-#define CFS_FS_ROOTFS 0x08 /* fscache is / */
-#define CFS_FS_DIRTYINFO 0x10 /* fs_info needs to be written */
-#define CFS_FS_HASHPRINT 0x20 /* hash warning already printed once */
-
-/* types of consistency checking */
-#define CFS_FS_CONST_STRICT 11 /* strict consistency */
-#define CFS_FS_CONST_NOCONST 12 /* no consistency */
-#define CFS_FS_CONST_CODCONST 13 /* consistency on demand */
-
-#define CFSOP_INIT_COBJECT(FSCP, CP, VAP, CR) \
- (*(FSCP)->fs_cfsops->co_init_cobject)(FSCP, CP, VAP, CR)
-#define CFSOP_CHECK_COBJECT(FSCP, CP, WHAT, CR) \
- (*(FSCP)->fs_cfsops->co_check_cobject)(FSCP, CP, WHAT, CR)
-#define CFSOP_MODIFY_COBJECT(FSCP, CP, CR) \
- (*(FSCP)->fs_cfsops->co_modify_cobject)(FSCP, CP, CR)
-#define CFSOP_INVALIDATE_COBJECT(FSCP, CP, CR) \
- (*(FSCP)->fs_cfsops->co_invalidate_cobject)(FSCP, CP, CR)
-#define CFSOP_CONVERT_COBJECT(FSCP, CP, CR) \
- (*(FSCP)->fs_cfsops->co_convert_cobject)(FSCP, CP, CR)
-
-#define CFS_ISFS_SNR(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_DISCONNECTABLE)
-#define CFS_ISFS_SOFT(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_SOFT)
-
-#define CFS_ISFS_WRITE_AROUND(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_WRITE_AROUND)
-#define CFS_ISFS_NONSHARED(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_NONSHARED)
-
-#define CFS_ISFS_STRICT(FSCP) \
- (((FSCP)->fs_info.fi_mntflags & CFS_WRITE_AROUND) && \
- (((FSCP)->fs_info.fi_mntflags & \
- (CFS_NOCONST_MODE | CFS_CODCONST_MODE)) == 0))
-#define CFS_ISFS_NOCONST(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_NOCONST_MODE)
-#define CFS_ISFS_CODCONST(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_CODCONST_MODE)
-
-#define CFS_ISFS_LLOCK(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_LLOCK)
-#define CFS_ISFS_BACKFS_NFSV4(FSCP) \
- ((FSCP)->fs_info.fi_mntflags & CFS_BACKFS_NFSV4)
-
-fscache_t *fscache_create(cachefscache_t *cachep);
-void fscache_destory(fscache_t *fscp);
-int fscache_activate(fscache_t *fscp, ino64_t fsid, char *namep,
- struct cachefsoptions *optp, ino64_t backfileno);
-int fscache_enable(fscache_t *fscp, ino64_t fsid, char *namep,
- struct cachefsoptions *optp, ino64_t backfileno);
-void fscache_activate_rw(fscache_t *fscp);
-void fscache_hold(fscache_t *fscp);
-void fscache_rele(fscache_t *fscp);
-int fscache_cnodecnt(fscache_t *fscp, int cnt);
-int fscache_mounted(fscache_t *fscp, struct vfs *cfsvfsp, struct vfs *backvfsp);
-int fscache_compare_options(fscache_t *fscp, struct cachefsoptions *opnewp);
-void fscache_sync(fscache_t *fscp);
-void fscache_acset(fscache_t *fscp,
- uint_t acregmin, uint_t acregmax, uint_t acdirmin, uint_t acdirmax);
-
-fscache_t *fscache_list_find(cachefscache_t *cachep, ino64_t fsid);
-void fscache_list_add(cachefscache_t *cachep, fscache_t *fscp);
-void fscache_list_remove(cachefscache_t *cachep, fscache_t *fscp);
-void fscache_list_gc(cachefscache_t *cachep);
-int fscache_list_mounted(cachefscache_t *cachep);
-
-int fscache_name_to_fsid(cachefscache_t *cachep, char *namep, ino64_t *fsidp);
-
-int cachefs_cd_access(fscache_t *fscp, int waitconnected, int writing);
-int cachefs_cd_access_miss(fscache_t *fscp);
-void cachefs_cd_release(fscache_t *fscp);
-void cachefs_cd_timedout(fscache_t *fscp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_FS_CACHEFS_FSCACHE_H */
diff --git a/usr/src/uts/common/sys/fs/cachefs_ioctl.h b/usr/src/uts/common/sys/fs/cachefs_ioctl.h
deleted file mode 100644
index 1704295fb8..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_ioctl.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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 1996-1998,2001-2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SYS_FS_CACHEFS_IOCTL_H
-#define _SYS_FS_CACHEFS_IOCTL_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* set of subcommands to CACHEFSIO_DCMD */
-enum cfsdcmd_cmds {
- CFSDCMD_DAEMONID, CFSDCMD_STATEGET, CFSDCMD_STATESET,
- CFSDCMD_XWAIT, CFSDCMD_EXISTS, CFSDCMD_LOSTFOUND, CFSDCMD_GETINFO,
- CFSDCMD_CIDTOFID, CFSDCMD_GETATTRFID, CFSDCMD_GETATTRNAME,
- CFSDCMD_GETSTATS, CFSDCMD_ROOTFID,
- CFSDCMD_CREATE, CFSDCMD_REMOVE, CFSDCMD_LINK, CFSDCMD_RENAME,
- CFSDCMD_MKDIR, CFSDCMD_RMDIR, CFSDCMD_SYMLINK, CFSDCMD_SETATTR,
- CFSDCMD_SETSECATTR, CFSDCMD_PUSHBACK
-};
-typedef enum cfsdcmd_cmds cfsdcmd_cmds_t;
-
-/* file system states passed to stateset, returned from stateget */
-#define CFS_FS_CONNECTED 0x00 /* fscache connected to backfs */
-#define CFS_FS_DISCONNECTED 0x01 /* fscache disconnected from backfs */
-#define CFS_FS_RECONNECTING 0x02 /* fscache is reconnecting to backfs */
-
-/* bits returned by packinfo */
-#define CACHEFS_PACKED_FILE 1 /* file is marked as packed */
-#define CACHEFS_PACKED_DATA 2 /* file data is in the cache */
-#define CACHEFS_PACKED_NOCACHE 4 /* file marked as not for caching */
-
-struct cachefsio_pack {
- char p_name[MAXNAMELEN]; /* name of file */
- int p_status; /* status of operation */
-};
-typedef struct cachefsio_pack cachefsio_pack_t;
-
-struct cachefsio_dcmd {
- cfsdcmd_cmds_t d_cmd; /* cmd to execute */
- void *d_sdata; /* data for command */
- int d_slen; /* len of data */
- void *d_rdata; /* data to return */
- int d_rlen; /* len of data */
-};
-typedef struct cachefsio_dcmd cachefsio_dcmd_t;
-
-struct cachefsio_getinfo {
- cfs_cid_t gi_cid; /* entry to lookup */
- int gi_modified; /* returns if modified data */
- cfs_vattr_t gi_attr; /* return file attributes */
- cfs_cid_t gi_pcid; /* returns the parent dir */
- uint_t gi_seq; /* sequence number */
- char gi_name[MAXNAMELEN]; /* returns name of file */
-};
-typedef struct cachefsio_getinfo cachefsio_getinfo_t;
-
-struct cachefsio_lostfound_arg {
- cfs_cid_t lf_cid; /* file to move */
- char lf_name[MAXNAMELEN]; /* suggested name */
-};
-typedef struct cachefsio_lostfound_arg cachefsio_lostfound_arg_t;
-
-struct cachefsio_lostfound_return {
- char lf_name[MAXNAMELEN]; /* returns actual name */
-};
-typedef struct cachefsio_lostfound_return cachefsio_lostfound_return_t;
-
-struct cachefsio_getattrfid {
- cfs_fid_t cg_backfid; /* backfs fid of file */
- dl_cred_t cg_cred; /* creds */
- gid_t cg_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_getattrfid cachefsio_getattrfid_t;
-
-struct cachefsio_getattrname_arg {
- cfs_fid_t cg_dir; /* backfs fid of directory */
- char cg_name[MAXNAMELEN]; /* name of file in directory cg_dir */
- dl_cred_t cg_cred; /* creds */
- gid_t cg_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_getattrname_arg cachefsio_getattrname_arg_t;
-
-struct cachefsio_getattrname_return {
- cfs_vattr_t cg_attr; /* returns attributes of file */
- cfs_fid_t cg_fid; /* returns fid of file */
-};
-typedef struct cachefsio_getattrname_return cachefsio_getattrname_return_t;
-
-struct cachefsio_getstats {
- int gs_total; /* total blocks */
- int gs_gc; /* number of gc blocks */
- int gs_active; /* number of active blocks */
- int gs_packed; /* number of packed blocks */
- int gs_free; /* number of free blocks */
- cfs_time_t gs_gctime; /* atime of front of gc list */
-};
-typedef struct cachefsio_getstats cachefsio_getstats_t;
-
-struct cachefsio_create_arg {
- cfs_fid_t cr_backfid; /* backfs fid of directory */
- char cr_name[MAXNAMELEN]; /* name of file to create */
- cfs_cid_t cr_cid; /* cid of file being created */
- cfs_vattr_t cr_va; /* attributes for create */
- int cr_exclusive; /* exclusive create or not */
- int cr_mode; /* mode */
- dl_cred_t cr_cred; /* creds */
- gid_t cr_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_create_arg cachefsio_create_arg_t;
-
-struct cachefsio_create_return {
- cfs_fid_t cr_newfid; /* returns fid of new file */
- cfs_timestruc_t cr_ctime; /* returns new ctime */
- cfs_timestruc_t cr_mtime; /* returns new mtime */
-};
-typedef struct cachefsio_create_return cachefsio_create_return_t;
-
-struct cachefsio_pushback_arg {
- cfs_cid_t pb_cid; /* file to push back */
- cfs_fid_t pb_fid; /* back fs fid to push to */
- dl_cred_t pb_cred; /* creds */
- gid_t pb_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_pushback_arg cachefsio_pushback_arg_t;
-
-struct cachefsio_pushback_return {
- cfs_timestruc_t pb_ctime; /* returns new ctime */
- cfs_timestruc_t pb_mtime; /* returns new mtime */
-};
-typedef struct cachefsio_pushback_return cachefsio_pushback_return_t;
-
-struct cachefsio_remove {
- cfs_cid_t rm_cid; /* cid of deleted file */
- cfs_fid_t rm_fid; /* fid of parent directory */
- char rm_name[MAXNAMELEN]; /* name of file to remove */
- int rm_getctime; /* 1 means return new ctime */
- dl_cred_t rm_cred; /* creds */
- gid_t rm_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_remove cachefsio_remove_t;
-
-struct cachefsio_link {
- cfs_fid_t ln_dirfid; /* backfid of parent dir */
- char ln_name[MAXNAMELEN]; /* name of new link */
- cfs_fid_t ln_filefid; /* backfid of file to link to */
- cfs_cid_t ln_cid; /* cid of link */
- dl_cred_t ln_cred; /* creds */
- gid_t ln_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_link cachefsio_link_t;
-
-struct cachefsio_rename_arg {
- cfs_fid_t rn_olddir; /* backfs fid of old dir */
- char rn_oldname[MAXNAMELEN]; /* old name of file */
- cfs_fid_t rn_newdir; /* backfs fid of new dir */
- char rn_newname[MAXNAMELEN]; /* new name of file */
- cfs_cid_t rn_cid; /* cid of renamed file */
- int rn_del_getctime; /* 1 means fill in del_ctime */
- cfs_cid_t rn_del_cid; /* cid of deleted file */
- dl_cred_t rn_cred; /* creds */
- gid_t rn_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_rename_arg cachefsio_rename_arg_t;
-
-struct cachefsio_rename_return {
- cfs_timestruc_t rn_ctime; /* returns new file ctime */
- cfs_timestruc_t rn_del_ctime; /* returns new del file ctime */
-};
-typedef struct cachefsio_rename_return cachefsio_rename_return_t;
-
-struct cachefsio_mkdir {
- cfs_fid_t md_dirfid; /* backfs fid of dir */
- char md_name[MAXNAMELEN]; /* name of the new dir */
- cfs_cid_t md_cid; /* cid of dir being created */
- cfs_vattr_t md_vattr; /* attributes */
- dl_cred_t md_cred; /* creds */
- gid_t md_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_mkdir cachefsio_mkdir_t;
-
-struct cachefsio_rmdir {
- cfs_fid_t rd_dirfid; /* backfs fid of dir */
- char rd_name[MAXNAMELEN]; /* name of the dir to delete */
- dl_cred_t rd_cred; /* creds */
- gid_t rd_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_rmdir cachefsio_rmdir_t;
-
-struct cachefsio_symlink_arg {
- cfs_fid_t sy_dirfid; /* backfs fid of dir */
- char sy_name[MAXNAMELEN]; /* name of symlink to create */
- cfs_cid_t sy_cid; /* cid of symlink */
- char sy_link[MAXPATHLEN]; /* contents of the symlink */
- cfs_vattr_t sy_vattr; /* attributes */
- dl_cred_t sy_cred; /* creds */
- gid_t sy_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_symlink_arg cachefsio_symlink_arg_t;
-
-struct cachefsio_symlink_return {
- cfs_fid_t sy_newfid; /* returns fid of symlink */
- cfs_timestruc_t sy_ctime; /* returns new ctime */
- cfs_timestruc_t sy_mtime; /* returns new mtime */
-};
-typedef struct cachefsio_symlink_return cachefsio_symlink_return_t;
-
-struct cachefsio_setattr_arg {
- cfs_fid_t sa_backfid; /* backfs fid of file */
- cfs_cid_t sa_cid; /* cid of file */
- cfs_vattr_t sa_vattr; /* attributes */
- int sa_flags; /* flags */
- dl_cred_t sa_cred; /* creds */
- gid_t sa_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_setattr_arg cachefsio_setattr_arg_t;
-
-struct cachefsio_setattr_return {
- cfs_timestruc_t sa_ctime; /* returns new ctime */
- cfs_timestruc_t sa_mtime; /* returns new mtime */
-};
-typedef struct cachefsio_setattr_return cachefsio_setattr_return_t;
-
-struct cachefsio_setsecattr_arg {
- cfs_fid_t sc_backfid; /* backfs fid of file */
- cfs_cid_t sc_cid; /* cid of file */
- uint_t sc_mask; /* mask for setsec */
- int sc_aclcnt; /* count of ACLs */
- int sc_dfaclcnt; /* count of default ACLs */
- aclent_t sc_acl[MAX_ACL_ENTRIES]; /* ACLs */
- dl_cred_t sc_cred; /* creds */
- gid_t sc_groups[NGROUPS_MAX_DEFAULT-1];
-};
-typedef struct cachefsio_setsecattr_arg cachefsio_setsecattr_arg_t;
-
-struct cachefsio_setsecattr_return {
- cfs_timestruc_t sc_ctime; /* returns new ctime */
- cfs_timestruc_t sc_mtime; /* returns new mtime */
-};
-typedef struct cachefsio_setsecattr_return cachefsio_setsecattr_return_t;
-
-#ifdef _SYSCALL32
-
-/*
- * Solaris 64 - the following structs are used for user/kernel communication.
- */
-
-struct cachefsio_dcmd32 {
- cfsdcmd_cmds_t d_cmd; /* cmd to execute */
- caddr32_t d_sdata; /* data for command */
- int32_t d_slen; /* len of data */
- caddr32_t d_rdata; /* data to return */
- int32_t d_rlen; /* len of data */
-};
-typedef struct cachefsio_dcmd32 cachefsio_dcmd32_t;
-
-#endif /* _SYSCALL32 */
-
-int cachefs_pack(vnode_t *, char *, cred_t *);
-int cachefs_unpack(vnode_t *, char *, cred_t *);
-int cachefs_packinfo(vnode_t *dvp, char *name, int *statusp, cred_t *cr);
-int cachefs_unpackall(vnode_t *);
-
-int cachefs_io_daemonid(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_stateget(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_stateset(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_xwait(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_exists(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_lostfound(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_getinfo(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_cidtofid(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_getattrfid(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_getattrname(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_getstats(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_rootfid(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_create(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_remove(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_link(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_rename(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_mkdir(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_rmdir(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_symlink(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_setattr(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_setsecattr(vnode_t *vp, void *dinp, void *doutp);
-int cachefs_io_pushback(vnode_t *vp, void *dinp, void *doutp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_FS_CACHEFS_IOCTL_H */
diff --git a/usr/src/uts/common/sys/fs/cachefs_log.h b/usr/src/uts/common/sys/fs/cachefs_log.h
deleted file mode 100644
index 5f339b8249..0000000000
--- a/usr/src/uts/common/sys/fs/cachefs_log.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * 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_LOG_H
-#define _SYS_FS_CACHEFS_LOG_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/types32.h>
-#include <sys/vfs.h>
-#include <sys/fs/cachefs_fs.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* constants, etc. */
-
-#define CACHEFS_LOG_MAGIC 32321
-#define CACHEFS_LOG_FILE_REV 2
-
-#define CACHEFS_LOG_MOUNT 1
-#define CACHEFS_LOG_UMOUNT 2
-#define CACHEFS_LOG_GETPAGE 3
-#define CACHEFS_LOG_READDIR 4
-#define CACHEFS_LOG_READLINK 5
-#define CACHEFS_LOG_REMOVE 6
-#define CACHEFS_LOG_RMDIR 7
-#define CACHEFS_LOG_TRUNCATE 8
-#define CACHEFS_LOG_PUTPAGE 9
-#define CACHEFS_LOG_CREATE 10
-#define CACHEFS_LOG_MKDIR 11
-#define CACHEFS_LOG_RENAME 12
-#define CACHEFS_LOG_SYMLINK 13
-#define CACHEFS_LOG_POPULATE 14
-#define CACHEFS_LOG_CSYMLINK 15
-#define CACHEFS_LOG_FILLDIR 16
-#define CACHEFS_LOG_MDCREATE 17
-#define CACHEFS_LOG_GPFRONT 18
-#define CACHEFS_LOG_RFDIR 19
-#define CACHEFS_LOG_UALLOC 20
-#define CACHEFS_LOG_CALLOC 21
-#define CACHEFS_LOG_NOCACHE 22
-#define CACHEFS_LOG_NUMRECS 22
-
-/*
- * cachefs_log_* are stored on disk, so they need to be the same
- * 32-bit vs. 64-bit.
- */
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
-#endif
-
-/*
- * for communicating from user to kernel, or for storing state.
- */
-
-typedef struct cachefs_log_control {
- int lc_magic;
- char lc_path[MAXPATHLEN];
- uchar_t lc_which[(CACHEFS_LOG_NUMRECS / NBBY) + 1];
- uint64_t lc_cachep; /* really cachefscache_t * */
-} cachefs_log_control_t;
-
-/*
- * per-cachefscache information
- */
-
-typedef struct cachefs_log_cookie {
- void *cl_head; /* head of records to be written */
- void *cl_tail; /* tail of records to be written */
- uint_t cl_size; /* # of bytes to be written */
-
- struct vnode *cl_logvp; /* vnode for logfile */
-
- cachefs_log_control_t *cl_logctl; /* points at ksp->ks_data */
-
- int cl_magic; /* cheap sanity check */
-} cachefs_log_cookie_t;
-
-/* macros for determining which things we're logging + misc stuff */
-#define CACHEFS_LOG_LOGGING(cp, which) \
- ((cp != NULL) && \
- (cp->c_log != NULL) && \
- (cp->c_log_ctl->lc_which[which / NBBY] & \
- (1 << (which % NBBY))))
-#define CACHEFS_LOG_SET(lc, which) \
- (lc->lc_which[which / NBBY] |= (1 << (which % NBBY)))
-#define CACHEFS_LOG_CLEAR(lc, which) \
- (lc->lc_which[which / NBBY] &= ~(1 << (which % NBBY)))
-#define CLPAD(sname, field) \
- (sizeof (struct sname) - \
- offsetof(struct sname, field) - \
- sizeof (((struct sname *)0)->field))
-
-struct cachefs_log_logfile_header {
- uint_t lh_magic;
- uint_t lh_revision;
- int lh_errno;
- uint_t lh_blocks;
- uint_t lh_files;
- uint_t lh_maxbsize;
- uint_t lh_pagesize;
-};
-
-/*
- * declarations of the logging records.
- *
- * note -- the first three fields must be int, int, and time_t (time32_t),
- * corresponding to record type, error status, and timestamp.
- *
- * note -- the size of a trailing string should be large enough to
- * hold any necessary null-terminating bytes. i.e. for one string,
- * say `char foo[1]'. for two strings, null-separated, say `char
- * foo[2]'.
- *
- * XX64 time32_t (above) is going to be a problem when the underlying
- * filesystems support 64-bit time.
- */
-
-/*
- * XX64 - for now define all time types as 32-bits.
- */
-
-#if (defined(_SYSCALL32) && defined(_LP64))
-typedef uid32_t cfs_uid_t;
-#else /* not _SYSCALL32 && _LP64 */
-typedef uid_t cfs_uid_t;
-#endif /* _SYSCALL32 && _LP64 */
-
-struct cachefs_log_mount_record {
- int type; /* == CACHEFS_LOG_MOUNT */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* vfs pointer -- unique while mounted */
- uint_t flags; /* opt_flags from cachefsoptions */
- uint_t popsize; /* opt_popsize from cachefsoptions */
- uint_t fgsize; /* opt_fgsize from cachefsoptions */
- ushort_t pathlen; /* length of path */
- ushort_t cacheidlen; /* length of cacheid */
- char path[2]; /* the path of the mountpoint, and cacheid */
-};
-
-struct cachefs_log_umount_record {
- int type; /* == CACHEFS_LOG_UMOUNT */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* vfs pointer we're unmounting */
-};
-
-struct cachefs_log_getpage_record {
- int type; /* == CACHEFS_LOG_GETPAGE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* file identifier */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- u_offset_t offset; /* offset we're getting */
- uint_t len; /* how many bytes we're getting */
-};
-
-struct cachefs_log_readdir_record {
- int type; /* == CACHEFS_LOG_READDIR */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* file identifier */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- u_offset_t offset; /* offset into directory */
- int eof; /* like `*eofp' in VOP_READDIR */
-};
-
-struct cachefs_log_readlink_record {
- int type; /* == CACHEFS_LOG_READLINK */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* file identifier */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- uint_t length; /* length of symlink */
-};
-
-struct cachefs_log_remove_record {
- int type; /* == CACHEFS_LOG_REMOVE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of file being removed */
- /* (not the directory holding the file) */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_rmdir_record {
- int type; /* == CACHEFS_LOG_RMDIR */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of directory being removed */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_truncate_record {
- int type; /* == CACHEFS_LOG_TRUNCATE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* file being truncated */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- u_offset_t size; /* new size */
-};
-
-struct cachefs_log_putpage_record {
- int type; /* == CACHEFS_LOG_PUTPAGE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* file being written */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- u_offset_t offset; /* offset */
- uint_t len; /* length */
-};
-
-struct cachefs_log_create_record {
- int type; /* == CACHEFS_LOG_CREATE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of newly created file */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_mkdir_record {
- int type; /* == CACHEFS_LOG_MKDIR */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of newly created directory */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_rename_record {
- int type; /* == CACHEFS_LOG_RENAME */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t gone; /* fid of file removed (may be undefined) */
- ino64_t fileno; /* fileno */
- int removed; /* nonzero if file was removed */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_symlink_record {
- int type; /* == CACHEFS_LOG_SYMLINK */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of newly created symlink */
- ino64_t fileno; /* fileno */
- uint_t size; /* size of newly created symlink */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_populate_record {
- int type; /* == CACHEFS_LOG_POPULATE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of file being populated */
- ino64_t fileno; /* fileno */
- u_offset_t off; /* offset */
- uint_t size; /* popsize */
-};
-
-struct cachefs_log_csymlink_record {
- int type; /* == CACHEFS_LOG_CSYMLINK */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of symlink being cached */
- ino64_t fileno; /* fileno */
- int size; /* size of symlink being cached */
-};
-
-struct cachefs_log_filldir_record {
- int type; /* == CACHEFS_LOG_FILLDIR */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of directory being filled */
- ino64_t fileno; /* fileno */
- int size; /* size of frontfile after filling */
-};
-
-struct cachefs_log_mdcreate_record {
- int type; /* == CACHEFS_LOG_MDCREATE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of file for whom md slot is created */
- ino64_t fileno; /* fileno */
- uint_t count; /* new number of entries in attrcache */
-};
-
-struct cachefs_log_gpfront_record {
- int type; /* == CACHEFS_LOG_GPFRONT */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of file for whom md slot is created */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
- u_offset_t off; /* offset */
- uint_t len; /* length */
-};
-
-struct cachefs_log_rfdir_record {
- int type; /* == CACHEFS_LOG_GPFRONT */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of directory */
- ino64_t fileno; /* fileno */
- cfs_uid_t uid; /* uid of credential */
-};
-
-struct cachefs_log_ualloc_record {
- int type; /* == CACHEFS_LOG_UALLOC */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of allocmap-updated file */
- ino64_t fileno; /* fileno of allocmap-updated file */
- u_offset_t off; /* offset of new area */
- uint_t len; /* length of new area */
-};
-
-struct cachefs_log_calloc_record {
- int type; /* == CACHEFS_LOG_CALLOC */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of allocmap-checked file */
- ino64_t fileno; /* fileno of allocmap-checked file */
- u_offset_t off; /* offset of successful check_allocmap */
- uint_t len; /* length of successful check_allocmap */
-};
-
-struct cachefs_log_nocache_record {
- int type; /* == CACHEFS_LOG_NOCACHE */
- int error; /* errno */
- cfs_time_t time; /* timestamp */
- uint64_t vfsp; /* which filesystem */
- cfs_fid_t fid; /* fid of file being nocached */
- ino64_t fileno; /* fileno of file being nocached */
-};
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* _SYS_FS_CACHEFS_LOG_H */
diff --git a/usr/src/uts/common/sys/mntent.h b/usr/src/uts/common/sys/mntent.h
index e95ef3fccc..88c98dc5a4 100644
--- a/usr/src/uts/common/sys/mntent.h
+++ b/usr/src/uts/common/sys/mntent.h
@@ -21,6 +21,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
* All Rights Reserved
@@ -43,7 +44,6 @@ extern "C" {
#define MNTTYPE_NFS "nfs" /* NFS file system */
#define MNTTYPE_NFS3 "nfs3" /* NFS Version 3 file system */
#define MNTTYPE_NFS4 "nfs4" /* NFS Version 4 file system */
-#define MNTTYPE_CACHEFS "cachefs" /* Cache File System */
#define MNTTYPE_PCFS "pcfs" /* PC (MSDOS) file system */
#define MNTTYPE_PC MNTTYPE_PCFS /* Deprecated name; use MNTTYPE_PCFS */
#define MNTTYPE_LOFS "lofs" /* Loop back file system */
diff --git a/usr/src/uts/common/sys/vfs.h b/usr/src/uts/common/sys/vfs.h
index a74ce65f86..38c1fded4a 100644
--- a/usr/src/uts/common/sys/vfs.h
+++ b/usr/src/uts/common/sys/vfs.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -71,14 +71,6 @@ typedef struct {
* machine. This is typically called by a stateless file server
* in order to generate "file handles".
*
- * Do not change the definition of struct fid ... fid_t without
- * letting the CacheFS group know about it! They will have to do at
- * least two things, in the same change that changes this structure:
- * 1. change CFSVERSION in usr/src/uts/common/sys/fs/cachefs_fs.h
- * 2. put the old version # in the canupgrade array
- * in cachfs_upgrade() in usr/src/cmd/fs.d/cachefs/fsck/fsck.c
- * This is necessary because CacheFS stores FIDs on disk.
- *
* Many underlying file systems cast a struct fid into other
* file system dependent structures which may require 4 byte alignment.
* Because a fid starts with a short it may not be 4 byte aligned, the
diff --git a/usr/src/uts/common/sys/vtoc.h b/usr/src/uts/common/sys/vtoc.h
index cc0586a184..adaf7df5b9 100644
--- a/usr/src/uts/common/sys/vtoc.h
+++ b/usr/src/uts/common/sys/vtoc.h
@@ -24,6 +24,7 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
@@ -79,7 +80,7 @@ extern "C" {
#define V_VAR 0x07 /* Var partition */
#define V_HOME 0x08 /* Home partition */
#define V_ALTSCTR 0x09 /* Alternate sector partition */
-#define V_CACHE 0x0a /* Cache (cachefs) partition */
+#define V_CACHE 0x0a /* CacheFS partition (obsolete) */
/* Tags for EFI/GPT labels */
#define V_RESERVED 0x0b /* SMI reserved data */
diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel
index 9001670bf1..64b4962cae 100644
--- a/usr/src/uts/intel/Makefile.intel
+++ b/usr/src/uts/intel/Makefile.intel
@@ -521,7 +521,7 @@ SCHED_KMODS += IA RT TS RT_DPTBL TS_DPTBL FSS FX FX_DPTBL SDC
#
# File System Modules (/kernel/fs):
#
-FS_KMODS += autofs cachefs ctfs dcfs dev devfs fdfs fifofs hsfs lofs
+FS_KMODS += autofs ctfs dcfs dev devfs fdfs fifofs hsfs lofs
FS_KMODS += mntfs namefs nfs objfs zfs zut
FS_KMODS += pcfs procfs sockfs specfs tmpfs udfs ufs sharefs
FS_KMODS += smbfs
diff --git a/usr/src/uts/intel/cachefs/Makefile b/usr/src/uts/intel/cachefs/Makefile
deleted file mode 100644
index cad7332144..0000000000
--- a/usr/src/uts/intel/cachefs/Makefile
+++ /dev/null
@@ -1,103 +0,0 @@
-#
-# 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
-# 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
-#
-#
-# uts/intel/cachefs/Makefile
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# Copyright (c) 2011 Bayard G. Bell. All rights reserved.
-#
-# This makefile drives the production of the cachefs file system
-# kernel module.
-#
-# intel architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = cachefs
-OBJECTS = $(CACHEFS_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CACHEFS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/intel/Makefile.intel
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# Define dependency on rpcmod
-#
-LDFLAGS += -dy -N strmod/rpcmod
-
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
-LINTTAGS += -erroff=E_STATIC_UNUSED
-LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/intel/Makefile.targ
diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc
index 3a4a3f9c8b..d7c45a396e 100644
--- a/usr/src/uts/sparc/Makefile.sparc
+++ b/usr/src/uts/sparc/Makefile.sparc
@@ -21,6 +21,7 @@
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013 Andrew Stormont. All rights reserved.
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
@@ -352,7 +353,7 @@ SCHED_KMODS += RT TS RT_DPTBL TS_DPTBL IA FSS FX FX_DPTBL SDC
# File System Modules (/kernel/fs):
#
FS_KMODS += dev devfs fdfs fifofs hsfs lofs namefs nfs pcfs tmpfs zfs
-FS_KMODS += zut specfs udfs ufs autofs cachefs procfs sockfs mntfs
+FS_KMODS += zut specfs udfs ufs autofs procfs sockfs mntfs
FS_KMODS += ctfs objfs sharefs dcfs smbfs
#
diff --git a/usr/src/uts/sparc/cachefs/Makefile b/usr/src/uts/sparc/cachefs/Makefile
deleted file mode 100644
index 730d536ca2..0000000000
--- a/usr/src/uts/sparc/cachefs/Makefile
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# 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
-# 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
-#
-#
-# uts/sparc/cachefs/Makefile
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-# Copyright (c) 2011 Bayard G. Bell. All rights reserved.
-#
-# This makefile drives the production of the Cache file system
-# kernel module.
-#
-# sparc implementation architecture dependent
-#
-
-#
-# Path to the base of the uts directory tree (usually /usr/src/uts).
-#
-UTSBASE = ../..
-
-#
-# Define the module and object file sets.
-#
-MODULE = cachefs
-OBJECTS = $(CACHEFS_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(CACHEFS_OBJS:%.o=$(LINTS_DIR)/%.ln)
-ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE)
-
-#
-# Include common rules.
-#
-include $(UTSBASE)/sparc/Makefile.sparc
-
-#
-# Define targets
-#
-ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
-INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-
-#
-# Overrides.
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# Define dependency on rpcmod
-#
-LDFLAGS += -dy -N strmod/rpcmod
-
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
-LINTTAGS += -erroff=E_STATIC_UNUSED
-LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-#
-# Default build targets.
-#
-.KEEP_STATE:
-
-def: $(DEF_DEPS)
-
-all: $(ALL_DEPS)
-
-clean: $(CLEAN_DEPS)
-
-clobber: $(CLOBBER_DEPS)
-
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
-install: $(INSTALL_DEPS)
-
-#
-# Include common targets.
-#
-include $(UTSBASE)/sparc/Makefile.targ