|
@@ -25,40 +25,6 @@
|
|
|
#include "f2fs.h"
|
|
|
#include "xattr.h"
|
|
|
|
|
|
-static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
|
|
|
- struct dentry *dentry, char *list, size_t list_size,
|
|
|
- const char *name, size_t len)
|
|
|
-{
|
|
|
- struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
|
|
|
- const char *prefix;
|
|
|
- int total_len, prefix_len;
|
|
|
-
|
|
|
- switch (handler->flags) {
|
|
|
- case F2FS_XATTR_INDEX_USER:
|
|
|
- if (!test_opt(sbi, XATTR_USER))
|
|
|
- return -EOPNOTSUPP;
|
|
|
- break;
|
|
|
- case F2FS_XATTR_INDEX_TRUSTED:
|
|
|
- if (!capable(CAP_SYS_ADMIN))
|
|
|
- return -EPERM;
|
|
|
- break;
|
|
|
- case F2FS_XATTR_INDEX_SECURITY:
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- prefix = xattr_prefix(handler);
|
|
|
- prefix_len = strlen(prefix);
|
|
|
- total_len = prefix_len + len + 1;
|
|
|
- if (list && total_len <= list_size) {
|
|
|
- memcpy(list, prefix, prefix_len);
|
|
|
- memcpy(list + prefix_len, name, len);
|
|
|
- list[prefix_len + len] = '\0';
|
|
|
- }
|
|
|
- return total_len;
|
|
|
-}
|
|
|
-
|
|
|
static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
|
|
|
struct dentry *dentry, const char *name, void *buffer,
|
|
|
size_t size)
|
|
@@ -107,17 +73,16 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
|
|
|
value, size, NULL, flags);
|
|
|
}
|
|
|
|
|
|
-static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler,
|
|
|
- struct dentry *dentry, char *list, size_t list_size,
|
|
|
- const char *name, size_t len)
|
|
|
+static bool f2fs_xattr_user_list(struct dentry *dentry)
|
|
|
{
|
|
|
- const char *xname = F2FS_SYSTEM_ADVISE_NAME;
|
|
|
- size_t size;
|
|
|
+ struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
|
|
|
+
|
|
|
+ return test_opt(sbi, XATTR_USER);
|
|
|
+}
|
|
|
|
|
|
- size = strlen(xname) + 1;
|
|
|
- if (list && size <= list_size)
|
|
|
- memcpy(list, xname, size);
|
|
|
- return size;
|
|
|
+static bool f2fs_xattr_trusted_list(struct dentry *dentry)
|
|
|
+{
|
|
|
+ return capable(CAP_SYS_ADMIN);
|
|
|
}
|
|
|
|
|
|
static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
|
|
@@ -175,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir,
|
|
|
const struct xattr_handler f2fs_xattr_user_handler = {
|
|
|
.prefix = XATTR_USER_PREFIX,
|
|
|
.flags = F2FS_XATTR_INDEX_USER,
|
|
|
- .list = f2fs_xattr_generic_list,
|
|
|
+ .list = f2fs_xattr_user_list,
|
|
|
.get = f2fs_xattr_generic_get,
|
|
|
.set = f2fs_xattr_generic_set,
|
|
|
};
|
|
@@ -183,7 +148,7 @@ const struct xattr_handler f2fs_xattr_user_handler = {
|
|
|
const struct xattr_handler f2fs_xattr_trusted_handler = {
|
|
|
.prefix = XATTR_TRUSTED_PREFIX,
|
|
|
.flags = F2FS_XATTR_INDEX_TRUSTED,
|
|
|
- .list = f2fs_xattr_generic_list,
|
|
|
+ .list = f2fs_xattr_trusted_list,
|
|
|
.get = f2fs_xattr_generic_get,
|
|
|
.set = f2fs_xattr_generic_set,
|
|
|
};
|
|
@@ -191,7 +156,6 @@ const struct xattr_handler f2fs_xattr_trusted_handler = {
|
|
|
const struct xattr_handler f2fs_xattr_advise_handler = {
|
|
|
.name = F2FS_SYSTEM_ADVISE_NAME,
|
|
|
.flags = F2FS_XATTR_INDEX_ADVISE,
|
|
|
- .list = f2fs_xattr_advise_list,
|
|
|
.get = f2fs_xattr_advise_get,
|
|
|
.set = f2fs_xattr_advise_set,
|
|
|
};
|
|
@@ -199,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
|
|
|
const struct xattr_handler f2fs_xattr_security_handler = {
|
|
|
.prefix = XATTR_SECURITY_PREFIX,
|
|
|
.flags = F2FS_XATTR_INDEX_SECURITY,
|
|
|
- .list = f2fs_xattr_generic_list,
|
|
|
.get = f2fs_xattr_generic_get,
|
|
|
.set = f2fs_xattr_generic_set,
|
|
|
};
|
|
@@ -447,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|
|
list_for_each_xattr(entry, base_addr) {
|
|
|
const struct xattr_handler *handler =
|
|
|
f2fs_xattr_handler(entry->e_name_index);
|
|
|
+ const char *prefix;
|
|
|
+ size_t prefix_len;
|
|
|
size_t size;
|
|
|
|
|
|
- if (!handler)
|
|
|
+ if (!handler || (handler->list && !handler->list(dentry)))
|
|
|
continue;
|
|
|
|
|
|
- size = handler->list(handler, dentry, buffer, rest,
|
|
|
- entry->e_name, entry->e_name_len);
|
|
|
- if (buffer && size > rest) {
|
|
|
- error = -ERANGE;
|
|
|
- goto cleanup;
|
|
|
+ prefix = handler->prefix ?: handler->name;
|
|
|
+ prefix_len = strlen(prefix);
|
|
|
+ size = prefix_len + entry->e_name_len + 1;
|
|
|
+ if (buffer) {
|
|
|
+ if (size > rest) {
|
|
|
+ error = -ERANGE;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ memcpy(buffer, prefix, prefix_len);
|
|
|
+ buffer += prefix_len;
|
|
|
+ memcpy(buffer, entry->e_name, entry->e_name_len);
|
|
|
+ buffer += entry->e_name_len;
|
|
|
+ *buffer++ = 0;
|
|
|
}
|
|
|
-
|
|
|
- if (buffer)
|
|
|
- buffer += size;
|
|
|
rest -= size;
|
|
|
}
|
|
|
error = buffer_size - rest;
|