Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144324519
D13267.id36236.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D13267.id36236.diff
View Options
Index: kern/vfs_extattr.c
===================================================================
--- kern/vfs_extattr.c
+++ kern/vfs_extattr.c
@@ -150,16 +150,18 @@
/*-
* 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".
+ * Arguments: vnode "vp", attribute namespace "attrnamespace",
+ * "ioflag" for vnode locking control,
+ * kernelspace string pointer "attrname",
+ * buffer pointer "data", buffer length "nbytes",
+ * buffer uio adress-space control - "segflg", 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 thread *td)
+int
+extattr_set_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes, enum uio_seg segflg,
+ struct thread *td)
{
struct mount *mp;
struct uio auio;
@@ -167,26 +169,29 @@
ssize_t cnt;
int error;
- error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
- if (error)
- return (error);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
aiov.iov_base = data;
aiov.iov_len = nbytes;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_WRITE;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
cnt = nbytes;
+ if ((ioflg & IO_NODELOCKED) == 0) {
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error)
+ return (error);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ }
+
+ ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
+
#ifdef MAC
error = mac_vnode_check_setextattr(td->td_ucred, vp, attrnamespace,
attrname);
@@ -200,8 +205,11 @@
td->td_retval[0] = cnt;
done:
- VOP_UNLOCK(vp, 0);
- vn_finished_write(mp);
+ if ((ioflg & IO_NODELOCKED) == 0) {
+ vn_finished_write(mp);
+ VOP_UNLOCK(vp, 0);
+ }
+
return (error);
}
@@ -233,8 +241,8 @@
if (error)
return (error);
- error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ error = extattr_set_vp(fp->f_vnode, 0, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -268,8 +276,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ error = extattr_set_vp(nd.ni_vp, 0, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -303,8 +311,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ error = extattr_set_vp(nd.ni_vp, 0, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -313,16 +321,19 @@
/*-
* 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".
+ * Arguments: vnode "vp", "ioflag" for vnode locking control,
+ * attribute namespace "attrnamespace",
+ * kernelspace string pointer "attrname",
+ * buffer pointer "data", buffer length "nbytes",
+ * buffer uio adress-space control - "segflg", 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 thread *td)
+int
+extattr_get_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes, enum uio_seg segflg,
+ struct thread *td)
{
struct uio auio, *auiop;
struct iovec aiov;
@@ -330,7 +341,8 @@
size_t size, *sizep;
int error;
- vn_lock(vp, LK_SHARED | LK_RETRY);
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
/*
* Slightly unusual semantics: if the user provides a NULL data
@@ -346,19 +358,20 @@
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
auiop = &auio;
cnt = nbytes;
} else
sizep = &size;
+ if ((ioflg & IO_NODELOCKED) == 0)
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+
+ ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
+
#ifdef MAC
error = mac_vnode_check_getextattr(td->td_ucred, vp, attrnamespace,
attrname);
@@ -376,7 +389,9 @@
td->td_retval[0] = size;
done:
- VOP_UNLOCK(vp, 0);
+ if ((ioflg & IO_NODELOCKED) == 0)
+ VOP_UNLOCK(vp, 0);
+
return (error);
}
@@ -408,8 +423,8 @@
if (error)
return (error);
- error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
- attrname, uap->data, uap->nbytes, td);
+ error = extattr_get_vp(fp->f_vnode, 0, uap->attrnamespace,
+ attrname, uap->data, uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -442,8 +457,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ error = extattr_get_vp(nd.ni_vp, 0, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -477,8 +492,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
- uap->data, uap->nbytes, td);
+ error = extattr_get_vp(nd.ni_vp, 0, uap->attrnamespace, attrname,
+ uap->data, uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -488,23 +503,27 @@
* 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"
+ * Arguments: vnode "vp", "ioflag" for vnode locking control,
+ * attribute namespace "attrnamespace",
+ * kernelspace string pointer "attrname", 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_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
- struct thread *td)
+int
+extattr_delete_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, struct thread *td)
{
struct mount *mp;
int error;
- error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
- if (error)
- return (error);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if ((ioflg & IO_NODELOCKED) == 0) {
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error)
+ return (error);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ }
+
+ ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
#ifdef MAC
error = mac_vnode_check_deleteextattr(td->td_ucred, vp, attrnamespace,
@@ -521,8 +540,11 @@
#ifdef MAC
done:
#endif
- VOP_UNLOCK(vp, 0);
- vn_finished_write(mp);
+ if ((ioflg & IO_NODELOCKED) == 0) {
+ vn_finished_write(mp);
+ VOP_UNLOCK(vp, 0);
+ }
+
return (error);
}
@@ -552,7 +574,7 @@
if (error)
return (error);
- error = extattr_delete_vp(fp->f_vnode, uap->attrnamespace,
+ error = extattr_delete_vp(fp->f_vnode, 0, uap->attrnamespace,
attrname, td);
fdrop(fp, td);
return (error);
@@ -583,7 +605,7 @@
return(error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
+ error = extattr_delete_vp(nd.ni_vp, 0, uap->attrnamespace, attrname, td);
vrele(nd.ni_vp);
return(error);
}
@@ -613,7 +635,7 @@
return(error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
+ error = extattr_delete_vp(nd.ni_vp, 0, uap->attrnamespace, attrname, td);
vrele(nd.ni_vp);
return(error);
}
@@ -621,16 +643,17 @@
/*-
* 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".
+ * Arguments: vnode "vp", "ioflag" for vnode locking control,
+ * attribute namespace 'attrnamespace",
+ * buffer pointer "data", buffer length "nbytes",
+ * buffer uio adress-space control - "segflg", 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 thread *td)
+int
+extattr_list_vp(struct vnode *vp, int ioflg, int attrnamespace, void *data,
+ size_t nbytes, enum uio_seg segflg, struct thread *td)
{
struct uio auio, *auiop;
size_t size, *sizep;
@@ -638,7 +661,8 @@
ssize_t cnt;
int error;
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (nbytes > IOSIZE_MAX)
+ return (EINVAL);
auiop = NULL;
sizep = NULL;
@@ -649,19 +673,20 @@
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
- if (nbytes > IOSIZE_MAX) {
- error = EINVAL;
- goto done;
- }
auio.uio_resid = nbytes;
auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
+ auio.uio_segflg = segflg;
auio.uio_td = td;
auiop = &auio;
cnt = nbytes;
} else
sizep = &size;
+ if ((ioflg & IO_NODELOCKED) == 0)
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+
+ ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held");
+
#ifdef MAC
error = mac_vnode_check_listextattr(td->td_ucred, vp, attrnamespace);
if (error)
@@ -678,11 +703,12 @@
td->td_retval[0] = size;
done:
- VOP_UNLOCK(vp, 0);
+ if ((ioflg & IO_NODELOCKED) == 0)
+ VOP_UNLOCK(vp, 0);
+
return (error);
}
-
int
sys_extattr_list_fd(td, uap)
struct thread *td;
@@ -704,8 +730,8 @@
if (error)
return (error);
- error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ error = extattr_list_vp(fp->f_vnode, 0, uap->attrnamespace, uap->data,
+ uap->nbytes, UIO_USERSPACE, td);
fdrop(fp, td);
return (error);
@@ -731,8 +757,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ error = extattr_list_vp(nd.ni_vp, 0, uap->attrnamespace, uap->data,
+ uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
@@ -759,8 +785,8 @@
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
- uap->nbytes, td);
+ error = extattr_list_vp(nd.ni_vp, 0, uap->attrnamespace, uap->data,
+ uap->nbytes, UIO_USERSPACE, td);
vrele(nd.ni_vp);
return (error);
Index: sys/extattr.h
===================================================================
--- sys/extattr.h
+++ sys/extattr.h
@@ -63,12 +63,23 @@
#ifdef _KERNEL
#include <sys/types.h>
+#include <sys/uio.h>
struct thread;
struct ucred;
struct vnode;
int extattr_check_cred(struct vnode *vp, int attrnamespace,
struct ucred *cred, struct thread *td, accmode_t accmode);
+int extattr_delete_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, struct thread *td);
+int extattr_get_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes,
+ enum uio_seg segflg, struct thread *td);
+int extattr_list_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ void *data, size_t nbytes, enum uio_seg segflg, struct thread *td);
+int extattr_set_vp(struct vnode *vp, int ioflg, int attrnamespace,
+ const char *attrname, void *data, size_t nbytes,
+ enum uio_seg segflg, struct thread *td);
#else
#include <sys/cdefs.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 8, 8:41 PM (13 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28496053
Default Alt Text
D13267.id36236.diff (12 KB)
Attached To
Mode
D13267: Export extattr_*vp() functions to allow to use it in the linuxulator in future
Attached
Detach File
Event Timeline
Log In to Comment