summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nullfs/null_vfsops.c13
-rw-r--r--sys/fs/umapfs/umap_vfsops.c12
-rw-r--r--sys/kern/syscalls.master13
-rw-r--r--sys/kern/vfs_default.c5
-rw-r--r--sys/kern/vfs_extattr.c63
-rw-r--r--sys/kern/vfs_syscalls.c63
-rw-r--r--sys/kern/vfs_vnops.c17
-rw-r--r--sys/kern/vnode_if.src2
-rw-r--r--sys/miscfs/nullfs/null_vfsops.c13
-rw-r--r--sys/miscfs/umapfs/umap_vfsops.c12
-rw-r--r--sys/sys/acl.h8
-rw-r--r--sys/sys/capability.h5
-rw-r--r--sys/sys/extattr.h22
-rw-r--r--sys/sys/mount.h12
-rw-r--r--sys/sys/vnode.h12
-rw-r--r--sys/ufs/ufs/extattr.h11
-rw-r--r--sys/ufs/ufs/ufs_extattr.c222
17 files changed, 333 insertions, 172 deletions
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index b852cc4..c9a6801 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -73,7 +73,9 @@ static int nullfs_unmount(struct mount *mp, int mntflags, struct proc *p);
static int nullfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
static int nullfs_vptofh(struct vnode *vp, struct fid *fhp);
static int nullfs_extattrctl(struct mount *mp, int cmd,
- const char *attrname, caddr_t arg, struct proc *p);
+ struct vnode *filename_vp,
+ int namespace, const char *attrname,
+ struct proc *p);
/*
* Mount null layer
@@ -408,15 +410,16 @@ nullfs_vptofh(vp, fhp)
}
static int
-nullfs_extattrctl(mp, cmd, attrname, arg, p)
+nullfs_extattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
- return VFS_EXTATTRCTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, attrname,
- arg, p);
+ return VFS_EXTATTRCTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, filename_vp,
+ namespace, attrname, p);
}
diff --git a/sys/fs/umapfs/umap_vfsops.c b/sys/fs/umapfs/umap_vfsops.c
index 768ad48..abd1b07 100644
--- a/sys/fs/umapfs/umap_vfsops.c
+++ b/sys/fs/umapfs/umap_vfsops.c
@@ -74,7 +74,8 @@ static int umapfs_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int umapfs_vptofh __P((struct vnode *vp, struct fid *fhp));
static int umapfs_extattrctl __P((struct mount *mp, int cmd,
- const char *attrname, caddr_t arg,
+ struct vnode *filename_vp,
+ int namespace, const char *attrname,
struct proc *p));
/*
@@ -430,15 +431,16 @@ umapfs_vptofh(vp, fhp)
}
static int
-umapfs_extattrctl(mp, cmd, attrname, arg, p)
+umapfs_extattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
- return (VFS_EXTATTRCTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, attrname,
- arg, p));
+ return (VFS_EXTATTRCTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd,
+ filename_vp, namespace, attrname, p));
}
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 2c54df2..6e834d4 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -508,15 +508,16 @@
354 STD BSD { int __acl_aclcheck_fd(int filedes, acl_type_t type, \
struct acl *aclp); }
355 STD BSD { int extattrctl(const char *path, int cmd, \
- const char *attrname, char *arg); }
+ const char *filename, int namespace, \
+ const char *attrname); }
356 STD BSD { int extattr_set_file(const char *path, \
- const char *attrname, struct iovec *iovp, \
- unsigned iovcnt); }
+ int namespace, const char *attrname, \
+ struct iovec *iovp, unsigned iovcnt); }
357 STD BSD { int extattr_get_file(const char *path, \
- const char *attrname, struct iovec *iovp, \
- unsigned iovcnt); }
+ int namespace, const char *attrname, \
+ struct iovec *iovp, unsigned iovcnt); }
358 STD BSD { int extattr_delete_file(const char *path, \
- const char *attrname); }
+ int namespace, const char *attrname); }
359 STD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
360 STD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
361 STD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 3e9fc75..ee56c83 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -739,11 +739,12 @@ vfs_stduninit (vfsp)
}
int
-vfs_stdextattrctl(mp, cmd, attrname, arg, p)
+vfs_stdextattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
return(EOPNOTSUPP);
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index a6c9887..79abaf4 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -3681,20 +3681,65 @@ extattrctl(p, uap)
struct proc *p;
struct extattrctl_args *uap;
{
+ struct vnode *filename_vp;
struct nameidata nd;
struct mount *mp;
+ char attrname[EXTATTR_MAXNAMELEN];
int error;
+ /*
+ * SCARG(uap, attrname) not always defined. We check again later
+ * when we invoke the VFS call so as to pass in NULL there if needed.
+ */
+ if (SCARG(uap, attrname) != NULL) {
+ error = copyinstr(SCARG(uap, attrname), attrname,
+ EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * SCARG(uap, filename) not always defined. If it is, grab
+ * a vnode lock, which VFS_EXTATTRCTL() will later release.
+ */
+ filename_vp = NULL;
+ if (SCARG(uap, filename) != NULL) {
+ NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE,
+ SCARG(uap, filename), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ filename_vp = nd.ni_vp;
+ NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ }
+
+ /* SCARG(uap, path) always defined. */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
NDFREE(&nd, 0);
- if (error)
+ if (error) {
+ if (filename_vp)
+ vrele(filename_vp);
return (error);
- error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname),
- SCARG(uap, arg), p);
+ }
+
+ if (SCARG(uap, attrname) != NULL) {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), attrname, p);
+ } else {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), NULL, p);
+ }
+
vn_finished_write(mp);
+ /*
+ * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
+ * filename_vp, so vrele it if it is defined.
+ */
+ if (filename_vp != NULL)
+ vrele(filename_vp);
+
return (error);
}
@@ -3756,8 +3801,8 @@ extattr_set_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3823,8 +3868,8 @@ extattr_get_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_GETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3859,8 +3904,8 @@ extattr_delete_file(p, uap)
NDFREE(&nd, 0);
return (error);
}
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ NULL, p->p_cred->pc_ucred, p);
NDFREE(&nd, 0);
vn_finished_write(mp);
return(error);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index a6c9887..79abaf4 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3681,20 +3681,65 @@ extattrctl(p, uap)
struct proc *p;
struct extattrctl_args *uap;
{
+ struct vnode *filename_vp;
struct nameidata nd;
struct mount *mp;
+ char attrname[EXTATTR_MAXNAMELEN];
int error;
+ /*
+ * SCARG(uap, attrname) not always defined. We check again later
+ * when we invoke the VFS call so as to pass in NULL there if needed.
+ */
+ if (SCARG(uap, attrname) != NULL) {
+ error = copyinstr(SCARG(uap, attrname), attrname,
+ EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * SCARG(uap, filename) not always defined. If it is, grab
+ * a vnode lock, which VFS_EXTATTRCTL() will later release.
+ */
+ filename_vp = NULL;
+ if (SCARG(uap, filename) != NULL) {
+ NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE,
+ SCARG(uap, filename), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ filename_vp = nd.ni_vp;
+ NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ }
+
+ /* SCARG(uap, path) always defined. */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
if ((error = namei(&nd)) != 0)
return (error);
error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
NDFREE(&nd, 0);
- if (error)
+ if (error) {
+ if (filename_vp)
+ vrele(filename_vp);
return (error);
- error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname),
- SCARG(uap, arg), p);
+ }
+
+ if (SCARG(uap, attrname) != NULL) {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), attrname, p);
+ } else {
+ error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
+ SCARG(uap, namespace), NULL, p);
+ }
+
vn_finished_write(mp);
+ /*
+ * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
+ * filename_vp, so vrele it if it is defined.
+ */
+ if (filename_vp != NULL)
+ vrele(filename_vp);
+
return (error);
}
@@ -3756,8 +3801,8 @@ extattr_set_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3823,8 +3868,8 @@ extattr_get_file(p, uap)
iov++;
}
cnt = auio.uio_resid;
- error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_cred->pc_ucred,
- p);
+ error = VOP_GETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ &auio, p->p_cred->pc_ucred, p);
cnt -= auio.uio_resid;
p->p_retval[0] = cnt;
done:
@@ -3859,8 +3904,8 @@ extattr_delete_file(p, uap)
NDFREE(&nd, 0);
return (error);
}
- error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred,
- p);
+ error = VOP_SETEXTATTR(nd.ni_vp, SCARG(uap, namespace), attrname,
+ NULL, p->p_cred->pc_ucred, p);
NDFREE(&nd, 0);
vn_finished_write(mp);
return(error);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 760df67..6c8c0f9 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -808,8 +808,8 @@ vn_kqfilter(struct file *fp, struct knote *kn)
* Set IO_NODELOCKED in ioflg if the vnode is already locked.
*/
int
-vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
- char *buf, struct proc *p)
+vn_extattr_get(struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int *buflen, char *buf, struct proc *p)
{
struct uio auio;
struct iovec iov;
@@ -830,7 +830,7 @@ vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
/* authorize attribute retrieval as kernel */
- error = VOP_GETEXTATTR(vp, attrname, &auio, NULL, p);
+ error = VOP_GETEXTATTR(vp, namespace, attrname, &auio, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0)
VOP_UNLOCK(vp, 0, p);
@@ -846,8 +846,8 @@ vn_extattr_get(struct vnode *vp, int ioflg, const char *attrname, int *buflen,
* XXX failure mode if partially written?
*/
int
-vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
- char *buf, struct proc *p)
+vn_extattr_set(struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int buflen, char *buf, struct proc *p)
{
struct uio auio;
struct iovec iov;
@@ -872,7 +872,7 @@ vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
}
/* authorize attribute setting as kernel */
- error = VOP_SETEXTATTR(vp, attrname, &auio, NULL, p);
+ error = VOP_SETEXTATTR(vp, namespace, attrname, &auio, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0) {
vn_finished_write(mp);
@@ -883,7 +883,8 @@ vn_extattr_set(struct vnode *vp, int ioflg, const char *attrname, int buflen,
}
int
-vn_extattr_rm(struct vnode *vp, int ioflg, const char *attrname, struct proc *p)
+vn_extattr_rm(struct vnode *vp, int ioflg, int namespace, const char *attrname,
+ struct proc *p)
{
struct mount *mp;
int error;
@@ -895,7 +896,7 @@ vn_extattr_rm(struct vnode *vp, int ioflg, const char *attrname, struct proc *p)
}
/* authorize attribute removal as kernel */
- error = VOP_SETEXTATTR(vp, attrname, NULL, NULL, p);
+ error = VOP_SETEXTATTR(vp, namespace, attrname, NULL, NULL, p);
if ((ioflg & IO_NODELOCKED) == 0) {
vn_finished_write(mp);
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 87fe31c..9cbe079 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -529,6 +529,7 @@ vop_aclcheck {
#
vop_getextattr {
IN struct vnode *vp;
+ IN int namespace;
IN const char *name;
INOUT struct uio *uio;
IN struct ucred *cred;
@@ -540,6 +541,7 @@ vop_getextattr {
#
vop_setextattr {
IN struct vnode *vp;
+ IN int namespace;
IN const char *name;
INOUT struct uio *uio;
IN struct ucred *cred;
diff --git a/sys/miscfs/nullfs/null_vfsops.c b/sys/miscfs/nullfs/null_vfsops.c
index b852cc4..c9a6801 100644
--- a/sys/miscfs/nullfs/null_vfsops.c
+++ b/sys/miscfs/nullfs/null_vfsops.c
@@ -73,7 +73,9 @@ static int nullfs_unmount(struct mount *mp, int mntflags, struct proc *p);
static int nullfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);
static int nullfs_vptofh(struct vnode *vp, struct fid *fhp);
static int nullfs_extattrctl(struct mount *mp, int cmd,
- const char *attrname, caddr_t arg, struct proc *p);
+ struct vnode *filename_vp,
+ int namespace, const char *attrname,
+ struct proc *p);
/*
* Mount null layer
@@ -408,15 +410,16 @@ nullfs_vptofh(vp, fhp)
}
static int
-nullfs_extattrctl(mp, cmd, attrname, arg, p)
+nullfs_extattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
- return VFS_EXTATTRCTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, attrname,
- arg, p);
+ return VFS_EXTATTRCTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, filename_vp,
+ namespace, attrname, p);
}
diff --git a/sys/miscfs/umapfs/umap_vfsops.c b/sys/miscfs/umapfs/umap_vfsops.c
index 768ad48..abd1b07 100644
--- a/sys/miscfs/umapfs/umap_vfsops.c
+++ b/sys/miscfs/umapfs/umap_vfsops.c
@@ -74,7 +74,8 @@ static int umapfs_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int umapfs_vptofh __P((struct vnode *vp, struct fid *fhp));
static int umapfs_extattrctl __P((struct mount *mp, int cmd,
- const char *attrname, caddr_t arg,
+ struct vnode *filename_vp,
+ int namespace, const char *attrname,
struct proc *p));
/*
@@ -430,15 +431,16 @@ umapfs_vptofh(vp, fhp)
}
static int
-umapfs_extattrctl(mp, cmd, attrname, arg, p)
+umapfs_extattrctl(mp, cmd, filename_vp, namespace, attrname, p)
struct mount *mp;
int cmd;
+ struct vnode *filename_vp;
+ int namespace;
const char *attrname;
- caddr_t arg;
struct proc *p;
{
- return (VFS_EXTATTRCTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, attrname,
- arg, p));
+ return (VFS_EXTATTRCTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd,
+ filename_vp, namespace, attrname, p));
}
diff --git a/sys/sys/acl.h b/sys/sys/acl.h
index 26483fc..fdb6235 100644
--- a/sys/sys/acl.h
+++ b/sys/sys/acl.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2001 Robert N. M. Watson
+ * Copyright (c) 1999, 2000, 2001 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,10 @@
* POSIX.1e ACL types and related constants.
*/
-#define POSIX1E_ACL_ACCESS_EXTATTR_NAME "$posix1e.acl_access"
-#define POSIX1E_ACL_DEFAULT_EXTATTR_NAME "$posix1e.acl_default"
+#define POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM
+#define POSIX1E_ACL_ACCESS_EXTATTR_NAME "posix1e.acl_access"
+#define POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM
+#define POSIX1E_ACL_DEFAULT_EXTATTR_NAME "posix1e.acl_default"
#define ACL_MAX_ENTRIES 32 /* maximum entries in an ACL */
#define _POSIX_ACL_PATH_MAX ACL_MAX_ENTRIES
diff --git a/sys/sys/capability.h b/sys/sys/capability.h
index cc56c58..8661595 100644
--- a/sys/sys/capability.h
+++ b/sys/sys/capability.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 Robert N. M. Watson
+ * Copyright (c) 2000, 2001 Robert N. M. Watson
* All rights reserved.
*
* Copyright (c) 1999 Ilmar S. Habibulin
@@ -36,7 +36,8 @@
#ifndef _SYS_CAPABILITY_H
#define _SYS_CAPABILITY_H
-#define POSIX1E_CAPABILITY_EXTATTR_NAME "$posix1e.cap"
+#define POSIX1E_CAPABILITY_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM
+#define POSIX1E_CAPABILITY_EXTATTR_NAME "posix1e.cap"
typedef int cap_flag_t;
typedef int cap_flag_value_t;
diff --git a/sys/sys/extattr.h b/sys/sys/extattr.h
index d03d4fb..4b545da 100644
--- a/sys/sys/extattr.h
+++ b/sys/sys/extattr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999 Robert N. M. Watson
+ * Copyright (c) 1999, 2000, 2001 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,12 @@
#ifndef _SYS_EXTATTR_H_
#define _SYS_EXTATTR_H_
+
+#define EXTATTR_NAMESPACE_USER 0x00000001
+#define EXTATTR_NAMESPACE_USER_STRING "user"
+#define EXTATTR_NAMESPACE_SYSTEM 0x00000002
+#define EXTATTR_NAMESPACE_SYSTEM_STRING "system"
+
#ifdef _KERNEL
#define EXTATTR_MAXNAMELEN NAME_MAX
@@ -51,12 +57,14 @@
struct iovec;
__BEGIN_DECLS
-int extattrctl(const char *path, int cmd, const char *attrname, char *arg);
-int extattr_delete_file(const char *path, const char *attrname);
-int extattr_get_file(const char *path, const char *attrname,
- struct iovec *iovp, unsigned iovcnt);
-int extattr_set_file(const char *path, const char *attrname,
- struct iovec *iovp, unsigned iovcnt);
+int extattrctl(const char *path, int cmd, const char *filename,
+ int namespace, const char *attrname);
+int extattr_delete_file(const char *path, int namespace,
+ const char *attrname);
+int extattr_get_file(const char *path, int namespace,
+ const char *attrname, struct iovec *iovp, unsigned iovcnt);
+int extattr_set_file(const char *path, int namespace,
+ const char *attrname, struct iovec *iovp, unsigned iovcnt);
__END_DECLS
#endif /* !_KERNEL */
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 70d84f3..8858529 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -339,7 +339,8 @@ struct vfsops {
int (*vfs_init) __P((struct vfsconf *));
int (*vfs_uninit) __P((struct vfsconf *));
int (*vfs_extattrctl) __P((struct mount *mp, int cmd,
- const char *attrname, caddr_t arg,
+ struct vnode *filename_vp,
+ int namespace, const char *attrname,
struct proc *p));
};
@@ -357,8 +358,8 @@ struct vfsops {
#define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP)
#define VFS_CHECKEXP(MP, NAM, EXFLG, CRED) \
(*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED)
-#define VFS_EXTATTRCTL(MP, C, N, A, P) \
- (*(MP)->mnt_op->vfs_extattrctl)(MP, C, N, A, P)
+#define VFS_EXTATTRCTL(MP, C, FN, NS, N, P) \
+ (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N, P)
#include <sys/module.h>
@@ -453,8 +454,9 @@ int vfs_stdcheckexp __P((struct mount *mp, struct sockaddr *nam,
int vfs_stdvptofh __P((struct vnode *vp, struct fid *fhp));
int vfs_stdinit __P((struct vfsconf *));
int vfs_stduninit __P((struct vfsconf *));
-int vfs_stdextattrctl __P((struct mount *mp, int cmd, const char *attrname,
- caddr_t arg, struct proc *p));
+int vfs_stdextattrctl __P((struct mount *mp, int cmd,
+ struct vnode *filename_vp, int namespace, const char *attrname,
+ struct proc *p));
/* XXX - these should be indirect functions!!! */
int softdep_process_worklist __P((struct mount *));
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 7ff2c31..76093ae 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -607,12 +607,12 @@ dev_t vn_todev __P((struct vnode *vp));
int vn_write_suspend_wait __P((struct vnode *vp, struct mount *mp,
int flags));
int vn_writechk __P((struct vnode *vp));
-int vn_extattr_get __P((struct vnode *vp, int ioflg, const char *attrname,
- int *buflen, char *buf, struct proc *p));
-int vn_extattr_set __P((struct vnode *vp, int ioflg, const char *attrname,
- int buflen, char *buf, struct proc *p));
-int vn_extattr_rm(struct vnode *vp, int ioflg, const char *attrname,
- struct proc *p);
+int vn_extattr_get __P((struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int *buflen, char *buf, struct proc *p));
+int vn_extattr_set __P((struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, int buflen, char *buf, struct proc *p));
+int vn_extattr_rm(struct vnode *vp, int ioflg, int namespace,
+ const char *attrname, struct proc *p);
int vfs_cache_lookup __P((struct vop_lookup_args *ap));
int vfs_object_create __P((struct vnode *vp, struct proc *p,
struct ucred *cred));
diff --git a/sys/ufs/ufs/extattr.h b/sys/ufs/ufs/extattr.h
index 849e632..f7cbfaa 100644
--- a/sys/ufs/ufs/extattr.h
+++ b/sys/ufs/ufs/extattr.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, 2000 Robert N. M. Watson
+ * Copyright (c) 1999, 2000, 2001 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -73,8 +73,9 @@ MALLOC_DECLARE(M_EXTATTR);
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;
+ LIST_ENTRY(ufs_extattr_list_entry) uele_entries;
+ struct ufs_extattr_fileheader uele_fileheader;
+ int uele_namespace;
char uele_attrname[UFS_EXTATTR_MAXEXTATTRNAME];
struct vnode *uele_backing_vnode;
};
@@ -93,8 +94,8 @@ 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, const char *attrname,
- caddr_t arg, struct proc *p);
+int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename,
+ int namespace, const char *attrname, struct proc *p);
int ufs_vop_getextattr(struct vop_getextattr_args *ap);
int ufs_vop_setextattr(struct vop_setextattr_args *ap);
void ufs_extattr_vnode_inactive(struct vnode *vp, struct proc *p);
diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c
index 2c00b95..24d4a03 100644
--- a/sys/ufs/ufs/ufs_extattr.c
+++ b/sys/ufs/ufs/ufs_extattr.c
@@ -40,6 +40,7 @@
#include <sys/mount.h>
#include <sys/lock.h>
#include <sys/dirent.h>
+#include <sys/extattr.h>
#include <vm/vm_zone.h>
@@ -52,6 +53,8 @@
#include "opt_ffs.h"
+#ifdef FFS_EXTATTR
+
#define MIN(a,b) (((a)<(b))?(a):(b))
static MALLOC_DEFINE(M_UFS_EXTATTR, "ufs_extattr", "ufs extended attribute");
@@ -60,16 +63,18 @@ static int ufs_extattr_valid_attrname(const char *attrname);
static int ufs_extattr_credcheck(struct vnode *vp,
struct ufs_extattr_list_entry *uele, struct ucred *cred, struct proc *p,
int access);
-static int ufs_extattr_enable(struct ufsmount *ump, const char *attrname,
- struct vnode *backing_vnode, struct proc *p);
-static int ufs_extattr_disable(struct ufsmount *ump, const char *attrname,
- struct proc *p);
-static int ufs_extattr_get(struct vnode *vp, const char *name,
- struct uio *uio, struct ucred *cred, struct proc *p);
-static int ufs_extattr_set(struct vnode *vp, const char *name,
- struct uio *uio, struct ucred *cred, struct proc *p);
-static int ufs_extattr_rm(struct vnode *vp, const char *name,
- struct ucred *cred, struct proc *p);
+static int ufs_extattr_enable_with_open(struct ufsmount *ump,
+ struct vnode *vp, int namespace, const char *attrname, struct proc *p);
+static int ufs_extattr_enable(struct ufsmount *ump, int namespace,
+ const char *attrname, struct vnode *backing_vnode, struct proc *p);
+static int ufs_extattr_disable(struct ufsmount *ump, int namespace,
+ const char *attrname, struct proc *p);
+static int ufs_extattr_get(struct vnode *vp, int namespace,
+ const char *name, struct uio *uio, struct ucred *cred, struct proc *p);
+static int ufs_extattr_set(struct vnode *vp, int namespace,
+ const char *name, struct uio *uio, struct ucred *cred, struct proc *p);
+static int ufs_extattr_rm(struct vnode *vp, int namespace,
+ const char *name, struct ucred *cred, struct proc *p);
/*
* Per-FS attribute lock protecting attribute operations.
@@ -119,7 +124,8 @@ ufs_extattr_valid_attrname(const char *attrname)
* Must be holding uepm lock for the mount point.
*/
static struct ufs_extattr_list_entry *
-ufs_extattr_find_attr(struct ufsmount *ump, const char *attrname)
+ufs_extattr_find_attr(struct ufsmount *ump, int namespace,
+ const char *attrname)
{
struct ufs_extattr_list_entry *search_attribute;
@@ -127,7 +133,8 @@ ufs_extattr_find_attr(struct ufsmount *ump, const char *attrname)
search_attribute;
search_attribute = LIST_NEXT(search_attribute, uele_entries)) {
if (!(strncmp(attrname, search_attribute->uele_attrname,
- UFS_EXTATTR_MAXEXTATTRNAME))) {
+ UFS_EXTATTR_MAXEXTATTRNAME)) &&
+ (namespace == search_attribute->uele_namespace)) {
return (search_attribute);
}
}
@@ -291,17 +298,18 @@ ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, char *dirname,
*vp = target_vp;
return (0);
}
+#endif /* !FFS_EXTATTR_AUTOSTART */
/*
* Enable an EA using the passed file system, backing vnode, attribute name,
- * and proc. Will perform a VOP_OPEN() on the vp, so expects vp to be locked
- * when passed in. Will unlock vp, and grab its own reference, so the caller
- * needs to vrele(), just not vput(). If the call fails, the lock is not
- * released.
+ * namespace, and proc. Will perform a VOP_OPEN() on the vp, so expects vp
+ * to be locked when passed in. Will unlock vp, and grab its own reference,
+ * so the caller needs to vrele(), just not vput(). The unlock the vnode
+ * regardless of call success or failure.
*/
static int
ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
- char *attrname, struct proc *p)
+ int namespace, const char *attrname, struct proc *p)
{
int error;
@@ -309,6 +317,7 @@ ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
if (error) {
printf("ufs_extattr_enable_with_open.VOP_OPEN(): failed "
"with %d\n", error);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -322,6 +331,7 @@ ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
* XXX: bug replicated from vn_open(): should
* VOP_CLOSE() here.
*/
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -331,9 +341,10 @@ ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
VOP_UNLOCK(vp, 0, p);
- return (ufs_extattr_enable(ump, attrname, vp, p));
+ return (ufs_extattr_enable(ump, namespace, attrname, vp, p));
}
+#ifdef FFS_EXTATTR_AUTOSTART
/*
* Given a locked directory vnode, iterate over the names in the directory
* and use ufs_extattr_lookup() to retrieve locked vnodes of potential
@@ -344,7 +355,7 @@ ufs_extattr_enable_with_open(struct ufsmount *ump, struct vnode *vp,
*/
static int
ufs_extattr_iterate_directory(struct ufsmount *ump, struct vnode *dvp,
- struct proc *p)
+ int namespace, struct proc *p)
{
struct vop_readdir_args vargs;
struct dirent *dp, *edp;
@@ -412,19 +423,18 @@ ufs_extattr_iterate_directory(struct ufsmount *ump, struct vnode *dvp,
vput(attr_vp);
} else {
error = ufs_extattr_enable_with_open(ump,
- attr_vp, dp->d_name, p);
+ attr_vp, namespace, dp->d_name, p);
+ vrele(attr_vp);
if (error) {
printf("ufs_extattr_iterate_directory: "
"enable %s %d\n", dp->d_name,
error);
- vput(attr_vp);
} else {
/*
* While it's nice to have some visual output here, skip for the time-being.
* Probably should be enabled by -v at boot.
printf("Autostarted %s\n", dp->d_name);
*/
- vrele(attr_vp);
}
}
dp = (struct dirent *) ((char *)dp + dp->d_reclen);
@@ -448,8 +458,8 @@ ufs_extattr_autostart(struct mount *mp, struct proc *p)
int error;
/*
- * Does ".attribute" exist off the file system root? If so,
- * automatically start EA's.
+ * Does UFS_EXTATTR_FSROOTSUBDIR exist off the file system root?
+ * If so, automatically start EA's.
*/
error = VFS_ROOT(mp, &rvp);
if (error) {
@@ -458,7 +468,7 @@ ufs_extattr_autostart(struct mount *mp, struct proc *p)
}
error = ufs_extattr_lookup(rvp, UE_GETDIR_LOCKPARENT_DONT,
- ".attribute", &attr_dvp, p);
+ UFS_EXTATTR_FSROOTSUBDIR, &attr_dvp, p);
if (error) {
/* rvp ref'd but now unlocked */
vrele(rvp);
@@ -473,7 +483,8 @@ ufs_extattr_autostart(struct mount *mp, struct proc *p)
vrele(rvp);
if (attr_dvp->v_type != VDIR) {
- printf("ufs_extattr_autostart: .attribute != VDIR\n");
+ printf("ufs_extattr_autostart: %s != VDIR\n",
+ UFS_EXTATTR_FSROOTSUBDIR);
goto return_vput;
}
@@ -485,10 +496,15 @@ ufs_extattr_autostart(struct mount *mp, struct proc *p)
}
/*
- * Iterate over the directory. Eventually we may lookup sub-directories
- * and iterate over them independently.
+ * Iterate over the directory. Eventually we will lookup sub-
+ * directories and iterate over them independently with different
+ * EA namespaces.
+ *
+ * XXX: Right now, assert that all attributes are in the system
+ * namespace.
*/
- error = ufs_extattr_iterate_directory(VFSTOUFS(mp), attr_dvp, p);
+ error = ufs_extattr_iterate_directory(VFSTOUFS(mp), attr_dvp,
+ EXTATTR_NAMESPACE_SYSTEM, p);
if (error)
printf("ufs_extattr_iterate_directory returned %d\n", error);
@@ -521,7 +537,8 @@ ufs_extattr_stop(struct mount *mp, struct proc *p)
while (LIST_FIRST(&ump->um_extattr.uepm_list) != NULL) {
uele = LIST_FIRST(&ump->um_extattr.uepm_list);
- ufs_extattr_disable(ump, uele->uele_attrname, p);
+ ufs_extattr_disable(ump, uele->uele_namespace,
+ uele->uele_attrname, p);
}
ump->um_extattr.uepm_flags &= ~UFS_EXTATTR_UEPM_STARTED;
@@ -536,11 +553,11 @@ unlock:
}
/*
- * Enable a named attribute on the specified file system; provide a
- * backing vnode to hold the attribute data.
+ * Enable a named attribute on the specified file system; provide an
+ * unlocked backing vnode to hold the attribute data.
*/
static int
-ufs_extattr_enable(struct ufsmount *ump, const char *attrname,
+ufs_extattr_enable(struct ufsmount *ump, int namespace, const char *attrname,
struct vnode *backing_vnode, struct proc *p)
{
struct ufs_extattr_list_entry *attribute;
@@ -563,12 +580,13 @@ ufs_extattr_enable(struct ufsmount *ump, const char *attrname,
goto free_exit;
}
- if (ufs_extattr_find_attr(ump, attrname)) {
+ if (ufs_extattr_find_attr(ump, namespace, attrname)) {
error = EEXIST;
goto free_exit;
}
strncpy(attribute->uele_attrname, attrname, UFS_EXTATTR_MAXEXTATTRNAME);
+ attribute->uele_namespace = namespace;
bzero(&attribute->uele_fileheader,
sizeof(struct ufs_extattr_fileheader));
@@ -590,9 +608,8 @@ ufs_extattr_enable(struct ufsmount *ump, const char *attrname,
ump->um_extattr.uepm_ucred);
VOP_UNLOCK(backing_vnode, 0, p);
- if (error) {
+ if (error)
goto free_exit;
- }
if (auio.uio_resid != 0) {
printf("ufs_extattr_enable: malformed attribute header\n");
@@ -627,7 +644,8 @@ free_exit:
* Disable extended attribute support on an FS.
*/
static int
-ufs_extattr_disable(struct ufsmount *ump, const char *attrname, struct proc *p)
+ufs_extattr_disable(struct ufsmount *ump, int namespace, const char *attrname,
+ struct proc *p)
{
struct ufs_extattr_list_entry *uele;
int error = 0;
@@ -635,7 +653,7 @@ ufs_extattr_disable(struct ufsmount *ump, const char *attrname, struct proc *p)
if (!ufs_extattr_valid_attrname(attrname))
return (EINVAL);
- uele = ufs_extattr_find_attr(ump, attrname);
+ uele = ufs_extattr_find_attr(ump, namespace, attrname);
if (!uele)
return (ENOENT);
@@ -650,65 +668,83 @@ ufs_extattr_disable(struct ufsmount *ump, const char *attrname, struct proc *p)
}
/*
- * VFS call to manage extended attributes in UFS.
- * attrname, arg are userspace pointers from the syscall.
+ * VFS call to manage extended attributes in UFS. If filename_vp is
+ * non-NULL, it must be passed in locked, and regardless of errors in
+ * processing, will be unlocked.
*/
int
-ufs_extattrctl(struct mount *mp, int cmd, const char *attrname,
- caddr_t arg, struct proc *p)
+ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp,
+ int namespace, const char *attrname, struct proc *p)
{
- struct nameidata nd;
struct ufsmount *ump = VFSTOUFS(mp);
- struct vnode *vp;
- char local_attrname[UFS_EXTATTR_MAXEXTATTRNAME]; /* Incl. null. */
- char *filename;
- int error, flags;
- size_t len;
+ int error;
/*
* Processes with privilege, but in jail, are not allowed to
* configure extended attributes.
*/
- if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0)))
+ if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0))) {
+ if (filename_vp != NULL)
+ VOP_UNLOCK(filename_vp, 0, p);
return (error);
+ }
switch(cmd) {
case UFS_EXTATTR_CMD_START:
+ if (filename_vp != NULL) {
+ VOP_UNLOCK(filename_vp, 0, p);
+ return (EINVAL);
+ }
+ if (attrname != NULL)
+ return (EINVAL);
+
error = ufs_extattr_start(mp, p);
return (error);
case UFS_EXTATTR_CMD_STOP:
- return (ufs_extattr_stop(mp, p));
+ if (filename_vp != NULL) {
+ VOP_UNLOCK(filename_vp, 0, p);
+ return (EINVAL);
+ }
+ if (attrname != NULL)
+ return (EINVAL);
+
+ error = ufs_extattr_stop(mp, p);
+
+ return (error);
case UFS_EXTATTR_CMD_ENABLE:
- error = copyinstr(attrname, local_attrname,
- UFS_EXTATTR_MAXEXTATTRNAME, &len);
- if (error)
- return (error);
- filename = (char *) arg;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, filename, p);
- flags = FREAD | FWRITE;
- error = vn_open(&nd, &flags, 0);
- if (error)
- return (error);
+ if (filename_vp == NULL)
+ return (EINVAL);
+ if (attrname == NULL) {
+ VOP_UNLOCK(filename_vp, 0, p);
+ return (EINVAL);
+ }
- vp = nd.ni_vp;
- VOP_UNLOCK(vp, 0, p);
-
+ /*
+ * ufs_extattr_enable_with_open() will always unlock the
+ * vnode, regardless of failure.
+ */
ufs_extattr_uepm_lock(ump, p);
- error = ufs_extattr_enable(ump, local_attrname, vp, p);
+ error = ufs_extattr_enable_with_open(ump, filename_vp,
+ namespace, attrname, p);
ufs_extattr_uepm_unlock(ump, p);
return (error);
case UFS_EXTATTR_CMD_DISABLE:
- error = copyinstr(attrname, local_attrname,
- UFS_EXTATTR_MAXEXTATTRNAME, &len);
+
+ if (filename_vp != NULL) {
+ VOP_UNLOCK(filename_vp, 0, p);
+ return (EINVAL);
+ }
+ if (attrname == NULL)
+ return (EINVAL);
ufs_extattr_uepm_lock(ump, p);
- error = ufs_extattr_disable(ump, local_attrname, p);
+ error = ufs_extattr_disable(ump, namespace, attrname, p);
ufs_extattr_uepm_unlock(ump, p);
return (error);
@@ -726,10 +762,6 @@ static int
ufs_extattr_credcheck(struct vnode *vp, struct ufs_extattr_list_entry *uele,
struct ucred *cred, struct proc *p, int access)
{
- int system_namespace;
-
- system_namespace = (strlen(uele->uele_attrname) >= 1 &&
- uele->uele_attrname[0] == '$');
/*
* Kernel-invoked always succeeds.
@@ -744,10 +776,14 @@ ufs_extattr_credcheck(struct vnode *vp, struct ufs_extattr_list_entry *uele,
* XXX What capability should apply here?
* Probably CAP_SYS_SETFFLAG.
*/
- if (system_namespace)
+ switch (uele->uele_namespace) {
+ case EXTATTR_NAMESPACE_SYSTEM:
return (suser_xxx(cred, p, 0));
- else
+ case EXTATTR_NAMESPACE_USER:
return (VOP_ACCESS(vp, access, cred, p));
+ default:
+ return (EPERM);
+ }
}
/*
@@ -758,6 +794,7 @@ ufs_vop_getextattr(struct vop_getextattr_args *ap)
/*
vop_getextattr {
IN struct vnode *a_vp;
+ IN int a_namespace;
IN const char *a_name;
INOUT struct uio *a_uio;
IN struct ucred *a_cred;
@@ -771,8 +808,8 @@ vop_getextattr {
ufs_extattr_uepm_lock(ump, ap->a_p);
- error = ufs_extattr_get(ap->a_vp, ap->a_name, ap->a_uio, ap->a_cred,
- ap->a_p);
+ error = ufs_extattr_get(ap->a_vp, ap->a_namespace, ap->a_name,
+ ap->a_uio, ap->a_cred, ap->a_p);
ufs_extattr_uepm_unlock(ump, ap->a_p);
@@ -784,8 +821,8 @@ vop_getextattr {
* the attribute lock has already been grabbed.
*/
static int
-ufs_extattr_get(struct vnode *vp, const char *name, struct uio *uio,
- struct ucred *cred, struct proc *p)
+ufs_extattr_get(struct vnode *vp, int namespace, const char *name,
+ struct uio *uio, struct ucred *cred, struct proc *p)
{
struct ufs_extattr_list_entry *attribute;
struct ufs_extattr_header ueh;
@@ -801,12 +838,13 @@ ufs_extattr_get(struct vnode *vp, const char *name, struct uio *uio,
if (!(ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED))
return (EOPNOTSUPP);
- if (strlen(name) == 0 || (strlen(name) == 1 && name[0] == '$')) {
+ if (strlen(name) == 0) {
/* XXX retrieve attribute lists. */
+ /* XXX should probably be checking for name == NULL? */
return (EINVAL);
}
- attribute = ufs_extattr_find_attr(ump, name);
+ attribute = ufs_extattr_find_attr(ump, namespace, name);
if (!attribute)
return (ENOENT);
@@ -923,6 +961,7 @@ ufs_vop_setextattr(struct vop_setextattr_args *ap)
/*
vop_setextattr {
IN struct vnode *a_vp;
+ IN int a_namespace;
IN const char *a_name;
INOUT struct uio *a_uio;
IN struct ucred *a_cred;
@@ -938,11 +977,11 @@ vop_setextattr {
ufs_extattr_uepm_lock(ump, ap->a_p);
if (ap->a_uio != NULL)
- error = ufs_extattr_set(ap->a_vp, ap->a_name, ap->a_uio,
- ap->a_cred, ap->a_p);
+ error = ufs_extattr_set(ap->a_vp, ap->a_namespace, ap->a_name,
+ ap->a_uio, ap->a_cred, ap->a_p);
else
- error = ufs_extattr_rm(ap->a_vp, ap->a_name, ap->a_cred,
- ap->a_p);
+ error = ufs_extattr_rm(ap->a_vp, ap->a_namespace, ap->a_name,
+ ap->a_cred, ap->a_p);
ufs_extattr_uepm_unlock(ump, ap->a_p);
@@ -954,8 +993,8 @@ vop_setextattr {
* assumes that the attribute lock has already been grabbed.
*/
static int
-ufs_extattr_set(struct vnode *vp, const char *name, struct uio *uio,
- struct ucred *cred, struct proc *p)
+ufs_extattr_set(struct vnode *vp, int namespace, const char *name,
+ struct uio *uio, struct ucred *cred, struct proc *p)
{
struct ufs_extattr_list_entry *attribute;
struct ufs_extattr_header ueh;
@@ -974,7 +1013,7 @@ ufs_extattr_set(struct vnode *vp, const char *name, struct uio *uio,
if (!ufs_extattr_valid_attrname(name))
return (EINVAL);
- attribute = ufs_extattr_find_attr(ump, name);
+ attribute = ufs_extattr_find_attr(ump, namespace, name);
if (!attribute)
return (ENOENT);
@@ -1059,8 +1098,8 @@ vopunlock_exit:
* Assumes the attribute lock has already been grabbed.
*/
static int
-ufs_extattr_rm(struct vnode *vp, const char *name, struct ucred *cred,
- struct proc *p)
+ufs_extattr_rm(struct vnode *vp, int namespace, const char *name,
+ struct ucred *cred, struct proc *p)
{
struct ufs_extattr_list_entry *attribute;
struct ufs_extattr_header ueh;
@@ -1079,7 +1118,7 @@ ufs_extattr_rm(struct vnode *vp, const char *name, struct ucred *cred,
if (!ufs_extattr_valid_attrname(name))
return (EINVAL);
- attribute = ufs_extattr_find_attr(ump, name);
+ attribute = ufs_extattr_find_attr(ump, namespace, name);
if (!attribute)
return (ENOENT);
@@ -1191,7 +1230,10 @@ ufs_extattr_vnode_inactive(struct vnode *vp, struct proc *p)
}
LIST_FOREACH(uele, &ump->um_extattr.uepm_list, uele_entries)
- ufs_extattr_rm(vp, uele->uele_attrname, NULL, p);
+ ufs_extattr_rm(vp, uele->uele_namespace, uele->uele_attrname,
+ NULL, p);
ufs_extattr_uepm_unlock(ump, p);
}
+
+#endif /* !FFS_EXTATTR */
OpenPOWER on IntegriCloud