version 1.2, 1993/03/25 06:00:24 |
version 1.16, 1993/12/22 13:14:10 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
* |
* |
* $Id$ |
* $Id$ |
*/ |
*/ |
|
|
/* |
/* |
* Kernel parameter filesystem |
* Kernel parameter filesystem |
*/ |
*/ |
|
|
#include "param.h" |
#include <sys/param.h> |
#include "systm.h" |
#include <sys/systm.h> |
#include "kernel.h" |
#include <sys/kernel.h> |
#include "types.h" |
#include <sys/types.h> |
#include "time.h" |
#include <sys/time.h> |
#include "proc.h" |
#include <sys/proc.h> |
#include "file.h" |
#include <sys/file.h> |
#include "vnode.h" |
#include <sys/vnode.h> |
#include "stat.h" |
#include <sys/stat.h> |
#include "mount.h" |
#include <sys/mount.h> |
#include "namei.h" |
#include <sys/namei.h> |
#include "buf.h" |
#include <sys/buf.h> |
#include "miscfs/kernfs/kernfs.h" |
|
|
#include <ufs/dir.h> /* For readdir() XXX */ |
#include "../ufs/dir.h" /* For readdir() XXX */ |
|
|
#include <miscfs/kernfs/kernfs.h> |
#define KSTRING 256 /* Largest I/O available via this filesystem */ |
|
#define UIO_MX 32 |
struct kernfs_target kernfs_targets[] = { |
|
|
struct kern_target { |
|
char *kt_name; |
|
void *kt_data; |
|
#define KTT_NULL 1 |
|
#define KTT_TIME 5 |
|
#define KTT_INT 17 |
|
#define KTT_STRING 31 |
|
#define KTT_HOSTNAME 47 |
|
#define KTT_AVENRUN 53 |
|
int kt_tag; |
|
#define KTM_RO 0 |
|
#define KTM_RO_MODE (S_IRUSR|S_IRGRP|S_IROTH) |
|
#define KTM_RW 43 |
|
#define KTM_RW_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) |
|
#define KTM_DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) |
|
int kt_rw; |
|
int kt_vtype; |
|
} kern_targets[] = { |
|
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
/* NOTE: The name must be less than UIO_MX-16 chars in length */ |
/* name data tag ro/rw */ |
DIR_TARGET(".", 0, KTT_NULL, KTM_DIR_PERMS ) |
{ ".", 0, KTT_NULL, KTM_RO, VDIR }, |
DIR_TARGET("..", 0, KTT_NULL, KTM_DIR_PERMS ) |
{ "copyright", copyright, KTT_STRING, KTM_RO, VREG }, |
REG_TARGET("copyright", copyright, KTT_STRING, KTM_RO_PERMS ) |
{ "hostname", 0, KTT_HOSTNAME, KTM_RW, VREG }, |
REG_TARGET("hostname", 0, KTT_HOSTNAME, KTM_RW_PERMS ) |
{ "hz", &hz, KTT_INT, KTM_RO, VREG }, |
REG_TARGET("hz", &hz, KTT_INT, KTM_RO_PERMS ) |
{ "loadavg", 0, KTT_AVENRUN, KTM_RO, VREG }, |
REG_TARGET("loadavg", 0, KTT_AVENRUN, KTM_RO_PERMS ) |
{ "physmem", &physmem, KTT_INT, KTM_RO, VREG }, |
REG_TARGET("physmem", &physmem, KTT_INT, KTM_RO_PERMS ) |
{ "root", 0, KTT_NULL, KTM_RO, VDIR }, |
#ifdef KERNFS_HAVE_ROOTDIR |
{ "rootdev", 0, KTT_NULL, KTM_RO, VBLK }, |
DIR_TARGET("root", 0, KTT_NULL, KTM_DIR_PERMS ) |
{ "time", 0, KTT_TIME, KTM_RO, VREG }, |
#endif |
{ "version", version, KTT_STRING, KTM_RO, VREG }, |
BLK_TARGET("rootdev", 0, KTT_NULL, KTM_RO_PERMS ) |
|
CHR_TARGET("rrootdev", 0, KTT_NULL, KTM_RO_PERMS ) |
|
REG_TARGET("time", 0, KTT_TIME, KTM_RO_PERMS ) |
|
REG_TARGET("version", version, KTT_STRING, KTM_RO_PERMS ) |
}; |
}; |
|
|
static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); |
static int nkernfs_targets = sizeof(kernfs_targets) / sizeof(kernfs_targets[0]); |
|
|
static int |
static int |
kernfs_xread(kt, buf, len, lenp) |
kernfs_xread(kt, buf, len, lenp) |
struct kern_target *kt; |
struct kernfs_target *kt; |
char *buf; |
char *buf; |
int len; |
int len; |
int *lenp; |
int *lenp; |
Line 131 kernfs_xread(kt, buf, len, lenp) |
|
Line 115 kernfs_xread(kt, buf, len, lenp) |
|
char *cp = hostname; |
char *cp = hostname; |
int xlen = hostnamelen; |
int xlen = hostnamelen; |
|
|
if (xlen >= len) |
if (xlen + 2 > len) /* extra space for null and newline */ |
return (EINVAL); |
return (EINVAL); |
|
|
sprintf(buf, "%s\n", cp); |
bcopy(cp, buf, xlen); /* safer than sprintf */ |
|
buf[xlen] = '\n'; |
|
buf[xlen+1] = '\0'; |
break; |
break; |
} |
} |
|
|
case KTT_AVENRUN: |
case KTT_AVENRUN: |
sprintf(buf, "%d %d %d %d\n", |
sprintf(buf, "%d %d %d %d\n", |
averunnable[0], |
averunnable.ldavg[0], |
averunnable[1], |
averunnable.ldavg[1], |
averunnable[2], |
averunnable.ldavg[2], |
FSCALE); |
FSCALE); |
break; |
break; |
|
|
Line 156 kernfs_xread(kt, buf, len, lenp) |
|
Line 142 kernfs_xread(kt, buf, len, lenp) |
|
|
|
static int |
static int |
kernfs_xwrite(kt, buf, len) |
kernfs_xwrite(kt, buf, len) |
struct kern_target *kt; |
struct kernfs_target *kt; |
char *buf; |
char *buf; |
int len; |
int len; |
{ |
{ |
Line 165 kernfs_xwrite(kt, buf, len) |
|
Line 151 kernfs_xwrite(kt, buf, len) |
|
if (buf[len-1] == '\n') |
if (buf[len-1] == '\n') |
--len; |
--len; |
bcopy(buf, hostname, len); |
bcopy(buf, hostname, len); |
hostnamelen = len - 1; |
/* kernfs_write set buf[value_passed_as_len] = \0. |
|
* therefore, buf len (hostnamelen) = len. |
|
*/ |
|
hostnamelen = len; |
|
hostname[hostnamelen] = '\0'; /* null end of string. */ |
return (0); |
return (0); |
} |
} |
|
|
Line 198 kernfs_lookup(dvp, ndp, p) |
|
Line 188 kernfs_lookup(dvp, ndp, p) |
|
/*VOP_LOCK(dvp);*/ |
/*VOP_LOCK(dvp);*/ |
return (0); |
return (0); |
} |
} |
|
|
|
#ifdef KERNFS_HAVE_ROOTDIR |
if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) { |
if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) { |
ndp->ni_dvp = rootdir; |
ndp->ni_dvp = dvp; |
ndp->ni_vp = rootdir; |
ndp->ni_vp = rootdir; |
VREF(rootdir); |
VREF(rootdir); |
VREF(rootdir); |
|
VOP_LOCK(rootdir); |
VOP_LOCK(rootdir); |
return (0); |
return (0); |
} |
} |
|
#endif |
|
|
/* |
/* |
* /kern/rootdev is the root device |
* /kern/rootdev is the root device |
*/ |
*/ |
if (ndp->ni_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) { |
if (ndp->ni_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) { |
if (vfinddev(rootdev, VBLK, &fvp)) |
if (!rootvp) { |
return (ENXIO); |
error = ENOENT; |
|
goto bad; |
|
} |
ndp->ni_dvp = dvp; |
ndp->ni_dvp = dvp; |
ndp->ni_vp = fvp; |
ndp->ni_vp = rootvp; |
VREF(fvp); |
VREF(rootvp); |
VOP_LOCK(fvp); |
VOP_LOCK(rootvp); |
return (0); |
return (0); |
} |
} |
|
|
for (i = 0; i < nkern_targets; i++) { |
/* |
struct kern_target *kt = &kern_targets[i]; |
* /kern/rrootdev is the raw root device |
|
*/ |
|
if (ndp->ni_namelen == 8 && bcmp(pname, "rrootdev", 7) == 0) { |
|
if (!rrootdevvp) { |
|
error = ENOENT; |
|
goto bad; |
|
} |
|
ndp->ni_dvp = dvp; |
|
ndp->ni_vp = rrootdevvp; |
|
VREF(rrootdevvp); |
|
VOP_LOCK(rrootdevvp); |
|
return (0); |
|
} |
|
|
|
for (i = 0; i < nkernfs_targets; i++) { |
|
struct kernfs_target *kt = &kernfs_targets[i]; |
if (ndp->ni_namelen == strlen(kt->kt_name) && |
if (ndp->ni_namelen == strlen(kt->kt_name) && |
bcmp(kt->kt_name, pname, ndp->ni_namelen) == 0) { |
bcmp(kt->kt_name, pname, ndp->ni_namelen) == 0) { |
error = 0; |
error = 0; |
Line 240 kernfs_lookup(dvp, ndp, p) |
|
Line 248 kernfs_lookup(dvp, ndp, p) |
|
#ifdef KERNFS_DIAGNOSTIC |
#ifdef KERNFS_DIAGNOSTIC |
printf("kernfs_lookup: allocate new vnode\n"); |
printf("kernfs_lookup: allocate new vnode\n"); |
#endif |
#endif |
error = getnewvnode(VT_UFS, dvp->v_mount, &kernfs_vnodeops, &fvp); |
error = getnewvnode(VT_KERNFS, dvp->v_mount, &kernfs_vnodeops, &fvp); |
if (error) |
if (error) |
goto bad; |
goto bad; |
VTOKERN(fvp)->kf_kt = &kern_targets[i]; |
VTOKERN(fvp)->kf_kt = &kernfs_targets[i]; |
fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype; |
fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype; |
ndp->ni_dvp = dvp; |
ndp->ni_dvp = dvp; |
ndp->ni_vp = fvp; |
ndp->ni_vp = fvp; |
Line 267 kernfs_open(vp, mode, cred, p) |
|
Line 275 kernfs_open(vp, mode, cred, p) |
|
struct ucred *cred; |
struct ucred *cred; |
struct proc *p; |
struct proc *p; |
{ |
{ |
int error; |
/* if access succeeded, this always does, too */ |
struct filedesc *fdp; |
|
struct file *fp; |
|
int dfd; |
|
int fd; |
|
|
|
#ifdef KERNFS_DIAGNOSTIC |
return (0); |
printf("kernfs_open\n"); |
} |
#endif |
|
|
|
|
/* |
|
* Check mode permission on target pointer. Mode is READ, WRITE or EXEC. |
|
* The mode is shifted to select the owner/group/other fields. The |
|
* super user is granted all permissions. |
|
*/ |
|
kernfs_access(vp, mode, cred, p) |
|
struct vnode *vp; |
|
register int mode; |
|
struct ucred *cred; |
|
struct proc *p; |
|
{ |
|
struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
|
register gid_t *gp; |
|
int i, error; |
|
|
|
#ifdef KERN_DIAGNOSTIC |
|
if (!VOP_ISLOCKED(vp)) { |
|
vprint("kernfs_access: not locked", vp); |
|
panic("kernfs_access: not locked"); |
|
} |
|
#endif |
/* |
/* |
* Can always open the root (modulo perms) |
* If you're the super-user, you always get access. |
*/ |
*/ |
if (vp->v_flag & VROOT) |
if (cred->cr_uid == 0) |
return (0); |
return (0); |
|
/* |
#ifdef KERNFS_DIAGNOSTIC |
* Access check is based on only one of owner, group, public. |
printf("kernfs_open, mode = %x, file = %s\n", |
* If not owner, then check group. If not a member of the |
mode, VTOKERN(vp)->kf_kt->kt_name); |
* group, then check public access. |
#endif |
*/ |
|
if (cred->cr_uid != /* kt->kt_uid XXX */ 0) { |
if ((mode & FWRITE) && VTOKERN(vp)->kf_kt->kt_rw != KTM_RW) |
mode >>= 3; |
return (EBADF); |
gp = cred->cr_groups; |
|
for (i = 0; i < cred->cr_ngroups; i++, gp++) |
return (0); |
if (/* kt->kt_gid XXX */ 0 == *gp) |
|
goto found; |
|
mode >>= 3; |
|
found: |
|
; |
|
} |
|
if ((kt->kt_perms & mode) == mode) |
|
return (0); |
|
return (EACCES); |
} |
} |
|
|
kernfs_getattr(vp, vap, cred, p) |
kernfs_getattr(vp, vap, cred, p) |
Line 302 kernfs_getattr(vp, vap, cred, p) |
|
Line 334 kernfs_getattr(vp, vap, cred, p) |
|
{ |
{ |
int error = 0; |
int error = 0; |
char strbuf[KSTRING]; |
char strbuf[KSTRING]; |
struct kern_target *kt = VTOKERN(vp)->kf_kt; |
struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
|
|
bzero((caddr_t) vap, sizeof(*vap)); |
bzero((caddr_t) vap, sizeof(*vap)); |
vattr_null(vap); |
vattr_null(vap); |
vap->va_uid = 0; |
vap->va_uid = kt->kt_uid; |
vap->va_gid = 0; |
vap->va_gid = kt->kt_gid; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; |
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; |
/* vap->va_qsize = 0; */ |
/* vap->va_qsize = 0; */ |
vap->va_blocksize = DEV_BSIZE; |
vap->va_blocksize = DEV_BSIZE; |
Line 319 kernfs_getattr(vp, vap, cred, p) |
|
Line 351 kernfs_getattr(vp, vap, cred, p) |
|
vap->va_rdev = 0; |
vap->va_rdev = 0; |
/* vap->va_qbytes = 0; */ |
/* vap->va_qbytes = 0; */ |
vap->va_bytes = 0; |
vap->va_bytes = 0; |
|
vap->va_type = kt->kt_vtype; |
|
vap->va_mode = kt->kt_perms; |
|
|
if (vp->v_flag & VROOT) { |
if (vp->v_flag & VROOT) { |
#ifdef KERNFS_DIAGNOSTIC |
#ifdef KERNFS_DIAGNOSTIC |
printf("kernfs_getattr: stat rootdir\n"); |
printf("kernfs_getattr: stat rootdir\n"); |
#endif |
#endif |
vap->va_type = VDIR; |
|
vap->va_mode = KTM_DIR_MODE; |
|
vap->va_nlink = 2; |
vap->va_nlink = 2; |
vap->va_fileid = 2; |
vap->va_fileid = 2; |
vap->va_size = DEV_BSIZE; |
vap->va_size = DEV_BSIZE; |
Line 333 kernfs_getattr(vp, vap, cred, p) |
|
Line 365 kernfs_getattr(vp, vap, cred, p) |
|
#ifdef KERNFS_DIAGNOSTIC |
#ifdef KERNFS_DIAGNOSTIC |
printf("kernfs_getattr: stat target %s\n", kt->kt_name); |
printf("kernfs_getattr: stat target %s\n", kt->kt_name); |
#endif |
#endif |
vap->va_type = kt->kt_vtype; |
|
vap->va_mode = (kt->kt_rw ? KTM_RW_MODE : KTM_RO_MODE); |
|
vap->va_nlink = 1; |
vap->va_nlink = 1; |
vap->va_fileid = 3 + (kt - kern_targets) / sizeof(*kt); |
vap->va_fileid = 3 + (kt - kernfs_targets) / sizeof(*kt); |
error = kernfs_xread(kt, strbuf, sizeof(strbuf), &vap->va_size); |
error = kernfs_xread(kt, strbuf, sizeof(strbuf), &vap->va_size); |
} |
} |
|
|
Line 347 kernfs_getattr(vp, vap, cred, p) |
|
Line 377 kernfs_getattr(vp, vap, cred, p) |
|
return (error); |
return (error); |
} |
} |
|
|
|
|
|
/* |
|
* Change the mode on a file. |
|
*/ |
|
kernfs_chmod1(vp, mode, p) |
|
register struct vnode *vp; |
|
register int mode; |
|
struct proc *p; |
|
{ |
|
register struct ucred *cred = p->p_ucred; |
|
register struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
|
int error; |
|
|
|
if ((mode & kt->kt_maxperms) != mode) /* can't set ro var to rw */ |
|
return (EPERM); |
|
|
|
if (cred->cr_uid != kt->kt_uid && |
|
(error = suser(cred, &p->p_acflag))) |
|
return (error); |
|
if (cred->cr_uid) { |
|
if (vp->v_type != VDIR && (mode & S_ISVTX)) |
|
return (EFTYPE); |
|
if (!groupmember(kt->kt_gid, cred) && (mode & S_ISGID)) |
|
return (EPERM); |
|
} |
|
kt->kt_perms &= ~07777; |
|
kt->kt_perms |= mode & 07777; |
|
/* ip->i_flag |= ICHG;*/ |
|
return (0); |
|
} |
|
|
|
/* |
|
* Perform chown operation on kernfs_target kt |
|
*/ |
|
kernfs_chown1(vp, uid, gid, p) |
|
register struct vnode *vp; |
|
uid_t uid; |
|
gid_t gid; |
|
struct proc *p; |
|
{ |
|
register struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
|
register struct ucred *cred = p->p_ucred; |
|
uid_t ouid; |
|
gid_t ogid; |
|
int error = 0; |
|
|
|
if (uid == (u_short)VNOVAL) |
|
uid = kt->kt_uid; |
|
if (gid == (u_short)VNOVAL) |
|
gid = kt->kt_gid; |
|
/* |
|
* If we don't own the file, are trying to change the owner |
|
* of the file, or are not a member of the target group, |
|
* the caller must be superuser or the call fails. |
|
*/ |
|
if ((cred->cr_uid != kt->kt_uid || uid != kt->kt_uid || |
|
!groupmember((gid_t)gid, cred)) && |
|
(error = suser(cred, &p->p_acflag))) |
|
return (error); |
|
ouid = kt->kt_uid; |
|
ogid = kt->kt_gid; |
|
|
|
kt->kt_uid = uid; |
|
kt->kt_gid = gid; |
|
|
|
/* if (ouid != uid || ogid != gid) |
|
ip->i_flag |= ICHG;*/ |
|
if (ouid != uid && cred->cr_uid != 0) |
|
kt->kt_perms &= ~S_ISUID; |
|
if (ogid != gid && cred->cr_uid != 0) |
|
kt->kt_perms &= ~S_ISGID; |
|
return (0); |
|
} |
|
|
|
/* |
|
* Set attribute vnode op. called from several syscalls |
|
*/ |
kernfs_setattr(vp, vap, cred, p) |
kernfs_setattr(vp, vap, cred, p) |
struct vnode *vp; |
struct vnode *vp; |
struct vattr *vap; |
struct vattr *vap; |
struct ucred *cred; |
struct ucred *cred; |
struct proc *p; |
struct proc *p; |
{ |
{ |
|
int error = 0; |
|
|
/* |
/* |
* Silently ignore attribute changes. |
* Check for unsetable attributes. |
* This allows for open with truncate to have no |
|
* effect until some data is written. I want to |
|
* do it this way because all writes are atomic. |
|
*/ |
*/ |
return (0); |
if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || |
|
(vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || |
|
(vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || |
|
((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { |
|
return (EINVAL); |
|
} |
|
/* |
|
* Go through the fields and update iff not VNOVAL. |
|
*/ |
|
if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL) |
|
if (error = kernfs_chown1(vp, vap->va_uid, vap->va_gid, p)) |
|
return (error); |
|
if (vap->va_size != VNOVAL) { |
|
if (vp->v_type == VDIR) |
|
return (EISDIR); |
|
/* else just nod and smile... */ |
|
} |
|
if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { |
|
/* if (cred->cr_uid != ip->i_uid && |
|
(error = suser(cred, &p->p_acflag))) |
|
return (error); |
|
if (vap->va_atime.tv_sec != VNOVAL) |
|
ip->i_flag |= IACC; |
|
if (vap->va_mtime.tv_sec != VNOVAL) |
|
ip->i_flag |= IUPD; |
|
ip->i_flag |= ICHG; |
|
if (error = iupdat(ip, &vap->va_atime, &vap->va_mtime, 1)) |
|
return (error); |
|
*/ |
|
} |
|
if (vap->va_mode != (u_short)VNOVAL) |
|
error = kernfs_chmod1(vp, (int)vap->va_mode, p); |
|
if (vap->va_flags != VNOVAL) { |
|
/* if (cred->cr_uid != ip->i_uid && |
|
(error = suser(cred, &p->p_acflag))) |
|
return (error); |
|
if (cred->cr_uid == 0) { |
|
ip->i_flags = vap->va_flags; |
|
} else { |
|
ip->i_flags &= 0xffff0000; |
|
ip->i_flags |= (vap->va_flags & 0xffff); |
|
} |
|
ip->i_flag |= ICHG; |
|
*/ |
|
} |
|
return (error); |
} |
} |
|
|
static int |
static int |
Line 370 kernfs_read(vp, uio, ioflag, cred) |
|
Line 520 kernfs_read(vp, uio, ioflag, cred) |
|
int ioflag; |
int ioflag; |
struct ucred *cred; |
struct ucred *cred; |
{ |
{ |
struct kern_target *kt = VTOKERN(vp)->kf_kt; |
struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
char strbuf[KSTRING]; |
char strbuf[KSTRING]; |
int off = uio->uio_offset; |
int off = uio->uio_offset; |
int len = 0; |
int len = 0; |
Line 395 kernfs_write(vp, uio, ioflag, cred) |
|
Line 545 kernfs_write(vp, uio, ioflag, cred) |
|
int ioflag; |
int ioflag; |
struct ucred *cred; |
struct ucred *cred; |
{ |
{ |
struct kern_target *kt = VTOKERN(vp)->kf_kt; |
struct kernfs_target *kt = VTOKERN(vp)->kf_kt; |
char strbuf[KSTRING]; |
char strbuf[KSTRING]; |
int len = uio->uio_resid; |
int len = uio->uio_resid; |
char *cp = strbuf; |
char *cp = strbuf; |
Line 417 kernfs_write(vp, uio, ioflag, cred) |
|
Line 567 kernfs_write(vp, uio, ioflag, cred) |
|
return (kernfs_xwrite(kt, strbuf, xlen)); |
return (kernfs_xwrite(kt, strbuf, xlen)); |
} |
} |
|
|
kernfs_readdir(vp, uio, cred, eofflagp) |
kernfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) |
struct vnode *vp; |
struct vnode *vp; |
struct uio *uio; |
struct uio *uio; |
struct ucred *cred; |
struct ucred *cred; |
int *eofflagp; |
int *eofflagp; |
|
u_int *cookies; |
|
int ncookies; |
{ |
{ |
struct filedesc *fdp; |
struct filedesc *fdp; |
int i; |
int i; |
Line 429 kernfs_readdir(vp, uio, cred, eofflagp) |
|
Line 581 kernfs_readdir(vp, uio, cred, eofflagp) |
|
|
|
i = uio->uio_offset / UIO_MX; |
i = uio->uio_offset / UIO_MX; |
error = 0; |
error = 0; |
while (uio->uio_resid > 0) { |
while (uio->uio_resid > 0 && (!cookies || ncookies > 0)) { |
#ifdef KERNFS_DIAGNOSTIC |
#ifdef KERNFS_DIAGNOSTIC |
printf("kernfs_readdir: i = %d\n", i); |
printf("kernfs_readdir: i = %d\n", i); |
#endif |
#endif |
if (i >= nkern_targets) { |
if (i >= nkernfs_targets) { |
*eofflagp = 1; |
*eofflagp = 1; |
break; |
break; |
} |
} |
{ |
{ |
struct direct d; |
struct direct d; |
struct direct *dp = &d; |
struct direct *dp = &d; |
struct kern_target *kt = &kern_targets[i]; |
struct kernfs_target *kt = &kernfs_targets[i]; |
|
|
bzero((caddr_t) dp, UIO_MX); |
bzero((caddr_t) dp, UIO_MX); |
|
|
Line 462 kernfs_readdir(vp, uio, cred, eofflagp) |
|
Line 614 kernfs_readdir(vp, uio, cred, eofflagp) |
|
error = uiomove((caddr_t) dp, UIO_MX, uio); |
error = uiomove((caddr_t) dp, UIO_MX, uio); |
if (error) |
if (error) |
break; |
break; |
|
if (cookies) { |
|
*cookies = (i + 1) * UIO_MX; |
|
ncookies--; |
|
} |
} |
} |
i++; |
i++; |
} |
} |
Line 490 kernfs_inactive(vp, p) |
|
Line 646 kernfs_inactive(vp, p) |
|
* Print out the contents of a kernfs vnode. |
* Print out the contents of a kernfs vnode. |
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
kernfs_print(vp) |
kernfs_print(vp) |
struct vnode *vp; |
struct vnode *vp; |
{ |
{ |
printf("tag VT_NON, kernfs vnode\n"); |
printf("tag VT_KERNFS, kernfs vnode\n"); |
|
return (0); |
} |
} |
|
|
/* |
/* |
|
|
int fflag, \ |
int fflag, \ |
struct ucred *cred, \ |
struct ucred *cred, \ |
struct proc *p))) nullop) |
struct proc *p))) nullop) |
#define kernfs_access ((int (*) __P(( \ |
|
struct vnode *vp, \ |
|
int mode, \ |
|
struct ucred *cred, \ |
|
struct proc *p))) nullop) |
|
#define kernfs_ioctl ((int (*) __P(( \ |
#define kernfs_ioctl ((int (*) __P(( \ |
struct vnode *vp, \ |
struct vnode *vp, \ |
int command, \ |
int command, \ |