Date: Fri, 7 Nov 2003 06:26:51 -0800 (PST) From: Chris Vance <cvance@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 41640 for review Message-ID: <200311071426.hA7EQphL047979@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=41640 Change 41640 by cvance@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311071426.hA7EQphL047979>