#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/mbcache.h>
#include <linux/quotaops.h>
#include <linux/iversion.h>
#include "ext4_jbd2.h"
#include "ext4.h"
#include "xattr.h"
#include "acl.h"
#ifdef EXT4_XATTR_DEBUG
#define ea_idebug …
#define ea_bdebug …
#else
#define ea_idebug(inode, fmt, ...) …
#define ea_bdebug(bh, fmt, ...) …
#endif
static void ext4_xattr_block_cache_insert(struct mb_cache *,
struct buffer_head *);
static struct buffer_head *
ext4_xattr_block_cache_find(struct inode *, struct ext4_xattr_header *,
struct mb_cache_entry **);
static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value,
size_t value_count);
static __le32 ext4_xattr_hash_entry_signed(char *name, size_t name_len, __le32 *value,
size_t value_count);
static void ext4_xattr_rehash(struct ext4_xattr_header *);
static const struct xattr_handler * const ext4_xattr_handler_map[] = …;
const struct xattr_handler * const ext4_xattr_handlers[] = …;
#define EA_BLOCK_CACHE(inode) …
#define EA_INODE_CACHE(inode) …
static int
ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
struct inode *inode);
#ifdef CONFIG_LOCKDEP
void ext4_xattr_inode_set_class(struct inode *ea_inode)
{ … }
#endif
static __le32 ext4_xattr_block_csum(struct inode *inode,
sector_t block_nr,
struct ext4_xattr_header *hdr)
{ … }
static int ext4_xattr_block_csum_verify(struct inode *inode,
struct buffer_head *bh)
{ … }
static void ext4_xattr_block_csum_set(struct inode *inode,
struct buffer_head *bh)
{ … }
static inline const char *ext4_xattr_prefix(int name_index,
struct dentry *dentry)
{ … }
static int
check_xattrs(struct inode *inode, struct buffer_head *bh,
struct ext4_xattr_entry *entry, void *end, void *value_start,
const char *function, unsigned int line)
{ … }
static inline int
__ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
const char *function, unsigned int line)
{ … }
#define ext4_xattr_check_block(inode, bh) …
static inline int
__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
void *end, const char *function, unsigned int line)
{ … }
#define xattr_check_inode(inode, header, end) …
static int
xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry,
void *end, int name_index, const char *name, int sorted)
{ … }
static u32
ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size)
{ … }
static u64 ext4_xattr_inode_get_ref(struct inode *ea_inode)
{ … }
static void ext4_xattr_inode_set_ref(struct inode *ea_inode, u64 ref_count)
{ … }
static u32 ext4_xattr_inode_get_hash(struct inode *ea_inode)
{ … }
static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash)
{ … }
static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
{ … }
#define EXT4_XATTR_INODE_GET_PARENT(inode) …
static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
u32 ea_inode_hash, struct inode **ea_inode)
{ … }
void ext4_evict_ea_inode(struct inode *inode)
{ … }
static int
ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
struct ext4_xattr_entry *entry, void *buffer,
size_t size)
{ … }
static int
ext4_xattr_inode_get(struct inode *inode, struct ext4_xattr_entry *entry,
void *buffer, size_t size)
{ … }
static int
ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{ … }
int
ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{ … }
int
ext4_xattr_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{ … }
static int
ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
char *buffer, size_t buffer_size)
{ … }
static int
ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
{ … }
static int
ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
{ … }
ssize_t
ext4_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{ … }
static void ext4_xattr_update_super_block(handle_t *handle,
struct super_block *sb)
{ … }
int ext4_get_inode_usage(struct inode *inode, qsize_t *usage)
{ … }
static inline size_t round_up_cluster(struct inode *inode, size_t length)
{ … }
static int ext4_xattr_inode_alloc_quota(struct inode *inode, size_t len)
{ … }
static void ext4_xattr_inode_free_quota(struct inode *parent,
struct inode *ea_inode,
size_t len)
{ … }
int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
struct buffer_head *block_bh, size_t value_len,
bool is_create)
{ … }
static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
int ref_change)
{ … }
static int ext4_xattr_inode_inc_ref(handle_t *handle, struct inode *ea_inode)
{ … }
static int ext4_xattr_inode_dec_ref(handle_t *handle, struct inode *ea_inode)
{ … }
static int ext4_xattr_inode_inc_ref_all(handle_t *handle, struct inode *parent,
struct ext4_xattr_entry *first)
{ … }
static int ext4_xattr_restart_fn(handle_t *handle, struct inode *inode,
struct buffer_head *bh, bool block_csum, bool dirty)
{ … }
static void
ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent,
struct buffer_head *bh,
struct ext4_xattr_entry *first, bool block_csum,
struct ext4_xattr_inode_array **ea_inode_array,
int extra_credits, bool skip_quota)
{ … }
static void
ext4_xattr_release_block(handle_t *handle, struct inode *inode,
struct buffer_head *bh,
struct ext4_xattr_inode_array **ea_inode_array,
int extra_credits)
{ … }
static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
size_t *min_offs, void *base, int *total)
{ … }
static int ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode,
const void *buf, int bufsize)
{ … }
static struct inode *ext4_xattr_inode_create(handle_t *handle,
struct inode *inode, u32 hash)
{ … }
static struct inode *
ext4_xattr_inode_cache_find(struct inode *inode, const void *value,
size_t value_len, u32 hash)
{ … }
static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle,
struct inode *inode, const void *value, size_t value_len)
{ … }
#define EXT4_XATTR_BLOCK_RESERVE(inode) …
static int ext4_xattr_set_entry(struct ext4_xattr_info *i,
struct ext4_xattr_search *s,
handle_t *handle, struct inode *inode,
struct inode *new_ea_inode,
bool is_block)
{ … }
struct ext4_xattr_block_find { … };
static int
ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
struct ext4_xattr_block_find *bs)
{ … }
static int
ext4_xattr_block_set(handle_t *handle, struct inode *inode,
struct ext4_xattr_info *i,
struct ext4_xattr_block_find *bs)
{ … }
int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
struct ext4_xattr_ibody_find *is)
{ … }
int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
struct ext4_xattr_info *i,
struct ext4_xattr_ibody_find *is)
{ … }
static int ext4_xattr_value_same(struct ext4_xattr_search *s,
struct ext4_xattr_info *i)
{ … }
static struct buffer_head *ext4_xattr_get_block(struct inode *inode)
{ … }
int
ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
const char *name, const void *value, size_t value_len,
int flags)
{ … }
int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
bool is_create, int *credits)
{ … }
int
ext4_xattr_set(struct inode *inode, int name_index, const char *name,
const void *value, size_t value_len, int flags)
{ … }
static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
int value_offs_shift, void *to,
void *from, size_t n)
{ … }
static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
struct ext4_inode *raw_inode,
struct ext4_xattr_entry *entry)
{ … }
static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
struct ext4_inode *raw_inode,
int isize_diff, size_t ifree,
size_t bfree, int *total_ino)
{ … }
int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
struct ext4_inode *raw_inode, handle_t *handle)
{ … }
#define EIA_INCR …
#define EIA_MASK …
static int
ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
struct inode *inode)
{ … }
int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
struct ext4_xattr_inode_array **ea_inode_array,
int extra_credits)
{ … }
void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *ea_inode_array)
{ … }
static void
ext4_xattr_block_cache_insert(struct mb_cache *ea_block_cache,
struct buffer_head *bh)
{ … }
static int
ext4_xattr_cmp(struct ext4_xattr_header *header1,
struct ext4_xattr_header *header2)
{ … }
static struct buffer_head *
ext4_xattr_block_cache_find(struct inode *inode,
struct ext4_xattr_header *header,
struct mb_cache_entry **pce)
{ … }
#define NAME_HASH_SHIFT …
#define VALUE_HASH_SHIFT …
static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value,
size_t value_count)
{ … }
static __le32 ext4_xattr_hash_entry_signed(char *name, size_t name_len, __le32 *value, size_t value_count)
{ … }
#undef NAME_HASH_SHIFT
#undef VALUE_HASH_SHIFT
#define BLOCK_HASH_SHIFT …
static void ext4_xattr_rehash(struct ext4_xattr_header *header)
{ … }
#undef BLOCK_HASH_SHIFT
#define HASH_BUCKET_BITS …
struct mb_cache *
ext4_xattr_create_cache(void)
{ … }
void ext4_xattr_destroy_cache(struct mb_cache *cache)
{ … }