Page MenuHomeFreeBSD

D13528.id37667.diff
No OneTemporary

D13528.id37667.diff

Index: sys/fs/fuse/fuse_kernel.h
===================================================================
--- sys/fs/fuse/fuse_kernel.h
+++ sys/fs/fuse/fuse_kernel.h
@@ -282,7 +282,12 @@
__u32 padding;
};
-struct fuse_setxattr_in {
+struct fuse_listxattr_in {
+ __u32 size;
+ __u32 flags;
+};
+
+struct fuse_listxattr_out {
__u32 size;
__u32 flags;
};
@@ -297,6 +302,11 @@
__u32 padding;
};
+struct fuse_setxattr_in {
+ __u32 size;
+ __u32 flags;
+};
+
struct fuse_lk_in {
__u64 fh;
__u64 owner;
Index: sys/fs/fuse/fuse_vnops.c
===================================================================
--- sys/fs/fuse/fuse_vnops.c
+++ sys/fs/fuse/fuse_vnops.c
@@ -2049,7 +2049,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;
@@ -2079,13 +2079,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);
@@ -2235,14 +2233,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;
@@ -2263,17 +2263,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);
@@ -2284,32 +2282,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
Thu, Mar 19, 6:24 AM (17 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29951661
Default Alt Text
D13528.id37667.diff (4 KB)

Event Timeline