nilfs2: implement listxattr and getxattr functionality
Subsystems (2)
RFC PATCH 9/15 nilfs2: implement listxattr and getxattr functionality
From: Vyacheslav Dubeyko <[email protected]>
Subject: [RFC][PATCH 09/15] nilfs2: implement listxattr and getxattr functionality
This patch adds functionality listxattr and getxattr operations.
Signed-off-by Vyacheslav Dubeyko <[email protected]>
CC Ryusuke Konishi <[email protected]>
--- fs/nilfs2/xafile.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nilfs2/xafile.h | 20 +++++++ fs/nilfs2/xattr.c | 64 ++++++++++++++++++++ fs/nilfs2/xattr.h | 44 ++++++++++++++ 4 files changed, 295 insertions(+) create mode 100644 fs/nilfs2/xattr.c create mode 100644 fs/nilfs2/xattr.h
fs/nilfs2/xafile.c +167 -0
@@ -220,6 +220,19 @@ struct nilfs_xattr_search { (!IS_SEARCH_KEY_EMPTY (data) && \IS_SEARCH_RESULT_EMPTY (data)) +/* Map of xattr handlers */ +static const struct xattr_handler *nilfs_xattr_handler_map[] = { + [NILFS_USER_XATTR_ID ] = &nilfs_xattr_user_handler, +#ifdef CONFIG_NILFS2_FS_POSIX_ACL + [NILFS_POSIX_ACL_ACCESS_XATTR_ID ] = &nilfs_xattr_acl_access_handler, + [NILFS_POSIX_ACL_DEFAULT_XATTR_ID ] = &nilfs_xattr_acl_default_handler, +#endif + [NILFS_TRUSTED_XATTR_ID ] = &nilfs_xattr_trusted_handler, +#ifdef CONFIG_NILFS2_FS_SECURITY + [NILFS_SECURITY_XATTR_ID ] = &nilfs_xattr_security_handler, +#endif +}; +/* * NILFS_XAFILE_I - convert inode info into xafile inode info */
@@ -230,6 +243,19 @@ struct nilfs_xafile_info *NILFS_XAFILE_I(struct inode *xafile) }/* +* nilfs_xattr_handler - get xattr handler by name index +*/ +static inline +const struct xattr_handler *nilfs_xattr_handler (int name_index) +{ +const struct xattr_handler *handler =NULL ; + +if (name_index >0 && name_index <ARRAY_SIZE (nilfs_xattr_handler_map)) + handler = nilfs_xattr_handler_map[name_index]; +return handler; +} + +/* * nilfs_xafile_get_node - get xafile node * @xafile: xafile inode * @node_id: node number
@@ -1300,3 +1326,144 @@ void nilfs_xafile_abort_new_node(struct inode *inode,nilfs_xafile_abort_node_creation (xafile, &data->node.req);nilfs_xafile_abort_node_change (data); } + +/* +* nilfs_xattr_list_entries - list inode's xattrs from one xanode +* @dentry: dentry object +* @bh: xanode's buffer +* @buf: buffer for getting xattrs' list [out] +* @size: buffer size +*/ +static +int nilfs_xattr_list_entries (struct dentry *dentry,struct buffer_head *bh, +char *buf,size_t buf_size) +{ +union nilfs_xanode_header *hdr =NILFS_XANODE_HDR (BH_DATA (bh)); +union nilfs_xattr_key *key; +size_t rest = buf_size; + + key =NILFS_XANODE_FIRST_NOT_INDEX_KEY (hdr); + +for (; !IS_END_KEY (key); key =NEXT_KEY (key,1 )) { +u8 name_index =NILFS_XANODE_NAME_HASH (key)->name_index; +const struct nilfs_xanode_entry *entry = +NILFS_XANODE_ENTRY (key,BH_DATA (bh)); +const struct xattr_handler *handler = +nilfs_xattr_handler (name_index); +__u8 name_len =NILFS_XANODE_NAME_HASH (key)->name_len; + +if (handler) { +size_t size = handler->list (dentry, buf, rest, + entry->name, name_len, + handler->flags); +if (buf) { +if (size > rest) +return -ERANGE ; + buf += size; + } + rest -= size; + } + } + +return buf_size - rest; +} + +/* +* nilfs_xafile_listxattr - list all inode's xattrs +* @dentry: dentry object +* @buffer: buffer for getting xattrs' list [out] +* @size: buffer size +*/ +ssize_t nilfs_xafile_listxattr (struct dentry *dentry,char *buffer,size_t size) +{ +ssize_t ret =0 , err =0 ; +struct inode *inode = dentry->d_inode; +struct the_nilfs *nilfs = inode->i_sb->s_fs_info; +struct buffer_head *bh =NULL ; +__u64 node =NILFS_I (inode)->i_xattr; + +if (!nilfs_has_xafile (nilfs)) +return -EOPNOTSUPP ; + +if (node ==NILFS_INVALID_XANODE ) +return 0 ; + + err =nilfs_xafile_get_checked_node (inode, node, &bh); +if (unlikely (err)) + goto failed_xafile_listxattr; + + err =nilfs_xattr_list_entries (dentry, bh, buffer, size); +if (unlikely (err <0 )) + goto cleanup_after_failure; +else + ret += err; + +brelse (bh); +return ret; + +cleanup_after_failure: +brelse (bh); + +failed_xafile_listxattr: +return err; +} + +/* +* nilfs_xafile_getxattr - get xattr +* @inode: inode pointer +* @name: xattr's name +* @value: buffer for xattr's value [out] +* @size: buffer size +*/ +ssize_t nilfs_xafile_getxattr (struct inode *inode, +int name_index,const char *name, +void *value,size_t size) +{ +ssize_t ret, err; +struct the_nilfs *nilfs = inode->i_sb->s_fs_info; +struct nilfs_xattr_search data; + +if (!nilfs_has_xafile (nilfs)) +return -EOPNOTSUPP ; + +if (NILFS_I (inode)->i_xattr ==NILFS_INVALID_XANODE ) +return -ENODATA ; + + err =nilfs_xattr_search_init (inode, name_index, (char *)name, &data); +if (unlikely (err)) +return err; + + err =nilfs_xafile_find_node (inode, &data); +if (unlikely (err)) { + ret = err; + goto failed_xafile_getxattr; + } + +if (!data.result.found) { + ret = -ENODATA ; + goto cleanup_after_failure; + } + + ret =NILFS_XANODE_ENTRY_SIZE (data.result.key) - +NILFS_XANODE_NAME_HASH (data.result.key)->name_len; + +if (value) { +char *xattr_value; + +if (ret > size) { + ret = -ERANGE ; + goto cleanup_after_failure; + } + + xattr_value =NILFS_XATTR_VALUE (data.result.entry, + data.result.key); +memcpy (value, xattr_value, ret); + } + +cleanup_after_failure: +brelse (NODE_BH (&data.node)); + +failed_xafile_getxattr: +nilfs_xattr_search_release (&data); +return ret; +}
fs/nilfs2/xafile.h +20 -0
@@ -29,6 +29,20 @@/* Magic number of xafile node */ #define NILFS_XANODE_MAGIC 0x5841/* XA */ +/* Name indexes */ +#define NILFS_USER_XATTR_ID 1 +#define NILFS_POSIX_ACL_ACCESS_XATTR_ID 2 +#define NILFS_POSIX_ACL_DEFAULT_XATTR_ID 3 +#define NILFS_TRUSTED_XATTR_ID 4 +#define NILFS_SECURITY_XATTR_ID 5 +#define NILFS_SYSTEM_XATTR_ID 6 +#define NILFS_RICHACL_XATTR_ID 7 +#define NILFS_XATTR_MAX_ID 255 + +#define IS_NAME_ID_VALID (name_index) \ + (name_index < NILFS_USER_XATTR_ID || \ + name_index > NILFS_RICHACL_XATTR_ID) +/* Xanode types */ #define NILFS_UNKNOWN_XANODE_TYPE 0/* Temporary, numbers from 1 till 6 are simply reserved */
@@ -417,6 +431,12 @@ NILFS_XANODE_LAST_ENTRY(union nilfs_xanode_header *hdr)#define NILFS_XATTR_VALUE (entry, key) \ ((char *)(entry) + NILFS_XANODE_NAME_HASH(key)->name_len) +extern const struct xattr_handler nilfs_xattr_user_handler; +extern const struct xattr_handler nilfs_xattr_trusted_handler; +extern const struct xattr_handler nilfs_xattr_acl_access_handler; +extern const struct xattr_handler nilfs_xattr_acl_default_handler; +extern const struct xattr_handler nilfs_xattr_security_handler; +/* Xafile API */ ssize_t nilfs_xafile_listxattr (struct dentry *dentry,char *buf,size_t size); ssize_t nilfs_xafile_getxattr(struct inode *inode,
fs/nilfs2/xattr.c new file +64 -0
64 lines not on this page · raw message
fs/nilfs2/xattr.h new file +44 -0
44 lines not on this page · raw message
Signature · 8 lines
1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html