Experimental support for extended attributes on UFS1 file systems, using a
backing file per attribute type indexed by inode number to hold the extended attributes. This is working pretty well on my test systems, except for the "autostart" feature. I need someone with a better handle on the VFS locking protocol to go over that. This is a work-in-progress. There are parts of this that could be re-factored allowing this approach to be used on other types of file systems. Adapted from FreeBSD.
This commit is contained in:
parent
3876130b24
commit
e1afed9c2d
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.567 2005/08/20 17:23:53 rpaulo Exp $
|
||||
# $NetBSD: mi,v 1.568 2005/08/28 19:37:58 thorpej Exp $
|
||||
. base-sys-root
|
||||
./altroot base-sys-root
|
||||
./bin base-sys-root
|
||||
|
@ -964,6 +964,7 @@
|
|||
./usr/sbin/envstat base-sysutil-bin
|
||||
./usr/sbin/eshconfig base-sysutil-bin
|
||||
./usr/sbin/etcupdate base-sysutil-bin
|
||||
./usr/sbin/extattrctl base-sysutil-bin
|
||||
./usr/sbin/faithd base-router-bin inet6
|
||||
./usr/sbin/fixmount base-nfsclient-bin
|
||||
./usr/sbin/flush base-obsolete obsolete
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.808 2005/08/23 17:47:07 elad Exp $
|
||||
# $NetBSD: mi,v 1.809 2005/08/28 19:37:58 thorpej Exp $
|
||||
./etc/mtree/set.comp comp-sys-root
|
||||
./usr/bin/addr2line comp-debug-bin bfd
|
||||
./usr/bin/ar comp-util-bin bfd
|
||||
|
@ -1486,6 +1486,7 @@
|
|||
./usr/include/ufs/ufs/dinode.h comp-c-include
|
||||
./usr/include/ufs/ufs/dir.h comp-c-include
|
||||
./usr/include/ufs/ufs/dirhash.h comp-obsolete obsolete
|
||||
./usr/include/ufs/ufs/extattr.h comp-c-include
|
||||
./usr/include/ufs/ufs/inode.h comp-c-include
|
||||
./usr/include/ufs/ufs/quota.h comp-c-include
|
||||
./usr/include/ufs/ufs/ufs_bswap.h comp-c-include
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.818 2005/08/23 12:14:01 peter Exp $
|
||||
# $NetBSD: mi,v 1.819 2005/08/28 19:37:58 thorpej Exp $
|
||||
./etc/mtree/set.man man-sys-root
|
||||
./usr/share/info/am-utils.info man-amd-info info
|
||||
./usr/share/info/as.info man-computil-info bfd,info
|
||||
|
@ -1757,6 +1757,7 @@
|
|||
./usr/share/man/cat8/evbsh3/makedev.0 man-obsolete obsolete
|
||||
./usr/share/man/cat8/evbsh5/MAKEDEV.0 man-obsolete obsolete
|
||||
./usr/share/man/cat8/evbsh5/makedev.0 man-obsolete obsolete
|
||||
./usr/share/man/cat8/extattrctl.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/faithd.0 man-router-catman inet6,.cat
|
||||
./usr/share/man/cat8/fastboot.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/fasthalt.0 man-sysutil-catman .cat
|
||||
|
@ -4019,6 +4020,7 @@
|
|||
./usr/share/man/man8/evbsh3/makedev.8 man-obsolete obsolete
|
||||
./usr/share/man/man8/evbsh5/MAKEDEV.8 man-obsolete obsolete
|
||||
./usr/share/man/man8/evbsh5/makedev.8 man-obsolete obsolete
|
||||
./usr/share/man/man8/extattrctl.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/faithd.8 man-router-man inet6,.man
|
||||
./usr/share/man/man8/fastboot.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/fasthalt.8 man-sysutil-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ffs_extern.h,v 1.43 2005/07/15 05:01:16 thorpej Exp $ */
|
||||
/* $NetBSD: ffs_extern.h,v 1.44 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
|
@ -136,6 +136,8 @@ int ffs_sync(struct mount *, int, struct ucred *, struct proc *);
|
|||
int ffs_vget(struct mount *, ino_t, struct vnode **);
|
||||
int ffs_fhtovp(struct mount *, struct fid *, struct vnode **);
|
||||
int ffs_vptofh(struct vnode *, struct fid *);
|
||||
int ffs_extattrctl(struct mount *, int, struct vnode *, int,
|
||||
const char *, struct proc *);
|
||||
int ffs_sbupdate(struct ufsmount *, int);
|
||||
int ffs_cgupdate(struct ufsmount *, int);
|
||||
|
||||
|
@ -155,6 +157,12 @@ int ffs_reclaim(void *);
|
|||
int ffs_getpages(void *);
|
||||
int ffs_putpages(void *);
|
||||
void ffs_gop_size(struct vnode *, off_t, off_t *, int);
|
||||
int ffs_openextattr(void *);
|
||||
int ffs_closeextattr(void *);
|
||||
int ffs_getextattr(void *);
|
||||
int ffs_setextattr(void *);
|
||||
int ffs_listextattr(void *);
|
||||
int ffs_deleteextattr(void *);
|
||||
|
||||
#ifdef SYSCTL_SETUP_PROTO
|
||||
SYSCTL_SETUP_PROTO(sysctl_vfs_ffs_setup);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ffs_vfsops.c,v 1.169 2005/08/23 08:05:13 christos Exp $ */
|
||||
/* $NetBSD: ffs_vfsops.c,v 1.170 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1991, 1993, 1994
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.169 2005/08/23 08:05:13 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.170 2005/08/28 19:37:59 thorpej Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_ffs.h"
|
||||
|
@ -108,7 +108,7 @@ struct vfsops ffs_vfsops = {
|
|||
ffs_mountroot,
|
||||
ufs_check_export,
|
||||
ffs_snapshot,
|
||||
vfs_stdextattrctl,
|
||||
ffs_extattrctl,
|
||||
ffs_vnodeopv_descs,
|
||||
};
|
||||
VFS_ATTACH(ffs_vfsops);
|
||||
|
@ -979,6 +979,22 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
|
|||
}
|
||||
if (ronly == 0 && fs->fs_snapinum[0] != 0)
|
||||
ffs_snapshot_mount(mp);
|
||||
#ifdef UFS_EXTATTR
|
||||
/*
|
||||
* Initialize file-backed extended attributes on UFS1 file
|
||||
* systems.
|
||||
*/
|
||||
if (ump->um_fstype == UFS1) {
|
||||
ufs_extattr_uepm_init(&ump->um_extattr);
|
||||
#ifdef UFS_EXTATTR_AUTOSTART
|
||||
/*
|
||||
* XXX Just ignore errors. Not clear that we should
|
||||
* XXX fail the mount in this case.
|
||||
*/
|
||||
(void) ufs_extattr_autostart(mp, p);
|
||||
#endif
|
||||
}
|
||||
#endif /* UFS_EXTATTR */
|
||||
return (0);
|
||||
out:
|
||||
if (fs)
|
||||
|
@ -1116,14 +1132,24 @@ ffs_oldfscompat_write(struct fs *fs, struct ufsmount *ump)
|
|||
int
|
||||
ffs_unmount(struct mount *mp, int mntflags, struct proc *p)
|
||||
{
|
||||
struct ufsmount *ump;
|
||||
struct fs *fs;
|
||||
struct ufsmount *ump = VFSTOUFS(mp);
|
||||
struct fs *fs = ump->um_fs;
|
||||
int error, flags, penderr;
|
||||
|
||||
penderr = 0;
|
||||
flags = 0;
|
||||
if (mntflags & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
#ifdef UFS_EXTATTR
|
||||
if (ump->um_fstype == UFS1) {
|
||||
error = ufs_extattr_stop(mp, p);
|
||||
if (error)
|
||||
printf("%s: ufs_extattr_stop returned %d\n",
|
||||
fs->fs_fsmnt, error);
|
||||
else
|
||||
ufs_extattr_uepm_destroy(&ump->um_extattr);
|
||||
}
|
||||
#endif /* UFS_EXTATTR */
|
||||
if (mp->mnt_flag & MNT_SOFTDEP) {
|
||||
if ((error = softdep_flushfiles(mp, flags, p)) != 0)
|
||||
return (error);
|
||||
|
@ -1131,8 +1157,6 @@ ffs_unmount(struct mount *mp, int mntflags, struct proc *p)
|
|||
if ((error = ffs_flushfiles(mp, flags, p)) != 0)
|
||||
return (error);
|
||||
}
|
||||
ump = VFSTOUFS(mp);
|
||||
fs = ump->um_fs;
|
||||
if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
|
||||
printf("%s: unmount pending error: blocks %" PRId64
|
||||
" files %d\n",
|
||||
|
@ -1685,3 +1709,19 @@ ffs_cgupdate(struct ufsmount *mp, int waitfor)
|
|||
allerror = error;
|
||||
return (allerror);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_extattrctl(struct mount *mp, int cmd, struct vnode *vp,
|
||||
int attrnamespace, const char *attrname, struct proc *p)
|
||||
{
|
||||
#ifdef UFS_EXTATTR
|
||||
/*
|
||||
* File-backed extended attributes are only supported on UFS1.
|
||||
* UFS2 has native extended attributes.
|
||||
*/
|
||||
if (VFSTOUFS(mp)->um_fstype == UFS1)
|
||||
return (ufs_extattrctl(mp, cmd, vp, attrnamespace, attrname,
|
||||
p));
|
||||
#endif
|
||||
return (vfs_stdextattrctl(mp, cmd, vp, attrnamespace, attrname, p));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ffs_vnops.c,v 1.72 2005/07/26 12:14:46 yamt Exp $ */
|
||||
/* $NetBSD: ffs_vnops.c,v 1.73 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.72 2005/07/26 12:14:46 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.73 2005/08/28 19:37:59 thorpej Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -117,6 +117,12 @@ const struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
|
|||
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
|
||||
{ &vop_getpages_desc, ffs_getpages }, /* getpages */
|
||||
{ &vop_putpages_desc, ffs_putpages }, /* putpages */
|
||||
{ &vop_openextattr_desc, ffs_openextattr }, /* openextattr */
|
||||
{ &vop_closeextattr_desc, ffs_closeextattr }, /* closeextattr */
|
||||
{ &vop_getextattr_desc, ffs_getextattr }, /* getextattr */
|
||||
{ &vop_setextattr_desc, ffs_setextattr }, /* setextattr */
|
||||
{ &vop_listextattr_desc, ffs_listextattr }, /* listextattr */
|
||||
{ &vop_deleteextattr_desc, ffs_deleteextattr }, /* deleteextattr */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
const struct vnodeopv_desc ffs_vnodeop_opv_desc =
|
||||
|
@ -172,6 +178,12 @@ const struct vnodeopv_entry_desc ffs_specop_entries[] = {
|
|||
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
|
||||
{ &vop_getpages_desc, spec_getpages }, /* getpages */
|
||||
{ &vop_putpages_desc, spec_putpages }, /* putpages */
|
||||
{ &vop_openextattr_desc, ffs_openextattr }, /* openextattr */
|
||||
{ &vop_closeextattr_desc, ffs_closeextattr }, /* closeextattr */
|
||||
{ &vop_getextattr_desc, ffs_getextattr }, /* getextattr */
|
||||
{ &vop_setextattr_desc, ffs_setextattr }, /* setextattr */
|
||||
{ &vop_listextattr_desc, ffs_listextattr }, /* listextattr */
|
||||
{ &vop_deleteextattr_desc, ffs_deleteextattr }, /* deleteextattr */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
const struct vnodeopv_desc ffs_specop_opv_desc =
|
||||
|
@ -226,6 +238,12 @@ const struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
|
|||
{ &vop_update_desc, ffs_update }, /* update */
|
||||
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
|
||||
{ &vop_putpages_desc, fifo_putpages }, /* putpages */
|
||||
{ &vop_openextattr_desc, ffs_openextattr }, /* openextattr */
|
||||
{ &vop_closeextattr_desc, ffs_closeextattr }, /* closeextattr */
|
||||
{ &vop_getextattr_desc, ffs_getextattr }, /* getextattr */
|
||||
{ &vop_setextattr_desc, ffs_setextattr }, /* setextattr */
|
||||
{ &vop_listextattr_desc, ffs_listextattr }, /* listextattr */
|
||||
{ &vop_deleteextattr_desc, ffs_deleteextattr }, /* deleteextattr */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
const struct vnodeopv_desc ffs_fifoop_opv_desc =
|
||||
|
@ -611,3 +629,141 @@ ffs_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
|
|||
*eobp = blkroundup(fs, size);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ffs_openextattr(void *v)
|
||||
{
|
||||
struct vop_openextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
/* Not supported for UFS1 file systems. */
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_closeextattr(void *v)
|
||||
{
|
||||
struct vop_closeextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_commit;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
/* Not supported for UFS1 file systems. */
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_getextattr(void *v)
|
||||
{
|
||||
struct vop_getextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_attrnamespace;
|
||||
const char *a_name;
|
||||
struct uio *a_uio;
|
||||
size_t *a_size;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC) {
|
||||
#ifdef UFS_EXTATTR
|
||||
return (ufs_getextattr(ap));
|
||||
#else
|
||||
return (EOPNOTSUPP);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_setextattr(void *v)
|
||||
{
|
||||
struct vop_setextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_attrnamespace;
|
||||
const char *a_name;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC) {
|
||||
#ifdef UFS_EXTATTR
|
||||
return (ufs_setextattr(ap));
|
||||
#else
|
||||
return (EOPNOTSUPP);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_listextattr(void *v)
|
||||
{
|
||||
struct vop_listextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_attrnamespace;
|
||||
struct uio *a_uio;
|
||||
size_t *a_size;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
/* Not supported for UFS1 file systems. */
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
ffs_deleteextattr(void *v)
|
||||
{
|
||||
struct vop_deleteextattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_attrnamespace;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
struct fs *fs = ip->i_fs;
|
||||
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC) {
|
||||
#ifdef UFS_EXTATTR
|
||||
return (ufs_deleteextattr(ap));
|
||||
#else
|
||||
return (EOPNOTSUPP);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX Not implemented for UFS2 file systems. */
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.ufs,v 1.10 2005/07/10 01:08:52 thorpej Exp $
|
||||
# $NetBSD: files.ufs,v 1.11 2005/08/28 19:37:58 thorpej Exp $
|
||||
|
||||
deffs FFS
|
||||
deffs EXT2FS
|
||||
|
@ -7,6 +7,7 @@ deffs fs_lfs.h LFS # XXX
|
|||
|
||||
defflag opt_ffs.h FFS_EI FFS_NO_SNAPSHOT APPLE_UFS
|
||||
UFS_DIRHASH
|
||||
UFS_EXTATTR UFS_EXTATTR_AUTOSTART
|
||||
|
||||
file ufs/ext2fs/ext2fs_alloc.c ext2fs
|
||||
file ufs/ext2fs/ext2fs_balloc.c ext2fs
|
||||
|
@ -50,6 +51,7 @@ file ufs/mfs/mfs_vnops.c mfs
|
|||
|
||||
file ufs/ufs/ufs_bmap.c ffs | lfs | mfs | ext2fs
|
||||
file ufs/ufs/ufs_dirhash.c (ffs | lfs | mfs | ext2fs) & ufs_dirhash
|
||||
file ufs/ufs/ufs_extattr.c (ffs | mfs) & ufs_extattr
|
||||
file ufs/ufs/ufs_ihash.c ffs | lfs | mfs | ext2fs
|
||||
file ufs/ufs/ufs_inode.c ffs | lfs | mfs
|
||||
file ufs/ufs/ufs_lookup.c ffs | lfs | mfs | ext2fs
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.3 2005/01/24 01:32:22 rumble Exp $
|
||||
# $NetBSD: Makefile,v 1.4 2005/08/28 19:37:59 thorpej Exp $
|
||||
|
||||
INCSDIR= /usr/include/ufs/ufs
|
||||
|
||||
INCS= dinode.h dir.h inode.h quota.h ufs_bswap.h ufs_extern.h ufsmount.h
|
||||
INCS= dinode.h dir.h extattr.h inode.h quota.h ufs_bswap.h ufs_extern.h \
|
||||
ufsmount.h
|
||||
|
||||
.include <bsd.kinc.mk>
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* $NetBSD: extattr.h,v 1.1 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* 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: src/sys/ufs/ufs/extattr.h,v 1.20 2005/01/31 08:16:45 imp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Support for file system extended attributes on the UFS1 file system.
|
||||
* Developed by the TrustedBSD Project.
|
||||
*/
|
||||
|
||||
#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 {
|
||||
uint32_t uef_magic; /* magic number for sanity checking */
|
||||
uint32_t uef_version; /* version of attribute file */
|
||||
uint32_t uef_size; /* size of attributes, w/o header */
|
||||
};
|
||||
|
||||
struct ufs_extattr_header {
|
||||
uint32_t ueh_flags; /* flags for attribute */
|
||||
uint32_t ueh_len; /* local defined length; <= uef_size */
|
||||
uint32_t ueh_i_gen; /* generation number for sanity */
|
||||
/* data follows the header */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_EXTATTR);
|
||||
#endif
|
||||
|
||||
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;
|
||||
int uele_flags;
|
||||
};
|
||||
|
||||
/* uele_flags */
|
||||
#define UELE_F_NEEDSWAP 0x01 /* needs byte swap */
|
||||
|
||||
#define UELE_NEEDSWAP(uele) ((uele)->uele_flags & UELE_F_NEEDSWAP)
|
||||
|
||||
struct lock;
|
||||
struct ucred;
|
||||
struct ufs_extattr_per_mount {
|
||||
struct lock uepm_lock;
|
||||
struct ufs_extattr_list_head uepm_list;
|
||||
struct ucred *uepm_ucred;
|
||||
int uepm_flags;
|
||||
};
|
||||
|
||||
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 proc *p);
|
||||
int ufs_extattr_autostart(struct mount *mp, struct proc *p);
|
||||
int ufs_extattr_stop(struct mount *mp, struct proc *p);
|
||||
int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename,
|
||||
int attrnamespace, const char *attrname, struct proc *p);
|
||||
int ufs_getextattr(struct vop_getextattr_args *ap);
|
||||
int ufs_deleteextattr(struct vop_deleteextattr_args *ap);
|
||||
int ufs_setextattr(struct vop_setextattr_args *ap);
|
||||
int ufs_listextattr(struct vop_listextattr_args *ap);
|
||||
void ufs_extattr_vnode_inactive(struct vnode *vp, struct proc *p);
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* !_UFS_UFS_EXTATTR_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ufs_inode.c,v 1.51 2005/07/23 12:18:41 yamt Exp $ */
|
||||
/* $NetBSD: ufs_inode.c,v 1.52 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.51 2005/07/23 12:18:41 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.52 2005/08/28 19:37:59 thorpej Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_ffs.h"
|
||||
|
@ -59,6 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.51 2005/07/23 12:18:41 yamt Exp $");
|
|||
#ifdef UFS_DIRHASH
|
||||
#include <ufs/ufs/dirhash.h>
|
||||
#endif
|
||||
#ifdef UFS_EXTATTR
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#endif
|
||||
|
||||
#include <uvm/uvm.h>
|
||||
|
||||
|
@ -97,6 +100,9 @@ ufs_inactive(void *v)
|
|||
#ifdef QUOTA
|
||||
if (!getinoquota(ip))
|
||||
(void)chkiq(ip, -1, NOCRED, 0);
|
||||
#endif
|
||||
#ifdef UFS_EXTATTR
|
||||
ufs_extattr_vnode_inactive(vp, p);
|
||||
#endif
|
||||
if (ip->i_size != 0) {
|
||||
error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, p);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ufsmount.h,v 1.18 2005/05/22 08:35:28 hannken Exp $ */
|
||||
/* $NetBSD: ufsmount.h,v 1.19 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
|
@ -58,6 +58,8 @@ struct mfs_args {
|
|||
#include "opt_ffs.h"
|
||||
#endif
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
|
||||
struct buf;
|
||||
struct inode;
|
||||
struct nameidata;
|
||||
|
@ -84,6 +86,9 @@ struct ufsmount {
|
|||
#define um_e2fs ufsmount_u.e2fs
|
||||
#define um_e2fsb ufsmount_u.e2fs->s_es
|
||||
|
||||
/* Extended attribute information. */
|
||||
struct ufs_extattr_per_mount um_extattr;
|
||||
|
||||
struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */
|
||||
struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */
|
||||
u_long um_nindir; /* indirect ptrs per block */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.204 2005/07/11 15:37:05 kiyohara Exp $
|
||||
# $NetBSD: Makefile,v 1.205 2005/08/28 19:37:58 thorpej Exp $
|
||||
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
@ -6,7 +6,7 @@
|
|||
SUBDIR= ac accton altq amd apm apmd arp bad144 bind bootp catman \
|
||||
chown chroot chrtbl cnwctl cron dev_mkdb \
|
||||
dhcp diskpart dumpfs dumplfs edquota eeprom \
|
||||
envstat eshconfig etcupdate fssconfig fwctl grfconfig \
|
||||
envstat eshconfig etcupdate extattrctl fssconfig fwctl grfconfig \
|
||||
grfinfo gspa hilinfo ifwatchd inetd installboot \
|
||||
iopctl iostat ipwctl irdaattach isdn iteconfig iwictl\
|
||||
kgmon lastlogin link lpr mailwrapper makefs \
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.1 2005/08/28 19:37:59 thorpej Exp $
|
||||
|
||||
PROG= extattrctl
|
||||
MAN= extattrctl.8
|
||||
|
||||
WARNS?= 3
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,209 @@
|
|||
.\" $NetBSD: extattrctl.8,v 1.1 2005/08/28 19:37:59 thorpej Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2000-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: src/usr.sbin/extattrctl/extattrctl.8,v 1.24 2005/02/09 18:04:40 ru Exp $
|
||||
.\"
|
||||
.\" Developed by the TrustedBSD Project.
|
||||
.\" Support for file system extended attribute.
|
||||
.\"
|
||||
.Dd July 11, 2005
|
||||
.Dt EXTATTRCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm extattrctl
|
||||
.Nd manage UFS1 extended attributes
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm start
|
||||
.Ar path
|
||||
.Nm
|
||||
.Cm stop
|
||||
.Ar path
|
||||
.Nm
|
||||
.Cm initattr
|
||||
.Op Fl f
|
||||
.Op Fl p Ar path
|
||||
.Ar attrsize
|
||||
.Ar attrfile
|
||||
.Nm
|
||||
.Cm showattr
|
||||
.Ar attrfile
|
||||
.Nm
|
||||
.Cm enable
|
||||
.Ar path
|
||||
.Ar attrnamespace
|
||||
.Ar attrname
|
||||
.Ar attrfile
|
||||
.Nm
|
||||
.Cm disable
|
||||
.Ar path
|
||||
.Ar attrnamespace
|
||||
.Ar attrname
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
is the management utility for extended attributes over the UFS1 file system.
|
||||
It allows the starting and stopping of extended attributes on a file system,
|
||||
as well as initialization of attribute backing files, and enabling and
|
||||
disabling of specific extended attributes on a file system.
|
||||
.Pp
|
||||
The first argument on the command line indicates the operation to be
|
||||
performed.
|
||||
Operation must be one of the following:
|
||||
.Bl -tag -width indent
|
||||
.It Cm start Ar path
|
||||
Start extended attribute support on the file system named using
|
||||
.Ar path .
|
||||
The file system must be an UFS1 file system, and the UFS_EXTATTR kernel
|
||||
option must have been enabled.
|
||||
.It Cm stop Ar path
|
||||
Stop extended attribute support on the file system named using
|
||||
.Ar path .
|
||||
Extended attribute support must previously have been started.
|
||||
.It Xo
|
||||
.Cm initattr
|
||||
.Op Fl f
|
||||
.Op Fl p Ar path
|
||||
.Ar attrsize attrfile
|
||||
.Xc
|
||||
Create and initialize a file to use as an attribute backing file.
|
||||
You must specify a maximum per-inode size for the attribute in bytes in
|
||||
.Ar attrsize ,
|
||||
as well as the file where the attribute will be stored, using
|
||||
.Ar attrfile .
|
||||
.Pp
|
||||
The
|
||||
.Fl f
|
||||
argument may be used to indicate that it is alright to overwrite an
|
||||
existing attribute backing file; otherwise, if the target file exists,
|
||||
an error will be returned.
|
||||
.Pp
|
||||
The
|
||||
.Fl p Ar path
|
||||
argument may be used to preallocate space for all attributes rather than
|
||||
relying on sparse files to conserve space.
|
||||
This has the advantage of guaranteeing that space will be available
|
||||
for attributes when they are written, preventing low disk space conditions
|
||||
from denying attribute service.
|
||||
.Pp
|
||||
This file should not exist before running
|
||||
.Cm initattr .
|
||||
.It Cm showattr Ar attrfile
|
||||
Show the attribute header values in the attribute file named by
|
||||
.Ar attrfile .
|
||||
.It Cm enable Ar path attrnamespace attrname attrfile
|
||||
Enable an attribute named
|
||||
.Ar attrname
|
||||
in the namespace
|
||||
.Ar attrnamespace
|
||||
on the file system identified using
|
||||
.Ar path ,
|
||||
and backed by initialized attribute file
|
||||
.Ar attrfile .
|
||||
Available namespaces are "user" and "system".
|
||||
The backing file must have been initialized using
|
||||
.Cm initattr
|
||||
before its first use.
|
||||
Attributes must have been started on the file system prior to the
|
||||
enabling of any attributes.
|
||||
.It Cm disable Ar path attrnamespace attrname
|
||||
Disable the attributed named
|
||||
.Ar attrname
|
||||
in namespace
|
||||
.Ar attrnamespace
|
||||
on the file system identified by
|
||||
.Ar path .
|
||||
Available namespaces are "user" and "system".
|
||||
The file system must have attributes started on it, and the attribute
|
||||
most have been enabled using
|
||||
.Cm enable .
|
||||
.El
|
||||
.Pp
|
||||
The kernel also includes support for automatic starting of extended
|
||||
attributes on a file system at mount time once configured with
|
||||
.Nm .
|
||||
If the kernel is built with the
|
||||
.Dq UFS_EXTATTR_AUTOSTART
|
||||
option, UFS will search for a
|
||||
.Pa .attribute
|
||||
sub-directory of the file system root during the mount operation.
|
||||
If found, extended attribute support will be started for the file system.
|
||||
UFS will then search for
|
||||
.Pa system
|
||||
and
|
||||
.Pa user
|
||||
sub-directories of the
|
||||
.Pa .attribute
|
||||
directory for any potential backing files and enable an extended attribute
|
||||
for each valid backing file with the backing file name as the attribute
|
||||
name.
|
||||
.Sh EXAMPLES
|
||||
.Dl extattrctl start /
|
||||
.Pp
|
||||
Start extended attributes on the root file system.
|
||||
.Pp
|
||||
.Dl extattrctl initattr 17 /.attribute/system/md5
|
||||
.Pp
|
||||
Create an attribute backing file in /.attribute/system/md5, and set the maximum
|
||||
size of each attribute to 17 bytes, with a sparse file used for storing
|
||||
the attributes.
|
||||
.Pp
|
||||
.Dl extattrctl enable / system md5 /.attribute/system/md5
|
||||
.Pp
|
||||
Enable an attribute named md5 on the root file system, backed from the file
|
||||
/.attribute/system/md5.
|
||||
.Pp
|
||||
.Dl extattrctl disable / md5
|
||||
.Pp
|
||||
Disable the attribute named md5 on the root file system.
|
||||
.Pp
|
||||
.Dl extattrctl stop /
|
||||
.Pp
|
||||
Stop extended attributes on the root file system.
|
||||
.Sh SEE ALSO
|
||||
.Xr extattr_get_file 2 ,
|
||||
.\" .Xr ffs 7 ,
|
||||
.Xr getextattr 1 ,
|
||||
.Xr extattr 9
|
||||
.Sh HISTORY
|
||||
Extended attribute support was developed as part of the TrustedBSD Project,
|
||||
and introduced in
|
||||
.Fx 5.0
|
||||
and
|
||||
.Nx 4.0 .
|
||||
It was developed to support security extensions requiring additional labels
|
||||
to be associated with each file or directory.
|
||||
.Sh AUTHORS
|
||||
Robert N M Watson
|
||||
.Sh BUGS
|
||||
.Nm
|
||||
works only on UFS1 file systems.
|
||||
The kernel support for extended attribute backing files and this control
|
||||
program should be generalized for any file system that lacks native extended
|
||||
attribute support.
|
|
@ -0,0 +1,281 @@
|
|||
/* $NetBSD: extattrctl.c,v 1.1 2005/08/28 19:37:59 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999-2002 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: src/usr.sbin/extattrctl/extattrctl.c,v 1.19 2002/04/19 01:42:55 rwatson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Developed by the TrustedBSD Project.
|
||||
* Support for file system extended attribute.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/extattr.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <machine/bswap.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
static int needswap;
|
||||
|
||||
static uint32_t
|
||||
rw32(uint32_t v)
|
||||
{
|
||||
if (needswap)
|
||||
return (bswap32(v));
|
||||
return (v);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"usage:\n"
|
||||
" %s start path\n"
|
||||
" %s stop path\n"
|
||||
" %s initattr [-f] [-p path] attrsize attrfile\n"
|
||||
" %s showattr attrfile\n"
|
||||
" %s enable path attrnamespace attrname attrfile\n"
|
||||
" %s disable path attrnamespace attrname\n",
|
||||
getprogname(), getprogname(), getprogname(),
|
||||
getprogname(), getprogname(), getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
num_inodes_by_path(const char *path)
|
||||
{
|
||||
struct statvfs buf;
|
||||
|
||||
if (statvfs(path, &buf) == -1) {
|
||||
warn("statvfs(%s)", path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (buf.f_files);
|
||||
}
|
||||
|
||||
static const char zero_buf[8192];
|
||||
|
||||
static int
|
||||
initattr(int argc, char *argv[])
|
||||
{
|
||||
struct ufs_extattr_fileheader uef;
|
||||
char *fs_path = NULL;
|
||||
int ch, i, error, flags;
|
||||
ssize_t wlen;
|
||||
size_t easize;
|
||||
|
||||
flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
|
||||
optind = 0;
|
||||
while ((ch = getopt(argc, argv, "fp:r:w:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
flags &= ~O_EXCL;
|
||||
break;
|
||||
case 'p':
|
||||
fs_path = optarg;
|
||||
break;
|
||||
case 'B':
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
if (strcmp(optarg, "le") == 0)
|
||||
needswap = 0;
|
||||
else if (strcmp(optarg, "be") == 0)
|
||||
needswap = 1;
|
||||
else
|
||||
usage();
|
||||
#else
|
||||
if (strcmp(optarg, "be") == 0)
|
||||
needswap = 0;
|
||||
else if (strcmp(optarg, "le") == 0)
|
||||
needswap = 1;
|
||||
else
|
||||
usage();
|
||||
#endif
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
error = 0;
|
||||
if ((i = open(argv[1], flags, 0600)) == -1) {
|
||||
warn("open(%s)", argv[1]);
|
||||
return (-1);
|
||||
}
|
||||
uef.uef_magic = rw32(UFS_EXTATTR_MAGIC);
|
||||
uef.uef_version = rw32(UFS_EXTATTR_VERSION);
|
||||
uef.uef_size = rw32(atoi(argv[0]));
|
||||
if (write(i, &uef, sizeof(uef)) != sizeof(uef)) {
|
||||
warn("unable to write arribute file header");
|
||||
error = -1;
|
||||
} else if (fs_path != NULL) {
|
||||
easize = (sizeof(uef) + uef.uef_size) *
|
||||
num_inodes_by_path(fs_path);
|
||||
while (easize > 0) {
|
||||
size_t x = (easize > sizeof(zero_buf)) ?
|
||||
sizeof(zero_buf) : easize;
|
||||
wlen = write(i, zero_buf, x);
|
||||
if (wlen != x) {
|
||||
warn("unable to write attribute file");
|
||||
error = -1;
|
||||
break;
|
||||
}
|
||||
easize -= wlen;
|
||||
}
|
||||
}
|
||||
if (error == -1) {
|
||||
unlink(argv[1]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
showattr(int argc, char *argv[])
|
||||
{
|
||||
struct ufs_extattr_fileheader uef;
|
||||
int i, fd;
|
||||
const char *bo;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
fd = open(argv[0], O_RDONLY);
|
||||
if (fd == -1) {
|
||||
warn("open(%s)", argv[0]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
i = read(fd, &uef, sizeof(uef));
|
||||
if (i != sizeof(uef)) {
|
||||
warn("unable to read attribute file header");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (rw32(uef.uef_magic) != UFS_EXTATTR_MAGIC) {
|
||||
needswap = 1;
|
||||
if (rw32(uef.uef_magic) != UFS_EXTATTR_MAGIC) {
|
||||
fprintf(stderr, "%s: bad magic\n", argv[0]);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
bo = needswap ? "big-endian" : "little-endian";
|
||||
#else
|
||||
bo = needswap ? "little-endian" : "big-endian";
|
||||
#endif
|
||||
|
||||
printf("%s: version %u, size %u, byte-order: %s\n",
|
||||
argv[0], rw32(uef.uef_version), rw32(uef.uef_size), bo);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int error = 0, attrnamespace;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
if (!strcmp(argv[1], "start")) {
|
||||
if (argc != 3)
|
||||
usage();
|
||||
error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0,
|
||||
NULL);
|
||||
if (error)
|
||||
err(1, "start");
|
||||
} else if (!strcmp(argv[1], "stop")) {
|
||||
if (argc != 3)
|
||||
usage();
|
||||
error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0,
|
||||
NULL);
|
||||
if (error)
|
||||
err(1, "stop");
|
||||
} else if (!strcmp(argv[1], "enable")) {
|
||||
if (argc != 6)
|
||||
usage();
|
||||
error = extattr_string_to_namespace(argv[3], &attrnamespace);
|
||||
if (error)
|
||||
errx(1, "bad namespace: %s", argv[3]);
|
||||
error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5],
|
||||
attrnamespace, argv[4]);
|
||||
if (error)
|
||||
err(1, "enable");
|
||||
} else if (!strcmp(argv[1], "disable")) {
|
||||
if (argc != 5)
|
||||
usage();
|
||||
error = extattr_string_to_namespace(argv[3], &attrnamespace);
|
||||
if (error)
|
||||
errx(1, "bad namespace: %s", argv[3]);
|
||||
error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL,
|
||||
attrnamespace, argv[4]);
|
||||
if (error)
|
||||
err(1, "disable");
|
||||
} else if (!strcmp(argv[1], "initattr")) {
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
error = initattr(argc, argv);
|
||||
if (error)
|
||||
return (1);
|
||||
} else if (!strcmp(argv[1], "showattr")) {
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
error = showattr(argc, argv);
|
||||
if (error)
|
||||
return (1);
|
||||
} else
|
||||
usage();
|
||||
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue