From e788edda6ff465c5d0824f803c9a28efe73421d8 Mon Sep 17 00:00:00 2001 From: Francois Tigeot Date: Sat, 6 Aug 2011 23:02:32 +0200 Subject: [PATCH] VFS accounting: implement an initialization framework Only enable accounting for a short list of whitelisted filesystem types --- sys/conf/files | 1 + sys/kern/vfs_default.c | 66 ++++++++++++++++++++++++++++++++++++++++++ sys/kern/vfs_init.c | 9 +++++- sys/kern/vfs_quota.c | 49 +++++++++++++++++++++++++++++++ sys/kern/vfs_vfsops.c | 8 ++++- sys/sys/mount.h | 8 +++++ sys/sys/vfs_quota.h | 45 ++++++++++++++++++++++++++++ 7 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 sys/kern/vfs_quota.c create mode 100644 sys/sys/vfs_quota.h diff --git a/sys/conf/files b/sys/conf/files index d2756ad40a..3077b98984 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1008,6 +1008,7 @@ kern/vfs_subr.c standard kern/vfs_vm.c standard kern/vfs_lock.c standard kern/vfs_mount.c standard +kern/vfs_quota.c standard kern/vfs_sync.c standard kern/vfs_synth.c standard kern/vfs_syscalls.c standard diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index e6e4da434e..a32f77f68a 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -56,6 +56,7 @@ #include #include #include +#include #include @@ -1456,10 +1457,75 @@ vfs_stdextattrctl(struct mount *mp, int cmd, struct vnode *vp, return(EOPNOTSUPP); } +#define ACCOUNTING_NB_FSTYPES 8 + +static const char *accounting_fstypes[ACCOUNTING_NB_FSTYPES] = { + "ext2fs", "hammer", "hpfs", "mfs", "ntfs", "null", "tmpfs", "ufs" }; + +int +vfs_stdac_init(struct mount *mp) +{ + const char* fs_type; + int i, fstype_ok = 0; + + /* if mounted fs is read-only, do not do anything */ + if (mp->mnt_flag & MNT_RDONLY) + return (0); + + /* is mounted fs type one we want to do some accounting for ? */ + for (i=0; imnt_stat.f_fstypename, fs_type, + sizeof(mp->mnt_stat)) == 0) { + fstype_ok = 1; + break; + } + } + if (fstype_ok == 0) + return (0); + + kprintf("vfs_quota: enabling accounting for %s\n", + mp->mnt_stat.f_mntonname); + vq_init(mp); + return (0); +} + +int +vfs_stdac_done(struct mount *mp) +{ + const char* fs_type; + int i, fstype_ok = 0; + + /* if mounted fs is read-only, do not do anything */ + if (mp->mnt_flag & MNT_RDONLY) + return (0); + + /* is mounted fs type one we want to do some accounting for ? */ + for (i=0; imnt_stat.f_fstypename, fs_type, + sizeof(mp->mnt_stat)) == 0) { + fstype_ok = 1; + break; + } + } + if (fstype_ok == 0) + return (0); + + vq_done(mp); + return (0); +} + int vfs_stdaccount(struct mount *mp, uid_t uid, gid_t gid, int64_t delta) { return(0); } +int +vfs_noaccount(struct mount *mp, uid_t uid, gid_t gid, int64_t delta) +{ + return(0); +} + /* end of vfs default ops */ diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 4ac5b5c9f1..020812bc6d 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -420,8 +420,15 @@ vfs_register(struct vfsconf *vfc) /* extended attribute control */ vfsops->vfs_extattrctl = vfs_stdextattrctl; } + + /* file system uid and gid accounting */ + if (vfsops->vfs_acinit == NULL) { + vfsops->vfs_acinit = vfs_stdac_init; + } + if (vfsops->vfs_acdone == NULL) { + vfsops->vfs_acdone = vfs_stdac_done; + } if (vfsops->vfs_account == NULL) { - /* file system uid and gid accounting */ vfsops->vfs_account = vfs_stdaccount; } diff --git a/sys/kern/vfs_quota.c b/sys/kern/vfs_quota.c new file mode 100644 index 0000000000..c7aa371888 --- /dev/null +++ b/sys/kern/vfs_quota.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 François Tigeot + * 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. Neither the name of The DragonFly Project 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include +#include +#include +#include +#include +#include + +/* initializes global accounting data */ +void +vq_init(struct mount *mp) { +} + + +void +vq_done(struct mount *mp) { +} diff --git a/sys/kern/vfs_vfsops.c b/sys/kern/vfs_vfsops.c index 7b22462c34..bc5bc8fc67 100644 --- a/sys/kern/vfs_vfsops.c +++ b/sys/kern/vfs_vfsops.c @@ -106,6 +106,10 @@ vfs_start(struct mount *mp, int flags) VFS_MPLOCK1(mp); error = (mp->mnt_op->vfs_start)(mp, flags); + if (error == 0) + /* do not call vfs_acinit on mount updates */ + if ((mp->mnt_flag & MNT_UPDATE) == 0) + error = (mp->mnt_op->vfs_acinit)(mp); VFS_MPUNLOCK(mp); return (error); } @@ -120,7 +124,9 @@ vfs_unmount(struct mount *mp, int mntflags) int error; VFS_MPLOCK1(mp); - error = (mp->mnt_op->vfs_unmount)(mp, mntflags); + error = (mp->mnt_op->vfs_acdone)(mp); + if (error == 0) + error = (mp->mnt_op->vfs_unmount)(mp, mntflags); VFS_MPUNLOCK(mp); return (error); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 495314fa35..2289880f40 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -62,6 +62,7 @@ #ifndef _SYS_THREAD_H_ #include #endif +#include #endif struct thread; @@ -501,6 +502,8 @@ typedef int vfs_uninit_t(struct vfsconf *); typedef int vfs_extattrctl_t(struct mount *mp, int cmd, struct vnode *vp, int attrnamespace, const char *attrname, struct ucred *cred); +typedef int vfs_acinit_t(struct mount *mp); +typedef int vfs_acdone_t(struct mount *mp); typedef int vfs_account_t(struct mount *mp, uid_t uid, gid_t gid, int64_t delta); @@ -543,6 +546,8 @@ struct vfsops { vfs_uninit_t *vfs_uninit; vfs_extattrctl_t *vfs_extattrctl; vfs_statvfs_t *vfs_statvfs; + vfs_acinit_t *vfs_acinit; + vfs_acdone_t *vfs_acdone; vfs_account_t *vfs_account; }; @@ -676,7 +681,10 @@ vfs_vptofh_t vfs_stdvptofh; vfs_init_t vfs_stdinit; vfs_uninit_t vfs_stduninit; vfs_extattrctl_t vfs_stdextattrctl; +vfs_acinit_t vfs_stdac_init; +vfs_acdone_t vfs_stdac_done; vfs_account_t vfs_stdaccount; +vfs_account_t vfs_noaccount; struct vop_access_args; int vop_helper_access(struct vop_access_args *ap, uid_t ino_uid, gid_t ino_gid, diff --git a/sys/sys/vfs_quota.h b/sys/sys/vfs_quota.h new file mode 100644 index 0000000000..b4676cd69e --- /dev/null +++ b/sys/sys/vfs_quota.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 François Tigeot + * All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by François Tigeot + * + * 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. Neither the name of The DragonFly Project 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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. + */ + +#ifndef _SYS_VFSQUOTA_H_ +#define _SYS_VFSQUOTA_H_ + +#include + +extern void vq_init(struct mount*); +extern void vq_done(struct mount*); + +#endif + -- 2.41.0