Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.106 retrieving revision 1.124 diff -u -p -r1.106 -r1.124 --- src/sys/miscfs/kernfs/kernfs_vnops.c 2004/10/27 06:55:53 1.106 +++ src/sys/miscfs/kernfs/kernfs_vnops.c 2006/06/23 20:30:11 1.124 @@ -1,4 +1,4 @@ -/* $NetBSD: kernfs_vnops.c,v 1.106 2004/10/27 06:55:53 skrll Exp $ */ +/* $NetBSD: kernfs_vnops.c,v 1.124 2006/06/23 20:30:11 bouyer Exp $ */ /* * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.106 2004/10/27 06:55:53 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.124 2006/06/23 20:30:11 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -90,8 +90,8 @@ const struct kern_target kern_targets[] { DT_DIR, N("."), 0, KFSkern, VDIR, DIR_MODE }, { DT_DIR, N(".."), 0, KFSroot, VDIR, DIR_MODE }, { DT_REG, N("boottime"), &boottime.tv_sec, KFSint, VREG, READ_MODE }, - /* XXX cast away const */ - { DT_REG, N("copyright"), (void *)copyright, + /* XXXUNCONST */ + { DT_REG, N("copyright"), __UNCONST(copyright), KFSstring, VREG, READ_MODE }, { DT_REG, N("hostname"), 0, KFShostname, VREG, WRITE_MODE }, { DT_REG, N("hz"), &hz, KFSint, VREG, READ_MODE }, @@ -109,8 +109,8 @@ const struct kern_target kern_targets[] { DT_BLK, N("rootdev"), &rootdev, KFSdevice, VBLK, READ_MODE }, { DT_CHR, N("rrootdev"), &rrootdev, KFSdevice, VCHR, READ_MODE }, { DT_REG, N("time"), 0, KFStime, VREG, READ_MODE }, - /* XXX cast away const */ - { DT_REG, N("version"), (void *)version, + /* XXXUNCONST */ + { DT_REG, N("version"), __UNCONST(version), KFSstring, VREG, READ_MODE }, }; const struct kern_target subdir_targets[] = { @@ -151,72 +151,71 @@ int nkern_dirs = 2; #endif int kernfs_try_fileop(kfstype, kfsfileop, void *, int); +int kernfs_try_xread(kfstype, const struct kernfs_node *, char **, + size_t, int); int kernfs_try_xwrite(kfstype, const struct kernfs_node *, char *, size_t, int); +static int kernfs_default_xread(void *v); static int kernfs_default_xwrite(void *v); static int kernfs_default_fileop_getattr(void *); /* must include all fileop's */ const struct kernfs_fileop kernfs_default_fileops[] = { + { .kf_fileop = KERNFS_XREAD }, { .kf_fileop = KERNFS_XWRITE }, { .kf_fileop = KERNFS_FILEOP_OPEN }, { .kf_fileop = KERNFS_FILEOP_GETATTR, .kf_genop = {kernfs_default_fileop_getattr} }, { .kf_fileop = KERNFS_FILEOP_IOCTL }, - { .kf_fileop = KERNFS_FILEOP_MMAP }, { .kf_fileop = KERNFS_FILEOP_CLOSE }, + { .kf_fileop = KERNFS_FILEOP_READ, .kf_genop = {kernfs_default_xread} }, { .kf_fileop = KERNFS_FILEOP_WRITE, .kf_genop = {kernfs_default_xwrite} }, }; -int kernfs_lookup __P((void *)); +int kernfs_lookup(void *); #define kernfs_create genfs_eopnotsupp #define kernfs_mknod genfs_eopnotsupp -int kernfs_open __P((void *)); -int kernfs_close __P((void *)); -int kernfs_access __P((void *)); -int kernfs_getattr __P((void *)); -int kernfs_setattr __P((void *)); -int kernfs_read __P((void *)); -int kernfs_write __P((void *)); +int kernfs_open(void *); +int kernfs_close(void *); +int kernfs_access(void *); +int kernfs_getattr(void *); +int kernfs_setattr(void *); +int kernfs_read(void *); +int kernfs_write(void *); #define kernfs_fcntl genfs_fcntl -int kernfs_ioctl __P((void *)); +int kernfs_ioctl(void *); #define kernfs_poll genfs_poll #define kernfs_revoke genfs_revoke -int kernfs_mmap __P((void *)); #define kernfs_fsync genfs_nullop #define kernfs_seek genfs_nullop #define kernfs_remove genfs_eopnotsupp -int kernfs_link __P((void *)); +int kernfs_link(void *); #define kernfs_rename genfs_eopnotsupp #define kernfs_mkdir genfs_eopnotsupp #define kernfs_rmdir genfs_eopnotsupp -int kernfs_symlink __P((void *)); -int kernfs_readdir __P((void *)); +int kernfs_symlink(void *); +int kernfs_readdir(void *); #define kernfs_readlink genfs_eopnotsupp #define kernfs_abortop genfs_abortop -int kernfs_inactive __P((void *)); -int kernfs_reclaim __P((void *)); +int kernfs_inactive(void *); +int kernfs_reclaim(void *); #define kernfs_lock genfs_lock #define kernfs_unlock genfs_unlock #define kernfs_bmap genfs_badop #define kernfs_strategy genfs_badop -int kernfs_print __P((void *)); +int kernfs_print(void *); #define kernfs_islocked genfs_islocked -int kernfs_pathconf __P((void *)); +int kernfs_pathconf(void *); #define kernfs_advlock genfs_einval -#define kernfs_blkatoff genfs_eopnotsupp -#define kernfs_valloc genfs_eopnotsupp -#define kernfs_vfree genfs_nullop -#define kernfs_truncate genfs_eopnotsupp -#define kernfs_update genfs_nullop #define kernfs_bwrite genfs_eopnotsupp #define kernfs_putpages genfs_putpages -static int kernfs_xread __P((struct kernfs_node *, int, char **, size_t, size_t *)); -static int kernfs_xwrite __P((const struct kernfs_node *, char *, size_t)); +static int kernfs_xread(struct kernfs_node *, int, char **, + size_t, size_t *); +static int kernfs_xwrite(const struct kernfs_node *, char *, size_t); -int (**kernfs_vnodeop_p) __P((void *)); +int (**kernfs_vnodeop_p)(void *); const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { { &vop_default_desc, vn_default_error }, { &vop_lookup_desc, kernfs_lookup }, /* lookup */ @@ -233,7 +232,6 @@ const struct vnodeopv_entry_desc kernfs_ { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ { &vop_poll_desc, kernfs_poll }, /* poll */ { &vop_revoke_desc, kernfs_revoke }, /* revoke */ - { &vop_mmap_desc, kernfs_mmap }, /* mmap */ { &vop_fsync_desc, kernfs_fsync }, /* fsync */ { &vop_seek_desc, kernfs_seek }, /* seek */ { &vop_remove_desc, kernfs_remove }, /* remove */ @@ -255,11 +253,6 @@ const struct vnodeopv_entry_desc kernfs_ { &vop_islocked_desc, kernfs_islocked }, /* islocked */ { &vop_pathconf_desc, kernfs_pathconf }, /* pathconf */ { &vop_advlock_desc, kernfs_advlock }, /* advlock */ - { &vop_blkatoff_desc, kernfs_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, kernfs_valloc }, /* valloc */ - { &vop_vfree_desc, kernfs_vfree }, /* vfree */ - { &vop_truncate_desc, kernfs_truncate }, /* truncate */ - { &vop_update_desc, kernfs_update }, /* update */ { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */ { &vop_putpages_desc, kernfs_putpages }, /* putpages */ { NULL, NULL } @@ -267,7 +260,7 @@ const struct vnodeopv_entry_desc kernfs_ const struct vnodeopv_desc kernfs_vnodeop_opv_desc = { &kernfs_vnodeop_p, kernfs_vnodeop_entries }; -static __inline int +static inline int kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b) { if (a->kf_type < b->kf_type) @@ -328,7 +321,21 @@ kernfs_try_fileop(kfstype type, kfsfileo } int -kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *buf, +kernfs_try_xread(kfstype type, const struct kernfs_node *kfs, char **bfp, + size_t len, int error) +{ + struct kernfs_fileop *kf, skf; + + skf.kf_type = type; + skf.kf_fileop = KERNFS_XREAD; + if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) + if (kf->kf_xread) + return kf->kf_xread(kfs, bfp, len); + return error; +} + +int +kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *bf, size_t len, int error) { struct kernfs_fileop *kf, skf; @@ -337,7 +344,7 @@ kernfs_try_xwrite(kfstype type, const st skf.kf_fileop = KERNFS_XWRITE; if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) if (kf->kf_xwrite) - return kf->kf_xwrite(kfs, buf, len); + return kf->kf_xwrite(kfs, bf, len); return error; } @@ -382,6 +389,7 @@ kernfs_xread(kfs, off, bufp, len, wrlen) #ifdef IPSEC struct mbuf *m; #endif + int err; kt = kfs->kfs_kt; @@ -516,8 +524,10 @@ kernfs_xread(kfs, off, bufp, len, wrlen) #endif default: - *wrlen = 0; - return (0); + err = kernfs_try_xread(kfs->kfs_type, kfs, bufp, len, + EOPNOTSUPP); + if (err) + return err; } len = strlen(*bufp); @@ -531,23 +541,23 @@ kernfs_xread(kfs, off, bufp, len, wrlen) } static int -kernfs_xwrite(kfs, buf, len) +kernfs_xwrite(kfs, bf, len) const struct kernfs_node *kfs; - char *buf; + char *bf; size_t len; { switch (kfs->kfs_type) { case KFShostname: - if (buf[len-1] == '\n') + if (bf[len-1] == '\n') --len; - memcpy(hostname, buf, len); + memcpy(hostname, bf, len); hostname[len] = '\0'; hostnamelen = (size_t) len; return (0); default: - return kernfs_try_xwrite(kfs->kfs_type, kfs, buf, len, EIO); + return kernfs_try_xwrite(kfs->kfs_type, kfs, bf, len, EIO); } } @@ -706,8 +716,8 @@ kernfs_open(v) struct vop_open_args /* { struct vnode *a_vp; int a_mode; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); #ifdef IPSEC @@ -747,8 +757,8 @@ kernfs_close(v) struct vop_close_args /* { struct vnode *a_vp; int a_fflag; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); @@ -774,13 +784,13 @@ kernfs_access(v) struct vop_access_args /* { struct vnode *a_vp; int a_mode; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct vattr va; int error; - if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0) + if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_l)) != 0) return (error); return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid, @@ -794,8 +804,8 @@ kernfs_default_fileop_getattr(v) struct vop_getattr_args /* { struct vnode *a_vp; struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct vattr *vap = ap->a_vap; @@ -812,14 +822,14 @@ kernfs_getattr(v) struct vop_getattr_args /* { struct vnode *a_vp; struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); struct kernfs_subdir *ks; struct vattr *vap = ap->a_vap; int error = 0; - char strbuf[KSTRING], *buf; + char strbuf[KSTRING], *bf; size_t nread, total; VATTR_NULL(vap); @@ -831,17 +841,12 @@ kernfs_getattr(v) vap->va_flags = 0; vap->va_size = 0; vap->va_blocksize = DEV_BSIZE; - /* - * Make all times be current TOD, except for the "boottime" node. - * Avoid microtime(9), it's slow. - * We don't guard the read from time(9) with splclock(9) since we - * don't actually need to be THAT sure the access is atomic. - */ - if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 && + /* Make all times be current TOD, except for the "boottime" node. */ + if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 && !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) { TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime); } else { - TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime); + getnanotime(&vap->va_ctime); } vap->va_atime = vap->va_mtime = vap->va_ctime; vap->va_gen = 0; @@ -881,8 +886,8 @@ kernfs_getattr(v) vap->va_nlink = 1; total = 0; do { - buf = strbuf; - error = kernfs_xread(kfs, total, &buf, + bf = strbuf; + error = kernfs_xread(kfs, total, &bf, sizeof(strbuf), &nread); total += nread; } while (error == 0 && nread != 0); @@ -922,32 +927,56 @@ kernfs_setattr(v) } int -kernfs_read(v) +kernfs_default_xread(v) void *v; { struct vop_read_args /* { struct vnode *a_vp; struct uio *a_uio; int a_ioflag; - struct ucred *a_cred; + kauth_cred_t a_cred; } */ *ap = v; struct uio *uio = ap->a_uio; struct kernfs_node *kfs = VTOKERN(ap->a_vp); - char strbuf[KSTRING], *buf; - off_t off; + char strbuf[KSTRING], *bf; + int off; size_t len; int error; if (ap->a_vp->v_type == VDIR) return (EOPNOTSUPP); - off = uio->uio_offset; - buf = strbuf; - if ((error = kernfs_xread(kfs, off, &buf, sizeof(strbuf), &len)) == 0) - error = uiomove(buf, len, uio); + off = (int)uio->uio_offset; + /* Don't allow negative offsets */ + if (off < 0) + return EINVAL; + + bf = strbuf; + if ((error = kernfs_xread(kfs, off, &bf, sizeof(strbuf), &len)) == 0) + error = uiomove(bf, len, uio); return (error); } +int +kernfs_read(v) + void *v; +{ + struct vop_read_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + if (kfs->kfs_type < KFSlasttype) { + /* use default function */ + return kernfs_default_xread(v); + } + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_READ, v, + EOPNOTSUPP); +} + static int kernfs_default_xwrite(v) void *v; @@ -956,7 +985,7 @@ kernfs_default_xwrite(v) struct vnode *a_vp; struct uio *a_uio; int a_ioflag; - struct ucred *a_cred; + kauth_cred_t a_cred; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); struct uio *uio = ap->a_uio; @@ -986,11 +1015,16 @@ kernfs_write(v) struct vnode *a_vp; struct uio *a_uio; int a_ioflag; - struct ucred *a_cred; + kauth_cred_t a_cred; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); - return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, 0); + if (kfs->kfs_type < KFSlasttype) { + /* use default function */ + return kernfs_default_xwrite(v); + } + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, + EOPNOTSUPP); } int @@ -1003,8 +1037,8 @@ kernfs_ioctl(v) u_long a_command; void *a_data; int a_fflag; - struct ucred *a_cred; - struct proc *a_p; + kauth_cred_t a_cred; + struct lwp *a_l; } */ *ap = v; struct kernfs_node *kfs = VTOKERN(ap->a_vp); @@ -1012,22 +1046,6 @@ kernfs_ioctl(v) EPASSTHROUGH); } -int -kernfs_mmap(v) - void *v; -{ - struct vop_mmap_args /* { - const struct vnodeop_desc *a_desc; - struct vnode *a_vp; - int a_fflags; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap = v; - struct kernfs_node *kfs = VTOKERN(ap->a_vp); - - return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_MMAP, v, 0); -} - static int kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt, u_int32_t value, struct vop_readdir_args *ap) @@ -1041,10 +1059,11 @@ kernfs_setdirentfileno_kt(struct dirent return error; if (kt->kt_tag == KFSdevice) { struct vattr va; - if ((error = VOP_GETATTR(vp, &va, ap->a_cred, - ap->a_uio->uio_segflg == UIO_USERSPACE ? - ap->a_uio->uio_procp : &proc0)) != 0) - return (error); + + error = VOP_GETATTR(vp, &va, ap->a_cred, curlwp); + if (error != 0) { + return error; + } d->d_fileno = va.va_fileid; } else { kfs = VTOKERN(vp); @@ -1088,7 +1107,7 @@ kernfs_readdir(v) struct vop_readdir_args /* { struct vnode *a_vp; struct uio *a_uio; - struct ucred *a_cred; + kauth_cred_t a_cred; int *a_eofflag; off_t **a_cookies; int a_*ncookies; @@ -1145,9 +1164,9 @@ kernfs_readdir(v) break; } else { dkt = SIMPLEQ_NEXT(dkt, dkt_queue); - if (dkt == NULL) - break; } + if (dkt == NULL) + break; kt = &dkt->dkt_kt; } if (kt->kt_tag == KFSdevice) { @@ -1406,7 +1425,7 @@ kernfs_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; - struct proc *a_p; + struct lwp *a_l; } */ *ap = v; struct vnode *vp = ap->a_vp; const struct kernfs_node *kfs = VTOKERN(ap->a_vp); @@ -1507,15 +1526,15 @@ kernfs_print(v) } int -kernfs_link(v) +kernfs_link(v) void *v; { struct vop_link_args /* { struct vnode *a_dvp; - struct vnode *a_vp; + struct vnode *a_vp; struct componentname *a_cnp; } */ *ap = v; - + VOP_ABORTOP(ap->a_dvp, ap->a_cnp); vput(ap->a_dvp); return (EROFS); @@ -1532,7 +1551,7 @@ kernfs_symlink(v) struct vattr *a_vap; char *a_target; } */ *ap = v; - + VOP_ABORTOP(ap->a_dvp, ap->a_cnp); vput(ap->a_dvp); return (EROFS);