Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110456064
D13528.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D13528.diff
View Options
Index: head/sys/fs/fuse/fuse_kernel.h
===================================================================
--- head/sys/fs/fuse/fuse_kernel.h
+++ head/sys/fs/fuse/fuse_kernel.h
@@ -282,11 +282,16 @@
__u32 padding;
};
-struct fuse_setxattr_in {
+struct fuse_listxattr_in {
__u32 size;
__u32 flags;
};
+struct fuse_listxattr_out {
+ __u32 size;
+ __u32 flags;
+};
+
struct fuse_getxattr_in {
__u32 size;
__u32 padding;
@@ -295,6 +300,11 @@
struct fuse_getxattr_out {
__u32 size;
__u32 padding;
+};
+
+struct fuse_setxattr_in {
+ __u32 size;
+ __u32 flags;
};
struct fuse_lk_in {
Index: head/sys/fs/fuse/fuse_vnops.c
===================================================================
--- head/sys/fs/fuse/fuse_vnops.c
+++ head/sys/fs/fuse/fuse_vnops.c
@@ -2047,7 +2047,7 @@
* fuse_getxattr_out. If we pass in a non-zero size, we get back
* that much data, without the struct fuse_getxattr_out header.
*/
- if (ap->a_size != NULL)
+ if (uio == NULL)
get_xattr_in->size = 0;
else
get_xattr_in->size = uio->uio_resid;
@@ -2065,25 +2065,13 @@
goto out;
}
- /*
- * If we get to this point (i.e. no error), we should have a valid
- * answer of some sort. i.e. non-zero iosize and a valid pointer.
- */
- if ((fdi.answ == NULL) || (fdi.iosize == 0)) {
- debug_printf("getxattr: err = 0, but answ = %p, iosize = %zu\n",
- fdi.answ, fdi.iosize);
- err = EINVAL;
- goto out;
- }
get_xattr_out = fdi.answ;
- if (ap->a_size != NULL) {
+ if (ap->a_size != NULL)
*ap->a_size = get_xattr_out->size;
- } else if (fdi.iosize > 0) {
+
+ if (uio != NULL)
err = uiomove(fdi.answ, fdi.iosize, uio);
- } else {
- err = EINVAL;
- }
out:
fdisp_destroy(&fdi);
@@ -2233,14 +2221,16 @@
struct vnode *vp = ap->a_vp;
struct uio *uio = ap->a_uio;
struct fuse_dispatcher fdi = {0};
- struct fuse_getxattr_in *get_xattr_in;
- struct fuse_getxattr_out *get_xattr_out;
+ struct fuse_listxattr_in *list_xattr_in;
+ struct fuse_listxattr_out *list_xattr_out;
struct mount *mp = vnode_mount(vp);
size_t len;
char *prefix;
char *attr_str;
char *bsd_list = NULL;
+ char *linux_list;
int bsd_list_len;
+ int linux_list_len;
struct thread *td = ap->a_td;
struct ucred *cred = ap->a_cred;
int err = 0;
@@ -2261,17 +2251,15 @@
len = strlen(prefix) + sizeof(extattr_namespace_separator) + 1;
- fdisp_init(&fdi, sizeof(*get_xattr_in) + len);
+ fdisp_init(&fdi, sizeof(*list_xattr_in) + len);
fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred);
- get_xattr_in = fdi.indata;
- if (ap->a_size != NULL)
- get_xattr_in->size = 0;
- else
- get_xattr_in->size = uio->uio_resid + sizeof(*get_xattr_out);
-
-
- attr_str = (char *)fdi.indata + sizeof(*get_xattr_in);
+ /*
+ * Retrieve Linux / FUSE compatible list size.
+ */
+ list_xattr_in = fdi.indata;
+ list_xattr_in->size = 0;
+ attr_str = (char *)fdi.indata + sizeof(*list_xattr_in);
snprintf(attr_str, len, "%s%c", prefix, extattr_namespace_separator);
err = fdisp_wait_answ(&fdi);
@@ -2282,32 +2270,47 @@
goto out;
}
- if ((fdi.answ == NULL) || (fdi.iosize == 0)) {
- err = EINVAL;
+ list_xattr_out = fdi.answ;
+ linux_list_len = list_xattr_out->size;
+ if (linux_list_len == 0) {
+ if (ap->a_size != NULL)
+ *ap->a_size = linux_list_len;
goto out;
}
- get_xattr_out = fdi.answ;
- if (ap->a_size != NULL) {
- *ap->a_size = get_xattr_out->size;
- } else if (fdi.iosize > 0) {
- /*
- * The Linux / FUSE attribute list format isn't the same
- * as FreeBSD's format. So we need to transform it into
- * FreeBSD's format before giving it to the user.
- */
- bsd_list = malloc(fdi.iosize, M_TEMP, M_WAITOK);
- err = fuse_xattrlist_convert(prefix, fdi.answ, fdi.iosize,
- bsd_list, &bsd_list_len);
- if (err != 0)
- goto out;
+ /*
+ * Retrieve Linux / FUSE compatible list values.
+ */
+ fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred);
+ list_xattr_in = fdi.indata;
+ list_xattr_in->size = linux_list_len + sizeof(*list_xattr_out);
+ attr_str = (char *)fdi.indata + sizeof(*list_xattr_in);
+ snprintf(attr_str, len, "%s%c", prefix, extattr_namespace_separator);
+ err = fdisp_wait_answ(&fdi);
+ if (err != 0)
+ goto out;
+
+ linux_list = fdi.answ;
+ linux_list_len = fdi.iosize;
+
+ /*
+ * Retrieve the BSD compatible list values.
+ * The Linux / FUSE attribute list format isn't the same
+ * as FreeBSD's format. So we need to transform it into
+ * FreeBSD's format before giving it to the user.
+ */
+ bsd_list = malloc(linux_list_len, M_TEMP, M_WAITOK);
+ err = fuse_xattrlist_convert(prefix, linux_list, linux_list_len,
+ bsd_list, &bsd_list_len);
+ if (err != 0)
+ goto out;
+
+ if (ap->a_size != NULL)
+ *ap->a_size = bsd_list_len;
+
+ if (uio != NULL)
err = uiomove(bsd_list, bsd_list_len, uio);
- } else {
- debug_printf("listextattr: returned iosize %zu for %s attribute list is "
- "too small\n", fdi.iosize, prefix);
- err = EINVAL;
- }
out:
free(bsd_list, M_TEMP);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 19, 5:05 PM (20 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16724530
Default Alt Text
D13528.diff (4 KB)
Attached To
Mode
D13528: fuse extattrs: fix issue when neither uio nor size were not passed to VOP_* (logic only).
Attached
Detach File
Event Timeline
Log In to Comment