Page MenuHomeFreeBSD

D13528.diff
No OneTemporary

D13528.diff

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

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)

Event Timeline