Index: head/lib/libprocstat/common_kvm.c =================================================================== --- head/lib/libprocstat/common_kvm.c (revision 305902) +++ head/lib/libprocstat/common_kvm.c (revision 305903) @@ -1,207 +1,214 @@ /*- * Copyright (c) 2009 Stanislav Sedov * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #define _KERNEL #include #include #include #include +#include +#include #include #include #undef _KERNEL #include #include #include #include #include #include #include #include #include #include "common_kvm.h" int kvm_read_all(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes) { ssize_t error; if (nbytes >= SSIZE_MAX) return (0); error = kvm_read(kd, addr, buf, nbytes); return (error == (ssize_t)(nbytes)); } int kdevtoname(kvm_t *kd, struct cdev *dev, char *buf) { struct cdev si; assert(buf); if (!kvm_read_all(kd, (unsigned long)dev, &si, sizeof(si))) return (1); strlcpy(buf, si.si_name, SPECNAMELEN + 1); return (0); } int ufs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) { struct inode inode; + struct ufsmount um; if (!kvm_read_all(kd, (unsigned long)VTOI(vp), &inode, sizeof(inode))) { warnx("can't read inode at %p", (void *)VTOI(vp)); return (1); } + if (!kvm_read_all(kd, (unsigned long)inode.i_ump, &um, sizeof(um))) { + warnx("can't read ufsmount at %p", (void *)inode.i_ump); + return (1); + } /* * The st_dev from stat(2) is a dev_t. These kernel structures * contain cdev pointers. We need to convert to dev_t to make * comparisons */ - vn->vn_fsid = dev2udev(kd, inode.i_dev); + vn->vn_fsid = dev2udev(kd, um.um_dev); vn->vn_fileid = inode.i_number; vn->vn_mode = (mode_t)inode.i_mode; vn->vn_size = inode.i_size; return (0); } int devfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) { struct devfs_dirent devfs_dirent; struct mount mount; if (!kvm_read_all(kd, (unsigned long)getvnodedata(vp), &devfs_dirent, sizeof(devfs_dirent))) { warnx("can't read devfs_dirent at %p", (void *)vp->v_data); return (1); } if (!kvm_read_all(kd, (unsigned long)getvnodemount(vp), &mount, sizeof(mount))) { warnx("can't read mount at %p", (void *)getvnodemount(vp)); return (1); } vn->vn_fsid = mount.mnt_stat.f_fsid.val[0]; vn->vn_fileid = devfs_dirent.de_inode; vn->vn_mode = (devfs_dirent.de_mode & ~S_IFMT) | S_IFCHR; vn->vn_size = 0; return (0); } int nfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) { struct nfsnode nfsnode; mode_t mode; if (!kvm_read_all(kd, (unsigned long)VTONFS(vp), &nfsnode, sizeof(nfsnode))) { warnx("can't read nfsnode at %p", (void *)VTONFS(vp)); return (1); } vn->vn_fsid = nfsnode.n_vattr.va_fsid; vn->vn_fileid = nfsnode.n_vattr.va_fileid; vn->vn_size = nfsnode.n_size; mode = (mode_t)nfsnode.n_vattr.va_mode; switch (vp->v_type) { case VREG: mode |= S_IFREG; break; case VDIR: mode |= S_IFDIR; break; case VBLK: mode |= S_IFBLK; break; case VCHR: mode |= S_IFCHR; break; case VLNK: mode |= S_IFLNK; break; case VSOCK: mode |= S_IFSOCK; break; case VFIFO: mode |= S_IFIFO; break; default: break; }; vn->vn_mode = mode; return (0); } /* * Read the cdev structure in the kernel in order to work out the * associated dev_t */ dev_t dev2udev(kvm_t *kd, struct cdev *dev) { struct cdev_priv priv; assert(kd); if (kvm_read_all(kd, (unsigned long)cdev2priv(dev), &priv, sizeof(priv))) { return ((dev_t)priv.cdp_inode); } else { warnx("can't convert cdev *%p to a dev_t\n", dev); return (-1); } } void * getvnodedata(struct vnode *vp) { return (vp->v_data); } struct mount * getvnodemount(struct vnode *vp) { return (vp->v_mount); } Index: head/sys/ufs/ufs/extattr.h =================================================================== --- head/sys/ufs/ufs/extattr.h (revision 305902) +++ head/sys/ufs/ufs/extattr.h (revision 305903) @@ -1,157 +1,161 @@ /*- * Copyright (c) 1999-2001 Robert N. M. Watson * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Developed by the TrustedBSD Project. * Support for extended filesystem attributes. */ #ifndef _UFS_UFS_EXTATTR_H_ #define _UFS_UFS_EXTATTR_H_ #define UFS_EXTATTR_MAGIC 0x00b5d5ec #define UFS_EXTATTR_VERSION 0x00000003 #define UFS_EXTATTR_FSROOTSUBDIR ".attribute" #define UFS_EXTATTR_SUBDIR_SYSTEM "system" #define UFS_EXTATTR_SUBDIR_USER "user" #define UFS_EXTATTR_MAXEXTATTRNAME 65 /* including null */ #define UFS_EXTATTR_ATTR_FLAG_INUSE 0x00000001 /* attr has been set */ #define UFS_EXTATTR_PERM_KERNEL 0x00000000 #define UFS_EXTATTR_PERM_ROOT 0x00000001 #define UFS_EXTATTR_PERM_OWNER 0x00000002 #define UFS_EXTATTR_PERM_ANYONE 0x00000003 #define UFS_EXTATTR_UEPM_INITIALIZED 0x00000001 #define UFS_EXTATTR_UEPM_STARTED 0x00000002 #define UFS_EXTATTR_CMD_START 0x00000001 #define UFS_EXTATTR_CMD_STOP 0x00000002 #define UFS_EXTATTR_CMD_ENABLE 0x00000003 #define UFS_EXTATTR_CMD_DISABLE 0x00000004 struct ufs_extattr_fileheader { u_int uef_magic; /* magic number for sanity checking */ u_int uef_version; /* version of attribute file */ u_int uef_size; /* size of attributes, w/o header */ }; struct ufs_extattr_header { u_int ueh_flags; /* flags for attribute */ u_int ueh_len; /* local defined length; <= uef_size */ u_int32_t ueh_i_gen; /* generation number for sanity */ /* data follows the header */ }; /* * This structure defines the required fields of an extended-attribute header. */ struct extattr { int32_t ea_length; /* length of this attribute */ int8_t ea_namespace; /* name space of this attribute */ int8_t ea_contentpadlen; /* bytes of padding at end of attribute */ int8_t ea_namelength; /* length of attribute name */ char ea_name[1]; /* null-terminated attribute name */ /* extended attribute content follows */ }; /* * These macros are used to access and manipulate an extended attribute: * * EXTATTR_NEXT(eap) returns a pointer to the next extended attribute * following eap. * EXTATTR_CONTENT(eap) returns a pointer to the extended attribute * content referenced by eap. * EXTATTR_CONTENT_SIZE(eap) returns the size of the extended attribute * content referenced by eap. * EXTATTR_SET_LENGTHS(eap, contentsize) called after initializing the * attribute name to calculate and set the ea_length, ea_namelength, * and ea_contentpadlen fields of the extended attribute structure. */ #define EXTATTR_NEXT(eap) \ ((struct extattr *)(((void *)(eap)) + (eap)->ea_length)) #define EXTATTR_CONTENT(eap) (((void *)(eap)) + EXTATTR_BASE_LENGTH(eap)) #define EXTATTR_CONTENT_SIZE(eap) \ ((eap)->ea_length - EXTATTR_BASE_LENGTH(eap) - (eap)->ea_contentpadlen) #define EXTATTR_BASE_LENGTH(eap) \ ((sizeof(struct extattr) + (eap)->ea_namelength + 7) & ~7) #define EXTATTR_SET_LENGTHS(eap, contentsize) do { \ KASSERT(((eap)->ea_name[0] != 0), \ ("Must initialize name before setting lengths")); \ (eap)->ea_namelength = strlen((eap)->ea_name); \ (eap)->ea_contentpadlen = ((contentsize) % 8) ? \ 8 - ((contentsize) % 8) : 0; \ (eap)->ea_length = EXTATTR_BASE_LENGTH(eap) + \ (contentsize) + (eap)->ea_contentpadlen; \ } while (0) #ifdef _KERNEL #include struct vnode; LIST_HEAD(ufs_extattr_list_head, ufs_extattr_list_entry); struct ufs_extattr_list_entry { LIST_ENTRY(ufs_extattr_list_entry) uele_entries; struct ufs_extattr_fileheader uele_fileheader; int uele_attrnamespace; char uele_attrname[UFS_EXTATTR_MAXEXTATTRNAME]; struct vnode *uele_backing_vnode; }; struct ucred; struct ufs_extattr_per_mount { struct sx uepm_lock; struct ufs_extattr_list_head uepm_list; struct ucred *uepm_ucred; int uepm_flags; }; +struct vop_getextattr_args; +struct vop_deleteextattr_args; +struct vop_setextattr_args; + void ufs_extattr_uepm_init(struct ufs_extattr_per_mount *uepm); void ufs_extattr_uepm_destroy(struct ufs_extattr_per_mount *uepm); int ufs_extattr_start(struct mount *mp, struct thread *td); int ufs_extattr_autostart(struct mount *mp, struct thread *td); int ufs_extattr_stop(struct mount *mp, struct thread *td); int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename, int attrnamespace, const char *attrname); int ufs_getextattr(struct vop_getextattr_args *ap); int ufs_deleteextattr(struct vop_deleteextattr_args *ap); int ufs_setextattr(struct vop_setextattr_args *ap); void ufs_extattr_vnode_inactive(struct vnode *vp, struct thread *td); #else /* User-level definition of KASSERT for macros above */ #define KASSERT(cond, str) do { \ if (!(cond)) { printf("panic: "); printf(str); printf("\n"); exit(1); }\ } while (0) #endif /* !_KERNEL */ #endif /* !_UFS_UFS_EXTATTR_H_ */ Index: head/sys/ufs/ufs/inode.h =================================================================== --- head/sys/ufs/ufs/inode.h (revision 305902) +++ head/sys/ufs/ufs/inode.h (revision 305903) @@ -1,207 +1,207 @@ /*- * Copyright (c) 1982, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)inode.h 8.9 (Berkeley) 5/14/95 * $FreeBSD$ */ #ifndef _UFS_UFS_INODE_H_ #define _UFS_UFS_INODE_H_ #include #include #include /* * This must agree with the definition in . */ #define doff_t int32_t /* * The inode is used to describe each active (or recently active) file in the * UFS filesystem. It is composed of two types of information. The first part * is the information that is needed only while the file is active (such as * the identity of the file and linkage to speed its lookup). The second part * is the permanent meta-data associated with the file which is read in * from the permanent dinode from long term storage when the file becomes * active, and is put back when the file is no longer being used. * * An inode may only be changed while holding either the exclusive * vnode lock or the shared vnode lock and the vnode interlock. We use * the latter only for "read" and "get" operations that require * changing i_flag, or a timestamp. This locking protocol allows executing * those operations without having to upgrade the vnode lock from shared to * exclusive. */ struct inode { TAILQ_ENTRY(inode) i_nextsnap; /* snapshot file list. */ struct vnode *i_vnode;/* Vnode associated with this inode. */ struct ufsmount *i_ump;/* Ufsmount point associated with this inode. */ struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ union { struct dirhash *dirhash; /* Hashing for large directories. */ daddr_t *snapblklist; /* Collect expunged snapshot blocks. */ } i_un; /* * The real copy of the on-disk inode. */ union { struct ufs1_dinode *din1; /* UFS1 on-disk dinode. */ struct ufs2_dinode *din2; /* UFS2 on-disk dinode. */ } dinode_u; ino_t i_number; /* The identity of the inode. */ u_int32_t i_flag; /* flags, see below */ int i_effnlink; /* i_nlink when I/O completes */ /* * Side effects; used during directory lookup. */ int32_t i_count; /* Size of free slot in directory. */ doff_t i_endoff; /* End of useful stuff in directory. */ doff_t i_diroff; /* Offset in dir, where we found last entry. */ doff_t i_offset; /* Offset of free space in directory. */ int i_nextclustercg; /* last cg searched for cluster */ /* * Data for extended attribute modification. */ u_char *i_ea_area; /* Pointer to malloced copy of EA area */ unsigned i_ea_len; /* Length of i_ea_area */ int i_ea_error; /* First errno in transaction */ int i_ea_refs; /* Number of users of EA area */ /* * Copies from the on-disk dinode itself. */ u_int64_t i_size; /* File byte count. */ u_int64_t i_gen; /* Generation number. */ u_int32_t i_flags; /* Status flags (chflags). */ u_int32_t i_uid; /* File owner. */ u_int32_t i_gid; /* File group. */ u_int16_t i_mode; /* IFMT, permissions; see below. */ int16_t i_nlink; /* File link count. */ }; /* * These flags are kept in i_flag. */ #define IN_ACCESS 0x0001 /* Access time update request. */ #define IN_CHANGE 0x0002 /* Inode change time update request. */ #define IN_UPDATE 0x0004 /* Modification time update request. */ #define IN_MODIFIED 0x0008 /* Inode has been modified. */ #define IN_NEEDSYNC 0x0010 /* Inode requires fsync. */ #define IN_LAZYMOD 0x0020 /* Modified, but don't write yet. */ #define IN_LAZYACCESS 0x0040 /* Process IN_ACCESS after the suspension finished */ #define IN_EA_LOCKED 0x0080 #define IN_EA_LOCKWAIT 0x0100 #define IN_TRUNCATED 0x0200 /* Journaled truncation pending. */ #define IN_UFS2 0x0400 /* UFS2 vs UFS1 */ #define i_dirhash i_un.dirhash #define i_snapblklist i_un.snapblklist #define i_din1 dinode_u.din1 #define i_din2 dinode_u.din2 #ifdef _KERNEL #define ITOUMP(ip) ((ip)->i_ump) #define ITODEV(ip) (ITOUMP(ip)->um_dev) #define ITODEVVP(ip) (ITOUMP(ip)->um_devvp) #define ITOFS(ip) (ITOUMP(ip)->um_fs) #define ITOVFS(ip) ((ip)->i_vnode->v_mount) -static inline bool +static inline _Bool I_IS_UFS1(const struct inode *ip) { return ((ip->i_flag & IN_UFS2) == 0); } -static inline bool +static inline _Bool I_IS_UFS2(const struct inode *ip) { return ((ip->i_flag & IN_UFS2) != 0); } /* * The DIP macro is used to access fields in the dinode that are * not cached in the inode itself. */ #define DIP(ip, field) (I_IS_UFS1(ip) ? (ip)->i_din1->d##field : \ (ip)->i_din2->d##field) #define DIP_SET(ip, field, val) do { \ if (I_IS_UFS1(ip)) \ (ip)->i_din1->d##field = (val); \ else \ (ip)->i_din2->d##field = (val); \ } while (0) #define SHORTLINK(ip) (I_IS_UFS1(ip) ? \ (caddr_t)(ip)->i_din1->di_db : (caddr_t)(ip)->i_din2->di_db) #define IS_SNAPSHOT(ip) ((ip)->i_flags & SF_SNAPSHOT) /* * Structure used to pass around logical block paths generated by * ufs_getlbns and used by truncate and bmap code. */ struct indir { ufs2_daddr_t in_lbn; /* Logical block number. */ int in_off; /* Offset in buffer. */ }; /* Convert between inode pointers and vnode pointers. */ #define VTOI(vp) ((struct inode *)(vp)->v_data) #define ITOV(ip) ((ip)->i_vnode) /* Determine if soft dependencies are being done */ #define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & (MNT_SOFTDEP | MNT_SUJ)) #define MOUNTEDSOFTDEP(mp) ((mp)->mnt_flag & (MNT_SOFTDEP | MNT_SUJ)) #define DOINGSUJ(vp) ((vp)->v_mount->mnt_flag & MNT_SUJ) #define MOUNTEDSUJ(mp) ((mp)->mnt_flag & MNT_SUJ) /* This overlays the fid structure (see mount.h). */ struct ufid { u_int16_t ufid_len; /* Length of structure. */ u_int16_t ufid_pad; /* Force 32-bit alignment. */ uint32_t ufid_ino; /* File number (ino). */ uint32_t ufid_gen; /* Generation number. */ }; #endif /* _KERNEL */ #endif /* !_UFS_UFS_INODE_H_ */