1170757Sdelphij/* 2170757Sdelphij * Copyright (c) 2000 Peter Edwards 330862Sache * Copyright (c) 1988, 1993 4170757Sdelphij * The Regents of the University of California. All rights reserved. 530862Sache * 6170757Sdelphij * This code is derived from software contributed to Berkeley by Peter Edwards 730862Sache * 830862Sache * Redistribution and use in source and binary forms, with or without 9170757Sdelphij * modification, are permitted provided that the following conditions 10170757Sdelphij * are met: 11170757Sdelphij * 1. Redistributions of source code must retain the above copyright 1230862Sache * notice, this list of conditions and the following disclaimer. 1330862Sache * 2. Redistributions in binary form must reproduce the above copyright 14170757Sdelphij * notice, this list of conditions and the following disclaimer in the 15170757Sdelphij * documentation and/or other materials provided with the distribution. 16170757Sdelphij * 3. All advertising materials mentioning features or use of this software 17170757Sdelphij * must display the following acknowledgement: 18170757Sdelphij * This product includes software developed by the University of 19170757Sdelphij * California, Berkeley and its contributors. 20170757Sdelphij * 4. Neither the name of the University nor the names of its contributors 21170757Sdelphij * may be used to endorse or promote products derived from this software 22170757Sdelphij * without specific prior written permission. 23170757Sdelphij * 24170757Sdelphij * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25170757Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26170757Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27170757Sdelphij * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28170757Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29170757Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30170757Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31170757Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32170757Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33170757Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34170757Sdelphij * SUCH DAMAGE. 35170757Sdelphij */ 36170757Sdelphij 37170757Sdelphij#include <sys/cdefs.h> 38170757Sdelphij__FBSDID("$FreeBSD$"); 39170757Sdelphij 40170757Sdelphij#include <sys/param.h> 41170757Sdelphij#include <sys/time.h> 42170757Sdelphij#include <sys/stat.h> 43170757Sdelphij#include <sys/vnode.h> 44170757Sdelphij 45170757Sdelphij#include <netinet/in.h> 46170757Sdelphij 47170757Sdelphij#define _KERNEL 48170757Sdelphij#include <sys/mount.h> 49170757Sdelphij#include <fs/msdosfs/bpb.h> 50170757Sdelphij#include <fs/msdosfs/msdosfsmount.h> 51170757Sdelphij#undef _KERNEL 52170757Sdelphij 53170757Sdelphij#include <fs/msdosfs/denode.h> 54170757Sdelphij#include <fs/msdosfs/direntry.h> 55170757Sdelphij#include <fs/msdosfs/fat.h> 56170757Sdelphij 57170757Sdelphij#include <err.h> 58170757Sdelphij#include <kvm.h> 59170757Sdelphij#include <stdio.h> 6030862Sache#include <stdlib.h> 6130862Sache 62170757Sdelphij/* 63170757Sdelphij * XXX - 6430862Sache * VTODE is defined in denode.h only if _KERNEL is defined, but that leads to 65170757Sdelphij * header explosion 66170757Sdelphij */ 6730862Sache#define VTODE(vp) ((struct denode *)getvnodedata(vp)) 68170757Sdelphij 69170757Sdelphij#include "libprocstat.h" 70170757Sdelphij#include "common_kvm.h" 71170757Sdelphij 72170757Sdelphijstruct dosmount { 73170757Sdelphij struct dosmount *next; 74170757Sdelphij struct msdosfsmount *kptr; /* Pointer in kernel space */ 75170757Sdelphij struct msdosfsmount data; /* User space copy of structure */ 76170757Sdelphij}; 77170757Sdelphij 78170757Sdelphijint 79170757Sdelphijmsdosfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) 80170757Sdelphij{ 81170757Sdelphij struct denode denode; 82170757Sdelphij static struct dosmount *mounts; 83170757Sdelphij struct dosmount *mnt; 84170757Sdelphij u_long dirsperblk; 85170757Sdelphij int fileid; 86170757Sdelphij 87170757Sdelphij if (!kvm_read_all(kd, (unsigned long)VTODE(vp), &denode, 88170757Sdelphij sizeof(denode))) { 89170757Sdelphij warnx("can't read denode at %p", (void *)VTODE(vp)); 90170757Sdelphij return (1); 91170757Sdelphij } 92170757Sdelphij 93170757Sdelphij /* 94170757Sdelphij * Find msdosfsmount structure for the vnode's filesystem. Needed 95170757Sdelphij * for some filesystem parameters 96170757Sdelphij */ 97170757Sdelphij for (mnt = mounts; mnt; mnt = mnt->next) 98170757Sdelphij if (mnt->kptr == denode.de_pmp) 99170757Sdelphij break; 100170757Sdelphij 101170757Sdelphij if (!mnt) { 102170757Sdelphij if ((mnt = malloc(sizeof(struct dosmount))) == NULL) { 103170757Sdelphij warn("malloc()"); 104170757Sdelphij return (1); 105170757Sdelphij } 106170757Sdelphij if (!kvm_read_all(kd, (unsigned long)denode.de_pmp, 107170757Sdelphij &mnt->data, sizeof(mnt->data))) { 108170757Sdelphij free(mnt); 109170757Sdelphij warnx("can't read mount info at %p", 110170757Sdelphij (void *)denode.de_pmp); 111170757Sdelphij return (1); 112170757Sdelphij } 113170757Sdelphij mnt->next = mounts; 114170757Sdelphij mounts = mnt; 115170757Sdelphij mnt->kptr = denode.de_pmp; 116170757Sdelphij } 117170757Sdelphij 118170757Sdelphij vn->vn_fsid = dev2udev(kd, mnt->data.pm_dev); 119170757Sdelphij vn->vn_mode = 0555; 120170757Sdelphij vn->vn_mode |= denode.de_Attributes & ATTR_READONLY ? 0 : 0222; 121170757Sdelphij vn->vn_mode &= mnt->data.pm_mask; 122170757Sdelphij 123170757Sdelphij /* Distinguish directories and files. No "special" files in FAT. */ 124170757Sdelphij vn->vn_mode |= denode.de_Attributes & ATTR_DIRECTORY ? S_IFDIR : S_IFREG; 125170757Sdelphij vn->vn_size = denode.de_FileSize; 126170757Sdelphij 127170757Sdelphij /* 128170757Sdelphij * XXX - 129170757Sdelphij * Culled from msdosfs_vnops.c. There appears to be a problem 130170757Sdelphij * here, in that a directory has the same inode number as the first 131170757Sdelphij * file in the directory. stat(2) suffers from this problem also, so 132170757Sdelphij * I won't try to fix it here. 133170757Sdelphij * 134170757Sdelphij * The following computation of the fileid must be the same as that 135170757Sdelphij * used in msdosfs_readdir() to compute d_fileno. If not, pwd 136170757Sdelphij * doesn't work. 137170757Sdelphij */ 138170757Sdelphij dirsperblk = mnt->data.pm_BytesPerSec / sizeof(struct direntry); 139170757Sdelphij if (denode.de_Attributes & ATTR_DIRECTORY) { 140170757Sdelphij fileid = cntobn(&mnt->data, denode.de_StartCluster) 141170757Sdelphij * dirsperblk; 142170757Sdelphij if (denode.de_StartCluster == MSDOSFSROOT) 143170757Sdelphij fileid = 1; 144170757Sdelphij } else { 145170757Sdelphij fileid = cntobn(&mnt->data, denode.de_dirclust) * dirsperblk; 146170757Sdelphij if (denode.de_dirclust == MSDOSFSROOT) 147170757Sdelphij fileid = roottobn(&mnt->data, 0) * dirsperblk; 148170757Sdelphij fileid += denode.de_diroffset / sizeof(struct direntry); 149170757Sdelphij } 150170757Sdelphij 151170757Sdelphij vn->vn_fileid = fileid; 152170757Sdelphij return (0); 153170757Sdelphij} 154170757Sdelphij