PERFORCE change 41640 for review
Chris Vance
cvance at FreeBSD.org
Fri Nov 7 14:26:51 GMT 2003
http://perforce.freebsd.org/chv.cgi?CH=41640
Change 41640 by cvance at cvance_osx_laptop on 2003/11/07 06:25:52
Add some stubbed out functions for extattrs:
- thirteen new system calls
- several new VOP calls
- hfs_extattr.{c.h} stub implementations
This commit is just to keep things from swaying too far out of sync,
just about everything is '#if 0' and ENOTSUP.
Affected files ...
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/conf/MASTER#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/conf/files#6 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_extattr.c#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_extattr.h#1 add
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_vnops.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/init_sysent.c#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/syscalls.c#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/malloc.h#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/vnode.h#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/vnode_if.h#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_vnops.c#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vnode_if.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vnode_if.src#3 edit
Differences ...
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/conf/MASTER#5 (text+ko) ====
@@ -161,6 +161,7 @@
#
options FFS # Fast Filesystem Support # <ffs>
options HFS # HFS/HFS+ support # <hfs>
+options HFS_EXTATTR # hfs extended attribute support# <hfs>
options FIFO # fifo support # <fifo>
options UNION # union_fs support # <union>
options FDESC # fdesc_fs support # <fdesc>
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/conf/files#6 (text+ko) ====
@@ -412,6 +412,7 @@
bsd/hfs/hfs_encodinghint.c optional hfs
bsd/hfs/hfs_encodings.c optional hfs
bsd/hfs/hfs_endian.c optional hfs
+bsd/hfs/hfs_extattr.c optional hfs
bsd/hfs/hfs_link.c optional hfs
bsd/hfs/hfs_lockf.c optional hfs
bsd/hfs/hfs_lookup.c optional hfs
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_vnops.c#2 (text+ko) ====
@@ -3684,6 +3684,9 @@
int hfs_readdirattr(); /* in hfs_attrlist.c */
int hfs_inactive(); /* in hfs_cnode.c */
int hfs_reclaim(); /* in hfs_cnode.c */
+int hfs_getextattr(); /* in hfs_extattr.c */
+int hfs_setextattr(); /* in hfs_extattr.c */
+int hfs_deleteextattr();/* in hfs_extattr.c */
int (**hfs_vnodeop_p)(void *);
@@ -3742,6 +3745,11 @@
{ &vop_blktooff_desc, (VOPFUNC)hfs_blktooff }, /* blktooff */
{ &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk }, /* offtoblk */
{ &vop_cmap_desc, (VOPFUNC)hfs_cmap }, /* cmap */
+#ifdef HFS_EXTATTR
+ { &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
+ { &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },
+ { &vop_setextattr_desc, (VOPFUNC)hfs_setextattr },
+#endif
{ NULL, (VOPFUNC)NULL }
};
@@ -3800,6 +3808,11 @@
{ &vop_copyfile_desc, (VOPFUNC)err_copyfile }, /* copyfile */
{ &vop_blktooff_desc, (VOPFUNC)hfs_blktooff }, /* blktooff */
{ &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk }, /* offtoblk */
+#ifdef HFS_EXTATTR
+ { &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
+ { &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },
+ { &vop_setextattr_desc, (VOPFUNC)hfs_setextattr },
+#endif
{ (struct vnodeop_desc*)NULL, (VOPFUNC)NULL }
};
struct vnodeopv_desc hfs_specop_opv_desc =
@@ -3858,6 +3871,11 @@
{ &vop_blktooff_desc, (VOPFUNC)hfs_blktooff }, /* blktooff */
{ &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk }, /* offtoblk */
{ &vop_cmap_desc, (VOPFUNC)hfs_cmap }, /* cmap */
+#ifdef HFS_EXTATTR
+ { &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
+ { &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },
+ { &vop_setextattr_desc, (VOPFUNC)hfs_setextattr },
+#endif
{ (struct vnodeop_desc*)NULL, (VOPFUNC)NULL }
};
struct vnodeopv_desc hfs_fifoop_opv_desc =
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/init_sysent.c#5 (text+ko) ====
@@ -311,6 +311,20 @@
int pthread_sigmask();
int __disable_threadsignal();
+int extattrctl();
+int extattr_set_file();
+int extattr_get_file();
+int extattr_delete_file();
+int extattr_set_fd();
+int extattr_get_fd();
+int extattr_delete_fd();
+int extattr_set_link();
+int extattr_get_link();
+int extattr_delete_link();
+int extattr_list_fd();
+int extattr_list_file();
+int extattr_list_link();
+
#ifdef MAC
int __mac_get_file();
int __mac_set_file();
@@ -749,6 +763,20 @@
syss(nosys,0), /* 346 */
syss(nosys,0), /* 347 */
syss(nosys,0), /* 348 */
- syss(nosys,0) /* 349 */
+ syss(nosys,0), /* 349 */
+
+ syss(extattrctl,0), /* 350 */
+ syss(extattr_set_file,0), /* 351 */
+ syss(extattr_get_file,0), /* 352 */
+ syss(extattr_delete_file,0), /* 353 */
+ syss(extattr_set_fd,0), /* 354 */
+ syss(extattr_get_fd,0), /* 355 */
+ syss(extattr_delete_fd,0), /* 356 */
+ syss(extattr_set_link,0), /* 357 */
+ syss(extattr_get_link,0), /* 358 */
+ syss(extattr_delete_link,0), /* 359 */
+ syss(extattr_list_fd,0), /* 360 */
+ syss(extattr_list_file,0), /* 361 */
+ syss(extattr_list_link,0) /* 362 */
};
int nsysent = sizeof(sysent) / sizeof(sysent[0]);
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/syscalls.c#2 (text+ko) ====
@@ -371,5 +371,19 @@
"#346", /* 346 */
"#347", /* 347 */
"#348", /* 348 */
- "#349" /* 349 */
+ "#349", /* 349 */
+
+ "extattrctl", /* 350 */
+ "extattr_set_file", /* 351 */
+ "extattr_get_file", /* 352 */
+ "extattr_delete_file", /* 353 */
+ "extattr_set_fd" /* 354 */
+ "extattr_get_fd" /* 355 */
+ "extattr_delete_fd" /* 356 */
+ "extattr_set_link" /* 357 */
+ "extattr_get_link" /* 358 */
+ "extattr_delete_link" /* 359 */
+ "extattr_list_fd" /* 360 */
+ "extattr_list_file" /* 361 */
+ "extattr_list_link" /* 362 */
};
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/malloc.h#5 (text+ko) ====
@@ -170,7 +170,8 @@
#define M_MACPIPELABEL 93
#define M_MACTEMP 94
#define M_SBUF 95
-#define M_LAST 96 /* Must be last type + 1 */
+#define M_HFS_EXTATTR 96
+#define M_LAST 97 /* Must be last type + 1 */
/* Strings corresponding to types of memory */
/* Must be in synch with the #defines above */
@@ -271,6 +272,7 @@
"macpipelabel", /* 93 M_MACPIPELABEL */\
"mactemp", /* 94 M_MACTEMP */\
"sbuf", /* 95 M_SBUF */\
+ "hfs extattr", /* 95 M_HFS_EXTATTR */\
}
struct kmemstats {
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/vnode.h#5 (text+ko) ====
@@ -492,6 +492,12 @@
void insmntque __P((struct vnode *vp, struct mount *mp));
void vattr_null __P((struct vattr *vap));
int vcount __P((struct vnode *vp));
+int vn_extattr_get __P((struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, int *buflen, char *buf, struct proc *p));
+int vn_extattr_set __P((struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, int buflen, char *buf, struct proc *p));
+int vn_extattr_rm __P((struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, struct proc *p));
int vflush __P((struct mount *mp, struct vnode *skipvp, int flags));
int vget __P((struct vnode *vp, int lockflag, struct proc *p));
void vgone __P((struct vnode *vp));
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/vnode_if.h#3 (text+ko) ====
@@ -1329,6 +1329,140 @@
return (VCALL(vp, VOFFSET(vop_setlabel), &a));
}
+struct vop_closeextattr_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ int a_commit;
+ struct ucred *a_cred;
+ struct proc *a_p;
+};
+extern struct vnodeop_desc vop_closeextattr_desc;
+#define VOP_CLOSEEXTATTR(vp, commit, cred, p) _VOP_CLOSEEXTATTR(vp, commit, cred, p)
+static __inline int _VOP_CLOSEEXTATTR(struct vnode *vp, int commit, struct ucred *cred, struct proc *p)
+{
+ struct vop_closeextattr_args a;
+ a.a_desc = VDESC(vop_closeextattr);
+ a.a_vp = vp;
+ a.a_commit = commit;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_closeextattr), &a));
+}
+
+struct vop_getextattr_args {
+ struct vnodeop_desc *a_desc;
+ 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;
+};
+extern struct vnodeop_desc vop_getextattr_desc;
+#define VOP_GETEXTATTR(vp, attrnamespace, name, uio, size, cred, p) _VOP_GETEXTATTR(vp, attrnamespace, name, uio, size, cred, p)
+static __inline int _VOP_GETEXTATTR(struct vnode *vp, int attrnamespace, const char *name, struct uio *uio, size_t *size, struct ucred *cred, struct proc *p)
+{
+ struct vop_getextattr_args a;
+ a.a_desc = VDESC(vop_getextattr);
+ a.a_vp = vp;
+ a.a_attrnamespace = attrnamespace;
+ a.a_name = name;
+ a.a_uio = uio;
+ a.a_size = size;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_getextattr), &a));
+}
+
+struct vop_listextattr_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ int a_attrnamespace;
+ struct uio *a_uio;
+ size_t *a_size;
+ struct ucred *a_cred;
+ struct proc *a_p;
+};
+extern struct vnodeop_desc vop_listextattr_desc;
+#define VOP_LISTEXTATTR(vp, attrnamespace, uio, size, cred, p) _VOP_LISTEXTATTR(vp, attrnamespace, uio, size, cred, p)
+static __inline int _VOP_LISTEXTATTR(struct vnode *vp, int attrnamespace, struct uio *uio, size_t *size, struct ucred *cred, struct proc *p)
+{
+ struct vop_listextattr_args a;
+ a.a_desc = VDESC(vop_listextattr);
+ a.a_vp = vp;
+ a.a_attrnamespace = attrnamespace;
+ a.a_uio = uio;
+ a.a_size = size;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_listextattr), &a));
+}
+
+struct vop_openextattr_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ struct ucred *a_cred;
+ struct proc *a_p;
+};
+extern struct vnodeop_desc vop_openextattr_desc;
+#define VOP_OPENEXTATTR(vp, cred, p) _VOP_OPENEXTATTR(vp, cred, p)
+static __inline int _VOP_OPENEXTATTR(struct vnode *vp, struct ucred *cred, struct proc *p)
+{
+ struct vop_openextattr_args a;
+ a.a_desc = VDESC(vop_openextattr);
+ a.a_vp = vp;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_openextattr), &a));
+}
+
+struct vop_deleteextattr_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ int a_attrnamespace;
+ const char *a_name;
+ struct ucred *a_cred;
+ struct proc *a_p;
+};
+extern struct vnodeop_desc vop_deleteextattr_desc;
+#define VOP_DELETEEXTATTR(vp, attrnamespace, name, cred, p) _VOP_DELETEEXTATTR(vp, attrnamespace, name, cred, p)
+static __inline int _VOP_DELETEEXTATTR(struct vnode *vp, int attrnamespace, const char *name, struct ucred *cred, struct proc *p)
+{
+ struct vop_deleteextattr_args a;
+ a.a_desc = VDESC(vop_deleteextattr);
+ a.a_vp = vp;
+ a.a_attrnamespace = attrnamespace;
+ a.a_name = name;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_deleteextattr), &a));
+}
+
+struct vop_setextattr_args {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ int a_attrnamespace;
+ const char *a_name;
+ struct uio *a_uio;
+ struct ucred *a_cred;
+ struct proc *a_p;
+};
+extern struct vnodeop_desc vop_setextattr_desc;
+#define VOP_SETEXTATTR(vp, attrnamespace, name, uio, cred, p) _VOP_SETEXTATTR(vp, attrnamespace, name, uio, cred, p)
+static __inline int _VOP_SETEXTATTR(struct vnode *vp, int attrnamespace, const char *name, struct uio *uio, struct ucred *cred, struct proc *p)
+{
+ struct vop_setextattr_args a;
+ a.a_desc = VDESC(vop_setextattr);
+ a.a_vp = vp;
+ a.a_attrnamespace = attrnamespace;
+ a.a_name = name;
+ a.a_uio = uio;
+ a.a_cred = cred;
+ a.a_p = p;
+ return (VCALL(vp, VOFFSET(vop_setextattr), &a));
+}
+
/* Special cases: */
#include <sys/buf.h>
#include <sys/vm.h>
==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#5 (text+ko) ====
@@ -3949,3 +3949,757 @@
return (error);
} /* end of sync_internal call */
+/*
+ * Syscall to push extended attribute configuration information into the
+ * VFS. Accepts a path, which it converts to a mountpoint, as well as
+ * a command (int cmd), and attribute name and misc data. For now, the
+ * attribute name is left in userspace for consumption by the VFS_op.
+ * It will probably be changed to be copied into sysspace by the
+ * syscall in the future, once issues with various consumers of the
+ * attribute code have raised their hands.
+ *
+ * Currently this is used only by UFS Extended Attributes.
+ */
+
+struct extattrctl_args {
+ char * path;
+ int cmd;
+ char * filename;
+ int attrnamespace;
+ char * attrname;
+};
+
+int
+extattrctl(p, uap, retval)
+ struct proc *p;
+ register struct extattrctl_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct vnode *filename_vp;
+ struct nameidata nd;
+ struct mount *mp, *mp_writable;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ /*
+ * uap->attrname is not always defined. We check again later when we
+ * invoke the VFS call so as to pass in NULL there if needed.
+ */
+ if (uap->attrname != NULL) {
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN,
+ NULL);
+ if (error)
+ return (error);
+ }
+
+ /*
+ * uap->filename is not always defined. If it is, grab a vnode lock,
+ * which VFS_EXTATTRCTL() will later release.
+ */
+ filename_vp = NULL;
+ if (uap->filename != NULL) {
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ uap->filename, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ filename_vp = nd.ni_vp;
+ NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
+ }
+
+ /* uap->path is always defined. */
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error) {
+ if (filename_vp != NULL)
+ vput(filename_vp);
+ return (error);
+ }
+ mp = nd.ni_vp->v_mount;
+ error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
+ NDFREE(&nd, 0);
+ if (error) {
+ if (filename_vp != NULL)
+ vput(filename_vp);
+ return (error);
+ }
+
+ error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
+ uap->attrname != NULL ? attrname : NULL, td);
+
+ vn_finished_write(mp_writable);
+ /*
+ * 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);
+#endif
+}
+
+/*-
+ * Set a named extended attribute on a file or directory
+ *
+ * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
+ * kernelspace string pointer "attrname", userspace buffer
+ * pointer "data", buffer length "nbytes", thread "td".
+ * Returns: 0 on success, an error number otherwise
+ * Locks: none
+ * References: vp must be a valid reference for the duration of the call
+ */
+static int
+extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
+ void *data, size_t nbytes, struct proc *p)
+{
+ return (ENOTSUP);
+#if 0
+ struct mount *mp;
+ struct uio auio;
+ struct iovec aiov;
+ ssize_t cnt;
+ int error;
+
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error)
+ return (error);
+ VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+
+ aiov.iov_base = data;
+ aiov.iov_len = nbytes;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ if (nbytes > INT_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ auio.uio_resid = nbytes;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+ cnt = nbytes;
+
+#ifdef MAC
+ error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
+ attrname, &auio);
+ if (error)
+ goto done;
+#endif
+
+ error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
+ td->td_ucred, td);
+ cnt -= auio.uio_resid;
+ td->td_retval[0] = cnt;
+
+done:
+ VOP_UNLOCK(vp, 0, td);
+ vn_finished_write(mp);
+ return (error);
+#endif
+}
+
+struct extattr_set_fd_args {
+ int fd;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_set_fd(p, uap, retval)
+ struct proc *p;
+ register struct extattr_set_fd_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct file *fp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
+ if (error)
+ return (error);
+
+ error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes, td);
+ fdrop(fp, td);
+
+ return (error);
+#endif
+}
+
+struct extattr_set_file_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_set_file(p, uap, retval)
+ struct proc *p;
+ register struct extattr_set_file_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+#endif
+}
+
+struct extattr_set_link_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_set_link(p, uap, retval)
+ struct proc *p;
+ register struct extattr_set_link_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+#endif
+}
+
+/*-
+ * Get a named extended attribute on a file or directory
+ *
+ * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
+ * kernelspace string pointer "attrname", userspace buffer
+ * pointer "data", buffer length "nbytes", thread "td".
+ * Returns: 0 on success, an error number otherwise
+ * Locks: none
+ * References: vp must be a valid reference for the duration of the call
+ */
+static int
+extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
+ void *data, size_t nbytes, struct proc *p)
+{
+ return (ENOTSUP);
+#if 0
+ struct uio auio, *auiop;
+ struct iovec aiov;
+ ssize_t cnt;
+ size_t size, *sizep;
+ int error;
+
+ /*
+ * XXX: Temporary API compatibility for applications that know
+ * about this hack ("" means list), but haven't been updated
+ * for the extattr_list_*() system calls yet. This will go
+ * away for FreeBSD 5.3.
+ */
+ if (strlen(attrname) == 0)
+ return (extattr_list_vp(vp, attrnamespace, data, nbytes, td));
+
+ VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+
+ /*
+ * Slightly unusual semantics: if the user provides a NULL data
+ * pointer, they don't want to receive the data, just the
+ * maximum read length.
+ */
+ auiop = NULL;
+ sizep = NULL;
+ cnt = 0;
+ if (data != NULL) {
+ aiov.iov_base = data;
+ aiov.iov_len = nbytes;
+ auio.uio_iov = &aiov;
+ auio.uio_offset = 0;
+ if (nbytes > INT_MAX) {
+ error = EINVAL;
+ goto done;
+ }
+ auio.uio_resid = nbytes;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_td = td;
+ auiop = &auio;
+ cnt = nbytes;
+ } else
+ sizep = &size;
+
+#ifdef MAC
+ error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace,
+ attrname, &auio);
+ if (error)
+ goto done;
+#endif
+
+ error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
+ td->td_ucred, td);
+
+ if (auiop != NULL) {
+ cnt -= auio.uio_resid;
+ td->td_retval[0] = cnt;
+ } else
+ td->td_retval[0] = size;
+
+done:
+ VOP_UNLOCK(vp, 0, td);
+ return (error);
+#endif
+}
+
+struct extattr_get_fd_args {
+ int fd;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_get_fd(p, uap, retval)
+ struct proc *p;
+ register struct extattr_get_fd_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct file *fp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
+ if (error)
+ return (error);
+
+ error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes, td);
+
+ fdrop(fp, td);
+ return (error);
+#endif
+}
+
+struct extattr_get_file_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_get_file(p, uap, retval)
+ struct proc *p;
+ register struct extattr_get_file_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+#endif
+}
+
+struct extattr_get_link_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+ void *data;
+ size_t nbytes;
+};
+
+int
+extattr_get_link(p, uap, retval)
+ struct proc *p;
+ register struct extattr_get_link_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, td);
+
+ vrele(nd.ni_vp);
+ return (error);
+#endif
+}
+
+/*
+ * extattr_delete_vp(): Delete a named extended attribute on a file or
+ * directory
+ *
+ * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
+ * kernelspace string pointer "attrname", proc "p"
+ * Returns: 0 on success, an error number otherwise
+ * Locks: none
+ * References: vp must be a valid reference for the duration of the call
+ */
+static int
+extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
+ struct proc *p)
+{
+ return (ENOTSUP);
+#if 0
+ struct mount *mp;
+ int error;
+
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error)
+ return (error);
+ VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+
+#ifdef MAC
+ error = mac_check_vnode_deleteextattr(td->td_ucred, vp, attrnamespace,
+ attrname);
+ if (error)
+ goto done;
+#endif
+
+ error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred,
+ td);
+ if (error == EOPNOTSUPP)
+ error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
+ td->td_ucred, td);
+#ifdef MAC
+done:
+#endif
+ VOP_UNLOCK(vp, 0, td);
+ vn_finished_write(mp);
+ return (error);
+#endif
+}
+
+struct extattr_delete_fd_args {
+ int fd;
+ int attrnamespace;
+ char *attrname;
+};
+
+int
+extattr_delete_fd(p, uap, retval)
+ struct proc *p;
+ register struct extattr_delete_fd_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct file *fp;
+ struct vnode *vp;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return (error);
+
+ error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
+ if (error)
+ return (error);
+ vp = fp->f_vnode;
+
+ error = extattr_delete_vp(vp, uap->attrnamespace, attrname, td);
+ fdrop(fp, td);
+ return (error);
+#endif
+}
+
+struct extattr_delete_file_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+};
+
+int
+extattr_delete_file(p, uap, retval)
+ struct proc *p;
+ register struct extattr_delete_file_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return(error);
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return(error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
+ vrele(nd.ni_vp);
+ return(error);
+#endif
+}
+
+struct extattr_delete_link_args {
+ char *path;
+ int attrnamespace;
+ char *attrname;
+};
+
+int
+extattr_delete_link(p, uap, retval)
+ struct proc *p;
+ register struct extattr_delete_link_args *uap;
+ register_t *retval;
+{
+ return (ENOTSUP);
+#if 0
+ struct nameidata nd;
+ char attrname[EXTATTR_MAXNAMELEN];
+ int error;
+
+ error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
+ if (error)
+ return(error);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
+ error = namei(&nd);
+ if (error)
+ return(error);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
+ vrele(nd.ni_vp);
+ return(error);
+#endif
+}
+
+/*-
+ * Retrieve a list of extended attributes on a file or directory.
+ *
+ * Arguments: unlocked vnode "vp", attribute namespace 'attrnamespace",
+ * userspace buffer pointer "data", buffer length "nbytes",
+ * thread "td".
+ * Returns: 0 on success, an error number otherwise
+ * Locks: none
+ * References: vp must be a valid reference for the duration of the call
+ */
+static int
+extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
+ size_t nbytes, struct proc *p)
+{
+ return (ENOTSUP);
+#if 0
+ struct uio auio, *auiop;
+ size_t size, *sizep;
+ struct iovec aiov;
+ ssize_t cnt;
+ int error;
+
+ VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+
+ auiop = NULL;
+ sizep = NULL;
+ cnt = 0;
+ if (data != NULL) {
+ aiov.iov_base = data;
+ aiov.iov_len = nbytes;
+ auio.uio_iov = &aiov;
+ auio.uio_offset = 0;
+ if (nbytes > INT_MAX) {
+ error = EINVAL;
+ goto done;
+ }
>>> TRUNCATED FOR MAIL (1000 lines) <<<
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list