2 * FUSE: Filesystem in Userspace
3 * Copyright (C) 2016 Canonical Ltd. <seth.forshee@canonical.com>
5 * This program can be distributed under the terms of the GNU GPL.
6 * See the file COPYING.
11 #include <linux/posix_acl.h>
12 #include <linux/posix_acl_xattr.h>
14 struct posix_acl
*fuse_get_acl(struct inode
*inode
, int type
)
16 struct fuse_conn
*fc
= get_fuse_conn(inode
);
20 struct posix_acl
*acl
;
22 if (!fc
->posix_acl
|| fc
->no_getxattr
)
25 if (type
== ACL_TYPE_ACCESS
)
26 name
= XATTR_NAME_POSIX_ACL_ACCESS
;
27 else if (type
== ACL_TYPE_DEFAULT
)
28 name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
30 return ERR_PTR(-EOPNOTSUPP
);
32 value
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
34 return ERR_PTR(-ENOMEM
);
35 size
= fuse_getxattr(inode
, name
, value
, PAGE_SIZE
);
37 acl
= posix_acl_from_xattr(fc
->user_ns
, value
, size
);
38 else if ((size
== 0) || (size
== -ENODATA
) ||
39 (size
== -EOPNOTSUPP
&& fc
->no_getxattr
))
41 else if (size
== -ERANGE
)
42 acl
= ERR_PTR(-E2BIG
);
50 int fuse_set_acl(struct inode
*inode
, struct posix_acl
*acl
, int type
)
52 struct fuse_conn
*fc
= get_fuse_conn(inode
);
56 if (!fc
->posix_acl
|| fc
->no_setxattr
)
59 if (type
== ACL_TYPE_ACCESS
)
60 name
= XATTR_NAME_POSIX_ACL_ACCESS
;
61 else if (type
== ACL_TYPE_DEFAULT
)
62 name
= XATTR_NAME_POSIX_ACL_DEFAULT
;
68 * Fuse userspace is responsible for updating access
69 * permissions in the inode, if needed. fuse_setxattr
70 * invalidates the inode attributes, which will force
71 * them to be refreshed the next time they are used,
72 * and it also updates i_ctime.
74 size_t size
= posix_acl_xattr_size(acl
->a_count
);
80 value
= kmalloc(size
, GFP_KERNEL
);
84 ret
= posix_acl_to_xattr(fc
->user_ns
, acl
, value
, size
);
90 ret
= fuse_setxattr(inode
, name
, value
, size
, 0);
93 ret
= fuse_removexattr(inode
, name
);
95 forget_all_cached_acls(inode
);
96 fuse_invalidate_attr(inode
);