Page MenuHomeFreeBSD

D13528.id36756.diff
No OneTemporary

D13528.id36756.diff

Index: fs/fuse/fuse_vnops.c
===================================================================
--- fs/fuse/fuse_vnops.c
+++ fs/fuse/fuse_vnops.c
@@ -2023,7 +2023,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;
@@ -2053,13 +2053,11 @@
}
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);
@@ -2216,7 +2214,9 @@
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;
@@ -2240,13 +2240,11 @@
fdisp_init(&fdi, sizeof(*get_xattr_in) + len);
fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred);
+ /*
+ * Retrieve Linux / FUSE compatible list size.
+ */
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);
-
-
+ get_xattr_in->size = 0;
attr_str = (char *)fdi.indata + sizeof(*get_xattr_in);
snprintf(attr_str, len, "%s%c", prefix, extattr_namespace_separator);
@@ -2258,32 +2256,46 @@
goto out;
}
- if ((fdi.answ == NULL) || (fdi.iosize == 0)) {
- err = EINVAL;
+ get_xattr_out = fdi.answ;
+ linux_list_len = get_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);
+ get_xattr_in->size = linux_list_len + sizeof(*get_xattr_out);
+ err = fdisp_wait_answ(&fdi);
+ if (err != 0) {
+ if (err == ENOSYS)
+ fsess_set_notimpl(mp, FUSE_LISTXATTR);
+ 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

Mime Type
text/plain
Expires
Thu, Jun 25, 6:36 AM (8 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34308754
Default Alt Text
D13528.id36756.diff (3 KB)

Event Timeline