2019-05-27 09:55:21 +03:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2021-05-07 04:06:44 +03:00
|
|
|
/*
|
2008-08-18 13:11:00 +04:00
|
|
|
* xattr.h
|
|
|
|
*
|
2008-10-23 12:33:03 +04:00
|
|
|
* Copyright (C) 2004, 2008 Oracle. All rights reserved.
|
2008-08-18 13:11:00 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef OCFS2_XATTR_H
|
|
|
|
#define OCFS2_XATTR_H
|
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/xattr.h>
|
|
|
|
|
|
|
|
enum ocfs2_xattr_type {
|
|
|
|
OCFS2_XATTR_INDEX_USER = 1,
|
|
|
|
OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS,
|
|
|
|
OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT,
|
|
|
|
OCFS2_XATTR_INDEX_TRUSTED,
|
|
|
|
OCFS2_XATTR_INDEX_SECURITY,
|
|
|
|
OCFS2_XATTR_MAX
|
|
|
|
};
|
|
|
|
|
2008-11-14 06:16:41 +03:00
|
|
|
struct ocfs2_security_xattr_info {
|
|
|
|
int enable;
|
2013-07-25 00:44:02 +04:00
|
|
|
const char *name;
|
2008-11-14 06:16:41 +03:00
|
|
|
void *value;
|
|
|
|
size_t value_len;
|
|
|
|
};
|
|
|
|
|
2010-05-14 04:53:22 +04:00
|
|
|
extern const struct xattr_handler ocfs2_xattr_user_handler;
|
|
|
|
extern const struct xattr_handler ocfs2_xattr_trusted_handler;
|
|
|
|
extern const struct xattr_handler ocfs2_xattr_security_handler;
|
|
|
|
extern const struct xattr_handler *ocfs2_xattr_handlers[];
|
2008-08-18 13:11:00 +04:00
|
|
|
|
2008-10-23 12:33:33 +04:00
|
|
|
ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
|
2008-11-14 06:16:53 +03:00
|
|
|
int ocfs2_xattr_get_nolock(struct inode *, struct buffer_head *, int,
|
|
|
|
const char *, void *, size_t);
|
2008-10-23 12:33:33 +04:00
|
|
|
int ocfs2_xattr_set(struct inode *, int, const char *, const void *,
|
|
|
|
size_t, int);
|
2008-11-14 06:16:03 +03:00
|
|
|
int ocfs2_xattr_set_handle(handle_t *, struct inode *, struct buffer_head *,
|
|
|
|
int, const char *, const void *, size_t, int,
|
|
|
|
struct ocfs2_alloc_context *,
|
|
|
|
struct ocfs2_alloc_context *);
|
2009-08-18 07:43:49 +04:00
|
|
|
int ocfs2_has_inline_xattr_value_outside(struct inode *inode,
|
|
|
|
struct ocfs2_dinode *di);
|
2008-10-23 12:33:33 +04:00
|
|
|
int ocfs2_xattr_remove(struct inode *, struct buffer_head *);
|
2008-11-14 06:16:41 +03:00
|
|
|
int ocfs2_init_security_get(struct inode *, struct inode *,
|
2011-02-01 19:05:39 +03:00
|
|
|
const struct qstr *,
|
2008-11-14 06:16:41 +03:00
|
|
|
struct ocfs2_security_xattr_info *);
|
|
|
|
int ocfs2_init_security_set(handle_t *, struct inode *,
|
|
|
|
struct buffer_head *,
|
|
|
|
struct ocfs2_security_xattr_info *,
|
|
|
|
struct ocfs2_alloc_context *,
|
|
|
|
struct ocfs2_alloc_context *);
|
|
|
|
int ocfs2_calc_security_init(struct inode *,
|
|
|
|
struct ocfs2_security_xattr_info *,
|
|
|
|
int *, int *, struct ocfs2_alloc_context **);
|
2008-11-14 06:17:41 +03:00
|
|
|
int ocfs2_calc_xattr_init(struct inode *, struct buffer_head *,
|
2011-07-26 10:55:32 +04:00
|
|
|
umode_t, struct ocfs2_security_xattr_info *,
|
2008-11-13 03:27:44 +03:00
|
|
|
int *, int *, int *);
|
ocfs2: Enable xattr set in index btree
Where the previous patches added the ability of list/get xattr in buckets
for ocfs2, this patch enables ocfs2 to store large numbers of EAs.
The original design doc is written by Mark Fasheh, and it can be found in
http://oss.oracle.com/osswiki/OCFS2/DesignDocs/IndexedEATrees. I only had to
make small modifications to it.
First, because the bucket size is 4K, a new field named xh_free_start is added
in ocfs2_xattr_header to indicate the next valid name/value offset in a bucket.
It is used when we store new EA name/value. With this field, we can find the
place more quickly and what's more, we don't need to sort the name/value every
time to let the last entry indicate the next unused space. This makes the
insert operation more efficient for blocksizes smaller than 4k.
Because of the new xh_free_start, another field named as xh_name_value_len is
also added in ocfs2_xattr_header. It records the total length of all the
name/values in the bucket. We need this so that we can check it and defragment
the bucket if there is not enough contiguous free space.
An xattr insertion looks like this:
1. xattr_index_block_find: find the right bucket by the name_hash, say bucketA.
2. check whether there is enough space in bucketA. If yes, insert it directly
and modify xh_free_start and xh_name_value_len accordingly. If not, check
xh_name_value_len to see whether we can store this by defragment the bucket.
If yes, defragment it and go on insertion.
3. If defragement doesn't work, check whether there is new empty bucket in
the clusters within this extent record. If yes, init the new bucket and move
all the buckets after bucketA one by one to the next bucket. Move half of the
entries in bucketA to the next bucket and go on insertion.
4. If there is no new bucket, grow the extent tree.
As for xattr deletion, we will delete an xattr bucket when all it's xattrs
are removed and move all the buckets after it to the previous one. When all
the xattr buckets in an extend record are freed, free this extend records
from ocfs2_xattr_tree.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
2008-08-18 13:38:53 +04:00
|
|
|
|
2008-12-10 01:24:33 +03:00
|
|
|
/*
|
|
|
|
* xattrs can live inside an inode, as part of an external xattr block,
|
|
|
|
* or inside an xattr bucket, which is the leaf of a tree rooted in an
|
|
|
|
* xattr block. Some of the xattr calls, especially the value setting
|
|
|
|
* functions, want to treat each of these locations as equal. Let's wrap
|
|
|
|
* them in a structure that we can pass around instead of raw buffer_heads.
|
|
|
|
*/
|
|
|
|
struct ocfs2_xattr_value_buf {
|
|
|
|
struct buffer_head *vb_bh;
|
|
|
|
ocfs2_journal_access_func vb_access;
|
|
|
|
struct ocfs2_xattr_value_root *vb_xv;
|
|
|
|
};
|
|
|
|
|
2009-09-21 09:04:19 +04:00
|
|
|
int ocfs2_xattr_attach_refcount_tree(struct inode *inode,
|
|
|
|
struct buffer_head *fe_bh,
|
|
|
|
struct ocfs2_caching_info *ref_ci,
|
|
|
|
struct buffer_head *ref_root_bh,
|
|
|
|
struct ocfs2_cached_dealloc_ctxt *dealloc);
|
2009-08-18 07:43:55 +04:00
|
|
|
int ocfs2_reflink_xattrs(struct inode *old_inode,
|
|
|
|
struct buffer_head *old_bh,
|
|
|
|
struct inode *new_inode,
|
2009-08-18 07:47:56 +04:00
|
|
|
struct buffer_head *new_bh,
|
|
|
|
bool preserve_security);
|
|
|
|
int ocfs2_init_security_and_acl(struct inode *dir,
|
2011-02-01 19:05:39 +03:00
|
|
|
struct inode *inode,
|
2016-05-13 01:42:18 +03:00
|
|
|
const struct qstr *qstr);
|
2008-08-18 13:11:00 +04:00
|
|
|
#endif /* OCFS2_XATTR_H */
|