11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fa60ce2cSMasahiro Yamada /*
3f56654c4STao Ma * xattr.c
4f56654c4STao Ma *
5c3cb6827STiger Yang * Copyright (C) 2004, 2008 Oracle. All rights reserved.
6f56654c4STao Ma *
7cf1d6c76STiger Yang * CREDITS:
8c3cb6827STiger Yang * Lots of code in this file is copy from linux/fs/ext3/xattr.c.
9c3cb6827STiger Yang * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
10f56654c4STao Ma */
11f56654c4STao Ma
12cf1d6c76STiger Yang #include <linux/capability.h>
13cf1d6c76STiger Yang #include <linux/fs.h>
14cf1d6c76STiger Yang #include <linux/types.h>
15cf1d6c76STiger Yang #include <linux/slab.h>
16cf1d6c76STiger Yang #include <linux/highmem.h>
17cf1d6c76STiger Yang #include <linux/pagemap.h>
18cf1d6c76STiger Yang #include <linux/uio.h>
19cf1d6c76STiger Yang #include <linux/sched.h>
20cf1d6c76STiger Yang #include <linux/splice.h>
21cf1d6c76STiger Yang #include <linux/mount.h>
22cf1d6c76STiger Yang #include <linux/writeback.h>
23cf1d6c76STiger Yang #include <linux/falloc.h>
2401225596STao Ma #include <linux/sort.h>
2599219aeaSMark Fasheh #include <linux/init.h>
2699219aeaSMark Fasheh #include <linux/module.h>
2799219aeaSMark Fasheh #include <linux/string.h>
28923f7f31STiger Yang #include <linux/security.h>
29cf1d6c76STiger Yang
30f56654c4STao Ma #include <cluster/masklog.h>
31f56654c4STao Ma
32f56654c4STao Ma #include "ocfs2.h"
33f56654c4STao Ma #include "alloc.h"
34d6b32bbbSJoel Becker #include "blockcheck.h"
35f56654c4STao Ma #include "dlmglue.h"
36f56654c4STao Ma #include "file.h"
37cf1d6c76STiger Yang #include "symlink.h"
38cf1d6c76STiger Yang #include "sysfile.h"
39f56654c4STao Ma #include "inode.h"
40f56654c4STao Ma #include "journal.h"
41f56654c4STao Ma #include "ocfs2_fs.h"
42f56654c4STao Ma #include "suballoc.h"
43f56654c4STao Ma #include "uptodate.h"
44f56654c4STao Ma #include "buffer_head_io.h"
450c044f0bSTao Ma #include "super.h"
46cf1d6c76STiger Yang #include "xattr.h"
47492a8a33STao Ma #include "refcounttree.h"
480fe9b66cSTao Ma #include "acl.h"
49402b4183STao Ma #include "ocfs2_trace.h"
50cf1d6c76STiger Yang
51cf1d6c76STiger Yang struct ocfs2_xattr_def_value_root {
52cf1d6c76STiger Yang struct ocfs2_xattr_value_root xv;
53cf1d6c76STiger Yang struct ocfs2_extent_rec er;
54cf1d6c76STiger Yang };
55cf1d6c76STiger Yang
560c044f0bSTao Ma struct ocfs2_xattr_bucket {
57ba937127SJoel Becker /* The inode these xattrs are associated with */
58ba937127SJoel Becker struct inode *bu_inode;
59ba937127SJoel Becker
60ba937127SJoel Becker /* The actual buffers that make up the bucket */
614ac6032dSJoel Becker struct buffer_head *bu_bhs[OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET];
62ba937127SJoel Becker
63ba937127SJoel Becker /* How many blocks make up one bucket for this filesystem */
64ba937127SJoel Becker int bu_blocks;
650c044f0bSTao Ma };
660c044f0bSTao Ma
6778f30c31STao Ma struct ocfs2_xattr_set_ctxt {
6885db90e7STao Ma handle_t *handle;
6978f30c31STao Ma struct ocfs2_alloc_context *meta_ac;
7078f30c31STao Ma struct ocfs2_alloc_context *data_ac;
7178f30c31STao Ma struct ocfs2_cached_dealloc_ctxt dealloc;
725f5261acSTao Ma int set_abort;
7378f30c31STao Ma };
7478f30c31STao Ma
75cf1d6c76STiger Yang #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
76cf1d6c76STiger Yang #define OCFS2_XATTR_INLINE_SIZE 80
774442f518STiger Yang #define OCFS2_XATTR_HEADER_GAP 4
78534eadddSTiger Yang #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \
79534eadddSTiger Yang - sizeof(struct ocfs2_xattr_header) \
804442f518STiger Yang - OCFS2_XATTR_HEADER_GAP)
8189c38bd0STiger Yang #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \
8289c38bd0STiger Yang - sizeof(struct ocfs2_xattr_block) \
8389c38bd0STiger Yang - sizeof(struct ocfs2_xattr_header) \
844442f518STiger Yang - OCFS2_XATTR_HEADER_GAP)
85cf1d6c76STiger Yang
86cf1d6c76STiger Yang static struct ocfs2_xattr_def_value_root def_xv = {
87cf1d6c76STiger Yang .xv.xr_list.l_count = cpu_to_le16(1),
88cf1d6c76STiger Yang };
89cf1d6c76STiger Yang
90537d81caSStephen Hemminger const struct xattr_handler *ocfs2_xattr_handlers[] = {
91cf1d6c76STiger Yang &ocfs2_xattr_user_handler,
92702e5bc6SChristoph Hellwig &ocfs2_xattr_trusted_handler,
93702e5bc6SChristoph Hellwig &ocfs2_xattr_security_handler,
94cf1d6c76STiger Yang NULL
95923f7f31STiger Yang };
96cf1d6c76STiger Yang
97cf1d6c76STiger Yang static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
98cf1d6c76STiger Yang [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
99537d81caSStephen Hemminger [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] = &nop_posix_acl_access,
100cf1d6c76STiger Yang [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &nop_posix_acl_default,
101929fb014STiger Yang [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
102702e5bc6SChristoph Hellwig [OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
103929fb014STiger Yang };
104702e5bc6SChristoph Hellwig
105cf1d6c76STiger Yang struct ocfs2_xattr_info {
106923f7f31STiger Yang int xi_name_index;
107cf1d6c76STiger Yang const char *xi_name;
108cf1d6c76STiger Yang int xi_name_len;
109cf1d6c76STiger Yang const void *xi_value;
1106b240ff6SJoel Becker size_t xi_value_len;
1116b240ff6SJoel Becker };
11218853b95SJoel Becker
1136b240ff6SJoel Becker struct ocfs2_xattr_search {
1146b240ff6SJoel Becker struct buffer_head *inode_bh;
115cf1d6c76STiger Yang /*
116cf1d6c76STiger Yang * xattr_bh point to the block buffer head which has extended attribute
117cf1d6c76STiger Yang * when extended attribute in inode, xattr_bh is equal to inode_bh.
118cf1d6c76STiger Yang */
119cf1d6c76STiger Yang struct buffer_head *xattr_bh;
120cf1d6c76STiger Yang struct ocfs2_xattr_header *header;
121cf1d6c76STiger Yang struct ocfs2_xattr_bucket *bucket;
122cf1d6c76STiger Yang void *base;
123cf1d6c76STiger Yang void *end;
124cf1d6c76STiger Yang struct ocfs2_xattr_entry *here;
125ba937127SJoel Becker int not_found;
126cf1d6c76STiger Yang };
127cf1d6c76STiger Yang
128cf1d6c76STiger Yang /* Operations on struct ocfs2_xa_entry */
129cf1d6c76STiger Yang struct ocfs2_xa_loc;
130cf1d6c76STiger Yang struct ocfs2_xa_loc_operations {
131cf1d6c76STiger Yang /*
13211179f2cSJoel Becker * Journal functions
13311179f2cSJoel Becker */
13411179f2cSJoel Becker int (*xlo_journal_access)(handle_t *handle, struct ocfs2_xa_loc *loc,
13511179f2cSJoel Becker int type);
136cf2bc809SJoel Becker void (*xlo_journal_dirty)(handle_t *handle, struct ocfs2_xa_loc *loc);
137cf2bc809SJoel Becker
138cf2bc809SJoel Becker /*
139cf2bc809SJoel Becker * Return a pointer to the appropriate buffer in loc->xl_storage
140cf2bc809SJoel Becker * at the given offset from loc->xl_header.
141cf2bc809SJoel Becker */
142cf2bc809SJoel Becker void *(*xlo_offset_pointer)(struct ocfs2_xa_loc *loc, int offset);
14311179f2cSJoel Becker
14411179f2cSJoel Becker /* Can we reuse the existing entry for the new value? */
14511179f2cSJoel Becker int (*xlo_can_reuse)(struct ocfs2_xa_loc *loc,
14611179f2cSJoel Becker struct ocfs2_xattr_info *xi);
14711179f2cSJoel Becker
14869a3e539SJoel Becker /* How much space is needed for the new value? */
14969a3e539SJoel Becker int (*xlo_check_space)(struct ocfs2_xa_loc *loc,
15069a3e539SJoel Becker struct ocfs2_xattr_info *xi);
15169a3e539SJoel Becker
15269a3e539SJoel Becker /*
15369a3e539SJoel Becker * Return the offset of the first name+value pair. This is
15469a3e539SJoel Becker * the start of our downward-filling free space.
15569a3e539SJoel Becker */
15669a3e539SJoel Becker int (*xlo_get_free_start)(struct ocfs2_xa_loc *loc);
15769a3e539SJoel Becker
15869a3e539SJoel Becker /*
15969a3e539SJoel Becker * Remove the name+value at this location. Do whatever is
16069a3e539SJoel Becker * appropriate with the remaining name+value pairs.
16169a3e539SJoel Becker */
16211179f2cSJoel Becker void (*xlo_wipe_namevalue)(struct ocfs2_xa_loc *loc);
16311179f2cSJoel Becker
16411179f2cSJoel Becker /* Fill xl_entry with a new entry */
16511179f2cSJoel Becker void (*xlo_add_entry)(struct ocfs2_xa_loc *loc, u32 name_hash);
16611179f2cSJoel Becker
16769a3e539SJoel Becker /* Add name+value storage to an entry */
16869a3e539SJoel Becker void (*xlo_add_namevalue)(struct ocfs2_xa_loc *loc, int size);
16969a3e539SJoel Becker
17069a3e539SJoel Becker /*
17169a3e539SJoel Becker * Initialize the value buf's access and bh fields for this entry.
17269a3e539SJoel Becker * ocfs2_xa_fill_value_buf() will handle the xv pointer.
1733fc12afaSJoel Becker */
1743fc12afaSJoel Becker void (*xlo_fill_value_buf)(struct ocfs2_xa_loc *loc,
1753fc12afaSJoel Becker struct ocfs2_xattr_value_buf *vb);
1763fc12afaSJoel Becker };
1773fc12afaSJoel Becker
1783fc12afaSJoel Becker /*
1793fc12afaSJoel Becker * Describes an xattr entry location. This is a memory structure
18011179f2cSJoel Becker * tracking the on-disk structure.
18111179f2cSJoel Becker */
18211179f2cSJoel Becker struct ocfs2_xa_loc {
18311179f2cSJoel Becker /* This xattr belongs to this inode */
18411179f2cSJoel Becker struct inode *xl_inode;
18511179f2cSJoel Becker
18611179f2cSJoel Becker /* The ocfs2_xattr_header inside the on-disk storage. Not NULL. */
187cf2bc809SJoel Becker struct ocfs2_xattr_header *xl_header;
188cf2bc809SJoel Becker
189cf2bc809SJoel Becker /* Bytes from xl_header to the end of the storage */
19011179f2cSJoel Becker int xl_size;
19111179f2cSJoel Becker
19211179f2cSJoel Becker /*
19311179f2cSJoel Becker * The ocfs2_xattr_entry this location describes. If this is
19411179f2cSJoel Becker * NULL, this location describes the on-disk structure where it
19511179f2cSJoel Becker * would have been.
19611179f2cSJoel Becker */
19711179f2cSJoel Becker struct ocfs2_xattr_entry *xl_entry;
19811179f2cSJoel Becker
19911179f2cSJoel Becker /*
20011179f2cSJoel Becker * Internal housekeeping
20111179f2cSJoel Becker */
20211179f2cSJoel Becker
20311179f2cSJoel Becker /* Buffer(s) containing this entry */
20411179f2cSJoel Becker void *xl_storage;
20511179f2cSJoel Becker
20611179f2cSJoel Becker /* Operations on the storage backing this location */
20711179f2cSJoel Becker const struct ocfs2_xa_loc_operations *xl_ops;
20811179f2cSJoel Becker };
20911179f2cSJoel Becker
21011179f2cSJoel Becker /*
21111179f2cSJoel Becker * Convenience functions to calculate how much space is needed for a
21211179f2cSJoel Becker * given name+value pair
21311179f2cSJoel Becker */
namevalue_size(int name_len,uint64_t value_len)214199799a3SJoel Becker static int namevalue_size(int name_len, uint64_t value_len)
215199799a3SJoel Becker {
216199799a3SJoel Becker if (value_len > OCFS2_XATTR_INLINE_SIZE)
217199799a3SJoel Becker return OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
218199799a3SJoel Becker else
219199799a3SJoel Becker return OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_SIZE(value_len);
220199799a3SJoel Becker }
221199799a3SJoel Becker
namevalue_size_xi(struct ocfs2_xattr_info * xi)222199799a3SJoel Becker static int namevalue_size_xi(struct ocfs2_xattr_info *xi)
223199799a3SJoel Becker {
224199799a3SJoel Becker return namevalue_size(xi->xi_name_len, xi->xi_value_len);
225199799a3SJoel Becker }
226199799a3SJoel Becker
namevalue_size_xe(struct ocfs2_xattr_entry * xe)227199799a3SJoel Becker static int namevalue_size_xe(struct ocfs2_xattr_entry *xe)
228199799a3SJoel Becker {
229199799a3SJoel Becker u64 value_len = le64_to_cpu(xe->xe_value_size);
230199799a3SJoel Becker
231199799a3SJoel Becker BUG_ON((value_len > OCFS2_XATTR_INLINE_SIZE) &&
232199799a3SJoel Becker ocfs2_xattr_is_local(xe));
233199799a3SJoel Becker return namevalue_size(xe->xe_name_len, value_len);
234199799a3SJoel Becker }
235199799a3SJoel Becker
236199799a3SJoel Becker
237199799a3SJoel Becker static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb,
238199799a3SJoel Becker struct ocfs2_xattr_header *xh,
239199799a3SJoel Becker int index,
240199799a3SJoel Becker int *block_off,
241fd68a894STao Ma int *new_offset);
242589dc260STao Ma
243589dc260STao Ma static int ocfs2_xattr_block_find(struct inode *inode,
244589dc260STao Ma int name_index,
245589dc260STao Ma const char *name,
246589dc260STao Ma struct ocfs2_xattr_search *xs);
24754f443f4SJoel Becker static int ocfs2_xattr_index_block_find(struct inode *inode,
24854f443f4SJoel Becker struct buffer_head *root_bh,
24954f443f4SJoel Becker int name_index,
25054f443f4SJoel Becker const char *name,
251589dc260STao Ma struct ocfs2_xattr_search *xs);
252589dc260STao Ma
253589dc260STao Ma static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
254589dc260STao Ma struct buffer_head *blk_bh,
255589dc260STao Ma char *buffer,
256589dc260STao Ma size_t buffer_size);
2570c044f0bSTao Ma
25847bca495STao Ma static int ocfs2_xattr_create_index_block(struct inode *inode,
2590c044f0bSTao Ma struct ocfs2_xattr_search *xs,
2600c044f0bSTao Ma struct ocfs2_xattr_set_ctxt *ctxt);
2610c044f0bSTao Ma
26201225596STao Ma static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
26378f30c31STao Ma struct ocfs2_xattr_info *xi,
26478f30c31STao Ma struct ocfs2_xattr_search *xs,
26501225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt);
26601225596STao Ma
26701225596STao Ma typedef int (xattr_tree_rec_func)(struct inode *inode,
26878f30c31STao Ma struct buffer_head *root_bh,
26978f30c31STao Ma u64 blkno, u32 cpos, u32 len, void *para);
27001225596STao Ma static int ocfs2_iterate_xattr_index_block(struct inode *inode,
27147bca495STao Ma struct buffer_head *root_bh,
27247bca495STao Ma xattr_tree_rec_func *rec_func,
27347bca495STao Ma void *para);
27447bca495STao Ma static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
27547bca495STao Ma struct ocfs2_xattr_bucket *bucket,
27647bca495STao Ma void *para);
27747bca495STao Ma static int ocfs2_rm_xattr_cluster(struct inode *inode,
27847bca495STao Ma struct buffer_head *root_bh,
27947bca495STao Ma u64 blkno,
28047bca495STao Ma u32 cpos,
28147bca495STao Ma u32 len,
28247bca495STao Ma void *para);
28347bca495STao Ma
28447bca495STao Ma static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle,
28547bca495STao Ma u64 src_blk, u64 last_blk, u64 to_blk,
28647bca495STao Ma unsigned int start_bucket,
28747bca495STao Ma u32 *first_hash);
288c58b6032SJoel Becker static int ocfs2_prepare_refcount_xattr(struct inode *inode,
289c58b6032SJoel Becker struct ocfs2_dinode *di,
290c58b6032SJoel Becker struct ocfs2_xattr_info *xi,
291c58b6032SJoel Becker struct ocfs2_xattr_search *xis,
292492a8a33STao Ma struct ocfs2_xattr_search *xbs,
293492a8a33STao Ma struct ocfs2_refcount_tree **ref_tree,
294492a8a33STao Ma int *meta_need,
295492a8a33STao Ma int *credits);
296492a8a33STao Ma static int ocfs2_get_xattr_tree_value_root(struct super_block *sb,
297492a8a33STao Ma struct ocfs2_xattr_bucket *bucket,
298492a8a33STao Ma int offset,
299492a8a33STao Ma struct ocfs2_xattr_value_root **xv,
300ce9c5a54STao Ma struct buffer_head **bh);
301ce9c5a54STao Ma
ocfs2_xattr_buckets_per_cluster(struct ocfs2_super * osb)302ce9c5a54STao Ma static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb)
303ce9c5a54STao Ma {
304ce9c5a54STao Ma return (1 << osb->s_clustersize_bits) / OCFS2_XATTR_BUCKET_SIZE;
305a3944256STao Ma }
3060030e001STiger Yang
ocfs2_blocks_per_xattr_bucket(struct super_block * sb)3070030e001STiger Yang static inline u16 ocfs2_blocks_per_xattr_bucket(struct super_block *sb)
3080030e001STiger Yang {
3090030e001STiger Yang return OCFS2_XATTR_BUCKET_SIZE / (1 << sb->s_blocksize_bits);
3100030e001STiger Yang }
3110030e001STiger Yang
3120030e001STiger Yang #define bucket_blkno(_b) ((_b)->bu_bhs[0]->b_blocknr)
3130030e001STiger Yang #define bucket_block(_b, _n) ((_b)->bu_bhs[(_n)]->b_data)
3140030e001STiger Yang #define bucket_xh(_b) ((struct ocfs2_xattr_header *)bucket_block((_b), 0))
3150030e001STiger Yang
ocfs2_xattr_bucket_new(struct inode * inode)3169c7759aaSJoel Becker static struct ocfs2_xattr_bucket *ocfs2_xattr_bucket_new(struct inode *inode)
31751def39fSJoel Becker {
3183e632946SJoel Becker struct ocfs2_xattr_bucket *bucket;
3199c7759aaSJoel Becker int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
320ba937127SJoel Becker
3216dde41d9SJoel Becker BUG_ON(blks > OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET);
322ba937127SJoel Becker
323ba937127SJoel Becker bucket = kzalloc(sizeof(struct ocfs2_xattr_bucket), GFP_NOFS);
3246dde41d9SJoel Becker if (bucket) {
325ba937127SJoel Becker bucket->bu_inode = inode;
326ba937127SJoel Becker bucket->bu_blocks = blks;
327ba937127SJoel Becker }
328ba937127SJoel Becker
329ba937127SJoel Becker return bucket;
330ba937127SJoel Becker }
331ba937127SJoel Becker
ocfs2_xattr_bucket_relse(struct ocfs2_xattr_bucket * bucket)332ba937127SJoel Becker static void ocfs2_xattr_bucket_relse(struct ocfs2_xattr_bucket *bucket)
333ba937127SJoel Becker {
334ba937127SJoel Becker int i;
335ba937127SJoel Becker
336ba937127SJoel Becker for (i = 0; i < bucket->bu_blocks; i++) {
337ba937127SJoel Becker brelse(bucket->bu_bhs[i]);
338ba937127SJoel Becker bucket->bu_bhs[i] = NULL;
339ba937127SJoel Becker }
340ba937127SJoel Becker }
3416dde41d9SJoel Becker
ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket * bucket)3426dde41d9SJoel Becker static void ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket *bucket)
3436dde41d9SJoel Becker {
3446dde41d9SJoel Becker if (bucket) {
3456dde41d9SJoel Becker ocfs2_xattr_bucket_relse(bucket);
346ba937127SJoel Becker bucket->bu_inode = NULL;
347ba937127SJoel Becker kfree(bucket);
348ba937127SJoel Becker }
349ba937127SJoel Becker }
350ba937127SJoel Becker
351ba937127SJoel Becker /*
352ba937127SJoel Becker * A bucket that has never been written to disk doesn't need to be
353ba937127SJoel Becker * read. We just need the buffer_heads. Don't call this for
354ba937127SJoel Becker * buckets that are already on disk. ocfs2_read_xattr_bucket() initializes
355784b816aSJoel Becker * them fully.
356784b816aSJoel Becker */
ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket * bucket,u64 xb_blkno,int new)357784b816aSJoel Becker static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
358784b816aSJoel Becker u64 xb_blkno, int new)
359784b816aSJoel Becker {
360784b816aSJoel Becker int i, rc = 0;
361ba937127SJoel Becker
3629c339255SWengang Wang for (i = 0; i < bucket->bu_blocks; i++) {
363784b816aSJoel Becker bucket->bu_bhs[i] = sb_getblk(bucket->bu_inode->i_sb,
364784b816aSJoel Becker xb_blkno + i);
365784b816aSJoel Becker if (!bucket->bu_bhs[i]) {
366ba937127SJoel Becker rc = -ENOMEM;
367ba937127SJoel Becker mlog_errno(rc);
368ba937127SJoel Becker break;
369784b816aSJoel Becker }
3707391a294SRui Xiang
371784b816aSJoel Becker if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode),
372784b816aSJoel Becker bucket->bu_bhs[i])) {
373784b816aSJoel Becker if (new)
374784b816aSJoel Becker ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode),
3758cb471e8SJoel Becker bucket->bu_bhs[i]);
3769c339255SWengang Wang else {
3779c339255SWengang Wang set_buffer_uptodate(bucket->bu_bhs[i]);
3788cb471e8SJoel Becker ocfs2_set_buffer_uptodate(INODE_CACHE(bucket->bu_inode),
379ba937127SJoel Becker bucket->bu_bhs[i]);
3809c339255SWengang Wang }
3819c339255SWengang Wang }
3829c339255SWengang Wang }
3839c339255SWengang Wang
3849c339255SWengang Wang if (rc)
3859c339255SWengang Wang ocfs2_xattr_bucket_relse(bucket);
386784b816aSJoel Becker return rc;
387784b816aSJoel Becker }
388784b816aSJoel Becker
389ba937127SJoel Becker /* Read the xattr bucket at xb_blkno */
ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket * bucket,u64 xb_blkno)390784b816aSJoel Becker static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
391784b816aSJoel Becker u64 xb_blkno)
392784b816aSJoel Becker {
393784b816aSJoel Becker int rc;
394ba937127SJoel Becker
395784b816aSJoel Becker rc = ocfs2_read_blocks(INODE_CACHE(bucket->bu_inode), xb_blkno,
396784b816aSJoel Becker bucket->bu_blocks, bucket->bu_bhs, 0,
397ba937127SJoel Becker NULL);
398784b816aSJoel Becker if (!rc) {
3998cb471e8SJoel Becker spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
400970e4936SJoel Becker rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb,
401970e4936SJoel Becker bucket->bu_bhs,
4024d0e214eSJoel Becker bucket->bu_blocks,
403c8b9cf9aSTao Ma &bucket_xh(bucket)->xh_check);
4044d0e214eSJoel Becker spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
4054d0e214eSJoel Becker if (rc)
4064d0e214eSJoel Becker mlog_errno(rc);
4074d0e214eSJoel Becker }
408c8b9cf9aSTao Ma
4094d0e214eSJoel Becker if (rc)
4104d0e214eSJoel Becker ocfs2_xattr_bucket_relse(bucket);
4114d0e214eSJoel Becker return rc;
4124d0e214eSJoel Becker }
413784b816aSJoel Becker
ocfs2_xattr_bucket_journal_access(handle_t * handle,struct ocfs2_xattr_bucket * bucket,int type)414ba937127SJoel Becker static int ocfs2_xattr_bucket_journal_access(handle_t *handle,
415784b816aSJoel Becker struct ocfs2_xattr_bucket *bucket,
416784b816aSJoel Becker int type)
417784b816aSJoel Becker {
4181224be02SJoel Becker int i, rc = 0;
4191224be02SJoel Becker
4201224be02SJoel Becker for (i = 0; i < bucket->bu_blocks; i++) {
4211224be02SJoel Becker rc = ocfs2_journal_access(handle,
4221224be02SJoel Becker INODE_CACHE(bucket->bu_inode),
4231224be02SJoel Becker bucket->bu_bhs[i], type);
424ba937127SJoel Becker if (rc) {
4250cf2f763SJoel Becker mlog_errno(rc);
4260cf2f763SJoel Becker break;
4271224be02SJoel Becker }
4281224be02SJoel Becker }
4291224be02SJoel Becker
4301224be02SJoel Becker return rc;
4311224be02SJoel Becker }
4321224be02SJoel Becker
ocfs2_xattr_bucket_journal_dirty(handle_t * handle,struct ocfs2_xattr_bucket * bucket)4331224be02SJoel Becker static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
4341224be02SJoel Becker struct ocfs2_xattr_bucket *bucket)
4351224be02SJoel Becker {
4361224be02SJoel Becker int i;
4371224be02SJoel Becker
4381224be02SJoel Becker spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
4391224be02SJoel Becker ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb,
440ba937127SJoel Becker bucket->bu_bhs, bucket->bu_blocks,
4411224be02SJoel Becker &bucket_xh(bucket)->xh_check);
442c8b9cf9aSTao Ma spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock);
4434d0e214eSJoel Becker
4444d0e214eSJoel Becker for (i = 0; i < bucket->bu_blocks; i++)
4454d0e214eSJoel Becker ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
446c8b9cf9aSTao Ma }
4474d0e214eSJoel Becker
ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket * dest,struct ocfs2_xattr_bucket * src)448ba937127SJoel Becker static void ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket *dest,
4491224be02SJoel Becker struct ocfs2_xattr_bucket *src)
4501224be02SJoel Becker {
4511224be02SJoel Becker int i;
452ba937127SJoel Becker int blocksize = src->bu_inode->i_sb->s_blocksize;
4534980c6daSJoel Becker
4544980c6daSJoel Becker BUG_ON(dest->bu_blocks != src->bu_blocks);
4554980c6daSJoel Becker BUG_ON(dest->bu_inode != src->bu_inode);
456ba937127SJoel Becker
4574980c6daSJoel Becker for (i = 0; i < src->bu_blocks; i++) {
458ba937127SJoel Becker memcpy(bucket_block(dest, i), bucket_block(src, i),
459ba937127SJoel Becker blocksize);
460ba937127SJoel Becker }
461ba937127SJoel Becker }
4624980c6daSJoel Becker
ocfs2_validate_xattr_block(struct super_block * sb,struct buffer_head * bh)4634980c6daSJoel Becker static int ocfs2_validate_xattr_block(struct super_block *sb,
4644980c6daSJoel Becker struct buffer_head *bh)
4654980c6daSJoel Becker {
4661224be02SJoel Becker int rc;
4674ae1d69bSJoel Becker struct ocfs2_xattr_block *xb =
4684ae1d69bSJoel Becker (struct ocfs2_xattr_block *)bh->b_data;
4694ae1d69bSJoel Becker
470d6b32bbbSJoel Becker trace_ocfs2_validate_xattr_block((unsigned long long)bh->b_blocknr);
4714ae1d69bSJoel Becker
4724ae1d69bSJoel Becker BUG_ON(!buffer_uptodate(bh));
4734ae1d69bSJoel Becker
474402b4183STao Ma /*
4754ae1d69bSJoel Becker * If the ecc fails, we return the error but otherwise
476d6b32bbbSJoel Becker * leave the filesystem running. We know any error is
477d6b32bbbSJoel Becker * local to this block.
478d6b32bbbSJoel Becker */
479d6b32bbbSJoel Becker rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &xb->xb_check);
480d6b32bbbSJoel Becker if (rc)
481d6b32bbbSJoel Becker return rc;
482d6b32bbbSJoel Becker
483d6b32bbbSJoel Becker /*
484d6b32bbbSJoel Becker * Errors after here are fatal
485d6b32bbbSJoel Becker */
486d6b32bbbSJoel Becker
487d6b32bbbSJoel Becker if (!OCFS2_IS_VALID_XATTR_BLOCK(xb)) {
488d6b32bbbSJoel Becker return ocfs2_error(sb,
489d6b32bbbSJoel Becker "Extended attribute block #%llu has bad signature %.*s\n",
490d6b32bbbSJoel Becker (unsigned long long)bh->b_blocknr, 7,
4914ae1d69bSJoel Becker xb->xb_signature);
49217a5b9abSGoldwyn Rodrigues }
4937ecef14aSJoe Perches
4944ae1d69bSJoel Becker if (le64_to_cpu(xb->xb_blkno) != bh->b_blocknr) {
4954ae1d69bSJoel Becker return ocfs2_error(sb,
4964ae1d69bSJoel Becker "Extended attribute block #%llu has an invalid xb_blkno of %llu\n",
4974ae1d69bSJoel Becker (unsigned long long)bh->b_blocknr,
4984ae1d69bSJoel Becker (unsigned long long)le64_to_cpu(xb->xb_blkno));
49917a5b9abSGoldwyn Rodrigues }
5007ecef14aSJoe Perches
5014ae1d69bSJoel Becker if (le32_to_cpu(xb->xb_fs_generation) != OCFS2_SB(sb)->fs_generation) {
5024ae1d69bSJoel Becker return ocfs2_error(sb,
5034ae1d69bSJoel Becker "Extended attribute block #%llu has an invalid xb_fs_generation of #%u\n",
5044ae1d69bSJoel Becker (unsigned long long)bh->b_blocknr,
5054ae1d69bSJoel Becker le32_to_cpu(xb->xb_fs_generation));
50617a5b9abSGoldwyn Rodrigues }
5077ecef14aSJoe Perches
5084ae1d69bSJoel Becker return 0;
5094ae1d69bSJoel Becker }
5104ae1d69bSJoel Becker
ocfs2_read_xattr_block(struct inode * inode,u64 xb_blkno,struct buffer_head ** bh)5114ae1d69bSJoel Becker static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno,
5124ae1d69bSJoel Becker struct buffer_head **bh)
5134ae1d69bSJoel Becker {
5144ae1d69bSJoel Becker int rc;
5154ae1d69bSJoel Becker struct buffer_head *tmp = *bh;
5164ae1d69bSJoel Becker
5174ae1d69bSJoel Becker rc = ocfs2_read_block(INODE_CACHE(inode), xb_blkno, &tmp,
5184ae1d69bSJoel Becker ocfs2_validate_xattr_block);
5194ae1d69bSJoel Becker
5204ae1d69bSJoel Becker /* If ocfs2_read_block() got us a new bh, pass it up. */
5218cb471e8SJoel Becker if (!rc && !*bh)
522970e4936SJoel Becker *bh = tmp;
5234ae1d69bSJoel Becker
5244ae1d69bSJoel Becker return rc;
5254ae1d69bSJoel Becker }
5264ae1d69bSJoel Becker
ocfs2_xattr_prefix(int name_index)5274ae1d69bSJoel Becker static inline const char *ocfs2_xattr_prefix(int name_index)
5284ae1d69bSJoel Becker {
5294ae1d69bSJoel Becker const struct xattr_handler *handler = NULL;
5304ae1d69bSJoel Becker
531936b8834STao Ma if (name_index > 0 && name_index < OCFS2_XATTR_MAX)
532cf1d6c76STiger Yang handler = ocfs2_xattr_handler_map[name_index];
533537d81caSStephen Hemminger return handler ? xattr_prefix(handler) : NULL;
534cf1d6c76STiger Yang }
535cf1d6c76STiger Yang
ocfs2_xattr_name_hash(struct inode * inode,const char * name,int name_len)536cf1d6c76STiger Yang static u32 ocfs2_xattr_name_hash(struct inode *inode,
53798e9cb57SAndreas Gruenbacher const char *name,
538cf1d6c76STiger Yang int name_len)
539cf1d6c76STiger Yang {
54040daa16aSMark Fasheh /* Get hash value of uuid from super block */
5412057e5c6STao Ma u32 hash = OCFS2_SB(inode->i_sb)->uuid_hash;
542cf1d6c76STiger Yang int i;
543cf1d6c76STiger Yang
544cf1d6c76STiger Yang /* hash extended attribute name */
545cf1d6c76STiger Yang for (i = 0; i < name_len; i++) {
546cf1d6c76STiger Yang hash = (hash << OCFS2_HASH_SHIFT) ^
547cf1d6c76STiger Yang (hash >> (8*sizeof(hash) - OCFS2_HASH_SHIFT)) ^
548cf1d6c76STiger Yang *name++;
549cf1d6c76STiger Yang }
550cf1d6c76STiger Yang
551cf1d6c76STiger Yang return hash;
552cf1d6c76STiger Yang }
553cf1d6c76STiger Yang
ocfs2_xattr_entry_real_size(int name_len,size_t value_len)554cf1d6c76STiger Yang static int ocfs2_xattr_entry_real_size(int name_len, size_t value_len)
555cf1d6c76STiger Yang {
556cf1d6c76STiger Yang return namevalue_size(name_len, value_len) +
557cf1d6c76STiger Yang sizeof(struct ocfs2_xattr_entry);
558534eadddSTiger Yang }
559534eadddSTiger Yang
ocfs2_xi_entry_usage(struct ocfs2_xattr_info * xi)560199799a3SJoel Becker static int ocfs2_xi_entry_usage(struct ocfs2_xattr_info *xi)
561199799a3SJoel Becker {
562199799a3SJoel Becker return namevalue_size_xi(xi) +
563534eadddSTiger Yang sizeof(struct ocfs2_xattr_entry);
564199799a3SJoel Becker }
565199799a3SJoel Becker
ocfs2_xe_entry_usage(struct ocfs2_xattr_entry * xe)566199799a3SJoel Becker static int ocfs2_xe_entry_usage(struct ocfs2_xattr_entry *xe)
567199799a3SJoel Becker {
568199799a3SJoel Becker return namevalue_size_xe(xe) +
569534eadddSTiger Yang sizeof(struct ocfs2_xattr_entry);
570199799a3SJoel Becker }
571199799a3SJoel Becker
ocfs2_calc_security_init(struct inode * dir,struct ocfs2_security_xattr_info * si,int * want_clusters,int * xattr_credits,struct ocfs2_alloc_context ** xattr_ac)572199799a3SJoel Becker int ocfs2_calc_security_init(struct inode *dir,
573199799a3SJoel Becker struct ocfs2_security_xattr_info *si,
574534eadddSTiger Yang int *want_clusters,
575534eadddSTiger Yang int *xattr_credits,
576534eadddSTiger Yang struct ocfs2_alloc_context **xattr_ac)
577534eadddSTiger Yang {
578534eadddSTiger Yang int ret = 0;
579534eadddSTiger Yang struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
580534eadddSTiger Yang int s_size = ocfs2_xattr_entry_real_size(strlen(si->name),
581534eadddSTiger Yang si->value_len);
582534eadddSTiger Yang
583534eadddSTiger Yang /*
584534eadddSTiger Yang * The max space of security xattr taken inline is
585534eadddSTiger Yang * 256(name) + 80(value) + 16(entry) = 352 bytes,
586534eadddSTiger Yang * So reserve one metadata block for it is ok.
587534eadddSTiger Yang */
588534eadddSTiger Yang if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE ||
589534eadddSTiger Yang s_size > OCFS2_XATTR_FREE_IN_IBODY) {
590534eadddSTiger Yang ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac);
591534eadddSTiger Yang if (ret) {
592534eadddSTiger Yang mlog_errno(ret);
593534eadddSTiger Yang return ret;
594534eadddSTiger Yang }
595534eadddSTiger Yang *xattr_credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
596534eadddSTiger Yang }
597534eadddSTiger Yang
598534eadddSTiger Yang /* reserve clusters for xattr value which will be set in B tree*/
599534eadddSTiger Yang if (si->value_len > OCFS2_XATTR_INLINE_SIZE) {
600534eadddSTiger Yang int new_clusters = ocfs2_clusters_for_bytes(dir->i_sb,
601534eadddSTiger Yang si->value_len);
602534eadddSTiger Yang
6030e445b6fSTiger Yang *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb,
6040e445b6fSTiger Yang new_clusters);
605534eadddSTiger Yang *want_clusters += new_clusters;
6060e445b6fSTiger Yang }
6070e445b6fSTiger Yang return ret;
6080e445b6fSTiger Yang }
6090e445b6fSTiger Yang
ocfs2_calc_xattr_init(struct inode * dir,struct buffer_head * dir_bh,umode_t mode,struct ocfs2_security_xattr_info * si,int * want_clusters,int * xattr_credits,int * want_meta)6100e445b6fSTiger Yang int ocfs2_calc_xattr_init(struct inode *dir,
611534eadddSTiger Yang struct buffer_head *dir_bh,
612534eadddSTiger Yang umode_t mode,
613534eadddSTiger Yang struct ocfs2_security_xattr_info *si,
61489c38bd0STiger Yang int *want_clusters,
61589c38bd0STiger Yang int *xattr_credits,
61667697cbdSAl Viro int *want_meta)
61789c38bd0STiger Yang {
61889c38bd0STiger Yang int ret = 0;
61989c38bd0STiger Yang struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
6209b7895efSMark Fasheh int s_size = 0, a_size = 0, acl_len = 0, new_clusters;
62189c38bd0STiger Yang
62289c38bd0STiger Yang if (si->enable)
62389c38bd0STiger Yang s_size = ocfs2_xattr_entry_real_size(strlen(si->name),
6240e445b6fSTiger Yang si->value_len);
62589c38bd0STiger Yang
62689c38bd0STiger Yang if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
62789c38bd0STiger Yang down_read(&OCFS2_I(dir)->ip_xattr_sem);
62889c38bd0STiger Yang acl_len = ocfs2_xattr_get_nolock(dir, dir_bh,
62989c38bd0STiger Yang OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT,
63089c38bd0STiger Yang "", NULL, 0);
63116c8d569Spiaojun up_read(&OCFS2_I(dir)->ip_xattr_sem);
63289c38bd0STiger Yang if (acl_len > 0) {
63389c38bd0STiger Yang a_size = ocfs2_xattr_entry_real_size(0, acl_len);
63489c38bd0STiger Yang if (S_ISDIR(mode))
63516c8d569Spiaojun a_size <<= 1;
63689c38bd0STiger Yang } else if (acl_len != 0 && acl_len != -ENODATA) {
63789c38bd0STiger Yang ret = acl_len;
63889c38bd0STiger Yang mlog_errno(ret);
63989c38bd0STiger Yang return ret;
64089c38bd0STiger Yang }
641c0a1a6d7Spiaojun }
64289c38bd0STiger Yang
64389c38bd0STiger Yang if (!(s_size + a_size))
64489c38bd0STiger Yang return ret;
64589c38bd0STiger Yang
64689c38bd0STiger Yang /*
64789c38bd0STiger Yang * The max space of security xattr taken inline is
64889c38bd0STiger Yang * 256(name) + 80(value) + 16(entry) = 352 bytes,
64989c38bd0STiger Yang * The max space of acl xattr taken inline is
65089c38bd0STiger Yang * 80(value) + 16(entry) * 2(if directory) = 192 bytes,
65189c38bd0STiger Yang * when blocksize = 512, may reserve one more cluser for
65289c38bd0STiger Yang * xattr bucket, otherwise reserve one metadata block
65389c38bd0STiger Yang * for them is ok.
65489c38bd0STiger Yang * If this is a new directory with inline data,
65589c38bd0STiger Yang * we choose to reserve the entire inline area for
65689c38bd0STiger Yang * directory contents and force an external xattr block.
65789c38bd0STiger Yang */
6586c9fd1dcSTiger Yang if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE ||
6596c9fd1dcSTiger Yang (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) ||
6606c9fd1dcSTiger Yang (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) {
66189c38bd0STiger Yang *want_meta = *want_meta + 1;
66289c38bd0STiger Yang *xattr_credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
6636c9fd1dcSTiger Yang }
66489c38bd0STiger Yang
6659b7895efSMark Fasheh if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE &&
66689c38bd0STiger Yang (s_size + a_size) > OCFS2_XATTR_FREE_IN_BLOCK(dir)) {
66789c38bd0STiger Yang *want_clusters += 1;
66889c38bd0STiger Yang *xattr_credits += ocfs2_blocks_per_xattr_bucket(dir->i_sb);
66989c38bd0STiger Yang }
67089c38bd0STiger Yang
67189c38bd0STiger Yang /*
67289c38bd0STiger Yang * reserve credits and clusters for xattrs which has large value
67389c38bd0STiger Yang * and have to be set outside
67489c38bd0STiger Yang */
6750e445b6fSTiger Yang if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) {
6760e445b6fSTiger Yang new_clusters = ocfs2_clusters_for_bytes(dir->i_sb,
6770e445b6fSTiger Yang si->value_len);
6780e445b6fSTiger Yang *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb,
6790e445b6fSTiger Yang new_clusters);
6800e445b6fSTiger Yang *want_clusters += new_clusters;
68189c38bd0STiger Yang }
6820e445b6fSTiger Yang if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL &&
6830e445b6fSTiger Yang acl_len > OCFS2_XATTR_INLINE_SIZE) {
6840e445b6fSTiger Yang /* for directory, it has DEFAULT and ACCESS two types of acls */
6850e445b6fSTiger Yang new_clusters = (S_ISDIR(mode) ? 2 : 1) *
68689c38bd0STiger Yang ocfs2_clusters_for_bytes(dir->i_sb, acl_len);
68789c38bd0STiger Yang *xattr_credits += ocfs2_clusters_to_blocks(dir->i_sb,
6880e445b6fSTiger Yang new_clusters);
6890e445b6fSTiger Yang *want_clusters += new_clusters;
6900e445b6fSTiger Yang }
6910e445b6fSTiger Yang
6920e445b6fSTiger Yang return ret;
6930e445b6fSTiger Yang }
69489c38bd0STiger Yang
ocfs2_xattr_extend_allocation(struct inode * inode,u32 clusters_to_add,struct ocfs2_xattr_value_buf * vb,struct ocfs2_xattr_set_ctxt * ctxt)69589c38bd0STiger Yang static int ocfs2_xattr_extend_allocation(struct inode *inode,
69689c38bd0STiger Yang u32 clusters_to_add,
69789c38bd0STiger Yang struct ocfs2_xattr_value_buf *vb,
69889c38bd0STiger Yang struct ocfs2_xattr_set_ctxt *ctxt)
699f56654c4STao Ma {
700f56654c4STao Ma int status = 0, credits;
70119b801f4SJoel Becker handle_t *handle = ctxt->handle;
70278f30c31STao Ma enum ocfs2_alloc_restarted why;
703f56654c4STao Ma u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters);
704a78f9f46STao Ma struct ocfs2_extent_tree et;
70585db90e7STao Ma
706f56654c4STao Ma ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
70719b801f4SJoel Becker
708f99b9b7cSJoel Becker while (clusters_to_add) {
709f56654c4STao Ma trace_ocfs2_xattr_extend_allocation(clusters_to_add);
7105e404e9eSJoel Becker
711f99b9b7cSJoel Becker status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
712a78f9f46STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
713402b4183STao Ma if (status < 0) {
714402b4183STao Ma mlog_errno(status);
7150cf2f763SJoel Becker break;
716f56654c4STao Ma }
717f56654c4STao Ma
718f56654c4STao Ma prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
719a78f9f46STao Ma status = ocfs2_add_clusters_in_btree(handle,
720f56654c4STao Ma &et,
721f56654c4STao Ma &logical_start,
72219b801f4SJoel Becker clusters_to_add,
723cbee7e1aSJoel Becker 0,
724cbee7e1aSJoel Becker ctxt->data_ac,
725f56654c4STao Ma ctxt->meta_ac,
726f56654c4STao Ma &why);
727f56654c4STao Ma if ((status < 0) && (status != -EAGAIN)) {
72878f30c31STao Ma if (status != -ENOSPC)
72978f30c31STao Ma mlog_errno(status);
730f99b9b7cSJoel Becker break;
731a78f9f46STao Ma }
732a78f9f46STao Ma
733f56654c4STao Ma ocfs2_journal_dirty(handle, vb->vb_bh);
734a78f9f46STao Ma
735f56654c4STao Ma clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) -
736f56654c4STao Ma prev_clusters;
737ec20cec7SJoel Becker
738f56654c4STao Ma if (why != RESTART_NONE && clusters_to_add) {
739a78f9f46STao Ma /*
740a78f9f46STao Ma * We can only fail in case the alloc file doesn't give
741f56654c4STao Ma * up enough clusters.
742a78f9f46STao Ma */
74385db90e7STao Ma BUG_ON(why == RESTART_META);
744a78f9f46STao Ma
745a78f9f46STao Ma credits = ocfs2_calc_extend_credits(inode->i_sb,
74685db90e7STao Ma &vb->vb_xv->xr_list);
747a78f9f46STao Ma status = ocfs2_extend_trans(handle, credits);
748f56654c4STao Ma if (status < 0) {
749a78f9f46STao Ma status = -ENOMEM;
75006f9da6eSGoldwyn Rodrigues mlog_errno(status);
751a78f9f46STao Ma break;
752a78f9f46STao Ma }
753a78f9f46STao Ma }
754a78f9f46STao Ma }
755a78f9f46STao Ma
756a78f9f46STao Ma return status;
757a78f9f46STao Ma }
758a78f9f46STao Ma
__ocfs2_remove_xattr_range(struct inode * inode,struct ocfs2_xattr_value_buf * vb,u32 cpos,u32 phys_cpos,u32 len,unsigned int ext_flags,struct ocfs2_xattr_set_ctxt * ctxt)759f56654c4STao Ma static int __ocfs2_remove_xattr_range(struct inode *inode,
760f56654c4STao Ma struct ocfs2_xattr_value_buf *vb,
761f56654c4STao Ma u32 cpos, u32 phys_cpos, u32 len,
762f56654c4STao Ma unsigned int ext_flags,
763f56654c4STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
764d72cc72dSJoel Becker {
765f56654c4STao Ma int ret;
766492a8a33STao Ma u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
76778f30c31STao Ma handle_t *handle = ctxt->handle;
768f56654c4STao Ma struct ocfs2_extent_tree et;
769f56654c4STao Ma
770f56654c4STao Ma ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
77185db90e7STao Ma
772f99b9b7cSJoel Becker ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
773f56654c4STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
7745e404e9eSJoel Becker if (ret) {
775f99b9b7cSJoel Becker mlog_errno(ret);
7760cf2f763SJoel Becker goto out;
777f56654c4STao Ma }
778f56654c4STao Ma
779f56654c4STao Ma ret = ocfs2_remove_extent(handle, &et, cpos, len, ctxt->meta_ac,
78085db90e7STao Ma &ctxt->dealloc);
781f56654c4STao Ma if (ret) {
782f56654c4STao Ma mlog_errno(ret);
783dbdcf6a4SJoel Becker goto out;
78478f30c31STao Ma }
785f56654c4STao Ma
786f56654c4STao Ma le32_add_cpu(&vb->vb_xv->xr_clusters, -len);
78785db90e7STao Ma ocfs2_journal_dirty(handle, vb->vb_bh);
788f56654c4STao Ma
789f56654c4STao Ma if (ext_flags & OCFS2_EXT_REFCOUNTED)
790d72cc72dSJoel Becker ret = ocfs2_decrease_refcount(inode, handle,
791ec20cec7SJoel Becker ocfs2_blocks_to_clusters(inode->i_sb,
792f56654c4STao Ma phys_blkno),
793492a8a33STao Ma len, ctxt->meta_ac, &ctxt->dealloc, 1);
794492a8a33STao Ma else
795492a8a33STao Ma ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc,
796492a8a33STao Ma phys_blkno, len);
797492a8a33STao Ma if (ret)
798492a8a33STao Ma mlog_errno(ret);
799492a8a33STao Ma
800492a8a33STao Ma out:
801f56654c4STao Ma return ret;
802f56654c4STao Ma }
803f56654c4STao Ma
ocfs2_xattr_shrink_size(struct inode * inode,u32 old_clusters,u32 new_clusters,struct ocfs2_xattr_value_buf * vb,struct ocfs2_xattr_set_ctxt * ctxt)804f56654c4STao Ma static int ocfs2_xattr_shrink_size(struct inode *inode,
805f56654c4STao Ma u32 old_clusters,
806f56654c4STao Ma u32 new_clusters,
807f56654c4STao Ma struct ocfs2_xattr_value_buf *vb,
808f56654c4STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
809f56654c4STao Ma {
810f56654c4STao Ma int ret = 0;
81119b801f4SJoel Becker unsigned int ext_flags;
81278f30c31STao Ma u32 trunc_len, cpos, phys_cpos, alloc_size;
813f56654c4STao Ma u64 block;
814f56654c4STao Ma
815492a8a33STao Ma if (old_clusters <= new_clusters)
816f56654c4STao Ma return 0;
817f56654c4STao Ma
818f56654c4STao Ma cpos = new_clusters;
819f56654c4STao Ma trunc_len = old_clusters - new_clusters;
820f56654c4STao Ma while (trunc_len) {
821f56654c4STao Ma ret = ocfs2_xattr_get_clusters(inode, cpos, &phys_cpos,
822f56654c4STao Ma &alloc_size,
823f56654c4STao Ma &vb->vb_xv->xr_list, &ext_flags);
824f56654c4STao Ma if (ret) {
825f56654c4STao Ma mlog_errno(ret);
826d72cc72dSJoel Becker goto out;
827492a8a33STao Ma }
828f56654c4STao Ma
829f56654c4STao Ma if (alloc_size > trunc_len)
830f56654c4STao Ma alloc_size = trunc_len;
831f56654c4STao Ma
832f56654c4STao Ma ret = __ocfs2_remove_xattr_range(inode, vb, cpos,
833f56654c4STao Ma phys_cpos, alloc_size,
834f56654c4STao Ma ext_flags, ctxt);
835f56654c4STao Ma if (ret) {
83619b801f4SJoel Becker mlog_errno(ret);
837f56654c4STao Ma goto out;
838492a8a33STao Ma }
839f56654c4STao Ma
840f56654c4STao Ma block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
841f56654c4STao Ma ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode),
842f56654c4STao Ma block, alloc_size);
843f56654c4STao Ma cpos += alloc_size;
844f56654c4STao Ma trunc_len -= alloc_size;
8458cb471e8SJoel Becker }
8468cb471e8SJoel Becker
847f56654c4STao Ma out:
848f56654c4STao Ma return ret;
849f56654c4STao Ma }
850f56654c4STao Ma
ocfs2_xattr_value_truncate(struct inode * inode,struct ocfs2_xattr_value_buf * vb,int len,struct ocfs2_xattr_set_ctxt * ctxt)851f56654c4STao Ma static int ocfs2_xattr_value_truncate(struct inode *inode,
852f56654c4STao Ma struct ocfs2_xattr_value_buf *vb,
853f56654c4STao Ma int len,
854f56654c4STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
855f56654c4STao Ma {
856b3e5d379SJoel Becker int ret;
85778f30c31STao Ma u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb, len);
85878f30c31STao Ma u32 old_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
859f56654c4STao Ma
860f56654c4STao Ma if (new_clusters == old_clusters)
861f56654c4STao Ma return 0;
862b3e5d379SJoel Becker
863f56654c4STao Ma if (new_clusters > old_clusters)
864f56654c4STao Ma ret = ocfs2_xattr_extend_allocation(inode,
865f56654c4STao Ma new_clusters - old_clusters,
866f56654c4STao Ma vb, ctxt);
867f56654c4STao Ma else
868f56654c4STao Ma ret = ocfs2_xattr_shrink_size(inode,
869f56654c4STao Ma old_clusters, new_clusters,
870b3e5d379SJoel Becker vb, ctxt);
871f56654c4STao Ma
872f56654c4STao Ma return ret;
873f56654c4STao Ma }
874b3e5d379SJoel Becker
ocfs2_xattr_list_entry(struct super_block * sb,char * buffer,size_t size,size_t * result,int type,const char * name,int name_len)875f56654c4STao Ma static int ocfs2_xattr_list_entry(struct super_block *sb,
876f56654c4STao Ma char *buffer, size_t size,
877f56654c4STao Ma size_t *result, int type,
878cf1d6c76STiger Yang const char *name, int name_len)
8791046cb11SAndreas Gruenbacher {
8801046cb11SAndreas Gruenbacher char *p = buffer + *result;
8811046cb11SAndreas Gruenbacher const char *prefix;
882936b8834STao Ma int prefix_len;
883936b8834STao Ma int total_len;
884936b8834STao Ma
8851046cb11SAndreas Gruenbacher switch(type) {
8861046cb11SAndreas Gruenbacher case OCFS2_XATTR_INDEX_USER:
8871046cb11SAndreas Gruenbacher if (OCFS2_SB(sb)->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
888936b8834STao Ma return 0;
8891046cb11SAndreas Gruenbacher break;
8901046cb11SAndreas Gruenbacher
8911046cb11SAndreas Gruenbacher case OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS:
8921046cb11SAndreas Gruenbacher case OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT:
8931046cb11SAndreas Gruenbacher if (!(sb->s_flags & SB_POSIXACL))
8941046cb11SAndreas Gruenbacher return 0;
8951046cb11SAndreas Gruenbacher break;
8961046cb11SAndreas Gruenbacher
8971751e8a6SLinus Torvalds case OCFS2_XATTR_INDEX_TRUSTED:
8981046cb11SAndreas Gruenbacher if (!capable(CAP_SYS_ADMIN))
8991046cb11SAndreas Gruenbacher return 0;
9001046cb11SAndreas Gruenbacher break;
9011046cb11SAndreas Gruenbacher }
9021046cb11SAndreas Gruenbacher
9031046cb11SAndreas Gruenbacher prefix = ocfs2_xattr_prefix(type);
9041046cb11SAndreas Gruenbacher if (!prefix)
9051046cb11SAndreas Gruenbacher return 0;
9061046cb11SAndreas Gruenbacher prefix_len = strlen(prefix);
9071046cb11SAndreas Gruenbacher total_len = prefix_len + name_len + 1;
9081046cb11SAndreas Gruenbacher *result += total_len;
9091046cb11SAndreas Gruenbacher
9101046cb11SAndreas Gruenbacher /* we are just looking for how big our buffer needs to be */
9111046cb11SAndreas Gruenbacher if (!size)
912936b8834STao Ma return 0;
913936b8834STao Ma
914936b8834STao Ma if (*result > size)
915936b8834STao Ma return -ERANGE;
916936b8834STao Ma
917936b8834STao Ma memcpy(p, prefix, prefix_len);
918936b8834STao Ma memcpy(p + prefix_len, name, name_len);
919936b8834STao Ma p[prefix_len + name_len] = '\0';
920936b8834STao Ma
921936b8834STao Ma return 0;
922936b8834STao Ma }
923936b8834STao Ma
ocfs2_xattr_list_entries(struct inode * inode,struct ocfs2_xattr_header * header,char * buffer,size_t buffer_size)924936b8834STao Ma static int ocfs2_xattr_list_entries(struct inode *inode,
925936b8834STao Ma struct ocfs2_xattr_header *header,
926936b8834STao Ma char *buffer, size_t buffer_size)
927936b8834STao Ma {
928cf1d6c76STiger Yang size_t result = 0;
929cf1d6c76STiger Yang int i, type, ret;
930cf1d6c76STiger Yang const char *name;
931cf1d6c76STiger Yang
932936b8834STao Ma for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) {
933936b8834STao Ma struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
9341046cb11SAndreas Gruenbacher type = ocfs2_xattr_get_type(entry);
935cf1d6c76STiger Yang name = (const char *)header +
936cf1d6c76STiger Yang le16_to_cpu(entry->xe_name_offset);
937cf1d6c76STiger Yang
938936b8834STao Ma ret = ocfs2_xattr_list_entry(inode->i_sb,
939936b8834STao Ma buffer, buffer_size,
940936b8834STao Ma &result, type, name,
941936b8834STao Ma entry->xe_name_len);
9421046cb11SAndreas Gruenbacher if (ret)
9431046cb11SAndreas Gruenbacher return ret;
9441046cb11SAndreas Gruenbacher }
945cf1d6c76STiger Yang
946936b8834STao Ma return result;
947936b8834STao Ma }
948cf1d6c76STiger Yang
ocfs2_has_inline_xattr_value_outside(struct inode * inode,struct ocfs2_dinode * di)949cf1d6c76STiger Yang int ocfs2_has_inline_xattr_value_outside(struct inode *inode,
950936b8834STao Ma struct ocfs2_dinode *di)
951cf1d6c76STiger Yang {
952cf1d6c76STiger Yang struct ocfs2_xattr_header *xh;
9538b2c0dbaSTao Ma int i;
9548b2c0dbaSTao Ma
9558b2c0dbaSTao Ma xh = (struct ocfs2_xattr_header *)
9568b2c0dbaSTao Ma ((void *)di + inode->i_sb->s_blocksize -
9578b2c0dbaSTao Ma le16_to_cpu(di->i_xattr_inline_size));
9588b2c0dbaSTao Ma
9598b2c0dbaSTao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++)
9608b2c0dbaSTao Ma if (!ocfs2_xattr_is_local(&xh->xh_entries[i]))
9618b2c0dbaSTao Ma return 1;
9628b2c0dbaSTao Ma
9638b2c0dbaSTao Ma return 0;
9648b2c0dbaSTao Ma }
9658b2c0dbaSTao Ma
ocfs2_xattr_ibody_list(struct inode * inode,struct ocfs2_dinode * di,char * buffer,size_t buffer_size)9668b2c0dbaSTao Ma static int ocfs2_xattr_ibody_list(struct inode *inode,
9678b2c0dbaSTao Ma struct ocfs2_dinode *di,
9688b2c0dbaSTao Ma char *buffer,
9698b2c0dbaSTao Ma size_t buffer_size)
970cf1d6c76STiger Yang {
971cf1d6c76STiger Yang struct ocfs2_xattr_header *header = NULL;
972cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
973cf1d6c76STiger Yang int ret = 0;
974cf1d6c76STiger Yang
975cf1d6c76STiger Yang if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
976cf1d6c76STiger Yang return ret;
977cf1d6c76STiger Yang
978cf1d6c76STiger Yang header = (struct ocfs2_xattr_header *)
979cf1d6c76STiger Yang ((void *)di + inode->i_sb->s_blocksize -
980cf1d6c76STiger Yang le16_to_cpu(di->i_xattr_inline_size));
981cf1d6c76STiger Yang
982cf1d6c76STiger Yang ret = ocfs2_xattr_list_entries(inode, header, buffer, buffer_size);
983cf1d6c76STiger Yang
984cf1d6c76STiger Yang return ret;
985cf1d6c76STiger Yang }
986cf1d6c76STiger Yang
ocfs2_xattr_block_list(struct inode * inode,struct ocfs2_dinode * di,char * buffer,size_t buffer_size)987cf1d6c76STiger Yang static int ocfs2_xattr_block_list(struct inode *inode,
988cf1d6c76STiger Yang struct ocfs2_dinode *di,
989cf1d6c76STiger Yang char *buffer,
990cf1d6c76STiger Yang size_t buffer_size)
991cf1d6c76STiger Yang {
992cf1d6c76STiger Yang struct buffer_head *blk_bh = NULL;
993cf1d6c76STiger Yang struct ocfs2_xattr_block *xb;
994cf1d6c76STiger Yang int ret = 0;
995cf1d6c76STiger Yang
996cf1d6c76STiger Yang if (!di->i_xattr_loc)
9970c044f0bSTao Ma return ret;
998cf1d6c76STiger Yang
999cf1d6c76STiger Yang ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc),
1000cf1d6c76STiger Yang &blk_bh);
1001cf1d6c76STiger Yang if (ret < 0) {
1002cf1d6c76STiger Yang mlog_errno(ret);
10034ae1d69bSJoel Becker return ret;
10044ae1d69bSJoel Becker }
1005cf1d6c76STiger Yang
1006cf1d6c76STiger Yang xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1007cf1d6c76STiger Yang if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
1008cf1d6c76STiger Yang struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header;
1009cf1d6c76STiger Yang ret = ocfs2_xattr_list_entries(inode, header,
10100c044f0bSTao Ma buffer, buffer_size);
10110c044f0bSTao Ma } else
10120c044f0bSTao Ma ret = ocfs2_xattr_tree_list_index_block(inode, blk_bh,
10130c044f0bSTao Ma buffer, buffer_size);
10140c044f0bSTao Ma
101547bca495STao Ma brelse(blk_bh);
101647bca495STao Ma
10170c044f0bSTao Ma return ret;
10184ae1d69bSJoel Becker }
1019cf1d6c76STiger Yang
ocfs2_listxattr(struct dentry * dentry,char * buffer,size_t size)1020cf1d6c76STiger Yang ssize_t ocfs2_listxattr(struct dentry *dentry,
1021cf1d6c76STiger Yang char *buffer,
1022cf1d6c76STiger Yang size_t size)
1023cf1d6c76STiger Yang {
1024cf1d6c76STiger Yang int ret = 0, i_ret = 0, b_ret = 0;
1025cf1d6c76STiger Yang struct buffer_head *di_bh = NULL;
1026cf1d6c76STiger Yang struct ocfs2_dinode *di = NULL;
1027cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(d_inode(dentry));
1028cf1d6c76STiger Yang
1029cf1d6c76STiger Yang if (!ocfs2_supports_xattr(OCFS2_SB(dentry->d_sb)))
1030cf1d6c76STiger Yang return -EOPNOTSUPP;
10312b0143b5SDavid Howells
1032cf1d6c76STiger Yang if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
10338154da3dSTiger Yang return ret;
10348154da3dSTiger Yang
10358154da3dSTiger Yang ret = ocfs2_inode_lock(d_inode(dentry), &di_bh, 0);
1036cf1d6c76STiger Yang if (ret < 0) {
1037cf1d6c76STiger Yang mlog_errno(ret);
1038cf1d6c76STiger Yang return ret;
10392b0143b5SDavid Howells }
1040cf1d6c76STiger Yang
1041cf1d6c76STiger Yang di = (struct ocfs2_dinode *)di_bh->b_data;
1042cf1d6c76STiger Yang
1043cf1d6c76STiger Yang down_read(&oi->ip_xattr_sem);
1044cf1d6c76STiger Yang i_ret = ocfs2_xattr_ibody_list(d_inode(dentry), di, buffer, size);
1045cf1d6c76STiger Yang if (i_ret < 0)
1046cf1d6c76STiger Yang b_ret = 0;
1047cf1d6c76STiger Yang else {
10482b0143b5SDavid Howells if (buffer) {
1049cf1d6c76STiger Yang buffer += i_ret;
1050cf1d6c76STiger Yang size -= i_ret;
1051cf1d6c76STiger Yang }
1052cf1d6c76STiger Yang b_ret = ocfs2_xattr_block_list(d_inode(dentry), di,
1053cf1d6c76STiger Yang buffer, size);
1054cf1d6c76STiger Yang if (b_ret < 0)
1055cf1d6c76STiger Yang i_ret = 0;
10562b0143b5SDavid Howells }
1057cf1d6c76STiger Yang up_read(&oi->ip_xattr_sem);
1058cf1d6c76STiger Yang ocfs2_inode_unlock(d_inode(dentry), 0);
1059cf1d6c76STiger Yang
1060cf1d6c76STiger Yang brelse(di_bh);
1061cf1d6c76STiger Yang
10622b0143b5SDavid Howells return i_ret + b_ret;
1063cf1d6c76STiger Yang }
1064cf1d6c76STiger Yang
ocfs2_xattr_find_entry(struct inode * inode,int name_index,const char * name,struct ocfs2_xattr_search * xs)1065cf1d6c76STiger Yang static int ocfs2_xattr_find_entry(struct inode *inode, int name_index,
1066cf1d6c76STiger Yang const char *name,
1067cf1d6c76STiger Yang struct ocfs2_xattr_search *xs)
1068cf1d6c76STiger Yang {
1069cf1d6c76STiger Yang struct ocfs2_xattr_entry *entry;
1070cf1d6c76STiger Yang size_t name_len;
1071cf1d6c76STiger Yang int i, name_offset, cmp = 1;
1072cf1d6c76STiger Yang
1073cf1d6c76STiger Yang if (name == NULL)
1074cf1d6c76STiger Yang return -EINVAL;
1075cf1d6c76STiger Yang
1076cf1d6c76STiger Yang name_len = strlen(name);
1077cf1d6c76STiger Yang entry = xs->here;
1078cf1d6c76STiger Yang for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
1079cf1d6c76STiger Yang if ((void *)entry >= xs->end) {
1080cf1d6c76STiger Yang ocfs2_error(inode->i_sb, "corrupted xattr entries");
1081cf1d6c76STiger Yang return -EFSCORRUPTED;
1082cf1d6c76STiger Yang }
1083cf1d6c76STiger Yang cmp = name_index - ocfs2_xattr_get_type(entry);
1084cf1d6c76STiger Yang if (!cmp)
1085cf1d6c76STiger Yang cmp = name_len - entry->xe_name_len;
1086cf1d6c76STiger Yang if (!cmp) {
1087cf1d6c76STiger Yang name_offset = le16_to_cpu(entry->xe_name_offset);
1088cf1d6c76STiger Yang if ((xs->base + name_offset + name_len) > xs->end) {
1089cf1d6c76STiger Yang ocfs2_error(inode->i_sb,
1090cf1d6c76STiger Yang "corrupted xattr entries");
1091cf1d6c76STiger Yang return -EFSCORRUPTED;
1092cf1d6c76STiger Yang }
1093cf1d6c76STiger Yang cmp = memcmp(name, (xs->base + name_offset), name_len);
1094cf1d6c76STiger Yang }
1095cf1d6c76STiger Yang if (cmp == 0)
1096cf1d6c76STiger Yang break;
1097cf1d6c76STiger Yang entry += 1;
1098cf1d6c76STiger Yang }
1099cf1d6c76STiger Yang xs->here = entry;
1100589dc260STao Ma
1101cf1d6c76STiger Yang return cmp ? -ENODATA : 0;
1102cf1d6c76STiger Yang }
1103cf1d6c76STiger Yang
ocfs2_xattr_get_value_outside(struct inode * inode,struct ocfs2_xattr_value_root * xv,void * buffer,size_t len)1104cf1d6c76STiger Yang static int ocfs2_xattr_get_value_outside(struct inode *inode,
1105cf1d6c76STiger Yang struct ocfs2_xattr_value_root *xv,
1106cf1d6c76STiger Yang void *buffer,
1107cf1d6c76STiger Yang size_t len)
1108cf1d6c76STiger Yang {
1109cf1d6c76STiger Yang u32 cpos, p_cluster, num_clusters, bpc, clusters;
1110cf1d6c76STiger Yang u64 blkno;
1111cf1d6c76STiger Yang int i, ret = 0;
1112cf1d6c76STiger Yang size_t cplen, blocksize;
1113cf1d6c76STiger Yang struct buffer_head *bh = NULL;
1114cf1d6c76STiger Yang struct ocfs2_extent_list *el;
1115cf1d6c76STiger Yang
1116cf1d6c76STiger Yang el = &xv->xr_list;
1117cf1d6c76STiger Yang clusters = le32_to_cpu(xv->xr_clusters);
1118cf1d6c76STiger Yang bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
11191061f9c1STao Ma blocksize = inode->i_sb->s_blocksize;
1120cf1d6c76STiger Yang
1121cf1d6c76STiger Yang cpos = 0;
1122cf1d6c76STiger Yang while (cpos < clusters) {
1123cf1d6c76STiger Yang ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
1124cf1d6c76STiger Yang &num_clusters, el, NULL);
1125cf1d6c76STiger Yang if (ret) {
1126cf1d6c76STiger Yang mlog_errno(ret);
1127cf1d6c76STiger Yang goto out;
11288cb471e8SJoel Becker }
11298cb471e8SJoel Becker
1130cf1d6c76STiger Yang blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
1131cf1d6c76STiger Yang /* Copy ocfs2_xattr_value */
1132cf1d6c76STiger Yang for (i = 0; i < num_clusters * bpc; i++, blkno++) {
1133cf1d6c76STiger Yang ret = ocfs2_read_block(INODE_CACHE(inode), blkno,
1134cf1d6c76STiger Yang &bh, NULL);
1135cf1d6c76STiger Yang if (ret) {
1136cf1d6c76STiger Yang mlog_errno(ret);
1137cf1d6c76STiger Yang goto out;
1138cf1d6c76STiger Yang }
1139cf1d6c76STiger Yang
1140cf1d6c76STiger Yang cplen = len >= blocksize ? blocksize : len;
1141cf1d6c76STiger Yang memcpy(buffer, bh->b_data, cplen);
1142cf1d6c76STiger Yang len -= cplen;
1143cf1d6c76STiger Yang buffer += cplen;
1144cf1d6c76STiger Yang
1145cf1d6c76STiger Yang brelse(bh);
1146cf1d6c76STiger Yang bh = NULL;
1147cf1d6c76STiger Yang if (len == 0)
1148cf1d6c76STiger Yang break;
1149cf1d6c76STiger Yang }
1150cf1d6c76STiger Yang cpos += num_clusters;
1151cf1d6c76STiger Yang }
1152cf1d6c76STiger Yang out:
1153cf1d6c76STiger Yang return ret;
1154cf1d6c76STiger Yang }
1155cf1d6c76STiger Yang
ocfs2_xattr_ibody_get(struct inode * inode,int name_index,const char * name,void * buffer,size_t buffer_size,struct ocfs2_xattr_search * xs)1156cf1d6c76STiger Yang static int ocfs2_xattr_ibody_get(struct inode *inode,
1157cf1d6c76STiger Yang int name_index,
1158cf1d6c76STiger Yang const char *name,
1159cf1d6c76STiger Yang void *buffer,
1160589dc260STao Ma size_t buffer_size,
1161cf1d6c76STiger Yang struct ocfs2_xattr_search *xs)
1162cf1d6c76STiger Yang {
1163cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
1164cf1d6c76STiger Yang struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1165cf1d6c76STiger Yang struct ocfs2_xattr_value_root *xv;
1166cf1d6c76STiger Yang size_t size;
1167cf1d6c76STiger Yang int ret = 0;
1168cf1d6c76STiger Yang
1169cf1d6c76STiger Yang if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
1170cf1d6c76STiger Yang return -ENODATA;
1171cf1d6c76STiger Yang
1172cf1d6c76STiger Yang xs->end = (void *)di + inode->i_sb->s_blocksize;
1173cf1d6c76STiger Yang xs->header = (struct ocfs2_xattr_header *)
1174cf1d6c76STiger Yang (xs->end - le16_to_cpu(di->i_xattr_inline_size));
1175cf1d6c76STiger Yang xs->base = (void *)xs->header;
1176cf1d6c76STiger Yang xs->here = xs->header->xh_entries;
1177cf1d6c76STiger Yang
1178cf1d6c76STiger Yang ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
1179cf1d6c76STiger Yang if (ret)
1180cf1d6c76STiger Yang return ret;
1181cf1d6c76STiger Yang size = le64_to_cpu(xs->here->xe_value_size);
1182cf1d6c76STiger Yang if (buffer) {
1183cf1d6c76STiger Yang if (size > buffer_size)
1184cf1d6c76STiger Yang return -ERANGE;
1185589dc260STao Ma if (ocfs2_xattr_is_local(xs->here)) {
1186589dc260STao Ma memcpy(buffer, (void *)xs->base +
1187589dc260STao Ma le16_to_cpu(xs->here->xe_name_offset) +
1188589dc260STao Ma OCFS2_XATTR_SIZE(xs->here->xe_name_len), size);
1189589dc260STao Ma } else {
1190cf1d6c76STiger Yang xv = (struct ocfs2_xattr_value_root *)
1191cf1d6c76STiger Yang (xs->base + le16_to_cpu(
1192cf1d6c76STiger Yang xs->here->xe_name_offset) +
1193cf1d6c76STiger Yang OCFS2_XATTR_SIZE(xs->here->xe_name_len));
1194cf1d6c76STiger Yang ret = ocfs2_xattr_get_value_outside(inode, xv,
1195cf1d6c76STiger Yang buffer, size);
1196cf1d6c76STiger Yang if (ret < 0) {
1197cf1d6c76STiger Yang mlog_errno(ret);
1198cf1d6c76STiger Yang return ret;
1199cf1d6c76STiger Yang }
1200cf1d6c76STiger Yang }
1201cf1d6c76STiger Yang }
1202cf1d6c76STiger Yang
1203cf1d6c76STiger Yang return size;
1204cf1d6c76STiger Yang }
1205cf1d6c76STiger Yang
ocfs2_xattr_block_get(struct inode * inode,int name_index,const char * name,void * buffer,size_t buffer_size,struct ocfs2_xattr_search * xs)1206cf1d6c76STiger Yang static int ocfs2_xattr_block_get(struct inode *inode,
1207cf1d6c76STiger Yang int name_index,
1208cf1d6c76STiger Yang const char *name,
1209589dc260STao Ma void *buffer,
1210cf1d6c76STiger Yang size_t buffer_size,
121144d8e4e1SSubrata Modak struct ocfs2_xattr_search *xs)
12123f649ab7SKees Cook {
1213cf1d6c76STiger Yang struct ocfs2_xattr_block *xb;
1214ba937127SJoel Becker struct ocfs2_xattr_value_root *xv;
1215ba937127SJoel Becker size_t size;
1216ba937127SJoel Becker int ret = -ENODATA, name_offset, name_len, i;
1217ba937127SJoel Becker int block_off;
1218ba937127SJoel Becker
1219ba937127SJoel Becker xs->bucket = ocfs2_xattr_bucket_new(inode);
1220589dc260STao Ma if (!xs->bucket) {
122154f443f4SJoel Becker ret = -ENOMEM;
122254f443f4SJoel Becker mlog_errno(ret);
1223cf1d6c76STiger Yang goto cleanup;
1224cf1d6c76STiger Yang }
1225cf1d6c76STiger Yang
1226cf1d6c76STiger Yang ret = ocfs2_xattr_block_find(inode, name_index, name, xs);
12276c1e183eSTiger Yang if (ret) {
12286c1e183eSTiger Yang mlog_errno(ret);
12296c1e183eSTiger Yang goto cleanup;
12306c1e183eSTiger Yang }
12316c1e183eSTiger Yang
123254f443f4SJoel Becker if (xs->not_found) {
1233cf1d6c76STiger Yang ret = -ENODATA;
1234cf1d6c76STiger Yang goto cleanup;
1235cf1d6c76STiger Yang }
1236cf1d6c76STiger Yang
1237cf1d6c76STiger Yang xb = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
1238589dc260STao Ma size = le64_to_cpu(xs->here->xe_value_size);
1239589dc260STao Ma if (buffer) {
1240589dc260STao Ma ret = -ERANGE;
1241589dc260STao Ma if (size > buffer_size)
1242589dc260STao Ma goto cleanup;
1243589dc260STao Ma
1244fd68a894STao Ma name_offset = le16_to_cpu(xs->here->xe_name_offset);
1245ba937127SJoel Becker name_len = OCFS2_XATTR_SIZE(xs->here->xe_name_len);
1246589dc260STao Ma i = xs->here - xs->header->xh_entries;
1247589dc260STao Ma
1248589dc260STao Ma if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
1249023d4ea3SJoseph Qi ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
1250023d4ea3SJoseph Qi bucket_xh(xs->bucket),
1251023d4ea3SJoseph Qi i,
1252023d4ea3SJoseph Qi &block_off,
1253ba937127SJoel Becker &name_offset);
1254589dc260STao Ma if (ret) {
1255cf1d6c76STiger Yang mlog_errno(ret);
1256cf1d6c76STiger Yang goto cleanup;
1257589dc260STao Ma }
1258cf1d6c76STiger Yang xs->base = bucket_block(xs->bucket, block_off);
1259589dc260STao Ma }
1260589dc260STao Ma if (ocfs2_xattr_is_local(xs->here)) {
1261589dc260STao Ma memcpy(buffer, (void *)xs->base +
1262cf1d6c76STiger Yang name_offset + name_len, size);
1263cf1d6c76STiger Yang } else {
1264cf1d6c76STiger Yang xv = (struct ocfs2_xattr_value_root *)
1265cf1d6c76STiger Yang (xs->base + name_offset + name_len);
1266cf1d6c76STiger Yang ret = ocfs2_xattr_get_value_outside(inode, xv,
1267cf1d6c76STiger Yang buffer, size);
1268cf1d6c76STiger Yang if (ret < 0) {
1269cf1d6c76STiger Yang mlog_errno(ret);
1270cf1d6c76STiger Yang goto cleanup;
1271ba937127SJoel Becker }
1272cf1d6c76STiger Yang }
127354f443f4SJoel Becker }
127454f443f4SJoel Becker ret = size;
1275cf1d6c76STiger Yang cleanup:
1276cf1d6c76STiger Yang ocfs2_xattr_bucket_free(xs->bucket);
1277cf1d6c76STiger Yang
12784e3e9d02STiger Yang brelse(xs->xattr_bh);
12794e3e9d02STiger Yang xs->xattr_bh = NULL;
1280cf1d6c76STiger Yang return ret;
1281cf1d6c76STiger Yang }
1282cf1d6c76STiger Yang
ocfs2_xattr_get_nolock(struct inode * inode,struct buffer_head * di_bh,int name_index,const char * name,void * buffer,size_t buffer_size)1283cf1d6c76STiger Yang int ocfs2_xattr_get_nolock(struct inode *inode,
1284cf1d6c76STiger Yang struct buffer_head *di_bh,
1285cf1d6c76STiger Yang int name_index,
1286cf1d6c76STiger Yang const char *name,
1287cf1d6c76STiger Yang void *buffer,
1288cf1d6c76STiger Yang size_t buffer_size)
1289cf1d6c76STiger Yang {
1290cf1d6c76STiger Yang int ret;
1291cf1d6c76STiger Yang struct ocfs2_dinode *di = NULL;
1292cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
1293cf1d6c76STiger Yang struct ocfs2_xattr_search xis = {
1294cf1d6c76STiger Yang .not_found = -ENODATA,
12958154da3dSTiger Yang };
12968154da3dSTiger Yang struct ocfs2_xattr_search xbs = {
12978154da3dSTiger Yang .not_found = -ENODATA,
1298cf1d6c76STiger Yang };
12992b693005SJan Kara
1300cf1d6c76STiger Yang if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb)))
1301cf1d6c76STiger Yang return -EOPNOTSUPP;
1302cf1d6c76STiger Yang
1303cf1d6c76STiger Yang if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
1304cf1d6c76STiger Yang return -ENODATA;
1305cf1d6c76STiger Yang
13066c1e183eSTiger Yang xis.inode_bh = xbs.inode_bh = di_bh;
1307cf1d6c76STiger Yang di = (struct ocfs2_dinode *)di_bh->b_data;
1308cf1d6c76STiger Yang
13094e3e9d02STiger Yang ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer,
13104e3e9d02STiger Yang buffer_size, &xis);
13114e3e9d02STiger Yang if (ret == -ENODATA && di->i_xattr_loc)
13124e3e9d02STiger Yang ret = ocfs2_xattr_block_get(inode, name_index, name, buffer,
13134e3e9d02STiger Yang buffer_size, &xbs);
13144e3e9d02STiger Yang
13154e3e9d02STiger Yang return ret;
13164e3e9d02STiger Yang }
13174e3e9d02STiger Yang
13184e3e9d02STiger Yang /* ocfs2_xattr_get()
13194e3e9d02STiger Yang *
13204e3e9d02STiger Yang * Copy an extended attribute into the buffer provided.
13214e3e9d02STiger Yang * Buffer is NULL to compute the size of buffer required.
13224e3e9d02STiger Yang */
ocfs2_xattr_get(struct inode * inode,int name_index,const char * name,void * buffer,size_t buffer_size)13234e3e9d02STiger Yang static int ocfs2_xattr_get(struct inode *inode,
13248818efaaSEric Ren int name_index,
13254e3e9d02STiger Yang const char *name,
13268818efaaSEric Ren void *buffer,
13274e3e9d02STiger Yang size_t buffer_size)
13288818efaaSEric Ren {
13298818efaaSEric Ren int ret, had_lock;
13308818efaaSEric Ren struct buffer_head *di_bh = NULL;
13318818efaaSEric Ren struct ocfs2_lock_holder oh;
13324e3e9d02STiger Yang
13335e64b0d9STao Ma had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh);
13344e3e9d02STiger Yang if (had_lock < 0) {
13354e3e9d02STiger Yang mlog_errno(had_lock);
13365e64b0d9STao Ma return had_lock;
13374e3e9d02STiger Yang }
13388818efaaSEric Ren down_read(&OCFS2_I(inode)->ip_xattr_sem);
1339cf1d6c76STiger Yang ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index,
1340cf1d6c76STiger Yang name, buffer, buffer_size);
1341cf1d6c76STiger Yang up_read(&OCFS2_I(inode)->ip_xattr_sem);
1342cf1d6c76STiger Yang
1343cf1d6c76STiger Yang ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock);
1344cf1d6c76STiger Yang
1345cf1d6c76STiger Yang brelse(di_bh);
134685db90e7STao Ma
1347492a8a33STao Ma return ret;
1348cf1d6c76STiger Yang }
1349cf1d6c76STiger Yang
__ocfs2_xattr_set_value_outside(struct inode * inode,handle_t * handle,struct ocfs2_xattr_value_buf * vb,const void * value,int value_len)1350cf1d6c76STiger Yang static int __ocfs2_xattr_set_value_outside(struct inode *inode,
135171d548a6STao Ma handle_t *handle,
1352cf1d6c76STiger Yang struct ocfs2_xattr_value_buf *vb,
1353cf1d6c76STiger Yang const void *value,
1354cf1d6c76STiger Yang int value_len)
1355cf1d6c76STiger Yang {
1356cf1d6c76STiger Yang int ret = 0, i, cp_len;
1357cf1d6c76STiger Yang u16 blocksize = inode->i_sb->s_blocksize;
1358492a8a33STao Ma u32 p_cluster, num_clusters;
1359492a8a33STao Ma u32 cpos = 0, bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
1360cf1d6c76STiger Yang u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len);
1361cf1d6c76STiger Yang u64 blkno;
1362cf1d6c76STiger Yang struct buffer_head *bh = NULL;
1363cf1d6c76STiger Yang unsigned int ext_flags;
1364cf1d6c76STiger Yang struct ocfs2_xattr_value_root *xv = vb->vb_xv;
13651061f9c1STao Ma
1366492a8a33STao Ma BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
1367cf1d6c76STiger Yang
1368cf1d6c76STiger Yang while (cpos < clusters) {
136985db90e7STao Ma ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
1370cf1d6c76STiger Yang &num_clusters, &xv->xr_list,
1371cf1d6c76STiger Yang &ext_flags);
1372492a8a33STao Ma if (ret) {
1373492a8a33STao Ma mlog_errno(ret);
1374cf1d6c76STiger Yang goto out;
1375cf1d6c76STiger Yang }
1376cf1d6c76STiger Yang
13778cb471e8SJoel Becker BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED);
13788cb471e8SJoel Becker
1379cf1d6c76STiger Yang blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
1380cf1d6c76STiger Yang
138185db90e7STao Ma for (i = 0; i < num_clusters * bpc; i++, blkno++) {
1382cf1d6c76STiger Yang ret = ocfs2_read_block(INODE_CACHE(inode), blkno,
1383cf1d6c76STiger Yang &bh, NULL);
1384cf1d6c76STiger Yang if (ret) {
13850cf2f763SJoel Becker mlog_errno(ret);
1386cf1d6c76STiger Yang goto out;
1387cf1d6c76STiger Yang }
1388cf1d6c76STiger Yang
1389cf1d6c76STiger Yang ret = ocfs2_journal_access(handle,
139085db90e7STao Ma INODE_CACHE(inode),
1391cf1d6c76STiger Yang bh,
1392cf1d6c76STiger Yang OCFS2_JOURNAL_ACCESS_WRITE);
1393cf1d6c76STiger Yang if (ret < 0) {
1394cf1d6c76STiger Yang mlog_errno(ret);
1395cf1d6c76STiger Yang goto out;
1396cf1d6c76STiger Yang }
1397cf1d6c76STiger Yang
1398cf1d6c76STiger Yang cp_len = value_len > blocksize ? blocksize : value_len;
1399cf1d6c76STiger Yang memcpy(bh->b_data, value, cp_len);
1400cf1d6c76STiger Yang value_len -= cp_len;
1401ec20cec7SJoel Becker value += cp_len;
1402cf1d6c76STiger Yang if (cp_len < blocksize)
1403cf1d6c76STiger Yang memset(bh->b_data + cp_len, 0,
1404cf1d6c76STiger Yang blocksize - cp_len);
1405cf1d6c76STiger Yang
1406cf1d6c76STiger Yang ocfs2_journal_dirty(handle, bh);
1407cf1d6c76STiger Yang brelse(bh);
1408cf1d6c76STiger Yang bh = NULL;
1409cf1d6c76STiger Yang
1410cf1d6c76STiger Yang /*
1411cf1d6c76STiger Yang * XXX: do we need to empty all the following
1412cf1d6c76STiger Yang * blocks in this cluster?
1413cf1d6c76STiger Yang */
1414cf1d6c76STiger Yang if (!value_len)
1415cf1d6c76STiger Yang break;
1416cf1d6c76STiger Yang }
1417cf1d6c76STiger Yang cpos += num_clusters;
1418cf1d6c76STiger Yang }
1419cf1d6c76STiger Yang out:
142069a3e539SJoel Becker brelse(bh);
142169a3e539SJoel Becker
142269a3e539SJoel Becker return ret;
142369a3e539SJoel Becker }
142469a3e539SJoel Becker
ocfs2_xa_check_space_helper(int needed_space,int free_start,int num_entries)142569a3e539SJoel Becker static int ocfs2_xa_check_space_helper(int needed_space, int free_start,
142669a3e539SJoel Becker int num_entries)
142769a3e539SJoel Becker {
142869a3e539SJoel Becker int free_space;
142969a3e539SJoel Becker
143069a3e539SJoel Becker if (!needed_space)
143169a3e539SJoel Becker return 0;
143269a3e539SJoel Becker
143369a3e539SJoel Becker free_space = free_start -
143469a3e539SJoel Becker sizeof(struct ocfs2_xattr_header) -
143569a3e539SJoel Becker (num_entries * sizeof(struct ocfs2_xattr_entry)) -
143669a3e539SJoel Becker OCFS2_XATTR_HEADER_GAP;
143769a3e539SJoel Becker if (free_space < 0)
143869a3e539SJoel Becker return -EIO;
143969a3e539SJoel Becker if (free_space < needed_space)
1440cf2bc809SJoel Becker return -ENOSPC;
1441cf2bc809SJoel Becker
1442cf2bc809SJoel Becker return 0;
1443cf2bc809SJoel Becker }
1444cf2bc809SJoel Becker
ocfs2_xa_journal_access(handle_t * handle,struct ocfs2_xa_loc * loc,int type)1445cf2bc809SJoel Becker static int ocfs2_xa_journal_access(handle_t *handle, struct ocfs2_xa_loc *loc,
1446cf2bc809SJoel Becker int type)
1447cf2bc809SJoel Becker {
1448cf2bc809SJoel Becker return loc->xl_ops->xlo_journal_access(handle, loc, type);
1449cf2bc809SJoel Becker }
1450cf2bc809SJoel Becker
ocfs2_xa_journal_dirty(handle_t * handle,struct ocfs2_xa_loc * loc)145169a3e539SJoel Becker static void ocfs2_xa_journal_dirty(handle_t *handle, struct ocfs2_xa_loc *loc)
145269a3e539SJoel Becker {
145369a3e539SJoel Becker loc->xl_ops->xlo_journal_dirty(handle, loc);
145469a3e539SJoel Becker }
145569a3e539SJoel Becker
145669a3e539SJoel Becker /* Give a pointer into the storage for the given offset */
ocfs2_xa_offset_pointer(struct ocfs2_xa_loc * loc,int offset)145769a3e539SJoel Becker static void *ocfs2_xa_offset_pointer(struct ocfs2_xa_loc *loc, int offset)
1458cf1d6c76STiger Yang {
145911179f2cSJoel Becker BUG_ON(offset >= loc->xl_size);
146011179f2cSJoel Becker return loc->xl_ops->xlo_offset_pointer(loc, offset);
146111179f2cSJoel Becker }
146211179f2cSJoel Becker
146311179f2cSJoel Becker /*
146411179f2cSJoel Becker * Wipe the name+value pair and allow the storage to reclaim it. This
146511179f2cSJoel Becker * must be followed by either removal of the entry or a call to
146611179f2cSJoel Becker * ocfs2_xa_add_namevalue().
146711179f2cSJoel Becker */
ocfs2_xa_wipe_namevalue(struct ocfs2_xa_loc * loc)146869a3e539SJoel Becker static void ocfs2_xa_wipe_namevalue(struct ocfs2_xa_loc *loc)
146969a3e539SJoel Becker {
147069a3e539SJoel Becker loc->xl_ops->xlo_wipe_namevalue(loc);
147169a3e539SJoel Becker }
147269a3e539SJoel Becker
147369a3e539SJoel Becker /*
147469a3e539SJoel Becker * Find lowest offset to a name+value pair. This is the start of our
147569a3e539SJoel Becker * downward-growing free space.
147669a3e539SJoel Becker */
ocfs2_xa_get_free_start(struct ocfs2_xa_loc * loc)147769a3e539SJoel Becker static int ocfs2_xa_get_free_start(struct ocfs2_xa_loc *loc)
147869a3e539SJoel Becker {
147969a3e539SJoel Becker return loc->xl_ops->xlo_get_free_start(loc);
148069a3e539SJoel Becker }
148169a3e539SJoel Becker
148269a3e539SJoel Becker /* Can we reuse loc->xl_entry for xi? */
ocfs2_xa_can_reuse_entry(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)148369a3e539SJoel Becker static int ocfs2_xa_can_reuse_entry(struct ocfs2_xa_loc *loc,
148469a3e539SJoel Becker struct ocfs2_xattr_info *xi)
148569a3e539SJoel Becker {
148669a3e539SJoel Becker return loc->xl_ops->xlo_can_reuse(loc, xi);
148769a3e539SJoel Becker }
148869a3e539SJoel Becker
148969a3e539SJoel Becker /* How much free space is needed to set the new value */
ocfs2_xa_check_space(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)149069a3e539SJoel Becker static int ocfs2_xa_check_space(struct ocfs2_xa_loc *loc,
149194b07b6fSJoseph Qi struct ocfs2_xattr_info *xi)
149294b07b6fSJoseph Qi {
149394b07b6fSJoseph Qi return loc->xl_ops->xlo_check_space(loc, xi);
149494b07b6fSJoseph Qi }
149594b07b6fSJoseph Qi
ocfs2_xa_add_entry(struct ocfs2_xa_loc * loc,u32 name_hash)149694b07b6fSJoseph Qi static void ocfs2_xa_add_entry(struct ocfs2_xa_loc *loc, u32 name_hash)
149794b07b6fSJoseph Qi {
149894b07b6fSJoseph Qi loc->xl_ops->xlo_add_entry(loc, name_hash);
149994b07b6fSJoseph Qi loc->xl_entry->xe_name_hash = cpu_to_le32(name_hash);
150094b07b6fSJoseph Qi /*
150194b07b6fSJoseph Qi * We can't leave the new entry's xe_name_offset at zero or
150294b07b6fSJoseph Qi * add_namevalue() will go nuts. We set it to the size of our
150369a3e539SJoel Becker * storage so that it can never be less than any other entry.
150469a3e539SJoel Becker */
150569a3e539SJoel Becker loc->xl_entry->xe_name_offset = cpu_to_le16(loc->xl_size);
150669a3e539SJoel Becker }
150769a3e539SJoel Becker
ocfs2_xa_add_namevalue(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)150869a3e539SJoel Becker static void ocfs2_xa_add_namevalue(struct ocfs2_xa_loc *loc,
150969a3e539SJoel Becker struct ocfs2_xattr_info *xi)
151069a3e539SJoel Becker {
151169a3e539SJoel Becker int size = namevalue_size_xi(xi);
151269a3e539SJoel Becker int nameval_offset;
151369a3e539SJoel Becker char *nameval_buf;
151469a3e539SJoel Becker
151569a3e539SJoel Becker loc->xl_ops->xlo_add_namevalue(loc, size);
151669a3e539SJoel Becker loc->xl_entry->xe_value_size = cpu_to_le64(xi->xi_value_len);
151769a3e539SJoel Becker loc->xl_entry->xe_name_len = xi->xi_name_len;
151869a3e539SJoel Becker ocfs2_xattr_set_type(loc->xl_entry, xi->xi_name_index);
151969a3e539SJoel Becker ocfs2_xattr_set_local(loc->xl_entry,
152069a3e539SJoel Becker xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE);
152169a3e539SJoel Becker
152269a3e539SJoel Becker nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
15233fc12afaSJoel Becker nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset);
15243fc12afaSJoel Becker memset(nameval_buf, 0, size);
15253fc12afaSJoel Becker memcpy(nameval_buf, xi->xi_name, xi->xi_name_len);
15263fc12afaSJoel Becker }
15273fc12afaSJoel Becker
ocfs2_xa_fill_value_buf(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_value_buf * vb)15283fc12afaSJoel Becker static void ocfs2_xa_fill_value_buf(struct ocfs2_xa_loc *loc,
15293fc12afaSJoel Becker struct ocfs2_xattr_value_buf *vb)
153073857ee0SJoel Becker {
15313fc12afaSJoel Becker int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
15323fc12afaSJoel Becker int name_size = OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len);
15333fc12afaSJoel Becker
15343fc12afaSJoel Becker /* Value bufs are for value trees */
15353fc12afaSJoel Becker BUG_ON(ocfs2_xattr_is_local(loc->xl_entry));
15363fc12afaSJoel Becker BUG_ON(namevalue_size_xe(loc->xl_entry) !=
15373fc12afaSJoel Becker (name_size + OCFS2_XATTR_ROOT_SIZE));
15383fc12afaSJoel Becker
15393fc12afaSJoel Becker loc->xl_ops->xlo_fill_value_buf(loc, vb);
15403fc12afaSJoel Becker vb->vb_xv =
1541cf2bc809SJoel Becker (struct ocfs2_xattr_value_root *)ocfs2_xa_offset_pointer(loc,
1542cf2bc809SJoel Becker nameval_offset +
1543cf2bc809SJoel Becker name_size);
1544cf2bc809SJoel Becker }
1545cf2bc809SJoel Becker
ocfs2_xa_block_journal_access(handle_t * handle,struct ocfs2_xa_loc * loc,int type)1546cf2bc809SJoel Becker static int ocfs2_xa_block_journal_access(handle_t *handle,
1547cf2bc809SJoel Becker struct ocfs2_xa_loc *loc, int type)
1548cf2bc809SJoel Becker {
1549cf2bc809SJoel Becker struct buffer_head *bh = loc->xl_storage;
1550cf2bc809SJoel Becker ocfs2_journal_access_func access;
1551cf2bc809SJoel Becker
1552cf2bc809SJoel Becker if (loc->xl_size == (bh->b_size -
1553cf2bc809SJoel Becker offsetof(struct ocfs2_xattr_block,
1554cf2bc809SJoel Becker xb_attrs.xb_header)))
1555cf2bc809SJoel Becker access = ocfs2_journal_access_xb;
1556cf2bc809SJoel Becker else
1557cf2bc809SJoel Becker access = ocfs2_journal_access_di;
1558cf2bc809SJoel Becker return access(handle, INODE_CACHE(loc->xl_inode), bh, type);
1559cf2bc809SJoel Becker }
1560cf2bc809SJoel Becker
ocfs2_xa_block_journal_dirty(handle_t * handle,struct ocfs2_xa_loc * loc)1561cf2bc809SJoel Becker static void ocfs2_xa_block_journal_dirty(handle_t *handle,
1562cf2bc809SJoel Becker struct ocfs2_xa_loc *loc)
1563cf2bc809SJoel Becker {
156411179f2cSJoel Becker struct buffer_head *bh = loc->xl_storage;
156511179f2cSJoel Becker
156611179f2cSJoel Becker ocfs2_journal_dirty(handle, bh);
156711179f2cSJoel Becker }
156811179f2cSJoel Becker
ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc * loc,int offset)156911179f2cSJoel Becker static void *ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc *loc,
157069a3e539SJoel Becker int offset)
157169a3e539SJoel Becker {
157269a3e539SJoel Becker return (char *)loc->xl_header + offset;
157369a3e539SJoel Becker }
157469a3e539SJoel Becker
ocfs2_xa_block_can_reuse(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)157569a3e539SJoel Becker static int ocfs2_xa_block_can_reuse(struct ocfs2_xa_loc *loc,
157669a3e539SJoel Becker struct ocfs2_xattr_info *xi)
157769a3e539SJoel Becker {
157869a3e539SJoel Becker /*
157969a3e539SJoel Becker * Block storage is strict. If the sizes aren't exact, we will
158069a3e539SJoel Becker * remove the old one and reinsert the new.
158169a3e539SJoel Becker */
158269a3e539SJoel Becker return namevalue_size_xe(loc->xl_entry) ==
158369a3e539SJoel Becker namevalue_size_xi(xi);
158469a3e539SJoel Becker }
158569a3e539SJoel Becker
ocfs2_xa_block_get_free_start(struct ocfs2_xa_loc * loc)158669a3e539SJoel Becker static int ocfs2_xa_block_get_free_start(struct ocfs2_xa_loc *loc)
158769a3e539SJoel Becker {
158869a3e539SJoel Becker struct ocfs2_xattr_header *xh = loc->xl_header;
158969a3e539SJoel Becker int i, count = le16_to_cpu(xh->xh_count);
159069a3e539SJoel Becker int offset, free_start = loc->xl_size;
159169a3e539SJoel Becker
159269a3e539SJoel Becker for (i = 0; i < count; i++) {
159369a3e539SJoel Becker offset = le16_to_cpu(xh->xh_entries[i].xe_name_offset);
159469a3e539SJoel Becker if (offset < free_start)
159569a3e539SJoel Becker free_start = offset;
159669a3e539SJoel Becker }
159769a3e539SJoel Becker
159869a3e539SJoel Becker return free_start;
159969a3e539SJoel Becker }
160069a3e539SJoel Becker
ocfs2_xa_block_check_space(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)160169a3e539SJoel Becker static int ocfs2_xa_block_check_space(struct ocfs2_xa_loc *loc,
160269a3e539SJoel Becker struct ocfs2_xattr_info *xi)
160369a3e539SJoel Becker {
160469a3e539SJoel Becker int count = le16_to_cpu(loc->xl_header->xh_count);
160569a3e539SJoel Becker int free_start = ocfs2_xa_get_free_start(loc);
160669a3e539SJoel Becker int needed_space = ocfs2_xi_entry_usage(xi);
160769a3e539SJoel Becker
160869a3e539SJoel Becker /*
160969a3e539SJoel Becker * Block storage will reclaim the original entry before inserting
161069a3e539SJoel Becker * the new value, so we only need the difference. If the new
161169a3e539SJoel Becker * entry is smaller than the old one, we don't need anything.
161269a3e539SJoel Becker */
161369a3e539SJoel Becker if (loc->xl_entry) {
161469a3e539SJoel Becker /* Don't need space if we're reusing! */
161569a3e539SJoel Becker if (ocfs2_xa_can_reuse_entry(loc, xi))
161669a3e539SJoel Becker needed_space = 0;
161769a3e539SJoel Becker else
161869a3e539SJoel Becker needed_space -= ocfs2_xe_entry_usage(loc->xl_entry);
161969a3e539SJoel Becker }
162011179f2cSJoel Becker if (needed_space < 0)
162111179f2cSJoel Becker needed_space = 0;
162211179f2cSJoel Becker return ocfs2_xa_check_space_helper(needed_space, free_start, count);
162311179f2cSJoel Becker }
162411179f2cSJoel Becker
162511179f2cSJoel Becker /*
162611179f2cSJoel Becker * Block storage for xattrs keeps the name+value pairs compacted. When
162711179f2cSJoel Becker * we remove one, we have to shift any that preceded it towards the end.
162811179f2cSJoel Becker */
ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc * loc)162911179f2cSJoel Becker static void ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc *loc)
163011179f2cSJoel Becker {
163111179f2cSJoel Becker int i, offset;
163211179f2cSJoel Becker int namevalue_offset, first_namevalue_offset, namevalue_size;
1633199799a3SJoel Becker struct ocfs2_xattr_entry *entry = loc->xl_entry;
163469a3e539SJoel Becker struct ocfs2_xattr_header *xh = loc->xl_header;
163511179f2cSJoel Becker int count = le16_to_cpu(xh->xh_count);
163611179f2cSJoel Becker
163711179f2cSJoel Becker namevalue_offset = le16_to_cpu(entry->xe_name_offset);
163811179f2cSJoel Becker namevalue_size = namevalue_size_xe(entry);
163911179f2cSJoel Becker first_namevalue_offset = ocfs2_xa_get_free_start(loc);
164011179f2cSJoel Becker
164111179f2cSJoel Becker /* Shift the name+value pairs */
164211179f2cSJoel Becker memmove((char *)xh + first_namevalue_offset + namevalue_size,
164311179f2cSJoel Becker (char *)xh + first_namevalue_offset,
164411179f2cSJoel Becker namevalue_offset - first_namevalue_offset);
1645dfe4d3d6STao Ma memset((char *)xh + first_namevalue_offset, 0, namevalue_size);
164611179f2cSJoel Becker
164711179f2cSJoel Becker /* Now tell xh->xh_entries about it */
164811179f2cSJoel Becker for (i = 0; i < count; i++) {
164911179f2cSJoel Becker offset = le16_to_cpu(xh->xh_entries[i].xe_name_offset);
165011179f2cSJoel Becker if (offset <= namevalue_offset)
165111179f2cSJoel Becker le16_add_cpu(&xh->xh_entries[i].xe_name_offset,
165211179f2cSJoel Becker namevalue_size);
165311179f2cSJoel Becker }
165411179f2cSJoel Becker
165511179f2cSJoel Becker /*
165669a3e539SJoel Becker * Note that we don't update xh_free_start or xh_name_value_len
165769a3e539SJoel Becker * because they're not used in block-stored xattrs.
165869a3e539SJoel Becker */
165969a3e539SJoel Becker }
166069a3e539SJoel Becker
ocfs2_xa_block_add_entry(struct ocfs2_xa_loc * loc,u32 name_hash)166169a3e539SJoel Becker static void ocfs2_xa_block_add_entry(struct ocfs2_xa_loc *loc, u32 name_hash)
166269a3e539SJoel Becker {
166369a3e539SJoel Becker int count = le16_to_cpu(loc->xl_header->xh_count);
166469a3e539SJoel Becker loc->xl_entry = &(loc->xl_header->xh_entries[count]);
166569a3e539SJoel Becker le16_add_cpu(&loc->xl_header->xh_count, 1);
166669a3e539SJoel Becker memset(loc->xl_entry, 0, sizeof(struct ocfs2_xattr_entry));
166769a3e539SJoel Becker }
166869a3e539SJoel Becker
ocfs2_xa_block_add_namevalue(struct ocfs2_xa_loc * loc,int size)166969a3e539SJoel Becker static void ocfs2_xa_block_add_namevalue(struct ocfs2_xa_loc *loc, int size)
167069a3e539SJoel Becker {
16713fc12afaSJoel Becker int free_start = ocfs2_xa_get_free_start(loc);
16723fc12afaSJoel Becker
16733fc12afaSJoel Becker loc->xl_entry->xe_name_offset = cpu_to_le16(free_start - size);
16743fc12afaSJoel Becker }
16753fc12afaSJoel Becker
ocfs2_xa_block_fill_value_buf(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_value_buf * vb)16763fc12afaSJoel Becker static void ocfs2_xa_block_fill_value_buf(struct ocfs2_xa_loc *loc,
16773fc12afaSJoel Becker struct ocfs2_xattr_value_buf *vb)
16783fc12afaSJoel Becker {
16793fc12afaSJoel Becker struct buffer_head *bh = loc->xl_storage;
16803fc12afaSJoel Becker
16813fc12afaSJoel Becker if (loc->xl_size == (bh->b_size -
16823fc12afaSJoel Becker offsetof(struct ocfs2_xattr_block,
16833fc12afaSJoel Becker xb_attrs.xb_header)))
16843fc12afaSJoel Becker vb->vb_access = ocfs2_journal_access_xb;
168511179f2cSJoel Becker else
168611179f2cSJoel Becker vb->vb_access = ocfs2_journal_access_di;
168711179f2cSJoel Becker vb->vb_bh = bh;
168811179f2cSJoel Becker }
168911179f2cSJoel Becker
1690cf2bc809SJoel Becker /*
1691cf2bc809SJoel Becker * Operations for xattrs stored in blocks. This includes inline inode
169211179f2cSJoel Becker * storage and unindexed ocfs2_xattr_blocks.
169369a3e539SJoel Becker */
169469a3e539SJoel Becker static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = {
169569a3e539SJoel Becker .xlo_journal_access = ocfs2_xa_block_journal_access,
169611179f2cSJoel Becker .xlo_journal_dirty = ocfs2_xa_block_journal_dirty,
169769a3e539SJoel Becker .xlo_offset_pointer = ocfs2_xa_block_offset_pointer,
169869a3e539SJoel Becker .xlo_check_space = ocfs2_xa_block_check_space,
16993fc12afaSJoel Becker .xlo_can_reuse = ocfs2_xa_block_can_reuse,
170011179f2cSJoel Becker .xlo_get_free_start = ocfs2_xa_block_get_free_start,
170111179f2cSJoel Becker .xlo_wipe_namevalue = ocfs2_xa_block_wipe_namevalue,
1702cf2bc809SJoel Becker .xlo_add_entry = ocfs2_xa_block_add_entry,
1703cf2bc809SJoel Becker .xlo_add_namevalue = ocfs2_xa_block_add_namevalue,
1704cf2bc809SJoel Becker .xlo_fill_value_buf = ocfs2_xa_block_fill_value_buf,
1705cf2bc809SJoel Becker };
1706cf2bc809SJoel Becker
ocfs2_xa_bucket_journal_access(handle_t * handle,struct ocfs2_xa_loc * loc,int type)1707cf2bc809SJoel Becker static int ocfs2_xa_bucket_journal_access(handle_t *handle,
1708cf2bc809SJoel Becker struct ocfs2_xa_loc *loc, int type)
1709cf2bc809SJoel Becker {
1710cf2bc809SJoel Becker struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
1711cf2bc809SJoel Becker
1712cf2bc809SJoel Becker return ocfs2_xattr_bucket_journal_access(handle, bucket, type);
1713cf2bc809SJoel Becker }
1714cf2bc809SJoel Becker
ocfs2_xa_bucket_journal_dirty(handle_t * handle,struct ocfs2_xa_loc * loc)1715cf2bc809SJoel Becker static void ocfs2_xa_bucket_journal_dirty(handle_t *handle,
1716cf2bc809SJoel Becker struct ocfs2_xa_loc *loc)
1717cf2bc809SJoel Becker {
171811179f2cSJoel Becker struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
171911179f2cSJoel Becker
172011179f2cSJoel Becker ocfs2_xattr_bucket_journal_dirty(handle, bucket);
172111179f2cSJoel Becker }
172211179f2cSJoel Becker
ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc * loc,int offset)172311179f2cSJoel Becker static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc,
172411179f2cSJoel Becker int offset)
1725cf2bc809SJoel Becker {
1726cf2bc809SJoel Becker struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
172711179f2cSJoel Becker int block, block_offset;
172811179f2cSJoel Becker
172911179f2cSJoel Becker /* The header is at the front of the bucket */
173011179f2cSJoel Becker block = offset >> loc->xl_inode->i_sb->s_blocksize_bits;
173169a3e539SJoel Becker block_offset = offset % loc->xl_inode->i_sb->s_blocksize;
173269a3e539SJoel Becker
173369a3e539SJoel Becker return bucket_block(bucket, block) + block_offset;
173469a3e539SJoel Becker }
173569a3e539SJoel Becker
ocfs2_xa_bucket_can_reuse(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)173669a3e539SJoel Becker static int ocfs2_xa_bucket_can_reuse(struct ocfs2_xa_loc *loc,
173769a3e539SJoel Becker struct ocfs2_xattr_info *xi)
173869a3e539SJoel Becker {
173969a3e539SJoel Becker return namevalue_size_xe(loc->xl_entry) >=
174069a3e539SJoel Becker namevalue_size_xi(xi);
174169a3e539SJoel Becker }
174269a3e539SJoel Becker
ocfs2_xa_bucket_get_free_start(struct ocfs2_xa_loc * loc)174369a3e539SJoel Becker static int ocfs2_xa_bucket_get_free_start(struct ocfs2_xa_loc *loc)
174469a3e539SJoel Becker {
174569a3e539SJoel Becker struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
174669a3e539SJoel Becker return le16_to_cpu(bucket_xh(bucket)->xh_free_start);
174769a3e539SJoel Becker }
174869a3e539SJoel Becker
ocfs2_bucket_align_free_start(struct super_block * sb,int free_start,int size)174969a3e539SJoel Becker static int ocfs2_bucket_align_free_start(struct super_block *sb,
175069a3e539SJoel Becker int free_start, int size)
175169a3e539SJoel Becker {
175269a3e539SJoel Becker /*
175369a3e539SJoel Becker * We need to make sure that the name+value pair fits within
175469a3e539SJoel Becker * one block.
175569a3e539SJoel Becker */
175669a3e539SJoel Becker if (((free_start - size) >> sb->s_blocksize_bits) !=
175769a3e539SJoel Becker ((free_start - 1) >> sb->s_blocksize_bits))
175869a3e539SJoel Becker free_start -= free_start % sb->s_blocksize;
175969a3e539SJoel Becker
176069a3e539SJoel Becker return free_start;
176169a3e539SJoel Becker }
176269a3e539SJoel Becker
ocfs2_xa_bucket_check_space(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi)176369a3e539SJoel Becker static int ocfs2_xa_bucket_check_space(struct ocfs2_xa_loc *loc,
176469a3e539SJoel Becker struct ocfs2_xattr_info *xi)
176569a3e539SJoel Becker {
1766cf2bc809SJoel Becker int rc;
176769a3e539SJoel Becker int count = le16_to_cpu(loc->xl_header->xh_count);
176869a3e539SJoel Becker int free_start = ocfs2_xa_get_free_start(loc);
176969a3e539SJoel Becker int needed_space = ocfs2_xi_entry_usage(xi);
177069a3e539SJoel Becker int size = namevalue_size_xi(xi);
177169a3e539SJoel Becker struct super_block *sb = loc->xl_inode->i_sb;
177269a3e539SJoel Becker
177369a3e539SJoel Becker /*
177469a3e539SJoel Becker * Bucket storage does not reclaim name+value pairs it cannot
177569a3e539SJoel Becker * reuse. They live as holes until the bucket fills, and then
177669a3e539SJoel Becker * the bucket is defragmented. However, the bucket can reclaim
177769a3e539SJoel Becker * the ocfs2_xattr_entry.
177869a3e539SJoel Becker */
177969a3e539SJoel Becker if (loc->xl_entry) {
178069a3e539SJoel Becker /* Don't need space if we're reusing! */
178169a3e539SJoel Becker if (ocfs2_xa_can_reuse_entry(loc, xi))
178269a3e539SJoel Becker needed_space = 0;
178369a3e539SJoel Becker else
178469a3e539SJoel Becker needed_space -= sizeof(struct ocfs2_xattr_entry);
178569a3e539SJoel Becker }
178669a3e539SJoel Becker BUG_ON(needed_space < 0);
178769a3e539SJoel Becker
178869a3e539SJoel Becker if (free_start < size) {
178969a3e539SJoel Becker if (needed_space)
179069a3e539SJoel Becker return -ENOSPC;
179169a3e539SJoel Becker } else {
179269a3e539SJoel Becker /*
179369a3e539SJoel Becker * First we check if it would fit in the first place.
179469a3e539SJoel Becker * Below, we align the free start to a block. This may
179569a3e539SJoel Becker * slide us below the minimum gap. By checking unaligned
179669a3e539SJoel Becker * first, we avoid that error.
179769a3e539SJoel Becker */
179869a3e539SJoel Becker rc = ocfs2_xa_check_space_helper(needed_space, free_start,
179969a3e539SJoel Becker count);
180069a3e539SJoel Becker if (rc)
180169a3e539SJoel Becker return rc;
180269a3e539SJoel Becker free_start = ocfs2_bucket_align_free_start(sb, free_start,
180311179f2cSJoel Becker size);
180411179f2cSJoel Becker }
1805199799a3SJoel Becker return ocfs2_xa_check_space_helper(needed_space, free_start, count);
1806199799a3SJoel Becker }
180711179f2cSJoel Becker
ocfs2_xa_bucket_wipe_namevalue(struct ocfs2_xa_loc * loc)180811179f2cSJoel Becker static void ocfs2_xa_bucket_wipe_namevalue(struct ocfs2_xa_loc *loc)
180969a3e539SJoel Becker {
181069a3e539SJoel Becker le16_add_cpu(&loc->xl_header->xh_name_value_len,
181169a3e539SJoel Becker -namevalue_size_xe(loc->xl_entry));
181269a3e539SJoel Becker }
181369a3e539SJoel Becker
ocfs2_xa_bucket_add_entry(struct ocfs2_xa_loc * loc,u32 name_hash)181469a3e539SJoel Becker static void ocfs2_xa_bucket_add_entry(struct ocfs2_xa_loc *loc, u32 name_hash)
181569a3e539SJoel Becker {
181669a3e539SJoel Becker struct ocfs2_xattr_header *xh = loc->xl_header;
181769a3e539SJoel Becker int count = le16_to_cpu(xh->xh_count);
181869a3e539SJoel Becker int low = 0, high = count - 1, tmp;
181969a3e539SJoel Becker struct ocfs2_xattr_entry *tmp_xe;
182069a3e539SJoel Becker
182169a3e539SJoel Becker /*
182269a3e539SJoel Becker * We keep buckets sorted by name_hash, so we need to find
182369a3e539SJoel Becker * our insert place.
182469a3e539SJoel Becker */
182569a3e539SJoel Becker while (low <= high && count) {
182669a3e539SJoel Becker tmp = (low + high) / 2;
182769a3e539SJoel Becker tmp_xe = &xh->xh_entries[tmp];
182869a3e539SJoel Becker
182969a3e539SJoel Becker if (name_hash > le32_to_cpu(tmp_xe->xe_name_hash))
183069a3e539SJoel Becker low = tmp + 1;
183169a3e539SJoel Becker else if (name_hash < le32_to_cpu(tmp_xe->xe_name_hash))
183269a3e539SJoel Becker high = tmp - 1;
183369a3e539SJoel Becker else {
183469a3e539SJoel Becker low = tmp;
183569a3e539SJoel Becker break;
183669a3e539SJoel Becker }
183769a3e539SJoel Becker }
183869a3e539SJoel Becker
183969a3e539SJoel Becker if (low != count)
184069a3e539SJoel Becker memmove(&xh->xh_entries[low + 1],
184169a3e539SJoel Becker &xh->xh_entries[low],
184269a3e539SJoel Becker ((count - low) * sizeof(struct ocfs2_xattr_entry)));
184369a3e539SJoel Becker
184469a3e539SJoel Becker le16_add_cpu(&xh->xh_count, 1);
184569a3e539SJoel Becker loc->xl_entry = &xh->xh_entries[low];
184669a3e539SJoel Becker memset(loc->xl_entry, 0, sizeof(struct ocfs2_xattr_entry));
184769a3e539SJoel Becker }
1848cf2bc809SJoel Becker
ocfs2_xa_bucket_add_namevalue(struct ocfs2_xa_loc * loc,int size)184969a3e539SJoel Becker static void ocfs2_xa_bucket_add_namevalue(struct ocfs2_xa_loc *loc, int size)
185069a3e539SJoel Becker {
185169a3e539SJoel Becker int free_start = ocfs2_xa_get_free_start(loc);
185269a3e539SJoel Becker struct ocfs2_xattr_header *xh = loc->xl_header;
185369a3e539SJoel Becker struct super_block *sb = loc->xl_inode->i_sb;
185469a3e539SJoel Becker int nameval_offset;
185569a3e539SJoel Becker
185669a3e539SJoel Becker free_start = ocfs2_bucket_align_free_start(sb, free_start, size);
185769a3e539SJoel Becker nameval_offset = free_start - size;
185869a3e539SJoel Becker loc->xl_entry->xe_name_offset = cpu_to_le16(nameval_offset);
18593fc12afaSJoel Becker xh->xh_free_start = cpu_to_le16(nameval_offset);
18603fc12afaSJoel Becker le16_add_cpu(&xh->xh_name_value_len, size);
18613fc12afaSJoel Becker
18623fc12afaSJoel Becker }
1863cf2bc809SJoel Becker
ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_value_buf * vb)18643fc12afaSJoel Becker static void ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc *loc,
18653fc12afaSJoel Becker struct ocfs2_xattr_value_buf *vb)
18663fc12afaSJoel Becker {
18673fc12afaSJoel Becker struct ocfs2_xattr_bucket *bucket = loc->xl_storage;
18683fc12afaSJoel Becker struct super_block *sb = loc->xl_inode->i_sb;
18693fc12afaSJoel Becker int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
18703fc12afaSJoel Becker int size = namevalue_size_xe(loc->xl_entry);
18713fc12afaSJoel Becker int block_offset = nameval_offset >> sb->s_blocksize_bits;
18723fc12afaSJoel Becker
18733fc12afaSJoel Becker /* Values are not allowed to straddle block boundaries */
18743fc12afaSJoel Becker BUG_ON(block_offset !=
18753fc12afaSJoel Becker ((nameval_offset + size - 1) >> sb->s_blocksize_bits));
18763fc12afaSJoel Becker /* We expect the bucket to be filled in */
18773fc12afaSJoel Becker BUG_ON(!bucket->bu_bhs[block_offset]);
187811179f2cSJoel Becker
187911179f2cSJoel Becker vb->vb_access = ocfs2_journal_access;
1880cf2bc809SJoel Becker vb->vb_bh = bucket->bu_bhs[block_offset];
1881cf2bc809SJoel Becker }
188211179f2cSJoel Becker
188369a3e539SJoel Becker /* Operations for xattrs stored in buckets. */
188469a3e539SJoel Becker static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = {
188569a3e539SJoel Becker .xlo_journal_access = ocfs2_xa_bucket_journal_access,
188611179f2cSJoel Becker .xlo_journal_dirty = ocfs2_xa_bucket_journal_dirty,
188769a3e539SJoel Becker .xlo_offset_pointer = ocfs2_xa_bucket_offset_pointer,
188869a3e539SJoel Becker .xlo_check_space = ocfs2_xa_bucket_check_space,
18893fc12afaSJoel Becker .xlo_can_reuse = ocfs2_xa_bucket_can_reuse,
189011179f2cSJoel Becker .xlo_get_free_start = ocfs2_xa_bucket_get_free_start,
189111179f2cSJoel Becker .xlo_wipe_namevalue = ocfs2_xa_bucket_wipe_namevalue,
1892399ff3a7SJoel Becker .xlo_add_entry = ocfs2_xa_bucket_add_entry,
1893399ff3a7SJoel Becker .xlo_add_namevalue = ocfs2_xa_bucket_add_namevalue,
1894399ff3a7SJoel Becker .xlo_fill_value_buf = ocfs2_xa_bucket_fill_value_buf,
1895399ff3a7SJoel Becker };
1896399ff3a7SJoel Becker
ocfs2_xa_value_clusters(struct ocfs2_xa_loc * loc)1897399ff3a7SJoel Becker static unsigned int ocfs2_xa_value_clusters(struct ocfs2_xa_loc *loc)
1898399ff3a7SJoel Becker {
1899399ff3a7SJoel Becker struct ocfs2_xattr_value_buf vb;
1900399ff3a7SJoel Becker
1901399ff3a7SJoel Becker if (ocfs2_xattr_is_local(loc->xl_entry))
1902399ff3a7SJoel Becker return 0;
190373857ee0SJoel Becker
190473857ee0SJoel Becker ocfs2_xa_fill_value_buf(loc, &vb);
190573857ee0SJoel Becker return le32_to_cpu(vb.vb_xv->xr_clusters);
190673857ee0SJoel Becker }
190773857ee0SJoel Becker
ocfs2_xa_value_truncate(struct ocfs2_xa_loc * loc,u64 bytes,struct ocfs2_xattr_set_ctxt * ctxt)190873857ee0SJoel Becker static int ocfs2_xa_value_truncate(struct ocfs2_xa_loc *loc, u64 bytes,
190973857ee0SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
191073857ee0SJoel Becker {
191173857ee0SJoel Becker int trunc_rc, access_rc;
191273857ee0SJoel Becker struct ocfs2_xattr_value_buf vb;
191373857ee0SJoel Becker
191473857ee0SJoel Becker ocfs2_xa_fill_value_buf(loc, &vb);
191573857ee0SJoel Becker trunc_rc = ocfs2_xattr_value_truncate(loc->xl_inode, &vb, bytes,
191673857ee0SJoel Becker ctxt);
191773857ee0SJoel Becker
191873857ee0SJoel Becker /*
191973857ee0SJoel Becker * The caller of ocfs2_xa_value_truncate() has already called
192073857ee0SJoel Becker * ocfs2_xa_journal_access on the loc. However, The truncate code
192173857ee0SJoel Becker * calls ocfs2_extend_trans(). This may commit the previous
192273857ee0SJoel Becker * transaction and open a new one. If this is a bucket, truncate
192373857ee0SJoel Becker * could leave only vb->vb_bh set up for journaling. Meanwhile,
192473857ee0SJoel Becker * the caller is expecting to dirty the entire bucket. So we must
192573857ee0SJoel Becker * reset the journal work. We do this even if truncate has failed,
192673857ee0SJoel Becker * as it could have failed after committing the extend.
192773857ee0SJoel Becker */
192873857ee0SJoel Becker access_rc = ocfs2_xa_journal_access(ctxt->handle, loc,
192973857ee0SJoel Becker OCFS2_JOURNAL_ACCESS_WRITE);
193011179f2cSJoel Becker
193111179f2cSJoel Becker /* Errors in truncate take precedence */
1932bde1e540SJoel Becker return trunc_rc ? trunc_rc : access_rc;
1933bde1e540SJoel Becker }
1934bde1e540SJoel Becker
ocfs2_xa_remove_entry(struct ocfs2_xa_loc * loc)1935bde1e540SJoel Becker static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
193611179f2cSJoel Becker {
1937bde1e540SJoel Becker int index, count;
1938bde1e540SJoel Becker struct ocfs2_xattr_header *xh = loc->xl_header;
1939bde1e540SJoel Becker struct ocfs2_xattr_entry *entry = loc->xl_entry;
1940bde1e540SJoel Becker
1941bde1e540SJoel Becker ocfs2_xa_wipe_namevalue(loc);
1942bde1e540SJoel Becker loc->xl_entry = NULL;
1943bde1e540SJoel Becker
1944bde1e540SJoel Becker le16_add_cpu(&xh->xh_count, -1);
1945bde1e540SJoel Becker count = le16_to_cpu(xh->xh_count);
1946bde1e540SJoel Becker
1947bde1e540SJoel Becker /*
1948bde1e540SJoel Becker * Only zero out the entry if there are more remaining. This is
1949bde1e540SJoel Becker * important for an empty bucket, as it keeps track of the
1950bde1e540SJoel Becker * bucket's hash value. It doesn't hurt empty block storage.
1951bde1e540SJoel Becker */
1952bde1e540SJoel Becker if (count) {
1953bde1e540SJoel Becker index = ((char *)entry - (char *)&xh->xh_entries) /
1954bde1e540SJoel Becker sizeof(struct ocfs2_xattr_entry);
195511179f2cSJoel Becker memmove(&xh->xh_entries[index], &xh->xh_entries[index + 1],
195611179f2cSJoel Becker (count - index) * sizeof(struct ocfs2_xattr_entry));
1957399ff3a7SJoel Becker memset(&xh->xh_entries[count], 0,
1958399ff3a7SJoel Becker sizeof(struct ocfs2_xattr_entry));
1959399ff3a7SJoel Becker }
1960399ff3a7SJoel Becker }
1961399ff3a7SJoel Becker
1962399ff3a7SJoel Becker /*
1963399ff3a7SJoel Becker * If we have a problem adjusting the size of an external value during
1964399ff3a7SJoel Becker * ocfs2_xa_prepare_entry() or ocfs2_xa_remove(), we may have an xattr
1965399ff3a7SJoel Becker * in an intermediate state. For example, the value may be partially
1966399ff3a7SJoel Becker * truncated.
1967399ff3a7SJoel Becker *
1968399ff3a7SJoel Becker * If the value tree hasn't changed, the extend/truncate went nowhere.
1969399ff3a7SJoel Becker * We have nothing to do. The caller can treat it as a straight error.
1970399ff3a7SJoel Becker *
1971399ff3a7SJoel Becker * If the value tree got partially truncated, we now have a corrupted
1972399ff3a7SJoel Becker * extended attribute. We're going to wipe its entry and leak the
1973399ff3a7SJoel Becker * clusters. Better to leak some storage than leave a corrupt entry.
1974399ff3a7SJoel Becker *
1975399ff3a7SJoel Becker * If the value tree grew, it obviously didn't grow enough for the
1976399ff3a7SJoel Becker * new entry. We're not going to try and reclaim those clusters either.
1977399ff3a7SJoel Becker * If there was already an external value there (orig_clusters != 0),
1978399ff3a7SJoel Becker * the new clusters are attached safely and we can just leave the old
1979399ff3a7SJoel Becker * value in place. If there was no external value there, we remove
1980399ff3a7SJoel Becker * the entry.
1981399ff3a7SJoel Becker *
1982399ff3a7SJoel Becker * This way, the xattr block we store in the journal will be consistent.
1983399ff3a7SJoel Becker * If the size change broke because of the journal, no changes will hit
1984399ff3a7SJoel Becker * disk anyway.
1985399ff3a7SJoel Becker */
ocfs2_xa_cleanup_value_truncate(struct ocfs2_xa_loc * loc,const char * what,unsigned int orig_clusters)1986399ff3a7SJoel Becker static void ocfs2_xa_cleanup_value_truncate(struct ocfs2_xa_loc *loc,
1987399ff3a7SJoel Becker const char *what,
1988399ff3a7SJoel Becker unsigned int orig_clusters)
1989399ff3a7SJoel Becker {
1990399ff3a7SJoel Becker unsigned int new_clusters = ocfs2_xa_value_clusters(loc);
1991399ff3a7SJoel Becker char *nameval_buf = ocfs2_xa_offset_pointer(loc,
1992399ff3a7SJoel Becker le16_to_cpu(loc->xl_entry->xe_name_offset));
1993399ff3a7SJoel Becker
1994399ff3a7SJoel Becker if (new_clusters < orig_clusters) {
1995399ff3a7SJoel Becker mlog(ML_ERROR,
1996399ff3a7SJoel Becker "Partial truncate while %s xattr %.*s. Leaking "
1997399ff3a7SJoel Becker "%u clusters and removing the entry\n",
1998399ff3a7SJoel Becker what, loc->xl_entry->xe_name_len, nameval_buf,
1999399ff3a7SJoel Becker orig_clusters - new_clusters);
2000399ff3a7SJoel Becker ocfs2_xa_remove_entry(loc);
2001399ff3a7SJoel Becker } else if (!orig_clusters) {
2002399ff3a7SJoel Becker mlog(ML_ERROR,
2003399ff3a7SJoel Becker "Unable to allocate an external value for xattr "
2004399ff3a7SJoel Becker "%.*s safely. Leaking %u clusters and removing the "
2005399ff3a7SJoel Becker "entry\n",
2006399ff3a7SJoel Becker loc->xl_entry->xe_name_len, nameval_buf,
2007399ff3a7SJoel Becker new_clusters - orig_clusters);
2008399ff3a7SJoel Becker ocfs2_xa_remove_entry(loc);
2009399ff3a7SJoel Becker } else if (new_clusters > orig_clusters)
2010399ff3a7SJoel Becker mlog(ML_ERROR,
2011399ff3a7SJoel Becker "Unable to grow xattr %.*s safely. %u new clusters "
2012399ff3a7SJoel Becker "have been added, but the value will not be "
201373857ee0SJoel Becker "modified\n",
201473857ee0SJoel Becker loc->xl_entry->xe_name_len, nameval_buf,
201573857ee0SJoel Becker new_clusters - orig_clusters);
201673857ee0SJoel Becker }
2017399ff3a7SJoel Becker
ocfs2_xa_remove(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_set_ctxt * ctxt)201873857ee0SJoel Becker static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc,
201973857ee0SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
2020399ff3a7SJoel Becker {
202173857ee0SJoel Becker int rc = 0;
202273857ee0SJoel Becker unsigned int orig_clusters;
202373857ee0SJoel Becker
2024399ff3a7SJoel Becker if (!ocfs2_xattr_is_local(loc->xl_entry)) {
2025399ff3a7SJoel Becker orig_clusters = ocfs2_xa_value_clusters(loc);
2026399ff3a7SJoel Becker rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
2027399ff3a7SJoel Becker if (rc) {
2028399ff3a7SJoel Becker mlog_errno(rc);
2029399ff3a7SJoel Becker /*
2030399ff3a7SJoel Becker * Since this is remove, we can return 0 if
2031399ff3a7SJoel Becker * ocfs2_xa_cleanup_value_truncate() is going to
2032399ff3a7SJoel Becker * wipe the entry anyway. So we check the
2033399ff3a7SJoel Becker * cluster count as well.
2034399ff3a7SJoel Becker */
203573857ee0SJoel Becker if (orig_clusters != ocfs2_xa_value_clusters(loc))
203673857ee0SJoel Becker rc = 0;
203773857ee0SJoel Becker ocfs2_xa_cleanup_value_truncate(loc, "removing",
203873857ee0SJoel Becker orig_clusters);
203973857ee0SJoel Becker goto out;
204073857ee0SJoel Becker }
204173857ee0SJoel Becker }
204273857ee0SJoel Becker
204373857ee0SJoel Becker ocfs2_xa_remove_entry(loc);
204473857ee0SJoel Becker
204573857ee0SJoel Becker out:
204673857ee0SJoel Becker return rc;
204773857ee0SJoel Becker }
204873857ee0SJoel Becker
ocfs2_xa_install_value_root(struct ocfs2_xa_loc * loc)204973857ee0SJoel Becker static void ocfs2_xa_install_value_root(struct ocfs2_xa_loc *loc)
205073857ee0SJoel Becker {
205173857ee0SJoel Becker int name_size = OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len);
205273857ee0SJoel Becker char *nameval_buf;
205373857ee0SJoel Becker
205473857ee0SJoel Becker nameval_buf = ocfs2_xa_offset_pointer(loc,
205573857ee0SJoel Becker le16_to_cpu(loc->xl_entry->xe_name_offset));
205673857ee0SJoel Becker memcpy(nameval_buf + name_size, &def_xv, OCFS2_XATTR_ROOT_SIZE);
205773857ee0SJoel Becker }
205873857ee0SJoel Becker
205973857ee0SJoel Becker /*
206073857ee0SJoel Becker * Take an existing entry and make it ready for the new value. This
206173857ee0SJoel Becker * won't allocate space, but it may free space. It should be ready for
206273857ee0SJoel Becker * ocfs2_xa_prepare_entry() to finish the work.
206373857ee0SJoel Becker */
ocfs2_xa_reuse_entry(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_set_ctxt * ctxt)206473857ee0SJoel Becker static int ocfs2_xa_reuse_entry(struct ocfs2_xa_loc *loc,
206573857ee0SJoel Becker struct ocfs2_xattr_info *xi,
2066399ff3a7SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
206773857ee0SJoel Becker {
206873857ee0SJoel Becker int rc = 0;
206973857ee0SJoel Becker int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
207073857ee0SJoel Becker unsigned int orig_clusters;
207173857ee0SJoel Becker char *nameval_buf;
207273857ee0SJoel Becker int xe_local = ocfs2_xattr_is_local(loc->xl_entry);
207373857ee0SJoel Becker int xi_local = xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE;
207473857ee0SJoel Becker
207573857ee0SJoel Becker BUG_ON(OCFS2_XATTR_SIZE(loc->xl_entry->xe_name_len) !=
207673857ee0SJoel Becker name_size);
207773857ee0SJoel Becker
207873857ee0SJoel Becker nameval_buf = ocfs2_xa_offset_pointer(loc,
207973857ee0SJoel Becker le16_to_cpu(loc->xl_entry->xe_name_offset));
208073857ee0SJoel Becker if (xe_local) {
208173857ee0SJoel Becker memset(nameval_buf + name_size, 0,
2082399ff3a7SJoel Becker namevalue_size_xe(loc->xl_entry) - name_size);
208373857ee0SJoel Becker if (!xi_local)
208473857ee0SJoel Becker ocfs2_xa_install_value_root(loc);
2085399ff3a7SJoel Becker } else {
208673857ee0SJoel Becker orig_clusters = ocfs2_xa_value_clusters(loc);
2087399ff3a7SJoel Becker if (xi_local) {
208873857ee0SJoel Becker rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
208973857ee0SJoel Becker if (rc < 0)
209073857ee0SJoel Becker mlog_errno(rc);
209173857ee0SJoel Becker else
209273857ee0SJoel Becker memset(nameval_buf + name_size, 0,
209373857ee0SJoel Becker namevalue_size_xe(loc->xl_entry) -
209473857ee0SJoel Becker name_size);
2095399ff3a7SJoel Becker } else if (le64_to_cpu(loc->xl_entry->xe_value_size) >
209673857ee0SJoel Becker xi->xi_value_len) {
209773857ee0SJoel Becker rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len,
2098399ff3a7SJoel Becker ctxt);
2099399ff3a7SJoel Becker if (rc < 0)
2100399ff3a7SJoel Becker mlog_errno(rc);
2101399ff3a7SJoel Becker }
2102399ff3a7SJoel Becker
210373857ee0SJoel Becker if (rc) {
210473857ee0SJoel Becker ocfs2_xa_cleanup_value_truncate(loc, "reusing",
210573857ee0SJoel Becker orig_clusters);
210673857ee0SJoel Becker goto out;
210773857ee0SJoel Becker }
210873857ee0SJoel Becker }
210973857ee0SJoel Becker
211073857ee0SJoel Becker loc->xl_entry->xe_value_size = cpu_to_le64(xi->xi_value_len);
211173857ee0SJoel Becker ocfs2_xattr_set_local(loc->xl_entry, xi_local);
211273857ee0SJoel Becker
211369a3e539SJoel Becker out:
211469a3e539SJoel Becker return rc;
211569a3e539SJoel Becker }
211669a3e539SJoel Becker
211769a3e539SJoel Becker /*
211869a3e539SJoel Becker * Prepares loc->xl_entry to receive the new xattr. This includes
211969a3e539SJoel Becker * properly setting up the name+value pair region. If loc->xl_entry
212069a3e539SJoel Becker * already exists, it will take care of modifying it appropriately.
212169a3e539SJoel Becker *
212269a3e539SJoel Becker * Note that this modifies the data. You did journal_access already,
212373857ee0SJoel Becker * right?
212473857ee0SJoel Becker */
ocfs2_xa_prepare_entry(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi,u32 name_hash,struct ocfs2_xattr_set_ctxt * ctxt)212569a3e539SJoel Becker static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
212669a3e539SJoel Becker struct ocfs2_xattr_info *xi,
2127399ff3a7SJoel Becker u32 name_hash,
2128399ff3a7SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
212969a3e539SJoel Becker {
213069a3e539SJoel Becker int rc = 0;
213169a3e539SJoel Becker unsigned int orig_clusters;
213269a3e539SJoel Becker __le64 orig_value_size = 0;
213369a3e539SJoel Becker
213494b07b6fSJoseph Qi rc = ocfs2_xa_check_space(loc, xi);
213569a3e539SJoel Becker if (rc)
2136399ff3a7SJoel Becker goto out;
213773857ee0SJoel Becker
213873857ee0SJoel Becker if (loc->xl_entry) {
213969a3e539SJoel Becker if (ocfs2_xa_can_reuse_entry(loc, xi)) {
214073857ee0SJoel Becker orig_value_size = loc->xl_entry->xe_value_size;
214169a3e539SJoel Becker rc = ocfs2_xa_reuse_entry(loc, xi, ctxt);
214269a3e539SJoel Becker if (rc)
214373857ee0SJoel Becker goto out;
2144399ff3a7SJoel Becker goto alloc_value;
214573857ee0SJoel Becker }
214673857ee0SJoel Becker
214773857ee0SJoel Becker if (!ocfs2_xattr_is_local(loc->xl_entry)) {
2148399ff3a7SJoel Becker orig_clusters = ocfs2_xa_value_clusters(loc);
2149399ff3a7SJoel Becker rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
2150399ff3a7SJoel Becker if (rc) {
215173857ee0SJoel Becker mlog_errno(rc);
215273857ee0SJoel Becker ocfs2_xa_cleanup_value_truncate(loc,
215373857ee0SJoel Becker "overwriting",
215469a3e539SJoel Becker orig_clusters);
215594b07b6fSJoseph Qi goto out;
215694b07b6fSJoseph Qi }
215769a3e539SJoel Becker }
215869a3e539SJoel Becker ocfs2_xa_wipe_namevalue(loc);
215969a3e539SJoel Becker } else
216069a3e539SJoel Becker ocfs2_xa_add_entry(loc, name_hash);
216169a3e539SJoel Becker
216269a3e539SJoel Becker /*
216373857ee0SJoel Becker * If we get here, we have a blank entry. Fill it. We grow our
216473857ee0SJoel Becker * name+value pair back from the end.
216573857ee0SJoel Becker */
216673857ee0SJoel Becker ocfs2_xa_add_namevalue(loc, xi);
216773857ee0SJoel Becker if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE)
2168399ff3a7SJoel Becker ocfs2_xa_install_value_root(loc);
216973857ee0SJoel Becker
2170399ff3a7SJoel Becker alloc_value:
21715f5261acSTao Ma if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2172399ff3a7SJoel Becker orig_clusters = ocfs2_xa_value_clusters(loc);
2173399ff3a7SJoel Becker rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len, ctxt);
2174d5a7df06STao Ma if (rc < 0) {
2175d5a7df06STao Ma ctxt->set_abort = 1;
2176d5a7df06STao Ma ocfs2_xa_cleanup_value_truncate(loc, "growing",
2177d5a7df06STao Ma orig_clusters);
2178d5a7df06STao Ma /*
2179d5a7df06STao Ma * If we were growing an existing value,
2180d5a7df06STao Ma * ocfs2_xa_cleanup_value_truncate() won't remove
2181d5a7df06STao Ma * the entry. We need to restore the original value
2182d5a7df06STao Ma * size.
2183d5a7df06STao Ma */
218473857ee0SJoel Becker if (loc->xl_entry) {
218573857ee0SJoel Becker BUG_ON(!orig_value_size);
2186399ff3a7SJoel Becker loc->xl_entry->xe_value_size = orig_value_size;
218769a3e539SJoel Becker }
218869a3e539SJoel Becker mlog_errno(rc);
218969a3e539SJoel Becker }
219069a3e539SJoel Becker }
219169a3e539SJoel Becker
219269a3e539SJoel Becker out:
219373857ee0SJoel Becker return rc;
219473857ee0SJoel Becker }
219573857ee0SJoel Becker
219669a3e539SJoel Becker /*
219773857ee0SJoel Becker * Store the value portion of the name+value pair. This will skip
219873857ee0SJoel Becker * values that are stored externally. Their tree roots were set up
219973857ee0SJoel Becker * by ocfs2_xa_prepare_entry().
220069a3e539SJoel Becker */
ocfs2_xa_store_value(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_set_ctxt * ctxt)220173857ee0SJoel Becker static int ocfs2_xa_store_value(struct ocfs2_xa_loc *loc,
220269a3e539SJoel Becker struct ocfs2_xattr_info *xi,
220369a3e539SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
220469a3e539SJoel Becker {
220573857ee0SJoel Becker int rc = 0;
220669a3e539SJoel Becker int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset);
220769a3e539SJoel Becker int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
220873857ee0SJoel Becker char *nameval_buf;
220973857ee0SJoel Becker struct ocfs2_xattr_value_buf vb;
221073857ee0SJoel Becker
221173857ee0SJoel Becker nameval_buf = ocfs2_xa_offset_pointer(loc, nameval_offset);
221273857ee0SJoel Becker if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
221373857ee0SJoel Becker ocfs2_xa_fill_value_buf(loc, &vb);
221473857ee0SJoel Becker rc = __ocfs2_xattr_set_value_outside(loc->xl_inode,
221573857ee0SJoel Becker ctxt->handle, &vb,
221673857ee0SJoel Becker xi->xi_value,
221773857ee0SJoel Becker xi->xi_value_len);
221869a3e539SJoel Becker } else
221969a3e539SJoel Becker memcpy(nameval_buf + name_size, xi->xi_value, xi->xi_value_len);
2220bca5e9bdSJoel Becker
2221bca5e9bdSJoel Becker return rc;
2222bca5e9bdSJoel Becker }
2223bca5e9bdSJoel Becker
ocfs2_xa_set(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_set_ctxt * ctxt)2224bca5e9bdSJoel Becker static int ocfs2_xa_set(struct ocfs2_xa_loc *loc,
2225bca5e9bdSJoel Becker struct ocfs2_xattr_info *xi,
2226bca5e9bdSJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
2227bca5e9bdSJoel Becker {
2228bca5e9bdSJoel Becker int ret;
2229bca5e9bdSJoel Becker u32 name_hash = ocfs2_xattr_name_hash(loc->xl_inode, xi->xi_name,
2230bca5e9bdSJoel Becker xi->xi_name_len);
2231bca5e9bdSJoel Becker
2232bca5e9bdSJoel Becker ret = ocfs2_xa_journal_access(ctxt->handle, loc,
2233bca5e9bdSJoel Becker OCFS2_JOURNAL_ACCESS_WRITE);
2234bca5e9bdSJoel Becker if (ret) {
2235399ff3a7SJoel Becker mlog_errno(ret);
2236399ff3a7SJoel Becker goto out;
2237399ff3a7SJoel Becker }
2238399ff3a7SJoel Becker
2239399ff3a7SJoel Becker /*
2240399ff3a7SJoel Becker * From here on out, everything is going to modify the buffer a
2241bca5e9bdSJoel Becker * little. Errors are going to leave the xattr header in a
2242bca5e9bdSJoel Becker * sane state. Thus, even with errors we dirty the sucker.
2243bca5e9bdSJoel Becker */
2244399ff3a7SJoel Becker
2245bca5e9bdSJoel Becker /* Don't worry, we are never called with !xi_value and !xl_entry */
2246bca5e9bdSJoel Becker if (!xi->xi_value) {
2247bca5e9bdSJoel Becker ret = ocfs2_xa_remove(loc, ctxt);
2248bca5e9bdSJoel Becker goto out_dirty;
2249bca5e9bdSJoel Becker }
2250bca5e9bdSJoel Becker
2251399ff3a7SJoel Becker ret = ocfs2_xa_prepare_entry(loc, xi, name_hash, ctxt);
2252bca5e9bdSJoel Becker if (ret) {
2253bca5e9bdSJoel Becker if (ret != -ENOSPC)
2254bca5e9bdSJoel Becker mlog_errno(ret);
2255399ff3a7SJoel Becker goto out_dirty;
2256bca5e9bdSJoel Becker }
2257bca5e9bdSJoel Becker
2258399ff3a7SJoel Becker ret = ocfs2_xa_store_value(loc, xi, ctxt);
2259bca5e9bdSJoel Becker if (ret)
2260bca5e9bdSJoel Becker mlog_errno(ret);
2261bca5e9bdSJoel Becker
2262bca5e9bdSJoel Becker out_dirty:
2263bca5e9bdSJoel Becker ocfs2_xa_journal_dirty(ctxt->handle, loc);
2264bca5e9bdSJoel Becker
226511179f2cSJoel Becker out:
226611179f2cSJoel Becker return ret;
226711179f2cSJoel Becker }
226811179f2cSJoel Becker
ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc * loc,struct inode * inode,struct buffer_head * bh,struct ocfs2_xattr_entry * entry)226911179f2cSJoel Becker static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
227011179f2cSJoel Becker struct inode *inode,
227111179f2cSJoel Becker struct buffer_head *bh,
2272139ffaceSJoel Becker struct ocfs2_xattr_entry *entry)
2273139ffaceSJoel Becker {
2274cf2bc809SJoel Becker struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
227511179f2cSJoel Becker
227611179f2cSJoel Becker BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_XATTR_FL));
227711179f2cSJoel Becker
227811179f2cSJoel Becker loc->xl_inode = inode;
227911179f2cSJoel Becker loc->xl_ops = &ocfs2_xa_block_loc_ops;
228011179f2cSJoel Becker loc->xl_storage = bh;
228111179f2cSJoel Becker loc->xl_entry = entry;
228211179f2cSJoel Becker loc->xl_size = le16_to_cpu(di->i_xattr_inline_size);
228311179f2cSJoel Becker loc->xl_header =
228411179f2cSJoel Becker (struct ocfs2_xattr_header *)(bh->b_data + bh->b_size -
2285cf2bc809SJoel Becker loc->xl_size);
228611179f2cSJoel Becker }
228711179f2cSJoel Becker
ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc * loc,struct inode * inode,struct buffer_head * bh,struct ocfs2_xattr_entry * entry)228811179f2cSJoel Becker static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc,
228911179f2cSJoel Becker struct inode *inode,
229011179f2cSJoel Becker struct buffer_head *bh,
229111179f2cSJoel Becker struct ocfs2_xattr_entry *entry)
229211179f2cSJoel Becker {
229311179f2cSJoel Becker struct ocfs2_xattr_block *xb =
2294cf2bc809SJoel Becker (struct ocfs2_xattr_block *)bh->b_data;
229511179f2cSJoel Becker
229611179f2cSJoel Becker BUG_ON(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED);
229711179f2cSJoel Becker
229811179f2cSJoel Becker loc->xl_inode = inode;
229911179f2cSJoel Becker loc->xl_ops = &ocfs2_xa_block_loc_ops;
230011179f2cSJoel Becker loc->xl_storage = bh;
230111179f2cSJoel Becker loc->xl_header = &(xb->xb_attrs.xb_header);
230211179f2cSJoel Becker loc->xl_entry = entry;
230311179f2cSJoel Becker loc->xl_size = bh->b_size - offsetof(struct ocfs2_xattr_block,
230411179f2cSJoel Becker xb_attrs.xb_header);
230511179f2cSJoel Becker }
230611179f2cSJoel Becker
ocfs2_init_xattr_bucket_xa_loc(struct ocfs2_xa_loc * loc,struct ocfs2_xattr_bucket * bucket,struct ocfs2_xattr_entry * entry)2307cf2bc809SJoel Becker static void ocfs2_init_xattr_bucket_xa_loc(struct ocfs2_xa_loc *loc,
230811179f2cSJoel Becker struct ocfs2_xattr_bucket *bucket,
230911179f2cSJoel Becker struct ocfs2_xattr_entry *entry)
231011179f2cSJoel Becker {
231111179f2cSJoel Becker loc->xl_inode = bucket->bu_inode;
231211179f2cSJoel Becker loc->xl_ops = &ocfs2_xa_bucket_loc_ops;
231311179f2cSJoel Becker loc->xl_storage = bucket;
231411179f2cSJoel Becker loc->xl_header = bucket_xh(bucket);
2315ce9c5a54STao Ma loc->xl_entry = entry;
2316ce9c5a54STao Ma loc->xl_size = OCFS2_XATTR_BUCKET_SIZE;
2317ce9c5a54STao Ma }
2318ce9c5a54STao Ma
2319ce9c5a54STao Ma /*
2320ce9c5a54STao Ma * In xattr remove, if it is stored outside and refcounted, we may have
2321ce9c5a54STao Ma * the chance to split the refcount tree. So need the allocators.
2322ce9c5a54STao Ma */
ocfs2_lock_xattr_remove_allocators(struct inode * inode,struct ocfs2_xattr_value_root * xv,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh,struct ocfs2_alloc_context ** meta_ac,int * ref_credits)2323ce9c5a54STao Ma static int ocfs2_lock_xattr_remove_allocators(struct inode *inode,
2324ce9c5a54STao Ma struct ocfs2_xattr_value_root *xv,
2325cf1d6c76STiger Yang struct ocfs2_caching_info *ref_ci,
2326ce9c5a54STao Ma struct buffer_head *ref_root_bh,
2327ce9c5a54STao Ma struct ocfs2_alloc_context **meta_ac,
2328ce9c5a54STao Ma int *ref_credits)
232978f30c31STao Ma {
2330ce9c5a54STao Ma int ret, meta_add = 0;
2331ce9c5a54STao Ma u32 p_cluster, num_clusters;
2332ce9c5a54STao Ma unsigned int ext_flags;
2333ce9c5a54STao Ma
2334ce9c5a54STao Ma *ref_credits = 0;
2335ce9c5a54STao Ma ret = ocfs2_xattr_get_clusters(inode, 0, &p_cluster,
233685db90e7STao Ma &num_clusters,
233785db90e7STao Ma &xv->xr_list,
233885db90e7STao Ma &ext_flags);
233985db90e7STao Ma if (ret) {
2340ce9c5a54STao Ma mlog_errno(ret);
2341ce9c5a54STao Ma goto out;
2342ce9c5a54STao Ma }
2343ce9c5a54STao Ma
2344ce9c5a54STao Ma if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
2345ce9c5a54STao Ma goto out;
2346ce9c5a54STao Ma
2347ce9c5a54STao Ma ret = ocfs2_refcounted_xattr_delete_need(inode, ref_ci,
2348ce9c5a54STao Ma ref_root_bh, xv,
2349ce9c5a54STao Ma &meta_add, ref_credits);
2350ce9c5a54STao Ma if (ret) {
2351ce9c5a54STao Ma mlog_errno(ret);
2352ce9c5a54STao Ma goto out;
2353ce9c5a54STao Ma }
2354ce9c5a54STao Ma
2355ce9c5a54STao Ma ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb),
2356ce9c5a54STao Ma meta_add, meta_ac);
2357ce9c5a54STao Ma if (ret)
2358ce9c5a54STao Ma mlog_errno(ret);
2359ce9c5a54STao Ma
2360ce9c5a54STao Ma out:
2361ce9c5a54STao Ma return ret;
2362ce9c5a54STao Ma }
2363ce9c5a54STao Ma
ocfs2_remove_value_outside(struct inode * inode,struct ocfs2_xattr_value_buf * vb,struct ocfs2_xattr_header * header,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh)2364ce9c5a54STao Ma static int ocfs2_remove_value_outside(struct inode*inode,
2365ce9c5a54STao Ma struct ocfs2_xattr_value_buf *vb,
2366ce9c5a54STao Ma struct ocfs2_xattr_header *header,
2367ce9c5a54STao Ma struct ocfs2_caching_info *ref_ci,
2368ce9c5a54STao Ma struct buffer_head *ref_root_bh)
2369ce9c5a54STao Ma {
2370ce9c5a54STao Ma int ret = 0, i, ref_credits;
2371ce9c5a54STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2372ce9c5a54STao Ma struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
2373cf1d6c76STiger Yang void *val;
2374cf1d6c76STiger Yang
2375cf1d6c76STiger Yang ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
2376ce9c5a54STao Ma
2377ce9c5a54STao Ma for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
2378cf1d6c76STiger Yang struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
2379cf1d6c76STiger Yang
2380cf1d6c76STiger Yang if (ocfs2_xattr_is_local(entry))
23814311901dSJoel Becker continue;
2382cf1d6c76STiger Yang
2383ce9c5a54STao Ma val = (void *)header +
2384ce9c5a54STao Ma le16_to_cpu(entry->xe_name_offset);
2385ce9c5a54STao Ma vb->vb_xv = (struct ocfs2_xattr_value_root *)
2386ce9c5a54STao Ma (val + OCFS2_XATTR_SIZE(entry->xe_name_len));
2387ce9c5a54STao Ma
2388ce9c5a54STao Ma ret = ocfs2_lock_xattr_remove_allocators(inode, vb->vb_xv,
2389ce9c5a54STao Ma ref_ci, ref_root_bh,
2390ce9c5a54STao Ma &ctxt.meta_ac,
2391ce9c5a54STao Ma &ref_credits);
2392ce9c5a54STao Ma
2393ce9c5a54STao Ma ctxt.handle = ocfs2_start_trans(osb, ref_credits +
2394ce9c5a54STao Ma ocfs2_remove_extent_credits(osb->sb));
2395ce9c5a54STao Ma if (IS_ERR(ctxt.handle)) {
2396ce9c5a54STao Ma ret = PTR_ERR(ctxt.handle);
23974311901dSJoel Becker mlog_errno(ret);
2398ce9c5a54STao Ma break;
2399ce9c5a54STao Ma }
2400ce9c5a54STao Ma
2401ce9c5a54STao Ma ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt);
2402ce9c5a54STao Ma
2403cf1d6c76STiger Yang ocfs2_commit_trans(osb, ctxt.handle);
2404b8a0ae57SWengang Wang if (ctxt.meta_ac) {
2405b8a0ae57SWengang Wang ocfs2_free_alloc_context(ctxt.meta_ac);
2406b8a0ae57SWengang Wang ctxt.meta_ac = NULL;
2407b8a0ae57SWengang Wang }
2408b8a0ae57SWengang Wang
2409b8a0ae57SWengang Wang if (ret < 0) {
2410cf1d6c76STiger Yang mlog_errno(ret);
2411cf1d6c76STiger Yang break;
2412ce9c5a54STao Ma }
2413ce9c5a54STao Ma
241478f30c31STao Ma }
241578f30c31STao Ma
2416cf1d6c76STiger Yang if (ctxt.meta_ac)
2417cf1d6c76STiger Yang ocfs2_free_alloc_context(ctxt.meta_ac);
2418cf1d6c76STiger Yang ocfs2_schedule_truncate_log_flush(osb, 1);
2419cf1d6c76STiger Yang ocfs2_run_deallocs(osb, &ctxt.dealloc);
2420ce9c5a54STao Ma return ret;
2421ce9c5a54STao Ma }
2422ce9c5a54STao Ma
ocfs2_xattr_ibody_remove(struct inode * inode,struct buffer_head * di_bh,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh)2423cf1d6c76STiger Yang static int ocfs2_xattr_ibody_remove(struct inode *inode,
2424cf1d6c76STiger Yang struct buffer_head *di_bh,
2425cf1d6c76STiger Yang struct ocfs2_caching_info *ref_ci,
2426cf1d6c76STiger Yang struct buffer_head *ref_root_bh)
2427cf1d6c76STiger Yang {
24284311901dSJoel Becker
24294311901dSJoel Becker struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
24304311901dSJoel Becker struct ocfs2_xattr_header *header;
24314311901dSJoel Becker int ret;
2432cf1d6c76STiger Yang struct ocfs2_xattr_value_buf vb = {
2433cf1d6c76STiger Yang .vb_bh = di_bh,
2434cf1d6c76STiger Yang .vb_access = ocfs2_journal_access_di,
2435cf1d6c76STiger Yang };
2436cf1d6c76STiger Yang
2437ce9c5a54STao Ma header = (struct ocfs2_xattr_header *)
2438ce9c5a54STao Ma ((void *)di + inode->i_sb->s_blocksize -
2439cf1d6c76STiger Yang le16_to_cpu(di->i_xattr_inline_size));
2440cf1d6c76STiger Yang
2441cf1d6c76STiger Yang ret = ocfs2_remove_value_outside(inode, &vb, header,
2442cf1d6c76STiger Yang ref_ci, ref_root_bh);
2443ce9c5a54STao Ma
2444ce9c5a54STao Ma return ret;
2445ce9c5a54STao Ma }
2446ce9c5a54STao Ma
2447ce9c5a54STao Ma struct ocfs2_rm_xattr_bucket_para {
2448cf1d6c76STiger Yang struct ocfs2_caching_info *ref_ci;
2449ce9c5a54STao Ma struct buffer_head *ref_root_bh;
2450ce9c5a54STao Ma };
2451ce9c5a54STao Ma
ocfs2_xattr_block_remove(struct inode * inode,struct buffer_head * blk_bh,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh)2452cf1d6c76STiger Yang static int ocfs2_xattr_block_remove(struct inode *inode,
2453cf1d6c76STiger Yang struct buffer_head *blk_bh,
2454cf1d6c76STiger Yang struct ocfs2_caching_info *ref_ci,
24554311901dSJoel Becker struct buffer_head *ref_root_bh)
24564311901dSJoel Becker {
24574311901dSJoel Becker struct ocfs2_xattr_block *xb;
24584311901dSJoel Becker int ret = 0;
2459ce9c5a54STao Ma struct ocfs2_xattr_value_buf vb = {
2460ce9c5a54STao Ma .vb_bh = blk_bh,
2461ce9c5a54STao Ma .vb_access = ocfs2_journal_access_xb,
2462ce9c5a54STao Ma };
2463cf1d6c76STiger Yang struct ocfs2_rm_xattr_bucket_para args = {
2464cf1d6c76STiger Yang .ref_ci = ref_ci,
2465a3944256STao Ma .ref_root_bh = ref_root_bh,
2466a3944256STao Ma };
2467ce9c5a54STao Ma
2468ce9c5a54STao Ma xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
2469a3944256STao Ma if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
247047bca495STao Ma struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header);
247147bca495STao Ma ret = ocfs2_remove_value_outside(inode, &vb, header,
247247bca495STao Ma ref_ci, ref_root_bh);
2473ce9c5a54STao Ma } else
2474cf1d6c76STiger Yang ret = ocfs2_iterate_xattr_index_block(inode,
2475cf1d6c76STiger Yang blk_bh,
2476cf1d6c76STiger Yang ocfs2_rm_xattr_cluster,
2477cf1d6c76STiger Yang &args);
247808413899STao Ma
2479ce9c5a54STao Ma return ret;
2480ce9c5a54STao Ma }
2481ce9c5a54STao Ma
ocfs2_xattr_free_block(struct inode * inode,u64 block,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh)248208413899STao Ma static int ocfs2_xattr_free_block(struct inode *inode,
248308413899STao Ma u64 block,
248408413899STao Ma struct ocfs2_caching_info *ref_ci,
248508413899STao Ma struct buffer_head *ref_root_bh)
248608413899STao Ma {
248708413899STao Ma struct inode *xb_alloc_inode;
248808413899STao Ma struct buffer_head *xb_alloc_bh = NULL;
248908413899STao Ma struct buffer_head *blk_bh = NULL;
249008413899STao Ma struct ocfs2_xattr_block *xb;
249108413899STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
249208413899STao Ma handle_t *handle;
24934ae1d69bSJoel Becker int ret = 0;
249408413899STao Ma u64 blk, bg_blkno;
249508413899STao Ma u16 bit;
249608413899STao Ma
249708413899STao Ma ret = ocfs2_read_xattr_block(inode, block, &blk_bh);
249808413899STao Ma if (ret < 0) {
2499ce9c5a54STao Ma mlog_errno(ret);
250008413899STao Ma goto out;
250108413899STao Ma }
250208413899STao Ma
250308413899STao Ma ret = ocfs2_xattr_block_remove(inode, blk_bh, ref_ci, ref_root_bh);
250408413899STao Ma if (ret < 0) {
25054ae1d69bSJoel Becker mlog_errno(ret);
250608413899STao Ma goto out;
250708413899STao Ma }
250874380c47STao Ma
250974380c47STao Ma xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
251074380c47STao Ma blk = le64_to_cpu(xb->xb_blkno);
251108413899STao Ma bit = le16_to_cpu(xb->xb_suballoc_bit);
251208413899STao Ma if (xb->xb_suballoc_loc)
251308413899STao Ma bg_blkno = le64_to_cpu(xb->xb_suballoc_loc);
251408413899STao Ma else
251508413899STao Ma bg_blkno = ocfs2_which_suballoc_group(blk, bit);
251608413899STao Ma
251708413899STao Ma xb_alloc_inode = ocfs2_get_system_file_inode(osb,
251808413899STao Ma EXTENT_ALLOC_SYSTEM_INODE,
251908413899STao Ma le16_to_cpu(xb->xb_suballoc_slot));
252008413899STao Ma if (!xb_alloc_inode) {
25215955102cSAl Viro ret = -ENOMEM;
252208413899STao Ma mlog_errno(ret);
252308413899STao Ma goto out;
252408413899STao Ma }
252508413899STao Ma inode_lock(xb_alloc_inode);
252608413899STao Ma
252708413899STao Ma ret = ocfs2_inode_lock(xb_alloc_inode, &xb_alloc_bh, 1);
252808413899STao Ma if (ret < 0) {
252908413899STao Ma mlog_errno(ret);
253008413899STao Ma goto out_mutex;
253108413899STao Ma }
253208413899STao Ma
253308413899STao Ma handle = ocfs2_start_trans(osb, OCFS2_SUBALLOC_FREE);
253408413899STao Ma if (IS_ERR(handle)) {
253508413899STao Ma ret = PTR_ERR(handle);
253608413899STao Ma mlog_errno(ret);
253708413899STao Ma goto out_unlock;
253808413899STao Ma }
253908413899STao Ma
254008413899STao Ma ret = ocfs2_free_suballoc_bits(handle, xb_alloc_inode, xb_alloc_bh,
254108413899STao Ma bit, bg_blkno, 1);
254208413899STao Ma if (ret < 0)
254308413899STao Ma mlog_errno(ret);
254408413899STao Ma
254508413899STao Ma ocfs2_commit_trans(osb, handle);
25465955102cSAl Viro out_unlock:
254708413899STao Ma ocfs2_inode_unlock(xb_alloc_inode, 1);
254808413899STao Ma brelse(xb_alloc_bh);
254908413899STao Ma out_mutex:
255008413899STao Ma inode_unlock(xb_alloc_inode);
255108413899STao Ma iput(xb_alloc_inode);
255208413899STao Ma out:
2553cf1d6c76STiger Yang brelse(blk_bh);
2554cf1d6c76STiger Yang return ret;
2555cf1d6c76STiger Yang }
2556cf1d6c76STiger Yang
2557cf1d6c76STiger Yang /*
2558cf1d6c76STiger Yang * ocfs2_xattr_remove()
2559cf1d6c76STiger Yang *
2560cf1d6c76STiger Yang * Free extended attribute resources associated with this inode.
2561cf1d6c76STiger Yang */
ocfs2_xattr_remove(struct inode * inode,struct buffer_head * di_bh)2562ce9c5a54STao Ma int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
2563ce9c5a54STao Ma {
2564ce9c5a54STao Ma struct ocfs2_inode_info *oi = OCFS2_I(inode);
2565cf1d6c76STiger Yang struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
2566cf1d6c76STiger Yang struct ocfs2_refcount_tree *ref_tree = NULL;
2567cf1d6c76STiger Yang struct buffer_head *ref_root_bh = NULL;
25688154da3dSTiger Yang struct ocfs2_caching_info *ref_ci = NULL;
25698154da3dSTiger Yang handle_t *handle;
25708154da3dSTiger Yang int ret;
2571cf1d6c76STiger Yang
2572cf1d6c76STiger Yang if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb)))
2573cf1d6c76STiger Yang return 0;
257484e40080SDarrick J. Wong
2575ce9c5a54STao Ma if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
2576ce9c5a54STao Ma return 0;
2577ce9c5a54STao Ma
2578ce9c5a54STao Ma if (ocfs2_is_refcount_inode(inode)) {
2579ce9c5a54STao Ma ret = ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb),
2580ce9c5a54STao Ma le64_to_cpu(di->i_refcount_loc),
2581ce9c5a54STao Ma 1, &ref_tree, &ref_root_bh);
2582ce9c5a54STao Ma if (ret) {
2583ce9c5a54STao Ma mlog_errno(ret);
2584ce9c5a54STao Ma goto out;
2585ce9c5a54STao Ma }
2586cf1d6c76STiger Yang ref_ci = &ref_tree->rf_ci;
2587ce9c5a54STao Ma
2588ce9c5a54STao Ma }
2589cf1d6c76STiger Yang
2590cf1d6c76STiger Yang if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
2591cf1d6c76STiger Yang ret = ocfs2_xattr_ibody_remove(inode, di_bh,
2592cf1d6c76STiger Yang ref_ci, ref_root_bh);
2593cf1d6c76STiger Yang if (ret < 0) {
2594cf1d6c76STiger Yang mlog_errno(ret);
259508413899STao Ma goto out;
259608413899STao Ma }
2597ce9c5a54STao Ma }
2598ce9c5a54STao Ma
2599cf1d6c76STiger Yang if (di->i_xattr_loc) {
2600cf1d6c76STiger Yang ret = ocfs2_xattr_free_block(inode,
2601cf1d6c76STiger Yang le64_to_cpu(di->i_xattr_loc),
2602cf1d6c76STiger Yang ref_ci, ref_root_bh);
2603cf1d6c76STiger Yang if (ret < 0) {
2604cf1d6c76STiger Yang mlog_errno(ret);
2605cf1d6c76STiger Yang goto out;
2606cf1d6c76STiger Yang }
2607cf1d6c76STiger Yang }
2608cf1d6c76STiger Yang
2609cf1d6c76STiger Yang handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
2610cf1d6c76STiger Yang OCFS2_INODE_UPDATE_CREDITS);
2611cf1d6c76STiger Yang if (IS_ERR(handle)) {
26120cf2f763SJoel Becker ret = PTR_ERR(handle);
2613cf1d6c76STiger Yang mlog_errno(ret);
2614cf1d6c76STiger Yang goto out;
2615cf1d6c76STiger Yang }
2616cf1d6c76STiger Yang ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
2617cf1d6c76STiger Yang OCFS2_JOURNAL_ACCESS_WRITE);
2618cf1d6c76STiger Yang if (ret) {
261908413899STao Ma mlog_errno(ret);
2620cf1d6c76STiger Yang goto out_commit;
2621cf1d6c76STiger Yang }
2622cf1d6c76STiger Yang
2623cf1d6c76STiger Yang di->i_xattr_loc = 0;
2624cf1d6c76STiger Yang
26256fdb702dSDarrick J. Wong spin_lock(&oi->ip_lock);
2626cf1d6c76STiger Yang oi->ip_dyn_features &= ~(OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL);
2627ec20cec7SJoel Becker di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
2628cf1d6c76STiger Yang spin_unlock(&oi->ip_lock);
2629cf1d6c76STiger Yang ocfs2_update_inode_fsync_trans(handle, inode, 0);
2630cf1d6c76STiger Yang
2631ce9c5a54STao Ma ocfs2_journal_dirty(handle, di_bh);
2632ce9c5a54STao Ma out_commit:
2633ce9c5a54STao Ma ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
2634cf1d6c76STiger Yang out:
2635cf1d6c76STiger Yang if (ref_tree)
2636cf1d6c76STiger Yang ocfs2_unlock_refcount_tree(OCFS2_SB(inode->i_sb), ref_tree, 1);
2637cf1d6c76STiger Yang brelse(ref_root_bh);
2638cf1d6c76STiger Yang return ret;
2639cf1d6c76STiger Yang }
2640cf1d6c76STiger Yang
ocfs2_xattr_has_space_inline(struct inode * inode,struct ocfs2_dinode * di)2641cf1d6c76STiger Yang static int ocfs2_xattr_has_space_inline(struct inode *inode,
2642cf1d6c76STiger Yang struct ocfs2_dinode *di)
2643cf1d6c76STiger Yang {
2644cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
2645cf1d6c76STiger Yang unsigned int xattrsize = OCFS2_SB(inode->i_sb)->s_xattr_inline_size;
2646cf1d6c76STiger Yang int free;
2647cf1d6c76STiger Yang
2648cf1d6c76STiger Yang if (xattrsize < OCFS2_MIN_XATTR_INLINE_SIZE)
2649cf1d6c76STiger Yang return 0;
2650cf1d6c76STiger Yang
2651cf1d6c76STiger Yang if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
2652cf1d6c76STiger Yang struct ocfs2_inline_data *idata = &di->id2.i_data;
2653cf1d6c76STiger Yang free = le16_to_cpu(idata->id_count) - le64_to_cpu(di->i_size);
2654cf1d6c76STiger Yang } else if (ocfs2_inode_is_fast_symlink(inode)) {
2655cf1d6c76STiger Yang free = ocfs2_fast_symlink_chars(inode->i_sb) -
2656cf1d6c76STiger Yang le64_to_cpu(di->i_size);
2657cf1d6c76STiger Yang } else {
2658cf1d6c76STiger Yang struct ocfs2_extent_list *el = &di->id2.i_list;
2659cf1d6c76STiger Yang free = (le16_to_cpu(el->l_count) -
2660cf1d6c76STiger Yang le16_to_cpu(el->l_next_free_rec)) *
2661cf1d6c76STiger Yang sizeof(struct ocfs2_extent_rec);
2662cf1d6c76STiger Yang }
2663cf1d6c76STiger Yang if (free >= xattrsize)
2664cf1d6c76STiger Yang return 1;
2665cf1d6c76STiger Yang
2666cf1d6c76STiger Yang return 0;
2667cf1d6c76STiger Yang }
2668cf1d6c76STiger Yang
2669cf1d6c76STiger Yang /*
2670cf1d6c76STiger Yang * ocfs2_xattr_ibody_find()
2671cf1d6c76STiger Yang *
2672cf1d6c76STiger Yang * Find extended attribute in inode block and
2673cf1d6c76STiger Yang * fill search info into struct ocfs2_xattr_search.
2674cf1d6c76STiger Yang */
ocfs2_xattr_ibody_find(struct inode * inode,int name_index,const char * name,struct ocfs2_xattr_search * xs)2675cf1d6c76STiger Yang static int ocfs2_xattr_ibody_find(struct inode *inode,
2676cf1d6c76STiger Yang int name_index,
2677cf1d6c76STiger Yang const char *name,
2678cf1d6c76STiger Yang struct ocfs2_xattr_search *xs)
2679cf1d6c76STiger Yang {
2680cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
2681cf1d6c76STiger Yang struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
2682cf1d6c76STiger Yang int ret;
2683cf1d6c76STiger Yang int has_space = 0;
2684cf1d6c76STiger Yang
2685cf1d6c76STiger Yang if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE)
2686cf1d6c76STiger Yang return 0;
2687cf1d6c76STiger Yang
2688cf1d6c76STiger Yang if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
2689cf1d6c76STiger Yang down_read(&oi->ip_alloc_sem);
2690cf1d6c76STiger Yang has_space = ocfs2_xattr_has_space_inline(inode, di);
2691cf1d6c76STiger Yang up_read(&oi->ip_alloc_sem);
2692cf1d6c76STiger Yang if (!has_space)
2693cf1d6c76STiger Yang return 0;
2694cf1d6c76STiger Yang }
2695cf1d6c76STiger Yang
2696cf1d6c76STiger Yang xs->xattr_bh = xs->inode_bh;
2697cf1d6c76STiger Yang xs->end = (void *)di + inode->i_sb->s_blocksize;
2698cf1d6c76STiger Yang if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)
2699cf1d6c76STiger Yang xs->header = (struct ocfs2_xattr_header *)
2700cf1d6c76STiger Yang (xs->end - le16_to_cpu(di->i_xattr_inline_size));
2701cf1d6c76STiger Yang else
2702cf1d6c76STiger Yang xs->header = (struct ocfs2_xattr_header *)
2703cf1d6c76STiger Yang (xs->end - OCFS2_SB(inode->i_sb)->s_xattr_inline_size);
2704cf1d6c76STiger Yang xs->base = (void *)xs->header;
2705cf1d6c76STiger Yang xs->here = xs->header->xh_entries;
2706cf1d6c76STiger Yang
2707cf1d6c76STiger Yang /* Find the named attribute. */
2708cf1d6c76STiger Yang if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
2709cf1d6c76STiger Yang ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
2710cf1d6c76STiger Yang if (ret && ret != -ENODATA)
2711cf1d6c76STiger Yang return ret;
2712cf1d6c76STiger Yang xs->not_found = ret;
2713cf1d6c76STiger Yang }
2714139ffaceSJoel Becker
2715139ffaceSJoel Becker return 0;
2716139ffaceSJoel Becker }
2717139ffaceSJoel Becker
ocfs2_xattr_ibody_init(struct inode * inode,struct buffer_head * di_bh,struct ocfs2_xattr_set_ctxt * ctxt)2718139ffaceSJoel Becker static int ocfs2_xattr_ibody_init(struct inode *inode,
2719139ffaceSJoel Becker struct buffer_head *di_bh,
2720139ffaceSJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
2721139ffaceSJoel Becker {
2722139ffaceSJoel Becker int ret;
2723139ffaceSJoel Becker struct ocfs2_inode_info *oi = OCFS2_I(inode);
2724139ffaceSJoel Becker struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
2725139ffaceSJoel Becker struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2726139ffaceSJoel Becker unsigned int xattrsize = osb->s_xattr_inline_size;
2727139ffaceSJoel Becker
2728139ffaceSJoel Becker if (!ocfs2_xattr_has_space_inline(inode, di)) {
2729139ffaceSJoel Becker ret = -ENOSPC;
2730139ffaceSJoel Becker goto out;
2731139ffaceSJoel Becker }
2732139ffaceSJoel Becker
2733139ffaceSJoel Becker ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode), di_bh,
2734139ffaceSJoel Becker OCFS2_JOURNAL_ACCESS_WRITE);
2735139ffaceSJoel Becker if (ret) {
2736139ffaceSJoel Becker mlog_errno(ret);
2737139ffaceSJoel Becker goto out;
2738139ffaceSJoel Becker }
2739139ffaceSJoel Becker
2740139ffaceSJoel Becker /*
2741139ffaceSJoel Becker * Adjust extent record count or inline data size
2742139ffaceSJoel Becker * to reserve space for extended attribute.
2743139ffaceSJoel Becker */
2744139ffaceSJoel Becker if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
2745139ffaceSJoel Becker struct ocfs2_inline_data *idata = &di->id2.i_data;
2746139ffaceSJoel Becker le16_add_cpu(&idata->id_count, -xattrsize);
2747139ffaceSJoel Becker } else if (!(ocfs2_inode_is_fast_symlink(inode))) {
2748139ffaceSJoel Becker struct ocfs2_extent_list *el = &di->id2.i_list;
2749139ffaceSJoel Becker le16_add_cpu(&el->l_count, -(xattrsize /
2750139ffaceSJoel Becker sizeof(struct ocfs2_extent_rec)));
2751139ffaceSJoel Becker }
2752139ffaceSJoel Becker di->i_xattr_inline_size = cpu_to_le16(xattrsize);
2753139ffaceSJoel Becker
2754139ffaceSJoel Becker spin_lock(&oi->ip_lock);
2755ec20cec7SJoel Becker oi->ip_dyn_features |= OCFS2_INLINE_XATTR_FL|OCFS2_HAS_XATTR_FL;
2756139ffaceSJoel Becker di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
2757139ffaceSJoel Becker spin_unlock(&oi->ip_lock);
2758139ffaceSJoel Becker
2759139ffaceSJoel Becker ocfs2_journal_dirty(ctxt->handle, di_bh);
2760139ffaceSJoel Becker
2761cf1d6c76STiger Yang out:
2762cf1d6c76STiger Yang return ret;
2763cf1d6c76STiger Yang }
2764cf1d6c76STiger Yang
2765cf1d6c76STiger Yang /*
2766cf1d6c76STiger Yang * ocfs2_xattr_ibody_set()
2767cf1d6c76STiger Yang *
2768cf1d6c76STiger Yang * Set, replace or remove an extended attribute into inode block.
276978f30c31STao Ma *
277078f30c31STao Ma */
ocfs2_xattr_ibody_set(struct inode * inode,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xs,struct ocfs2_xattr_set_ctxt * ctxt)2771cf1d6c76STiger Yang static int ocfs2_xattr_ibody_set(struct inode *inode,
2772139ffaceSJoel Becker struct ocfs2_xattr_info *xi,
2773cf1d6c76STiger Yang struct ocfs2_xattr_search *xs,
2774139ffaceSJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
2775cf1d6c76STiger Yang {
2776cf1d6c76STiger Yang int ret;
2777cf1d6c76STiger Yang struct ocfs2_inode_info *oi = OCFS2_I(inode);
2778cf1d6c76STiger Yang struct ocfs2_xa_loc loc;
2779cf1d6c76STiger Yang
2780cf1d6c76STiger Yang if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE)
2781139ffaceSJoel Becker return -ENOSPC;
2782139ffaceSJoel Becker
2783139ffaceSJoel Becker down_write(&oi->ip_alloc_sem);
2784139ffaceSJoel Becker if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
2785139ffaceSJoel Becker ret = ocfs2_xattr_ibody_init(inode, xs->inode_bh, ctxt);
2786139ffaceSJoel Becker if (ret) {
2787139ffaceSJoel Becker if (ret != -ENOSPC)
2788139ffaceSJoel Becker mlog_errno(ret);
2789139ffaceSJoel Becker goto out;
2790139ffaceSJoel Becker }
2791139ffaceSJoel Becker }
2792139ffaceSJoel Becker
2793139ffaceSJoel Becker ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
2794139ffaceSJoel Becker xs->not_found ? NULL : xs->here);
2795139ffaceSJoel Becker ret = ocfs2_xa_set(&loc, xi, ctxt);
2796139ffaceSJoel Becker if (ret) {
2797139ffaceSJoel Becker if (ret != -ENOSPC)
2798139ffaceSJoel Becker mlog_errno(ret);
2799cf1d6c76STiger Yang goto out;
2800cf1d6c76STiger Yang }
2801cf1d6c76STiger Yang xs->here = loc.xl_entry;
2802cf1d6c76STiger Yang
2803cf1d6c76STiger Yang out:
2804cf1d6c76STiger Yang up_write(&oi->ip_alloc_sem);
2805cf1d6c76STiger Yang
2806cf1d6c76STiger Yang return ret;
2807cf1d6c76STiger Yang }
2808cf1d6c76STiger Yang
2809cf1d6c76STiger Yang /*
2810cf1d6c76STiger Yang * ocfs2_xattr_block_find()
2811cf1d6c76STiger Yang *
2812cf1d6c76STiger Yang * Find extended attribute in external block and
2813cf1d6c76STiger Yang * fill search info into struct ocfs2_xattr_search.
2814cf1d6c76STiger Yang */
ocfs2_xattr_block_find(struct inode * inode,int name_index,const char * name,struct ocfs2_xattr_search * xs)2815cf1d6c76STiger Yang static int ocfs2_xattr_block_find(struct inode *inode,
2816cf1d6c76STiger Yang int name_index,
2817cf1d6c76STiger Yang const char *name,
2818589dc260STao Ma struct ocfs2_xattr_search *xs)
2819cf1d6c76STiger Yang {
2820cf1d6c76STiger Yang struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
2821cf1d6c76STiger Yang struct buffer_head *blk_bh = NULL;
2822cf1d6c76STiger Yang struct ocfs2_xattr_block *xb;
2823cf1d6c76STiger Yang int ret = 0;
28244ae1d69bSJoel Becker
28254ae1d69bSJoel Becker if (!di->i_xattr_loc)
2826cf1d6c76STiger Yang return ret;
2827cf1d6c76STiger Yang
2828cf1d6c76STiger Yang ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc),
2829cf1d6c76STiger Yang &blk_bh);
2830f6087fb7SJoel Becker if (ret < 0) {
2831cf1d6c76STiger Yang mlog_errno(ret);
28324ae1d69bSJoel Becker return ret;
2833589dc260STao Ma }
2834589dc260STao Ma
2835589dc260STao Ma xs->xattr_bh = blk_bh;
2836cf1d6c76STiger Yang xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
2837cf1d6c76STiger Yang
2838cf1d6c76STiger Yang if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
2839cf1d6c76STiger Yang xs->header = &xb->xb_attrs.xb_header;
2840cf1d6c76STiger Yang xs->base = (void *)xs->header;
2841589dc260STao Ma xs->end = (void *)(blk_bh->b_data) + blk_bh->b_size;
2842589dc260STao Ma xs->here = xs->header->xh_entries;
2843589dc260STao Ma
2844589dc260STao Ma ret = ocfs2_xattr_find_entry(inode, name_index, name, xs);
2845589dc260STao Ma } else
2846cf1d6c76STiger Yang ret = ocfs2_xattr_index_block_find(inode, blk_bh,
2847cf1d6c76STiger Yang name_index,
2848cf1d6c76STiger Yang name, xs);
2849cf1d6c76STiger Yang
2850cf1d6c76STiger Yang if (ret && ret != -ENODATA) {
2851cf1d6c76STiger Yang xs->xattr_bh = NULL;
2852cf1d6c76STiger Yang goto cleanup;
2853cf1d6c76STiger Yang }
2854cf1d6c76STiger Yang xs->not_found = ret;
2855cf1d6c76STiger Yang return 0;
2856cf1d6c76STiger Yang cleanup:
2857cf1d6c76STiger Yang brelse(blk_bh);
2858d3981544SJoel Becker
28595aea1f0eSTao Ma return ret;
2860d3981544SJoel Becker }
2861d3981544SJoel Becker
ocfs2_create_xattr_block(struct inode * inode,struct buffer_head * inode_bh,struct ocfs2_xattr_set_ctxt * ctxt,int indexed,struct buffer_head ** ret_bh)2862d3981544SJoel Becker static int ocfs2_create_xattr_block(struct inode *inode,
2863cf1d6c76STiger Yang struct buffer_head *inode_bh,
28645aea1f0eSTao Ma struct ocfs2_xattr_set_ctxt *ctxt,
2865cf1d6c76STiger Yang int indexed,
2866cf1d6c76STiger Yang struct buffer_head **ret_bh)
28672b6cb576SJoel Becker {
28685aea1f0eSTao Ma int ret;
28695aea1f0eSTao Ma u16 suballoc_bit_start;
28705aea1f0eSTao Ma u32 num_got;
2871cf1d6c76STiger Yang u64 suballoc_loc, first_blkno;
2872d3981544SJoel Becker struct ocfs2_dinode *di = (struct ocfs2_dinode *)inode_bh->b_data;
2873d3981544SJoel Becker struct buffer_head *new_bh = NULL;
2874cf1d6c76STiger Yang struct ocfs2_xattr_block *xblk;
2875cf1d6c76STiger Yang
287685db90e7STao Ma ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode),
2877cf1d6c76STiger Yang inode_bh, OCFS2_JOURNAL_ACCESS_CREATE);
2878cf1d6c76STiger Yang if (ret < 0) {
28791ed9b777SJoel Becker mlog_errno(ret);
28802b6cb576SJoel Becker goto end;
28812b6cb576SJoel Becker }
2882cf1d6c76STiger Yang
2883cf1d6c76STiger Yang ret = ocfs2_claim_metadata(ctxt->handle, ctxt->meta_ac, 1,
288485db90e7STao Ma &suballoc_loc, &suballoc_bit_start,
2885cf1d6c76STiger Yang &num_got, &first_blkno);
2886cf1d6c76STiger Yang if (ret < 0) {
2887cf1d6c76STiger Yang mlog_errno(ret);
288858796207SRui Xiang goto end;
288958796207SRui Xiang }
289058796207SRui Xiang
289158796207SRui Xiang new_bh = sb_getblk(inode->i_sb, first_blkno);
289258796207SRui Xiang if (!new_bh) {
289358796207SRui Xiang ret = -ENOMEM;
28948cb471e8SJoel Becker mlog_errno(ret);
2895cf1d6c76STiger Yang goto end;
2896d3981544SJoel Becker }
28970cf2f763SJoel Becker
2898cf1d6c76STiger Yang ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
2899cf1d6c76STiger Yang
2900cf1d6c76STiger Yang ret = ocfs2_journal_access_xb(ctxt->handle, INODE_CACHE(inode),
290185db90e7STao Ma new_bh,
2902cf1d6c76STiger Yang OCFS2_JOURNAL_ACCESS_CREATE);
2903cf1d6c76STiger Yang if (ret < 0) {
2904cf1d6c76STiger Yang mlog_errno(ret);
2905cf1d6c76STiger Yang goto end;
2906cf1d6c76STiger Yang }
2907cf1d6c76STiger Yang
2908d3981544SJoel Becker /* Initialize ocfs2_xattr_block */
29092b6cb576SJoel Becker xblk = (struct ocfs2_xattr_block *)new_bh->b_data;
2910cf1d6c76STiger Yang memset(xblk, 0, inode->i_sb->s_blocksize);
29111ed9b777SJoel Becker strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
29121ed9b777SJoel Becker xblk->xb_suballoc_slot = cpu_to_le16(ctxt->meta_ac->ac_alloc_slot);
2913cf1d6c76STiger Yang xblk->xb_suballoc_loc = cpu_to_le64(suballoc_loc);
2914a7fe7a3aSTao Ma xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
2915a7fe7a3aSTao Ma xblk->xb_fs_generation =
2916a7fe7a3aSTao Ma cpu_to_le32(OCFS2_SB(inode->i_sb)->fs_generation);
2917a7fe7a3aSTao Ma xblk->xb_blkno = cpu_to_le64(first_blkno);
2918a7fe7a3aSTao Ma if (indexed) {
2919a7fe7a3aSTao Ma struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root;
2920a7fe7a3aSTao Ma xr->xt_clusters = cpu_to_le32(1);
2921a7fe7a3aSTao Ma xr->xt_last_eb_blk = 0;
2922a7fe7a3aSTao Ma xr->xt_list.l_tree_depth = 0;
2923a7fe7a3aSTao Ma xr->xt_list.l_count = cpu_to_le16(
2924d3981544SJoel Becker ocfs2_xattr_recs_per_xb(inode->i_sb));
2925a7fe7a3aSTao Ma xr->xt_list.l_next_free_rec = cpu_to_le16(1);
2926d3981544SJoel Becker xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED);
2927cf1d6c76STiger Yang }
2928d3981544SJoel Becker ocfs2_journal_dirty(ctxt->handle, new_bh);
2929d3981544SJoel Becker
2930d3981544SJoel Becker /* Add it to the inode */
2931d3981544SJoel Becker di->i_xattr_loc = cpu_to_le64(first_blkno);
2932d3981544SJoel Becker
2933d3981544SJoel Becker spin_lock(&OCFS2_I(inode)->ip_lock);
2934d3981544SJoel Becker OCFS2_I(inode)->ip_dyn_features |= OCFS2_HAS_XATTR_FL;
29355aea1f0eSTao Ma di->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
29365aea1f0eSTao Ma spin_unlock(&OCFS2_I(inode)->ip_lock);
29375aea1f0eSTao Ma
29385aea1f0eSTao Ma ocfs2_journal_dirty(ctxt->handle, inode_bh);
29395aea1f0eSTao Ma
29405aea1f0eSTao Ma *ret_bh = new_bh;
29415aea1f0eSTao Ma new_bh = NULL;
29425aea1f0eSTao Ma
29435aea1f0eSTao Ma end:
29445aea1f0eSTao Ma brelse(new_bh);
29455aea1f0eSTao Ma return ret;
29465aea1f0eSTao Ma }
29475aea1f0eSTao Ma
29485aea1f0eSTao Ma /*
29495aea1f0eSTao Ma * ocfs2_xattr_block_set()
29505aea1f0eSTao Ma *
29515aea1f0eSTao Ma * Set, replace or remove an extended attribute into external block.
29525aea1f0eSTao Ma *
29535aea1f0eSTao Ma */
ocfs2_xattr_block_set(struct inode * inode,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xs,struct ocfs2_xattr_set_ctxt * ctxt)29545aea1f0eSTao Ma static int ocfs2_xattr_block_set(struct inode *inode,
29555aea1f0eSTao Ma struct ocfs2_xattr_info *xi,
29565aea1f0eSTao Ma struct ocfs2_xattr_search *xs,
29575aea1f0eSTao Ma struct ocfs2_xattr_set_ctxt *ctxt)
2958d3981544SJoel Becker {
29595aea1f0eSTao Ma struct buffer_head *new_bh = NULL;
29605aea1f0eSTao Ma struct ocfs2_xattr_block *xblk = NULL;
2961d3981544SJoel Becker int ret;
2962d3981544SJoel Becker struct ocfs2_xa_loc loc;
29635aea1f0eSTao Ma
29645aea1f0eSTao Ma if (!xs->xattr_bh) {
29655aea1f0eSTao Ma ret = ocfs2_create_xattr_block(inode, xs->inode_bh, ctxt,
29665aea1f0eSTao Ma 0, &new_bh);
29675aea1f0eSTao Ma if (ret) {
29685aea1f0eSTao Ma mlog_errno(ret);
29695aea1f0eSTao Ma goto end;
29705aea1f0eSTao Ma }
29715aea1f0eSTao Ma
29725aea1f0eSTao Ma xs->xattr_bh = new_bh;
29735aea1f0eSTao Ma xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
297401225596STao Ma xs->header = &xblk->xb_attrs.xb_header;
297501225596STao Ma xs->base = (void *)xs->header;
2976cf1d6c76STiger Yang xs->end = (void *)xblk + inode->i_sb->s_blocksize;
297701225596STao Ma xs->here = xs->header->xh_entries;
2978d3981544SJoel Becker } else
2979d3981544SJoel Becker xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
298001225596STao Ma
2981d3981544SJoel Becker if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
2982d3981544SJoel Becker ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
2983d3981544SJoel Becker xs->not_found ? NULL : xs->here);
29845f5261acSTao Ma
2985d3981544SJoel Becker ret = ocfs2_xa_set(&loc, xi, ctxt);
2986d3981544SJoel Becker if (!ret)
298778f30c31STao Ma xs->here = loc.xl_entry;
298801225596STao Ma else if ((ret != -ENOSPC) || ctxt->set_abort)
298901225596STao Ma goto end;
299001225596STao Ma else {
2991d3981544SJoel Becker ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
299201225596STao Ma if (ret)
2993d3981544SJoel Becker goto end;
299478f30c31STao Ma }
299501225596STao Ma }
299601225596STao Ma
2997cf1d6c76STiger Yang if (le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)
2998cf1d6c76STiger Yang ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
2999cf1d6c76STiger Yang
300078f30c31STao Ma end:
300178f30c31STao Ma return ret;
300278f30c31STao Ma }
300378f30c31STao Ma
300478f30c31STao Ma /* Check whether the new xattr can be inserted into the inode. */
ocfs2_xattr_can_be_in_inode(struct inode * inode,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xs)300578f30c31STao Ma static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
300678f30c31STao Ma struct ocfs2_xattr_info *xi,
300778f30c31STao Ma struct ocfs2_xattr_search *xs)
300878f30c31STao Ma {
300978f30c31STao Ma struct ocfs2_xattr_entry *last;
301078f30c31STao Ma int free, i;
301178f30c31STao Ma size_t min_offs = xs->end - xs->base;
301278f30c31STao Ma
301378f30c31STao Ma if (!xs->header)
301478f30c31STao Ma return 0;
301578f30c31STao Ma
301678f30c31STao Ma last = xs->header->xh_entries;
301778f30c31STao Ma
301878f30c31STao Ma for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
301978f30c31STao Ma size_t offs = le16_to_cpu(last->xe_name_offset);
302078f30c31STao Ma if (offs < min_offs)
30214442f518STiger Yang min_offs = offs;
302278f30c31STao Ma last += 1;
302378f30c31STao Ma }
302478f30c31STao Ma
302578f30c31STao Ma free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP;
302678f30c31STao Ma if (free < 0)
3027199799a3SJoel Becker return 0;
302878f30c31STao Ma
302978f30c31STao Ma BUG_ON(!xs->not_found);
303078f30c31STao Ma
303178f30c31STao Ma if (free >= (sizeof(struct ocfs2_xattr_entry) + namevalue_size_xi(xi)))
303278f30c31STao Ma return 1;
303378f30c31STao Ma
303478f30c31STao Ma return 0;
303578f30c31STao Ma }
303678f30c31STao Ma
ocfs2_calc_xattr_set_need(struct inode * inode,struct ocfs2_dinode * di,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xis,struct ocfs2_xattr_search * xbs,int * clusters_need,int * meta_need,int * credits_need)303778f30c31STao Ma static int ocfs2_calc_xattr_set_need(struct inode *inode,
303878f30c31STao Ma struct ocfs2_dinode *di,
303985db90e7STao Ma struct ocfs2_xattr_info *xi,
304085db90e7STao Ma struct ocfs2_xattr_search *xis,
304178f30c31STao Ma struct ocfs2_xattr_search *xbs,
304278f30c31STao Ma int *clusters_need,
304385db90e7STao Ma int *meta_need,
304478f30c31STao Ma int *credits_need)
304578f30c31STao Ma {
304678f30c31STao Ma int ret = 0, old_in_xb = 0;
304778f30c31STao Ma int clusters_add = 0, meta_add = 0, credits = 0;
304878f30c31STao Ma struct buffer_head *bh = NULL;
304978f30c31STao Ma struct ocfs2_xattr_block *xb = NULL;
305078f30c31STao Ma struct ocfs2_xattr_entry *xe = NULL;
30516b240ff6SJoel Becker struct ocfs2_xattr_value_root *xv = NULL;
305278f30c31STao Ma char *base = NULL;
305378f30c31STao Ma int name_offset, name_len = 0;
305471d548a6STao Ma u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
305571d548a6STao Ma xi->xi_value_len);
305671d548a6STao Ma u64 value_size;
305771d548a6STao Ma
305871d548a6STao Ma /*
30596b240ff6SJoel Becker * Calculate the clusters we need to write.
306071d548a6STao Ma * No matter whether we replace an old one or add a new one,
306171d548a6STao Ma * we need this for writing.
306271d548a6STao Ma */
306378f30c31STao Ma if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE)
306485db90e7STao Ma credits += new_clusters *
306585db90e7STao Ma ocfs2_clusters_to_blocks(inode->i_sb, 1);
30666b240ff6SJoel Becker
306778f30c31STao Ma if (xis->not_found && xbs->not_found) {
306885db90e7STao Ma credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
306906f9da6eSGoldwyn Rodrigues
307085db90e7STao Ma if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
307178f30c31STao Ma clusters_add += new_clusters;
307278f30c31STao Ma credits += ocfs2_calc_extend_credits(inode->i_sb,
307378f30c31STao Ma &def_xv.xv.xr_list);
307478f30c31STao Ma }
307578f30c31STao Ma
307678f30c31STao Ma goto meta_guess;
307778f30c31STao Ma }
307878f30c31STao Ma
307978f30c31STao Ma if (!xis->not_found) {
308085db90e7STao Ma xe = xis->here;
308178f30c31STao Ma name_offset = le16_to_cpu(xe->xe_name_offset);
3082970e4936SJoel Becker name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
308378f30c31STao Ma base = xis->base;
308478f30c31STao Ma credits += OCFS2_INODE_UPDATE_CREDITS;
308578f30c31STao Ma } else {
308678f30c31STao Ma int i, block_off = 0;
308778f30c31STao Ma xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
308878f30c31STao Ma xe = xbs->here;
308978f30c31STao Ma name_offset = le16_to_cpu(xe->xe_name_offset);
309078f30c31STao Ma name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
3091fd68a894STao Ma i = xbs->here - xbs->header->xh_entries;
309278f30c31STao Ma old_in_xb = 1;
309378f30c31STao Ma
309478f30c31STao Ma if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
309578f30c31STao Ma ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
309685db90e7STao Ma bucket_xh(xbs->bucket),
309785db90e7STao Ma i, &block_off,
309878f30c31STao Ma &name_offset);
309985db90e7STao Ma base = bucket_block(xbs->bucket, block_off);
310085db90e7STao Ma credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
310185db90e7STao Ma } else {
310285db90e7STao Ma base = xbs->base;
310385db90e7STao Ma credits += OCFS2_XATTR_BLOCK_UPDATE_CREDITS;
310485db90e7STao Ma }
310585db90e7STao Ma }
310685db90e7STao Ma
310785db90e7STao Ma /*
310885db90e7STao Ma * delete a xattr doesn't need metadata and cluster allocation.
310985db90e7STao Ma * so just calculate the credits and return.
31106b240ff6SJoel Becker *
311185db90e7STao Ma * The credits for removing the value tree will be extended
3112a90714c1SJan Kara * by ocfs2_remove_extent itself.
311385db90e7STao Ma */
311485db90e7STao Ma if (!xi->xi_value) {
311578f30c31STao Ma if (!ocfs2_xattr_is_local(xe))
311678f30c31STao Ma credits += ocfs2_remove_extent_credits(inode->i_sb);
311778f30c31STao Ma
311878f30c31STao Ma goto out;
311978f30c31STao Ma }
312078f30c31STao Ma
312178f30c31STao Ma /* do cluster allocation guess first. */
312278f30c31STao Ma value_size = le64_to_cpu(xe->xe_value_size);
312378f30c31STao Ma
312478f30c31STao Ma if (old_in_xb) {
312578f30c31STao Ma /*
312678f30c31STao Ma * In xattr set, we always try to set the xe in inode first,
312778f30c31STao Ma * so if it can be inserted into inode successfully, the old
312878f30c31STao Ma * one will be removed from the xattr block, and this xattr
3129a90714c1SJan Kara * will be inserted into inode as a new xattr in inode.
313085db90e7STao Ma */
313185db90e7STao Ma if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
313285db90e7STao Ma clusters_add += new_clusters;
313385db90e7STao Ma credits += ocfs2_remove_extent_credits(inode->i_sb) +
313406f9da6eSGoldwyn Rodrigues OCFS2_INODE_UPDATE_CREDITS;
313578f30c31STao Ma if (!ocfs2_xattr_is_local(xe))
313678f30c31STao Ma credits += ocfs2_calc_extend_credits(
313778f30c31STao Ma inode->i_sb,
313878f30c31STao Ma &def_xv.xv.xr_list);
31396b240ff6SJoel Becker goto out;
314078f30c31STao Ma }
314178f30c31STao Ma }
314278f30c31STao Ma
314378f30c31STao Ma if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
314478f30c31STao Ma /* the new values will be stored outside. */
314578f30c31STao Ma u32 old_clusters = 0;
314678f30c31STao Ma
314778f30c31STao Ma if (!ocfs2_xattr_is_local(xe)) {
314897aff52aSTao Ma old_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
314978f30c31STao Ma value_size);
315078f30c31STao Ma xv = (struct ocfs2_xattr_value_root *)
315178f30c31STao Ma (base + name_offset + name_len);
315285db90e7STao Ma value_size = OCFS2_XATTR_ROOT_SIZE;
3153a90714c1SJan Kara } else
315478f30c31STao Ma xv = &def_xv.xv;
315585db90e7STao Ma
315678f30c31STao Ma if (old_clusters >= new_clusters) {
315778f30c31STao Ma credits += ocfs2_remove_extent_credits(inode->i_sb);
315885db90e7STao Ma goto out;
315906f9da6eSGoldwyn Rodrigues } else {
316097aff52aSTao Ma meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
316178f30c31STao Ma clusters_add += new_clusters - old_clusters;
316278f30c31STao Ma credits += ocfs2_calc_extend_credits(inode->i_sb,
316378f30c31STao Ma &xv->xr_list);
316478f30c31STao Ma if (value_size >= OCFS2_XATTR_ROOT_SIZE)
316578f30c31STao Ma goto out;
316678f30c31STao Ma }
316778f30c31STao Ma } else {
316878f30c31STao Ma /*
316978f30c31STao Ma * Now the new value will be stored inside. So if the new
31706b240ff6SJoel Becker * value is smaller than the size of value root or the old
31716b240ff6SJoel Becker * value, we don't need any allocation, otherwise we have
317278f30c31STao Ma * to guess metadata allocation.
31736b240ff6SJoel Becker */
317478f30c31STao Ma if ((ocfs2_xattr_is_local(xe) &&
317578f30c31STao Ma (value_size >= xi->xi_value_len)) ||
317678f30c31STao Ma (!ocfs2_xattr_is_local(xe) &&
317778f30c31STao Ma OCFS2_XATTR_ROOT_SIZE >= xi->xi_value_len))
317878f30c31STao Ma goto out;
317978f30c31STao Ma }
318078f30c31STao Ma
31814ae1d69bSJoel Becker meta_guess:
318278f30c31STao Ma /* calculate metadata allocation. */
318378f30c31STao Ma if (di->i_xattr_loc) {
318478f30c31STao Ma if (!xbs->xattr_bh) {
318578f30c31STao Ma ret = ocfs2_read_xattr_block(inode,
318678f30c31STao Ma le64_to_cpu(di->i_xattr_loc),
318778f30c31STao Ma &bh);
318878f30c31STao Ma if (ret) {
318978f30c31STao Ma mlog_errno(ret);
319078f30c31STao Ma goto out;
319178f30c31STao Ma }
319278f30c31STao Ma
319390cb546cSTao Ma xb = (struct ocfs2_xattr_block *)bh->b_data;
319490cb546cSTao Ma } else
319590cb546cSTao Ma xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
319690cb546cSTao Ma
319790cb546cSTao Ma /*
319890cb546cSTao Ma * If there is already an xattr tree, good, we can calculate
319990cb546cSTao Ma * like other b-trees. Otherwise we may have the chance of
320078f30c31STao Ma * create a tree, the credit calculation is borrowed from
320178f30c31STao Ma * ocfs2_calc_extend_credits with root_el = NULL. And the
320278f30c31STao Ma * new tree will be cluster based, so no meta is needed.
320378f30c31STao Ma */
320485db90e7STao Ma if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
320506f9da6eSGoldwyn Rodrigues struct ocfs2_extent_list *el =
320690cb546cSTao Ma &xb->xb_attrs.xb_root.xt_list;
320790cb546cSTao Ma meta_add += ocfs2_extend_meta_needed(el);
320878f30c31STao Ma credits += ocfs2_calc_extend_credits(inode->i_sb,
320978f30c31STao Ma el);
321078f30c31STao Ma } else
321178f30c31STao Ma credits += OCFS2_SUBALLOC_ALLOC + 1;
321278f30c31STao Ma
321378f30c31STao Ma /*
321478f30c31STao Ma * This cluster will be used either for new bucket or for
321578f30c31STao Ma * new xattr block.
321678f30c31STao Ma * If the cluster size is the same as the bucket size, one
321785db90e7STao Ma * more is needed since we may need to extend the bucket
321878f30c31STao Ma * also.
321985db90e7STao Ma */
322085db90e7STao Ma clusters_add += 1;
322178f30c31STao Ma credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
322285db90e7STao Ma if (OCFS2_XATTR_BUCKET_SIZE ==
322385db90e7STao Ma OCFS2_SB(inode->i_sb)->s_clustersize) {
322485db90e7STao Ma credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
32253ed2be71STariq Saeed clusters_add += 1;
32263ed2be71STariq Saeed }
32273ed2be71STariq Saeed } else {
32283ed2be71STariq Saeed credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
32293ed2be71STariq Saeed if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
32303ed2be71STariq Saeed struct ocfs2_extent_list *el = &def_xv.xv.xr_list;
32313ed2be71STariq Saeed meta_add += ocfs2_extend_meta_needed(el);
32323ed2be71STariq Saeed credits += ocfs2_calc_extend_credits(inode->i_sb,
323385db90e7STao Ma el);
323478f30c31STao Ma } else {
323578f30c31STao Ma meta_add += 1;
323678f30c31STao Ma }
323778f30c31STao Ma }
323878f30c31STao Ma out:
323985db90e7STao Ma if (clusters_need)
324085db90e7STao Ma *clusters_need = clusters_add;
324178f30c31STao Ma if (meta_need)
324278f30c31STao Ma *meta_need = meta_add;
324378f30c31STao Ma if (credits_need)
324478f30c31STao Ma *credits_need = credits;
324578f30c31STao Ma brelse(bh);
324678f30c31STao Ma return ret;
324778f30c31STao Ma }
324878f30c31STao Ma
ocfs2_init_xattr_set_ctxt(struct inode * inode,struct ocfs2_dinode * di,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xis,struct ocfs2_xattr_search * xbs,struct ocfs2_xattr_set_ctxt * ctxt,int extra_meta,int * credits)324978f30c31STao Ma static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
325085db90e7STao Ma struct ocfs2_dinode *di,
3251492a8a33STao Ma struct ocfs2_xattr_info *xi,
325285db90e7STao Ma struct ocfs2_xattr_search *xis,
325378f30c31STao Ma struct ocfs2_xattr_search *xbs,
325478f30c31STao Ma struct ocfs2_xattr_set_ctxt *ctxt,
325578f30c31STao Ma int extra_meta,
325678f30c31STao Ma int *credits)
325778f30c31STao Ma {
325878f30c31STao Ma int clusters_add, meta_add, ret;
325978f30c31STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
326078f30c31STao Ma
326178f30c31STao Ma memset(ctxt, 0, sizeof(struct ocfs2_xattr_set_ctxt));
326285db90e7STao Ma
326378f30c31STao Ma ocfs2_init_dealloc_ctxt(&ctxt->dealloc);
326478f30c31STao Ma
326578f30c31STao Ma ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
326678f30c31STao Ma &clusters_add, &meta_add, credits);
326778f30c31STao Ma if (ret) {
3268492a8a33STao Ma mlog_errno(ret);
3269402b4183STao Ma return ret;
3270402b4183STao Ma }
327178f30c31STao Ma
327278f30c31STao Ma meta_add += extra_meta;
327378f30c31STao Ma trace_ocfs2_init_xattr_set_ctxt(xi->xi_name, meta_add,
327478f30c31STao Ma clusters_add, *credits);
327578f30c31STao Ma
327678f30c31STao Ma if (meta_add) {
327778f30c31STao Ma ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
327878f30c31STao Ma &ctxt->meta_ac);
327978f30c31STao Ma if (ret) {
328078f30c31STao Ma mlog_errno(ret);
328178f30c31STao Ma goto out;
328278f30c31STao Ma }
328378f30c31STao Ma }
328478f30c31STao Ma
328578f30c31STao Ma if (clusters_add) {
328678f30c31STao Ma ret = ocfs2_reserve_clusters(osb, clusters_add, &ctxt->data_ac);
328778f30c31STao Ma if (ret)
328878f30c31STao Ma mlog_errno(ret);
328978f30c31STao Ma }
329078f30c31STao Ma out:
329178f30c31STao Ma if (ret) {
329278f30c31STao Ma if (ctxt->meta_ac) {
329378f30c31STao Ma ocfs2_free_alloc_context(ctxt->meta_ac);
329478f30c31STao Ma ctxt->meta_ac = NULL;
329578f30c31STao Ma }
329678f30c31STao Ma
329778f30c31STao Ma /*
329878f30c31STao Ma * We cannot have an error and a non null ctxt->data_ac.
329978f30c31STao Ma */
330078f30c31STao Ma }
330185db90e7STao Ma
330285db90e7STao Ma return ret;
330385db90e7STao Ma }
330485db90e7STao Ma
__ocfs2_xattr_set_handle(struct inode * inode,struct ocfs2_dinode * di,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xis,struct ocfs2_xattr_search * xbs,struct ocfs2_xattr_set_ctxt * ctxt)330585db90e7STao Ma static int __ocfs2_xattr_set_handle(struct inode *inode,
330685db90e7STao Ma struct ocfs2_dinode *di,
330785db90e7STao Ma struct ocfs2_xattr_info *xi,
33089f868f16STao Ma struct ocfs2_xattr_search *xis,
330985db90e7STao Ma struct ocfs2_xattr_search *xbs,
33106b240ff6SJoel Becker struct ocfs2_xattr_set_ctxt *ctxt)
331185db90e7STao Ma {
331285db90e7STao Ma int ret = 0, credits, old_found;
331385db90e7STao Ma
331485db90e7STao Ma if (!xi->xi_value) {
331585db90e7STao Ma /* Remove existing extended attribute */
331685db90e7STao Ma if (!xis->not_found)
331785db90e7STao Ma ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
331885db90e7STao Ma else if (!xbs->not_found)
331985db90e7STao Ma ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
332085db90e7STao Ma } else {
332185db90e7STao Ma /* We always try to set extended attribute into inode first*/
332285db90e7STao Ma ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
332385db90e7STao Ma if (!ret && !xbs->not_found) {
33246b240ff6SJoel Becker /*
33256b240ff6SJoel Becker * If succeed and that extended attribute existing in
332685db90e7STao Ma * external block, then we will remove it.
33279f868f16STao Ma */
332885db90e7STao Ma xi->xi_value = NULL;
332985db90e7STao Ma xi->xi_value_len = 0;
333085db90e7STao Ma
333185db90e7STao Ma old_found = xis->not_found;
333285db90e7STao Ma xis->not_found = -ENODATA;
333385db90e7STao Ma ret = ocfs2_calc_xattr_set_need(inode,
333485db90e7STao Ma di,
333585db90e7STao Ma xi,
333685db90e7STao Ma xis,
33379f868f16STao Ma xbs,
333885db90e7STao Ma NULL,
333985db90e7STao Ma NULL,
334085db90e7STao Ma &credits);
334185db90e7STao Ma xis->not_found = old_found;
334285db90e7STao Ma if (ret) {
3343c901fb00STao Ma mlog_errno(ret);
334485db90e7STao Ma goto out;
334585db90e7STao Ma }
334685db90e7STao Ma
334785db90e7STao Ma ret = ocfs2_extend_trans(ctxt->handle, credits);
334885db90e7STao Ma if (ret) {
33495f5261acSTao Ma mlog_errno(ret);
335085db90e7STao Ma goto out;
335185db90e7STao Ma }
33526b240ff6SJoel Becker ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
33536b240ff6SJoel Becker } else if ((ret == -ENOSPC) && !ctxt->set_abort) {
335485db90e7STao Ma if (di->i_xattr_loc && !xbs->xattr_bh) {
335585db90e7STao Ma ret = ocfs2_xattr_block_find(inode,
335685db90e7STao Ma xi->xi_name_index,
33579f868f16STao Ma xi->xi_name, xbs);
335885db90e7STao Ma if (ret)
335985db90e7STao Ma goto out;
336085db90e7STao Ma
336185db90e7STao Ma old_found = xis->not_found;
336285db90e7STao Ma xis->not_found = -ENODATA;
336385db90e7STao Ma ret = ocfs2_calc_xattr_set_need(inode,
336485db90e7STao Ma di,
336585db90e7STao Ma xi,
336685db90e7STao Ma xis,
33679f868f16STao Ma xbs,
336885db90e7STao Ma NULL,
336985db90e7STao Ma NULL,
337085db90e7STao Ma &credits);
337185db90e7STao Ma xis->not_found = old_found;
337285db90e7STao Ma if (ret) {
3373c901fb00STao Ma mlog_errno(ret);
337485db90e7STao Ma goto out;
337585db90e7STao Ma }
337685db90e7STao Ma
337785db90e7STao Ma ret = ocfs2_extend_trans(ctxt->handle, credits);
337885db90e7STao Ma if (ret) {
337985db90e7STao Ma mlog_errno(ret);
338085db90e7STao Ma goto out;
338185db90e7STao Ma }
338285db90e7STao Ma }
338385db90e7STao Ma /*
338485db90e7STao Ma * If no space in inode, we will set extended attribute
338585db90e7STao Ma * into external block.
338685db90e7STao Ma */
338785db90e7STao Ma ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
338885db90e7STao Ma if (ret)
338985db90e7STao Ma goto out;
339085db90e7STao Ma if (!xis->not_found) {
33916b240ff6SJoel Becker /*
33926b240ff6SJoel Becker * If succeed and that extended attribute
339385db90e7STao Ma * existing in inode, we will remove it.
339485db90e7STao Ma */
339585db90e7STao Ma xi->xi_value = NULL;
339685db90e7STao Ma xi->xi_value_len = 0;
339785db90e7STao Ma xbs->not_found = -ENODATA;
339885db90e7STao Ma ret = ocfs2_calc_xattr_set_need(inode,
339985db90e7STao Ma di,
340085db90e7STao Ma xi,
340185db90e7STao Ma xis,
340285db90e7STao Ma xbs,
340385db90e7STao Ma NULL,
340485db90e7STao Ma NULL,
340585db90e7STao Ma &credits);
340685db90e7STao Ma if (ret) {
3407c901fb00STao Ma mlog_errno(ret);
340885db90e7STao Ma goto out;
340985db90e7STao Ma }
341085db90e7STao Ma
341185db90e7STao Ma ret = ocfs2_extend_trans(ctxt->handle, credits);
341285db90e7STao Ma if (ret) {
341385db90e7STao Ma mlog_errno(ret);
341485db90e7STao Ma goto out;
341585db90e7STao Ma }
341685db90e7STao Ma ret = ocfs2_xattr_ibody_set(inode, xi,
341785db90e7STao Ma xis, ctxt);
34184b3f6209STao Ma }
34194b3f6209STao Ma }
34200cf2f763SJoel Becker }
342189a907afSTao Ma
34224b3f6209STao Ma if (!ret) {
34234b3f6209STao Ma /* Update inode ctime. */
34244b3f6209STao Ma ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode),
34254b3f6209STao Ma xis->inode_bh,
34264b3f6209STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
34274b3f6209STao Ma if (ret) {
3428078cd827SDeepa Dinamani mlog_errno(ret);
34294b3f6209STao Ma goto out;
34304b3f6209STao Ma }
34314b3f6209STao Ma
34324b3f6209STao Ma inode_set_ctime_current(inode);
343385db90e7STao Ma di->i_ctime = cpu_to_le64(inode_get_ctime_sec(inode));
343485db90e7STao Ma di->i_ctime_nsec = cpu_to_le32(inode_get_ctime_nsec(inode));
343585db90e7STao Ma ocfs2_journal_dirty(ctxt->handle, xis->inode_bh);
343685db90e7STao Ma }
3437cf1d6c76STiger Yang out:
34386c3faba4STiger Yang return ret;
34396c3faba4STiger Yang }
3440008aafafSTiger Yang
34416c3faba4STiger Yang /*
34426c3faba4STiger Yang * This function only called duing creating inode
34436c3faba4STiger Yang * for init security/acl xattrs of the new inode.
34446c3faba4STiger Yang * All transanction credits have been reserved in mknod.
34456c3faba4STiger Yang */
ocfs2_xattr_set_handle(handle_t * handle,struct inode * inode,struct buffer_head * di_bh,int name_index,const char * name,const void * value,size_t value_len,int flags,struct ocfs2_alloc_context * meta_ac,struct ocfs2_alloc_context * data_ac)34466c3faba4STiger Yang int ocfs2_xattr_set_handle(handle_t *handle,
34476c3faba4STiger Yang struct inode *inode,
34486c3faba4STiger Yang struct buffer_head *di_bh,
34496c3faba4STiger Yang int name_index,
34506c3faba4STiger Yang const char *name,
34516c3faba4STiger Yang const void *value,
34526c3faba4STiger Yang size_t value_len,
34536c3faba4STiger Yang int flags,
34546c3faba4STiger Yang struct ocfs2_alloc_context *meta_ac,
34556c3faba4STiger Yang struct ocfs2_alloc_context *data_ac)
34566c3faba4STiger Yang {
34576b240ff6SJoel Becker struct ocfs2_dinode *di;
34586b240ff6SJoel Becker int ret;
345918853b95SJoel Becker
34606b240ff6SJoel Becker struct ocfs2_xattr_info xi = {
34616b240ff6SJoel Becker .xi_name_index = name_index,
34626c3faba4STiger Yang .xi_name = name,
34636c3faba4STiger Yang .xi_name_len = strlen(name),
34646c3faba4STiger Yang .xi_value = value,
34656c3faba4STiger Yang .xi_value_len = value_len,
34666c3faba4STiger Yang };
34676c3faba4STiger Yang
34686c3faba4STiger Yang struct ocfs2_xattr_search xis = {
34696c3faba4STiger Yang .not_found = -ENODATA,
34706c3faba4STiger Yang };
34716c3faba4STiger Yang
34726c3faba4STiger Yang struct ocfs2_xattr_search xbs = {
34736c3faba4STiger Yang .not_found = -ENODATA,
34746c3faba4STiger Yang };
34756c3faba4STiger Yang
34766c3faba4STiger Yang struct ocfs2_xattr_set_ctxt ctxt = {
34776c3faba4STiger Yang .handle = handle,
34786c3faba4STiger Yang .meta_ac = meta_ac,
34796c3faba4STiger Yang .data_ac = data_ac,
34806c3faba4STiger Yang };
3481008aafafSTiger Yang
3482008aafafSTiger Yang if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb)))
3483008aafafSTiger Yang return -EOPNOTSUPP;
3484008aafafSTiger Yang
3485008aafafSTiger Yang /*
3486008aafafSTiger Yang * In extreme situation, may need xattr bucket when
3487008aafafSTiger Yang * block size is too small. And we have already reserved
3488008aafafSTiger Yang * the credits for bucket in mknod.
3489008aafafSTiger Yang */
3490008aafafSTiger Yang if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE) {
3491008aafafSTiger Yang xbs.bucket = ocfs2_xattr_bucket_new(inode);
3492008aafafSTiger Yang if (!xbs.bucket) {
3493008aafafSTiger Yang mlog_errno(-ENOMEM);
34946c3faba4STiger Yang return -ENOMEM;
34956c3faba4STiger Yang }
34966c3faba4STiger Yang }
34976c3faba4STiger Yang
34986c3faba4STiger Yang xis.inode_bh = xbs.inode_bh = di_bh;
34996c3faba4STiger Yang di = (struct ocfs2_dinode *)di_bh->b_data;
35006c3faba4STiger Yang
35016c3faba4STiger Yang down_write(&OCFS2_I(inode)->ip_xattr_sem);
35026c3faba4STiger Yang
35036c3faba4STiger Yang ret = ocfs2_xattr_ibody_find(inode, name_index, name, &xis);
35046c3faba4STiger Yang if (ret)
35056c3faba4STiger Yang goto cleanup;
35066c3faba4STiger Yang if (xis.not_found) {
35076c3faba4STiger Yang ret = ocfs2_xattr_block_find(inode, name_index, name, &xbs);
35086c3faba4STiger Yang if (ret)
35096c3faba4STiger Yang goto cleanup;
35106c3faba4STiger Yang }
35116c3faba4STiger Yang
35126c3faba4STiger Yang ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt);
3513008aafafSTiger Yang
35146c3faba4STiger Yang cleanup:
35156c3faba4STiger Yang up_write(&OCFS2_I(inode)->ip_xattr_sem);
35166c3faba4STiger Yang brelse(xbs.xattr_bh);
35176c3faba4STiger Yang ocfs2_xattr_bucket_free(xbs.bucket);
35186c3faba4STiger Yang
3519cf1d6c76STiger Yang return ret;
3520cf1d6c76STiger Yang }
3521cf1d6c76STiger Yang
3522cf1d6c76STiger Yang /*
3523cf1d6c76STiger Yang * ocfs2_xattr_set()
3524cf1d6c76STiger Yang *
3525cf1d6c76STiger Yang * Set, replace or remove an extended attribute for this inode.
3526cf1d6c76STiger Yang * value is NULL to remove an existing extended attribute, else either
3527cf1d6c76STiger Yang * create or replace an extended attribute.
3528cf1d6c76STiger Yang */
ocfs2_xattr_set(struct inode * inode,int name_index,const char * name,const void * value,size_t value_len,int flags)3529cf1d6c76STiger Yang int ocfs2_xattr_set(struct inode *inode,
3530cf1d6c76STiger Yang int name_index,
3531cf1d6c76STiger Yang const char *name,
3532cf1d6c76STiger Yang const void *value,
3533cf1d6c76STiger Yang size_t value_len,
35348818efaaSEric Ren int flags)
353578f30c31STao Ma {
353685db90e7STao Ma struct buffer_head *di_bh = NULL;
35376ea437a3SYounger Liu struct ocfs2_dinode *di;
3538492a8a33STao Ma int ret, credits, had_lock, ref_meta = 0, ref_credits = 0;
35398818efaaSEric Ren struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3540cf1d6c76STiger Yang struct inode *tl_inode = osb->osb_tl_inode;
3541cf1d6c76STiger Yang struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, };
35426b240ff6SJoel Becker struct ocfs2_refcount_tree *ref_tree = NULL;
35436b240ff6SJoel Becker struct ocfs2_lock_holder oh;
354418853b95SJoel Becker
35456b240ff6SJoel Becker struct ocfs2_xattr_info xi = {
35466b240ff6SJoel Becker .xi_name_index = name_index,
3547cf1d6c76STiger Yang .xi_name = name,
3548cf1d6c76STiger Yang .xi_name_len = strlen(name),
3549cf1d6c76STiger Yang .xi_value = value,
3550cf1d6c76STiger Yang .xi_value_len = value_len,
3551cf1d6c76STiger Yang };
3552cf1d6c76STiger Yang
3553cf1d6c76STiger Yang struct ocfs2_xattr_search xis = {
3554cf1d6c76STiger Yang .not_found = -ENODATA,
3555cf1d6c76STiger Yang };
3556cf1d6c76STiger Yang
35571119d3c0Spiaojun struct ocfs2_xattr_search xbs = {
35588154da3dSTiger Yang .not_found = -ENODATA,
35598154da3dSTiger Yang };
3560ba937127SJoel Becker
3561ba937127SJoel Becker if (!ocfs2_supports_xattr(osb))
3562ba937127SJoel Becker return -EOPNOTSUPP;
3563ba937127SJoel Becker
3564ba937127SJoel Becker /*
3565ba937127SJoel Becker * Only xbs will be used on indexed trees. xis doesn't need a
3566ba937127SJoel Becker * bucket.
3567ba937127SJoel Becker */
3568ba937127SJoel Becker xbs.bucket = ocfs2_xattr_bucket_new(inode);
3569ba937127SJoel Becker if (!xbs.bucket) {
35708818efaaSEric Ren mlog_errno(-ENOMEM);
35718818efaaSEric Ren return -ENOMEM;
35728818efaaSEric Ren }
3573cf1d6c76STiger Yang
3574ba937127SJoel Becker had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh);
3575cf1d6c76STiger Yang if (had_lock < 0) {
3576cf1d6c76STiger Yang ret = had_lock;
3577cf1d6c76STiger Yang mlog_errno(ret);
3578cf1d6c76STiger Yang goto cleanup_nolock;
3579cf1d6c76STiger Yang }
3580cf1d6c76STiger Yang xis.inode_bh = xbs.inode_bh = di_bh;
3581cf1d6c76STiger Yang di = (struct ocfs2_dinode *)di_bh->b_data;
358225985edcSLucas De Marchi
3583cf1d6c76STiger Yang down_write(&OCFS2_I(inode)->ip_xattr_sem);
3584cf1d6c76STiger Yang /*
3585cf1d6c76STiger Yang * Scan inode and external block to find the same name
3586cf1d6c76STiger Yang * extended attribute and collect search information.
3587cf1d6c76STiger Yang */
3588cf1d6c76STiger Yang ret = ocfs2_xattr_ibody_find(inode, name_index, name, &xis);
3589cf1d6c76STiger Yang if (ret)
3590cf1d6c76STiger Yang goto cleanup;
3591cf1d6c76STiger Yang if (xis.not_found) {
3592cf1d6c76STiger Yang ret = ocfs2_xattr_block_find(inode, name_index, name, &xbs);
3593cf1d6c76STiger Yang if (ret)
3594cf1d6c76STiger Yang goto cleanup;
3595cf1d6c76STiger Yang }
3596cf1d6c76STiger Yang
3597cf1d6c76STiger Yang if (xis.not_found && xbs.not_found) {
3598cf1d6c76STiger Yang ret = -ENODATA;
3599cf1d6c76STiger Yang if (flags & XATTR_REPLACE)
3600cf1d6c76STiger Yang goto cleanup;
3601cf1d6c76STiger Yang ret = 0;
3602cf1d6c76STiger Yang if (!value)
3603cf1d6c76STiger Yang goto cleanup;
3604cf1d6c76STiger Yang } else {
3605cf1d6c76STiger Yang ret = -EEXIST;
360625985edcSLucas De Marchi if (flags & XATTR_CREATE)
360784e40080SDarrick J. Wong goto cleanup;
3608492a8a33STao Ma }
3609492a8a33STao Ma
3610492a8a33STao Ma /* Check whether the value is refcounted and do some preparation. */
3611492a8a33STao Ma if (ocfs2_is_refcount_inode(inode) &&
3612492a8a33STao Ma (!xis.not_found || !xbs.not_found)) {
3613492a8a33STao Ma ret = ocfs2_prepare_refcount_xattr(inode, di, &xi,
3614492a8a33STao Ma &xis, &xbs, &ref_tree,
3615492a8a33STao Ma &ref_meta, &ref_credits);
3616492a8a33STao Ma if (ret) {
361785db90e7STao Ma mlog_errno(ret);
36185955102cSAl Viro goto cleanup;
361985db90e7STao Ma }
362085db90e7STao Ma }
362185db90e7STao Ma
362285db90e7STao Ma inode_lock(tl_inode);
36235955102cSAl Viro
362485db90e7STao Ma if (ocfs2_truncate_log_needs_flush(osb)) {
362585db90e7STao Ma ret = __ocfs2_flush_truncate_log(osb);
362685db90e7STao Ma if (ret < 0) {
362785db90e7STao Ma inode_unlock(tl_inode);
36285955102cSAl Viro mlog_errno(ret);
362985db90e7STao Ma goto cleanup;
363085db90e7STao Ma }
3631492a8a33STao Ma }
363278f30c31STao Ma inode_unlock(tl_inode);
363378f30c31STao Ma
363478f30c31STao Ma ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis,
363578f30c31STao Ma &xbs, &ctxt, ref_meta, &credits);
363678f30c31STao Ma if (ret) {
36374b3f6209STao Ma mlog_errno(ret);
36384b3f6209STao Ma goto cleanup;
3639492a8a33STao Ma }
364085db90e7STao Ma
364185db90e7STao Ma /* we need to update inode's ctime field, so add credit for it. */
364285db90e7STao Ma credits += OCFS2_INODE_UPDATE_CREDITS;
36436ea437a3SYounger Liu ctxt.handle = ocfs2_start_trans(osb, credits + ref_credits);
3644cf1d6c76STiger Yang if (IS_ERR(ctxt.handle)) {
364585db90e7STao Ma ret = PTR_ERR(ctxt.handle);
364685db90e7STao Ma mlog_errno(ret);
36476fdb702dSDarrick J. Wong goto out_free_ac;
364885db90e7STao Ma }
364985db90e7STao Ma
365085db90e7STao Ma ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt);
36516ea437a3SYounger Liu ocfs2_update_inode_fsync_trans(ctxt.handle, inode, 0);
365278f30c31STao Ma
365378f30c31STao Ma ocfs2_commit_trans(osb, ctxt.handle);
365478f30c31STao Ma
365578f30c31STao Ma out_free_ac:
365678f30c31STao Ma if (ctxt.data_ac)
365778f30c31STao Ma ocfs2_free_alloc_context(ctxt.data_ac);
365878f30c31STao Ma if (ctxt.meta_ac)
36598b2c0dbaSTao Ma ocfs2_free_alloc_context(ctxt.meta_ac);
3660cf1d6c76STiger Yang if (ocfs2_dealloc_has_cluster(&ctxt.dealloc))
3661492a8a33STao Ma ocfs2_schedule_truncate_log_flush(osb, 1);
3662492a8a33STao Ma ocfs2_run_deallocs(osb, &ctxt.dealloc);
3663cf1d6c76STiger Yang
36648b2c0dbaSTao Ma cleanup:
36658b2c0dbaSTao Ma if (ref_tree)
36668b2c0dbaSTao Ma ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
36678b2c0dbaSTao Ma up_write(&OCFS2_I(inode)->ip_xattr_sem);
36688b2c0dbaSTao Ma if (!value && !ret) {
36698818efaaSEric Ren ret = ocfs2_try_remove_refcount_tree(inode, di_bh);
3670ba937127SJoel Becker if (ret)
3671cf1d6c76STiger Yang mlog_errno(ret);
3672cf1d6c76STiger Yang }
3673ba937127SJoel Becker ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
3674cf1d6c76STiger Yang cleanup_nolock:
3675cf1d6c76STiger Yang brelse(di_bh);
3676cf1d6c76STiger Yang brelse(xbs.xattr_bh);
3677cf1d6c76STiger Yang ocfs2_xattr_bucket_free(xbs.bucket);
36780c044f0bSTao Ma
36790c044f0bSTao Ma return ret;
36800c044f0bSTao Ma }
36810c044f0bSTao Ma
36820c044f0bSTao Ma /*
36830c044f0bSTao Ma * Find the xattr extent rec which may contains name_hash.
36840c044f0bSTao Ma * e_cpos will be the first name hash of the xattr rec.
36850c044f0bSTao Ma * el must be the ocfs2_xattr_header.xb_attrs.xb_root.xt_list.
36860c044f0bSTao Ma */
ocfs2_xattr_get_rec(struct inode * inode,u32 name_hash,u64 * p_blkno,u32 * e_cpos,u32 * num_clusters,struct ocfs2_extent_list * el)36870c044f0bSTao Ma static int ocfs2_xattr_get_rec(struct inode *inode,
36880c044f0bSTao Ma u32 name_hash,
36890c044f0bSTao Ma u64 *p_blkno,
36900c044f0bSTao Ma u32 *e_cpos,
36910c044f0bSTao Ma u32 *num_clusters,
36920c044f0bSTao Ma struct ocfs2_extent_list *el)
36930c044f0bSTao Ma {
36940c044f0bSTao Ma int ret = 0, i;
36950c044f0bSTao Ma struct buffer_head *eb_bh = NULL;
36960c044f0bSTao Ma struct ocfs2_extent_block *eb;
3697facdb77fSJoel Becker struct ocfs2_extent_rec *rec = NULL;
3698facdb77fSJoel Becker u64 e_blkno = 0;
36990c044f0bSTao Ma
37000c044f0bSTao Ma if (el->l_tree_depth) {
37010c044f0bSTao Ma ret = ocfs2_find_leaf(INODE_CACHE(inode), el, name_hash,
37020c044f0bSTao Ma &eb_bh);
37030c044f0bSTao Ma if (ret) {
37040c044f0bSTao Ma mlog_errno(ret);
37050c044f0bSTao Ma goto out;
37060c044f0bSTao Ma }
37070c044f0bSTao Ma
370817a5b9abSGoldwyn Rodrigues eb = (struct ocfs2_extent_block *) eb_bh->b_data;
37097ecef14aSJoe Perches el = &eb->h_list;
37107ecef14aSJoe Perches
37110c044f0bSTao Ma if (el->l_tree_depth) {
37120c044f0bSTao Ma ret = ocfs2_error(inode->i_sb,
37130c044f0bSTao Ma "Inode %lu has non zero tree depth in xattr tree block %llu\n",
37140c044f0bSTao Ma inode->i_ino,
37150c044f0bSTao Ma (unsigned long long)eb_bh->b_blocknr);
37160c044f0bSTao Ma goto out;
37170c044f0bSTao Ma }
37180c044f0bSTao Ma }
37190c044f0bSTao Ma
37200c044f0bSTao Ma for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
37210c044f0bSTao Ma rec = &el->l_recs[i];
37220c044f0bSTao Ma
37230c044f0bSTao Ma if (le32_to_cpu(rec->e_cpos) <= name_hash) {
37240c044f0bSTao Ma e_blkno = le64_to_cpu(rec->e_blkno);
37250c044f0bSTao Ma break;
37267ecef14aSJoe Perches }
37277ecef14aSJoe Perches }
37280c044f0bSTao Ma
37290c044f0bSTao Ma if (!e_blkno) {
37300c044f0bSTao Ma ret = ocfs2_error(inode->i_sb, "Inode %lu has bad extent record (%u, %u, 0) in xattr\n",
37310c044f0bSTao Ma inode->i_ino,
37320c044f0bSTao Ma le32_to_cpu(rec->e_cpos),
37330c044f0bSTao Ma ocfs2_rec_clusters(el, rec));
37340c044f0bSTao Ma goto out;
37350c044f0bSTao Ma }
37360c044f0bSTao Ma
37370c044f0bSTao Ma *p_blkno = le64_to_cpu(rec->e_blkno);
37380c044f0bSTao Ma *num_clusters = le16_to_cpu(rec->e_leaf_clusters);
37390c044f0bSTao Ma if (e_cpos)
37400c044f0bSTao Ma *e_cpos = le32_to_cpu(rec->e_cpos);
37410c044f0bSTao Ma out:
37420c044f0bSTao Ma brelse(eb_bh);
37430c044f0bSTao Ma return ret;
37440c044f0bSTao Ma }
37450c044f0bSTao Ma
3746589dc260STao Ma typedef int (xattr_bucket_func)(struct inode *inode,
3747e2356a3fSJoel Becker struct ocfs2_xattr_bucket *bucket,
3748589dc260STao Ma void *para);
3749589dc260STao Ma
ocfs2_find_xe_in_bucket(struct inode * inode,struct ocfs2_xattr_bucket * bucket,int name_index,const char * name,u32 name_hash,u16 * xe_index,int * found)3750589dc260STao Ma static int ocfs2_find_xe_in_bucket(struct inode *inode,
3751589dc260STao Ma struct ocfs2_xattr_bucket *bucket,
3752589dc260STao Ma int name_index,
3753589dc260STao Ma const char *name,
3754589dc260STao Ma u32 name_hash,
3755e2356a3fSJoel Becker u16 *xe_index,
3756589dc260STao Ma int *found)
3757589dc260STao Ma {
3758589dc260STao Ma int i, ret = 0, cmp = 1, block_off, new_offset;
3759589dc260STao Ma struct ocfs2_xattr_header *xh = bucket_xh(bucket);
3760589dc260STao Ma size_t name_len = strlen(name);
3761589dc260STao Ma struct ocfs2_xattr_entry *xe = NULL;
3762589dc260STao Ma char *xe_name;
3763589dc260STao Ma
3764589dc260STao Ma /*
3765589dc260STao Ma * We don't use binary search in the bucket because there
3766589dc260STao Ma * may be multiple entries with the same name hash.
3767589dc260STao Ma */
3768589dc260STao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
3769589dc260STao Ma xe = &xh->xh_entries[i];
3770589dc260STao Ma
3771589dc260STao Ma if (name_hash > le32_to_cpu(xe->xe_name_hash))
3772589dc260STao Ma continue;
3773589dc260STao Ma else if (name_hash < le32_to_cpu(xe->xe_name_hash))
3774589dc260STao Ma break;
3775589dc260STao Ma
3776589dc260STao Ma cmp = name_index - ocfs2_xattr_get_type(xe);
3777589dc260STao Ma if (!cmp)
3778fd68a894STao Ma cmp = name_len - xe->xe_name_len;
3779589dc260STao Ma if (cmp)
3780589dc260STao Ma continue;
3781589dc260STao Ma
3782589dc260STao Ma ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
3783589dc260STao Ma xh,
3784589dc260STao Ma i,
3785589dc260STao Ma &block_off,
3786589dc260STao Ma &new_offset);
3787589dc260STao Ma if (ret) {
3788970e4936SJoel Becker mlog_errno(ret);
3789e2356a3fSJoel Becker break;
3790e2356a3fSJoel Becker }
3791589dc260STao Ma
3792589dc260STao Ma
3793589dc260STao Ma xe_name = bucket_block(bucket, block_off) + new_offset;
3794589dc260STao Ma if (!memcmp(name, xe_name, name_len)) {
3795589dc260STao Ma *xe_index = i;
3796589dc260STao Ma *found = 1;
3797589dc260STao Ma ret = 0;
3798589dc260STao Ma break;
3799589dc260STao Ma }
3800589dc260STao Ma }
3801589dc260STao Ma
3802589dc260STao Ma return ret;
3803589dc260STao Ma }
3804589dc260STao Ma
3805589dc260STao Ma /*
3806589dc260STao Ma * Find the specified xattr entry in a series of buckets.
3807589dc260STao Ma * This series start from p_blkno and last for num_clusters.
3808589dc260STao Ma * The ocfs2_xattr_header.xh_num_buckets of the first bucket contains
3809589dc260STao Ma * the num of the valid buckets.
3810589dc260STao Ma *
3811589dc260STao Ma * Return the buffer_head this xattr should reside in. And if the xattr's
3812589dc260STao Ma * hash is in the gap of 2 buckets, return the lower bucket.
3813589dc260STao Ma */
ocfs2_xattr_bucket_find(struct inode * inode,int name_index,const char * name,u32 name_hash,u64 p_blkno,u32 first_hash,u32 num_clusters,struct ocfs2_xattr_search * xs)3814589dc260STao Ma static int ocfs2_xattr_bucket_find(struct inode *inode,
3815589dc260STao Ma int name_index,
3816589dc260STao Ma const char *name,
3817589dc260STao Ma u32 name_hash,
3818589dc260STao Ma u64 p_blkno,
3819589dc260STao Ma u32 first_hash,
3820589dc260STao Ma u32 num_clusters,
3821589dc260STao Ma struct ocfs2_xattr_search *xs)
3822589dc260STao Ma {
3823589dc260STao Ma int ret, found = 0;
3824589dc260STao Ma struct ocfs2_xattr_header *xh = NULL;
3825e2356a3fSJoel Becker struct ocfs2_xattr_entry *xe = NULL;
3826e2356a3fSJoel Becker u16 index = 0;
3827589dc260STao Ma u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3828e2356a3fSJoel Becker int low_bucket = 0, bucket, high_bucket;
3829e2356a3fSJoel Becker struct ocfs2_xattr_bucket *search;
3830e2356a3fSJoel Becker u64 blkno, lower_blkno = 0;
3831e2356a3fSJoel Becker
3832e2356a3fSJoel Becker search = ocfs2_xattr_bucket_new(inode);
3833e2356a3fSJoel Becker if (!search) {
3834e2356a3fSJoel Becker ret = -ENOMEM;
3835e2356a3fSJoel Becker mlog_errno(ret);
3836589dc260STao Ma goto out;
3837589dc260STao Ma }
3838589dc260STao Ma
3839589dc260STao Ma ret = ocfs2_read_xattr_bucket(search, p_blkno);
3840589dc260STao Ma if (ret) {
3841e2356a3fSJoel Becker mlog_errno(ret);
3842589dc260STao Ma goto out;
3843589dc260STao Ma }
3844e2356a3fSJoel Becker
3845e2356a3fSJoel Becker xh = bucket_xh(search);
3846589dc260STao Ma high_bucket = le16_to_cpu(xh->xh_num_buckets) - 1;
3847589dc260STao Ma while (low_bucket <= high_bucket) {
3848e2356a3fSJoel Becker ocfs2_xattr_bucket_relse(search);
3849589dc260STao Ma
3850589dc260STao Ma bucket = (low_bucket + high_bucket) / 2;
3851589dc260STao Ma blkno = p_blkno + bucket * blk_per_bucket;
3852589dc260STao Ma ret = ocfs2_read_xattr_bucket(search, blkno);
3853589dc260STao Ma if (ret) {
3854e2356a3fSJoel Becker mlog_errno(ret);
3855589dc260STao Ma goto out;
3856589dc260STao Ma }
3857589dc260STao Ma
3858589dc260STao Ma xh = bucket_xh(search);
3859589dc260STao Ma xe = &xh->xh_entries[0];
3860589dc260STao Ma if (name_hash < le32_to_cpu(xe->xe_name_hash)) {
3861589dc260STao Ma high_bucket = bucket - 1;
3862589dc260STao Ma continue;
38635a095611STao Ma }
38645a095611STao Ma
3865589dc260STao Ma /*
38665a095611STao Ma * Check whether the hash of the last entry in our
3867589dc260STao Ma * bucket is larger than the search one. for an empty
38685a095611STao Ma * bucket, the last one is also the first one.
3869e2356a3fSJoel Becker */
3870e2356a3fSJoel Becker if (xh->xh_count)
3871589dc260STao Ma xe = &xh->xh_entries[le16_to_cpu(xh->xh_count) - 1];
3872589dc260STao Ma
3873589dc260STao Ma /* record lower_blkno which may be the insert place. */
3874589dc260STao Ma lower_blkno = blkno;
3875589dc260STao Ma
3876589dc260STao Ma if (name_hash > le32_to_cpu(xe->xe_name_hash)) {
3877589dc260STao Ma low_bucket = bucket + 1;
3878e2356a3fSJoel Becker continue;
3879589dc260STao Ma }
3880589dc260STao Ma
3881589dc260STao Ma /* the searched xattr should reside in this bucket if exists. */
3882589dc260STao Ma ret = ocfs2_find_xe_in_bucket(inode, search,
3883589dc260STao Ma name_index, name, name_hash,
3884589dc260STao Ma &index, &found);
3885589dc260STao Ma if (ret) {
3886589dc260STao Ma mlog_errno(ret);
3887589dc260STao Ma goto out;
3888589dc260STao Ma }
3889589dc260STao Ma break;
3890589dc260STao Ma }
3891589dc260STao Ma
3892589dc260STao Ma /*
3893e2356a3fSJoel Becker * Record the bucket we have found.
3894e2356a3fSJoel Becker * When the xattr's hash value is in the gap of 2 buckets, we will
3895e2356a3fSJoel Becker * always set it to the previous bucket.
3896e2356a3fSJoel Becker */
3897e2356a3fSJoel Becker if (!lower_blkno)
3898e2356a3fSJoel Becker lower_blkno = p_blkno;
3899e2356a3fSJoel Becker
3900e2356a3fSJoel Becker /* This should be in cache - we just read it during the search */
3901589dc260STao Ma ret = ocfs2_read_xattr_bucket(xs->bucket, lower_blkno);
3902589dc260STao Ma if (ret) {
3903ba937127SJoel Becker mlog_errno(ret);
3904ba937127SJoel Becker goto out;
3905589dc260STao Ma }
3906589dc260STao Ma
3907589dc260STao Ma xs->header = bucket_xh(xs->bucket);
3908589dc260STao Ma xs->base = bucket_block(xs->bucket, 0);
3909402b4183STao Ma xs->end = xs->base + inode->i_sb->s_blocksize;
3910402b4183STao Ma
3911402b4183STao Ma if (found) {
3912402b4183STao Ma xs->here = &xs->header->xh_entries[index];
3913589dc260STao Ma trace_ocfs2_xattr_bucket_find(OCFS2_I(inode)->ip_blkno,
3914589dc260STao Ma name, name_index, name_hash,
3915589dc260STao Ma (unsigned long long)bucket_blkno(xs->bucket),
3916589dc260STao Ma index);
3917e2356a3fSJoel Becker } else
3918589dc260STao Ma ret = -ENODATA;
3919589dc260STao Ma
3920589dc260STao Ma out:
3921589dc260STao Ma ocfs2_xattr_bucket_free(search);
3922589dc260STao Ma return ret;
3923589dc260STao Ma }
3924589dc260STao Ma
ocfs2_xattr_index_block_find(struct inode * inode,struct buffer_head * root_bh,int name_index,const char * name,struct ocfs2_xattr_search * xs)3925589dc260STao Ma static int ocfs2_xattr_index_block_find(struct inode *inode,
3926589dc260STao Ma struct buffer_head *root_bh,
3927589dc260STao Ma int name_index,
3928589dc260STao Ma const char *name,
3929589dc260STao Ma struct ocfs2_xattr_search *xs)
3930589dc260STao Ma {
3931589dc260STao Ma int ret;
3932589dc260STao Ma struct ocfs2_xattr_block *xb =
3933589dc260STao Ma (struct ocfs2_xattr_block *)root_bh->b_data;
39342057e5c6STao Ma struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root;
3935589dc260STao Ma struct ocfs2_extent_list *el = &xb_root->xt_list;
3936589dc260STao Ma u64 p_blkno = 0;
3937589dc260STao Ma u32 first_hash, num_clusters = 0;
3938589dc260STao Ma u32 name_hash = ocfs2_xattr_name_hash(inode, name, strlen(name));
3939402b4183STao Ma
3940402b4183STao Ma if (le16_to_cpu(el->l_next_free_rec) == 0)
3941402b4183STao Ma return -ENODATA;
3942402b4183STao Ma
3943589dc260STao Ma trace_ocfs2_xattr_index_block_find(OCFS2_I(inode)->ip_blkno,
3944589dc260STao Ma name, name_index, name_hash,
3945589dc260STao Ma (unsigned long long)root_bh->b_blocknr,
3946589dc260STao Ma -1);
3947589dc260STao Ma
3948589dc260STao Ma ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &first_hash,
3949589dc260STao Ma &num_clusters, el);
3950589dc260STao Ma if (ret) {
3951589dc260STao Ma mlog_errno(ret);
3952589dc260STao Ma goto out;
3953402b4183STao Ma }
3954402b4183STao Ma
3955402b4183STao Ma BUG_ON(p_blkno == 0 || num_clusters == 0 || first_hash > name_hash);
3956402b4183STao Ma
3957589dc260STao Ma trace_ocfs2_xattr_index_block_find_rec(OCFS2_I(inode)->ip_blkno,
3958589dc260STao Ma name, name_index, first_hash,
3959589dc260STao Ma (unsigned long long)p_blkno,
3960589dc260STao Ma num_clusters);
3961589dc260STao Ma
3962589dc260STao Ma ret = ocfs2_xattr_bucket_find(inode, name_index, name, name_hash,
3963589dc260STao Ma p_blkno, first_hash, num_clusters, xs);
3964589dc260STao Ma
39650c044f0bSTao Ma out:
39660c044f0bSTao Ma return ret;
39670c044f0bSTao Ma }
39680c044f0bSTao Ma
ocfs2_iterate_xattr_buckets(struct inode * inode,u64 blkno,u32 clusters,xattr_bucket_func * func,void * para)39690c044f0bSTao Ma static int ocfs2_iterate_xattr_buckets(struct inode *inode,
39700c044f0bSTao Ma u64 blkno,
39716dde41d9SJoel Becker u32 clusters,
39720c044f0bSTao Ma xattr_bucket_func *func,
39730c044f0bSTao Ma void *para)
3974ba937127SJoel Becker {
39750c044f0bSTao Ma int i, ret = 0;
3976ba937127SJoel Becker u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
3977ba937127SJoel Becker u32 num_buckets = clusters * bpc;
3978ba937127SJoel Becker struct ocfs2_xattr_bucket *bucket;
3979ba937127SJoel Becker
3980ba937127SJoel Becker bucket = ocfs2_xattr_bucket_new(inode);
39810c044f0bSTao Ma if (!bucket) {
3982402b4183STao Ma mlog_errno(-ENOMEM);
3983402b4183STao Ma return -ENOMEM;
3984402b4183STao Ma }
39850c044f0bSTao Ma
3986ba937127SJoel Becker trace_ocfs2_iterate_xattr_buckets(
3987ba937127SJoel Becker (unsigned long long)OCFS2_I(inode)->ip_blkno,
39880c044f0bSTao Ma (unsigned long long)blkno, clusters);
39890c044f0bSTao Ma
3990ba937127SJoel Becker for (i = 0; i < num_buckets; i++, blkno += bucket->bu_blocks) {
39910c044f0bSTao Ma ret = ocfs2_read_xattr_bucket(bucket, blkno);
39920c044f0bSTao Ma if (ret) {
39930c044f0bSTao Ma mlog_errno(ret);
39940c044f0bSTao Ma break;
39950c044f0bSTao Ma }
39960c044f0bSTao Ma
39970c044f0bSTao Ma /*
3998ba937127SJoel Becker * The real bucket num in this series of blocks is stored
39990c044f0bSTao Ma * in the 1st bucket.
4000402b4183STao Ma */
4001ba937127SJoel Becker if (i == 0)
40020c044f0bSTao Ma num_buckets = le16_to_cpu(bucket_xh(bucket)->xh_num_buckets);
4003ba937127SJoel Becker
4004a46fa684STao Ma trace_ocfs2_iterate_xattr_bucket((unsigned long long)blkno,
40050c044f0bSTao Ma le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash));
4006ba937127SJoel Becker if (func) {
4007ba937127SJoel Becker ret = func(inode, bucket, para);
4008ba937127SJoel Becker if (ret && ret != -ERANGE)
4009ba937127SJoel Becker mlog_errno(ret);
4010ba937127SJoel Becker /* Fall through to bucket_relse() */
40110c044f0bSTao Ma }
40120c044f0bSTao Ma
40130c044f0bSTao Ma ocfs2_xattr_bucket_relse(bucket);
4014ba937127SJoel Becker if (ret)
40150c044f0bSTao Ma break;
40160c044f0bSTao Ma }
40170c044f0bSTao Ma
40180c044f0bSTao Ma ocfs2_xattr_bucket_free(bucket);
40190c044f0bSTao Ma return ret;
40200c044f0bSTao Ma }
4021936b8834STao Ma
40220c044f0bSTao Ma struct ocfs2_xattr_tree_list {
40230c044f0bSTao Ma char *buffer;
4024fd68a894STao Ma size_t buffer_size;
40250c044f0bSTao Ma size_t result;
40260c044f0bSTao Ma };
40270c044f0bSTao Ma
ocfs2_xattr_bucket_get_name_value(struct super_block * sb,struct ocfs2_xattr_header * xh,int index,int * block_off,int * new_offset)40280c044f0bSTao Ma static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb,
40290c044f0bSTao Ma struct ocfs2_xattr_header *xh,
40300c044f0bSTao Ma int index,
40310c044f0bSTao Ma int *block_off,
40320c044f0bSTao Ma int *new_offset)
40330c044f0bSTao Ma {
40340c044f0bSTao Ma u16 name_offset;
40350c044f0bSTao Ma
40360c044f0bSTao Ma if (index < 0 || index >= le16_to_cpu(xh->xh_count))
4037fd68a894STao Ma return -EINVAL;
4038fd68a894STao Ma
40390c044f0bSTao Ma name_offset = le16_to_cpu(xh->xh_entries[index].xe_name_offset);
40400c044f0bSTao Ma
40410c044f0bSTao Ma *block_off = name_offset >> sb->s_blocksize_bits;
40420c044f0bSTao Ma *new_offset = name_offset % sb->s_blocksize;
40430c044f0bSTao Ma
40440c044f0bSTao Ma return 0;
40450c044f0bSTao Ma }
40460c044f0bSTao Ma
ocfs2_list_xattr_bucket(struct inode * inode,struct ocfs2_xattr_bucket * bucket,void * para)4047936b8834STao Ma static int ocfs2_list_xattr_bucket(struct inode *inode,
40480c044f0bSTao Ma struct ocfs2_xattr_bucket *bucket,
40490c044f0bSTao Ma void *para)
40501046cb11SAndreas Gruenbacher {
40510c044f0bSTao Ma int ret = 0, type;
40523e632946SJoel Becker struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para;
40533e632946SJoel Becker int i, block_off, new_offset;
4054936b8834STao Ma const char *name;
40550c044f0bSTao Ma
4056fd68a894STao Ma for (i = 0 ; i < le16_to_cpu(bucket_xh(bucket)->xh_count); i++) {
40573e632946SJoel Becker struct ocfs2_xattr_entry *entry = &bucket_xh(bucket)->xh_entries[i];
40580c044f0bSTao Ma type = ocfs2_xattr_get_type(entry);
40590c044f0bSTao Ma
40600c044f0bSTao Ma ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
40610c044f0bSTao Ma bucket_xh(bucket),
40620c044f0bSTao Ma i,
4063936b8834STao Ma &block_off,
406451def39fSJoel Becker &new_offset);
4065936b8834STao Ma if (ret)
40661046cb11SAndreas Gruenbacher break;
40671046cb11SAndreas Gruenbacher
4068936b8834STao Ma name = (const char *)bucket_block(bucket, block_off) +
4069936b8834STao Ma new_offset;
40701046cb11SAndreas Gruenbacher ret = ocfs2_xattr_list_entry(inode->i_sb,
40710c044f0bSTao Ma xl->buffer,
4072936b8834STao Ma xl->buffer_size,
4073936b8834STao Ma &xl->result,
40740c044f0bSTao Ma type, name,
40750c044f0bSTao Ma entry->xe_name_len);
40760c044f0bSTao Ma if (ret)
40770c044f0bSTao Ma break;
40780c044f0bSTao Ma }
407947bca495STao Ma
408047bca495STao Ma return ret;
408147bca495STao Ma }
408247bca495STao Ma
ocfs2_iterate_xattr_index_block(struct inode * inode,struct buffer_head * blk_bh,xattr_tree_rec_func * rec_func,void * para)40830c044f0bSTao Ma static int ocfs2_iterate_xattr_index_block(struct inode *inode,
408447bca495STao Ma struct buffer_head *blk_bh,
408547bca495STao Ma xattr_tree_rec_func *rec_func,
408647bca495STao Ma void *para)
40870c044f0bSTao Ma {
40880c044f0bSTao Ma struct ocfs2_xattr_block *xb =
40890c044f0bSTao Ma (struct ocfs2_xattr_block *)blk_bh->b_data;
40900c044f0bSTao Ma struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
409147bca495STao Ma int ret = 0;
40920c044f0bSTao Ma u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0;
40930c044f0bSTao Ma u64 p_blkno = 0;
40940c044f0bSTao Ma
40950c044f0bSTao Ma if (!el->l_next_free_rec || !rec_func)
40960c044f0bSTao Ma return 0;
40970c044f0bSTao Ma
40980c044f0bSTao Ma while (name_hash > 0) {
409947bca495STao Ma ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno,
41000c044f0bSTao Ma &e_cpos, &num_clusters, el);
41010c044f0bSTao Ma if (ret) {
410247bca495STao Ma mlog_errno(ret);
410347bca495STao Ma break;
41040c044f0bSTao Ma }
4105a46fa684STao Ma
41060c044f0bSTao Ma ret = rec_func(inode, blk_bh, p_blkno, e_cpos,
410747bca495STao Ma num_clusters, para);
41080c044f0bSTao Ma if (ret) {
41090c044f0bSTao Ma if (ret != -ERANGE)
41100c044f0bSTao Ma mlog_errno(ret);
41110c044f0bSTao Ma break;
41120c044f0bSTao Ma }
41130c044f0bSTao Ma
41140c044f0bSTao Ma if (e_cpos == 0)
41150c044f0bSTao Ma break;
411647bca495STao Ma
411747bca495STao Ma name_hash = e_cpos - 1;
411847bca495STao Ma }
411947bca495STao Ma
412047bca495STao Ma return ret;
412147bca495STao Ma
412247bca495STao Ma }
412347bca495STao Ma
ocfs2_list_xattr_tree_rec(struct inode * inode,struct buffer_head * root_bh,u64 blkno,u32 cpos,u32 len,void * para)412447bca495STao Ma static int ocfs2_list_xattr_tree_rec(struct inode *inode,
412547bca495STao Ma struct buffer_head *root_bh,
412647bca495STao Ma u64 blkno, u32 cpos, u32 len, void *para)
412747bca495STao Ma {
412847bca495STao Ma return ocfs2_iterate_xattr_buckets(inode, blkno, len,
412947bca495STao Ma ocfs2_list_xattr_bucket, para);
413047bca495STao Ma }
413147bca495STao Ma
ocfs2_xattr_tree_list_index_block(struct inode * inode,struct buffer_head * blk_bh,char * buffer,size_t buffer_size)413247bca495STao Ma static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
413347bca495STao Ma struct buffer_head *blk_bh,
413447bca495STao Ma char *buffer,
413547bca495STao Ma size_t buffer_size)
413647bca495STao Ma {
413747bca495STao Ma int ret;
413847bca495STao Ma struct ocfs2_xattr_tree_list xl = {
413947bca495STao Ma .buffer = buffer,
414047bca495STao Ma .buffer_size = buffer_size,
414147bca495STao Ma .result = 0,
414247bca495STao Ma };
414347bca495STao Ma
414447bca495STao Ma ret = ocfs2_iterate_xattr_index_block(inode, blk_bh,
414547bca495STao Ma ocfs2_list_xattr_tree_rec, &xl);
414647bca495STao Ma if (ret) {
4147936b8834STao Ma mlog_errno(ret);
41480c044f0bSTao Ma goto out;
41490c044f0bSTao Ma }
41500c044f0bSTao Ma
415101225596STao Ma ret = xl.result;
415201225596STao Ma out:
415301225596STao Ma return ret;
415401225596STao Ma }
415501225596STao Ma
cmp_xe(const void * a,const void * b)415601225596STao Ma static int cmp_xe(const void *a, const void *b)
415701225596STao Ma {
415801225596STao Ma const struct ocfs2_xattr_entry *l = a, *r = b;
415901225596STao Ma u32 l_hash = le32_to_cpu(l->xe_name_hash);
416001225596STao Ma u32 r_hash = le32_to_cpu(r->xe_name_hash);
416101225596STao Ma
416201225596STao Ma if (l_hash > r_hash)
416301225596STao Ma return 1;
416401225596STao Ma if (l_hash < r_hash)
416501225596STao Ma return -1;
416601225596STao Ma return 0;
416701225596STao Ma }
416801225596STao Ma
swap_xe(void * a,void * b,int size)416901225596STao Ma static void swap_xe(void *a, void *b, int size)
417001225596STao Ma {
417101225596STao Ma struct ocfs2_xattr_entry *l = a, *r = b, tmp;
417201225596STao Ma
417301225596STao Ma tmp = *l;
417401225596STao Ma memcpy(l, r, sizeof(struct ocfs2_xattr_entry));
417501225596STao Ma memcpy(r, &tmp, sizeof(struct ocfs2_xattr_entry));
417601225596STao Ma }
4177178eeac3SJoel Becker
4178178eeac3SJoel Becker /*
417901225596STao Ma * When the ocfs2_xattr_block is filled up, new bucket will be created
418001225596STao Ma * and all the xattr entries will be moved to the new bucket.
418101225596STao Ma * The header goes at the start of the bucket, and the names+values are
418201225596STao Ma * filled from the end. This is why *target starts as the last buffer.
418301225596STao Ma * Note: we need to sort the entries since they are not saved in order
4184178eeac3SJoel Becker * in the ocfs2_xattr_block.
418501225596STao Ma */
ocfs2_cp_xattr_block_to_bucket(struct inode * inode,struct buffer_head * xb_bh,struct ocfs2_xattr_bucket * bucket)418601225596STao Ma static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
4187178eeac3SJoel Becker struct buffer_head *xb_bh,
418801225596STao Ma struct ocfs2_xattr_bucket *bucket)
418901225596STao Ma {
419001225596STao Ma int i, blocksize = inode->i_sb->s_blocksize;
419101225596STao Ma int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
419201225596STao Ma u16 offset, size, off_change;
4193178eeac3SJoel Becker struct ocfs2_xattr_entry *xe;
419401225596STao Ma struct ocfs2_xattr_block *xb =
4195178eeac3SJoel Becker (struct ocfs2_xattr_block *)xb_bh->b_data;
4196178eeac3SJoel Becker struct ocfs2_xattr_header *xb_xh = &xb->xb_attrs.xb_header;
419701225596STao Ma struct ocfs2_xattr_header *xh = bucket_xh(bucket);
4198402b4183STao Ma u16 count = le16_to_cpu(xb_xh->xh_count);
419901225596STao Ma char *src = xb_bh->b_data;
4200178eeac3SJoel Becker char *target = bucket_block(bucket, blks - 1);
420101225596STao Ma
4202178eeac3SJoel Becker trace_ocfs2_cp_xattr_block_to_bucket_begin(
4203178eeac3SJoel Becker (unsigned long long)xb_bh->b_blocknr,
4204178eeac3SJoel Becker (unsigned long long)bucket_blkno(bucket));
420501225596STao Ma
420601225596STao Ma for (i = 0; i < blks; i++)
420701225596STao Ma memset(bucket_block(bucket, i), 0, blocksize);
420801225596STao Ma
420901225596STao Ma /*
421001225596STao Ma * Since the xe_name_offset is based on ocfs2_xattr_header,
421101225596STao Ma * there is a offset change corresponding to the change of
421201225596STao Ma * ocfs2_xattr_header's position.
421301225596STao Ma */
421401225596STao Ma off_change = offsetof(struct ocfs2_xattr_block, xb_attrs.xb_header);
421501225596STao Ma xe = &xb_xh->xh_entries[count - 1];
421601225596STao Ma offset = le16_to_cpu(xe->xe_name_offset) + off_change;
421701225596STao Ma size = blocksize - offset;
421801225596STao Ma
421901225596STao Ma /* copy all the names and values. */
422001225596STao Ma memcpy(target + offset, src + offset, size);
422101225596STao Ma
422201225596STao Ma /* Init new header now. */
422301225596STao Ma xh->xh_count = xb_xh->xh_count;
422401225596STao Ma xh->xh_num_buckets = cpu_to_le16(1);
4225178eeac3SJoel Becker xh->xh_name_value_len = cpu_to_le16(size);
422601225596STao Ma xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE - size);
422701225596STao Ma
422801225596STao Ma /* copy all the entries. */
422901225596STao Ma target = bucket_block(bucket, 0);
423001225596STao Ma offset = offsetof(struct ocfs2_xattr_header, xh_entries);
423101225596STao Ma size = count * sizeof(struct ocfs2_xattr_entry);
423201225596STao Ma memcpy(target + offset, (char *)xb_xh + offset, size);
423301225596STao Ma
423401225596STao Ma /* Change the xe offset for all the xe because of the move. */
423501225596STao Ma off_change = OCFS2_XATTR_BUCKET_SIZE - blocksize +
4236402b4183STao Ma offsetof(struct ocfs2_xattr_block, xb_attrs.xb_header);
423701225596STao Ma for (i = 0; i < count; i++)
423801225596STao Ma le16_add_cpu(&xh->xh_entries[i].xe_name_offset, off_change);
423901225596STao Ma
424001225596STao Ma trace_ocfs2_cp_xattr_block_to_bucket_end(offset, size, off_change);
424101225596STao Ma
424201225596STao Ma sort(target + offset, count, sizeof(struct ocfs2_xattr_entry),
424301225596STao Ma cmp_xe, swap_xe);
424401225596STao Ma }
424501225596STao Ma
424601225596STao Ma /*
424701225596STao Ma * After we move xattr from block to index btree, we have to
424801225596STao Ma * update ocfs2_xattr_search to the new xe and base.
424901225596STao Ma *
4250178eeac3SJoel Becker * When the entry is in xattr block, xattr_bh indicates the storage place.
425101225596STao Ma * While if the entry is in index b-tree, "bucket" indicates the
4252178eeac3SJoel Becker * real place of the xattr.
425301225596STao Ma */
ocfs2_xattr_update_xattr_search(struct inode * inode,struct ocfs2_xattr_search * xs,struct buffer_head * old_bh)425401225596STao Ma static void ocfs2_xattr_update_xattr_search(struct inode *inode,
425501225596STao Ma struct ocfs2_xattr_search *xs,
425601225596STao Ma struct buffer_head *old_bh)
4257178eeac3SJoel Becker {
425801225596STao Ma char *buf = old_bh->b_data;
4259ba937127SJoel Becker struct ocfs2_xattr_block *old_xb = (struct ocfs2_xattr_block *)buf;
4260178eeac3SJoel Becker struct ocfs2_xattr_header *old_xh = &old_xb->xb_attrs.xb_header;
426101225596STao Ma int i;
426201225596STao Ma
4263178eeac3SJoel Becker xs->header = bucket_xh(xs->bucket);
4264178eeac3SJoel Becker xs->base = bucket_block(xs->bucket, 0);
426501225596STao Ma xs->end = xs->base + inode->i_sb->s_blocksize;
426601225596STao Ma
426701225596STao Ma if (xs->not_found)
426801225596STao Ma return;
426901225596STao Ma
427001225596STao Ma i = xs->here - old_xh->xh_entries;
427178f30c31STao Ma xs->here = &xs->header->xh_entries[i];
427278f30c31STao Ma }
427301225596STao Ma
ocfs2_xattr_create_index_block(struct inode * inode,struct ocfs2_xattr_search * xs,struct ocfs2_xattr_set_ctxt * ctxt)427485db90e7STao Ma static int ocfs2_xattr_create_index_block(struct inode *inode,
427501225596STao Ma struct ocfs2_xattr_search *xs,
427601225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
427785db90e7STao Ma {
427801225596STao Ma int ret;
427901225596STao Ma u32 bit_off, len;
428001225596STao Ma u64 blkno;
428101225596STao Ma handle_t *handle = ctxt->handle;
428201225596STao Ma struct ocfs2_inode_info *oi = OCFS2_I(inode);
428301225596STao Ma struct buffer_head *xb_bh = xs->xattr_bh;
428401225596STao Ma struct ocfs2_xattr_block *xb =
4285402b4183STao Ma (struct ocfs2_xattr_block *)xb_bh->b_data;
428601225596STao Ma struct ocfs2_xattr_tree_root *xr;
428701225596STao Ma u16 xb_flags = le16_to_cpu(xb->xb_flags);
428801225596STao Ma
4289178eeac3SJoel Becker trace_ocfs2_xattr_create_index_block_begin(
429001225596STao Ma (unsigned long long)xb_bh->b_blocknr);
429101225596STao Ma
429201225596STao Ma BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
429301225596STao Ma BUG_ON(!xs->bucket);
429401225596STao Ma
429501225596STao Ma /*
429601225596STao Ma * XXX:
429701225596STao Ma * We can use this lock for now, and maybe move to a dedicated mutex
42980cf2f763SJoel Becker * if performance becomes a problem later.
429901225596STao Ma */
430001225596STao Ma down_write(&oi->ip_alloc_sem);
430101225596STao Ma
430285db90e7STao Ma ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), xb_bh,
430301225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
430401225596STao Ma if (ret) {
43051ed9b777SJoel Becker mlog_errno(ret);
430678f30c31STao Ma goto out;
430701225596STao Ma }
430801225596STao Ma
430985db90e7STao Ma ret = __ocfs2_claim_clusters(handle, ctxt->data_ac,
431001225596STao Ma 1, 1, &bit_off, &len);
431101225596STao Ma if (ret) {
431201225596STao Ma mlog_errno(ret);
431301225596STao Ma goto out;
431401225596STao Ma }
431501225596STao Ma
431601225596STao Ma /*
431701225596STao Ma * The bucket may spread in many blocks, and
431801225596STao Ma * we will only touch the 1st block and the last block
4319402b4183STao Ma * in the whole bucket(one for entry and one for data).
432001225596STao Ma */
43219c339255SWengang Wang blkno = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
4322178eeac3SJoel Becker
432301225596STao Ma trace_ocfs2_xattr_create_index_block((unsigned long long)blkno);
432485db90e7STao Ma
432501225596STao Ma ret = ocfs2_init_xattr_bucket(xs->bucket, blkno, 1);
432601225596STao Ma if (ret) {
4327178eeac3SJoel Becker mlog_errno(ret);
432801225596STao Ma goto out;
432901225596STao Ma }
433001225596STao Ma
433185db90e7STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
433201225596STao Ma OCFS2_JOURNAL_ACCESS_CREATE);
433301225596STao Ma if (ret) {
4334178eeac3SJoel Becker mlog_errno(ret);
4335178eeac3SJoel Becker goto out;
433601225596STao Ma }
4337178eeac3SJoel Becker
433801225596STao Ma ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
433901225596STao Ma ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
434001225596STao Ma
434101225596STao Ma ocfs2_xattr_update_xattr_search(inode, xs, xb_bh);
434201225596STao Ma
434301225596STao Ma /* Change from ocfs2_xattr_header to ocfs2_xattr_tree_root */
434401225596STao Ma memset(&xb->xb_attrs, 0, inode->i_sb->s_blocksize -
434501225596STao Ma offsetof(struct ocfs2_xattr_block, xb_attrs));
434601225596STao Ma
434701225596STao Ma xr = &xb->xb_attrs.xb_root;
434801225596STao Ma xr->xt_clusters = cpu_to_le32(1);
434901225596STao Ma xr->xt_last_eb_blk = 0;
435001225596STao Ma xr->xt_list.l_tree_depth = 0;
435101225596STao Ma xr->xt_list.l_count = cpu_to_le16(ocfs2_xattr_recs_per_xb(inode->i_sb));
435201225596STao Ma xr->xt_list.l_next_free_rec = cpu_to_le16(1);
435301225596STao Ma
435401225596STao Ma xr->xt_list.l_recs[0].e_cpos = 0;
435501225596STao Ma xr->xt_list.l_recs[0].e_blkno = cpu_to_le64(blkno);
435685db90e7STao Ma xr->xt_list.l_recs[0].e_leaf_clusters = cpu_to_le16(1);
435701225596STao Ma
435885db90e7STao Ma xb->xb_flags = cpu_to_le16(xb_flags | OCFS2_XATTR_INDEXED);
435901225596STao Ma
436001225596STao Ma ocfs2_journal_dirty(handle, xb_bh);
436101225596STao Ma
436201225596STao Ma out:
436301225596STao Ma up_write(&oi->ip_alloc_sem);
436401225596STao Ma
436501225596STao Ma return ret;
436601225596STao Ma }
436701225596STao Ma
cmp_xe_offset(const void * a,const void * b)436801225596STao Ma static int cmp_xe_offset(const void *a, const void *b)
436901225596STao Ma {
437001225596STao Ma const struct ocfs2_xattr_entry *l = a, *r = b;
437101225596STao Ma u32 l_name_offset = le16_to_cpu(l->xe_name_offset);
437201225596STao Ma u32 r_name_offset = le16_to_cpu(r->xe_name_offset);
437301225596STao Ma
437401225596STao Ma if (l_name_offset < r_name_offset)
437501225596STao Ma return 1;
437601225596STao Ma if (l_name_offset > r_name_offset)
437701225596STao Ma return -1;
437801225596STao Ma return 0;
437901225596STao Ma }
438001225596STao Ma
438101225596STao Ma /*
438201225596STao Ma * defrag a xattr bucket if we find that the bucket has some
438301225596STao Ma * holes beteen name/value pairs.
438485db90e7STao Ma * We will move all the name/value pairs to the end of the bucket
438501225596STao Ma * so that we can spare some space for insertion.
438601225596STao Ma */
ocfs2_defrag_xattr_bucket(struct inode * inode,handle_t * handle,struct ocfs2_xattr_bucket * bucket)438701225596STao Ma static int ocfs2_defrag_xattr_bucket(struct inode *inode,
4388199799a3SJoel Becker handle_t *handle,
438901225596STao Ma struct ocfs2_xattr_bucket *bucket)
439001225596STao Ma {
43919c7759aaSJoel Becker int ret, i;
439201225596STao Ma size_t end, offset, len;
439301225596STao Ma struct ocfs2_xattr_header *xh;
439401225596STao Ma char *entries, *buf, *bucket_buf = NULL;
439501225596STao Ma u64 blkno = bucket_blkno(bucket);
439601225596STao Ma u16 xh_free_start;
439701225596STao Ma size_t blocksize = inode->i_sb->s_blocksize;
439801225596STao Ma struct ocfs2_xattr_entry *xe;
439901225596STao Ma
440001225596STao Ma /*
440101225596STao Ma * In order to make the operation more efficient and generic,
440201225596STao Ma * we copy all the blocks into a contiguous memory and do the
440301225596STao Ma * defragment there, so if anything is error, we will not touch
440401225596STao Ma * the real block.
440501225596STao Ma */
440601225596STao Ma bucket_buf = kmalloc(OCFS2_XATTR_BUCKET_SIZE, GFP_NOFS);
440701225596STao Ma if (!bucket_buf) {
4408161d6f30SJoel Becker ret = -EIO;
44091c32a2fdSTao Ma goto out;
44101c32a2fdSTao Ma }
4411161d6f30SJoel Becker
44121c32a2fdSTao Ma buf = bucket_buf;
441301225596STao Ma for (i = 0; i < bucket->bu_blocks; i++, buf += blocksize)
441401225596STao Ma memcpy(buf, bucket_block(bucket, i), blocksize);
441501225596STao Ma
441685db90e7STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, bucket,
441701225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
441801225596STao Ma if (ret < 0) {
441901225596STao Ma mlog_errno(ret);
442001225596STao Ma goto out;
442101225596STao Ma }
442201225596STao Ma
4423402b4183STao Ma xh = (struct ocfs2_xattr_header *)bucket_buf;
4424de29c085SMark Fasheh entries = (char *)xh->xh_entries;
4425de29c085SMark Fasheh xh_free_start = le16_to_cpu(xh->xh_free_start);
442601225596STao Ma
442701225596STao Ma trace_ocfs2_defrag_xattr_bucket(
442801225596STao Ma (unsigned long long)blkno, le16_to_cpu(xh->xh_count),
442901225596STao Ma xh_free_start, le16_to_cpu(xh->xh_name_value_len));
443001225596STao Ma
443101225596STao Ma /*
443201225596STao Ma * sort all the entries by their offset.
443301225596STao Ma * the largest will be the first, so that we can
443401225596STao Ma * move them to the end one by one.
443501225596STao Ma */
443601225596STao Ma sort(entries, le16_to_cpu(xh->xh_count),
443701225596STao Ma sizeof(struct ocfs2_xattr_entry),
443801225596STao Ma cmp_xe_offset, swap_xe);
443901225596STao Ma
444001225596STao Ma /* Move all name/values to the end of the bucket. */
4441199799a3SJoel Becker xe = xh->xh_entries;
444201225596STao Ma end = OCFS2_XATTR_BUCKET_SIZE;
444301225596STao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++, xe++) {
444401225596STao Ma offset = le16_to_cpu(xe->xe_name_offset);
444501225596STao Ma len = namevalue_size_xe(xe);
444601225596STao Ma
444701225596STao Ma /*
444801225596STao Ma * We must make sure that the name/value pair
444901225596STao Ma * exist in the same block. So adjust end to
445001225596STao Ma * the previous block end if needed.
445101225596STao Ma */
445201225596STao Ma if (((end - len) / blocksize !=
445301225596STao Ma (end - 1) / blocksize))
445401225596STao Ma end = end - end % blocksize;
445501225596STao Ma
445601225596STao Ma if (end > offset + len) {
445701225596STao Ma memmove(bucket_buf + end - len,
445801225596STao Ma bucket_buf + offset, len);
445901225596STao Ma xe->xe_name_offset = cpu_to_le16(end - len);
446001225596STao Ma }
446101225596STao Ma
446201225596STao Ma mlog_bug_on_msg(end < offset + len, "Defrag check failed for "
446301225596STao Ma "bucket %llu\n", (unsigned long long)blkno);
446401225596STao Ma
446501225596STao Ma end -= len;
446601225596STao Ma }
446701225596STao Ma
446885db90e7STao Ma mlog_bug_on_msg(xh_free_start > end, "Defrag check failed for "
446901225596STao Ma "bucket %llu\n", (unsigned long long)blkno);
447001225596STao Ma
447101225596STao Ma if (xh_free_start == end)
447201225596STao Ma goto out;
447301225596STao Ma
447401225596STao Ma memset(bucket_buf + xh_free_start, 0, end - xh_free_start);
447501225596STao Ma xh->xh_free_start = cpu_to_le16(end);
447601225596STao Ma
447701225596STao Ma /* sort the entries by their name_hash. */
447801225596STao Ma sort(entries, le16_to_cpu(xh->xh_count),
44791c32a2fdSTao Ma sizeof(struct ocfs2_xattr_entry),
44801c32a2fdSTao Ma cmp_xe, swap_xe);
44811c32a2fdSTao Ma
448201225596STao Ma buf = bucket_buf;
448301225596STao Ma for (i = 0; i < bucket->bu_blocks; i++, buf += blocksize)
448401225596STao Ma memcpy(bucket_block(bucket, i), buf, blocksize);
448501225596STao Ma ocfs2_xattr_bucket_journal_dirty(handle, bucket);
448601225596STao Ma
448701225596STao Ma out:
448801225596STao Ma kfree(bucket_buf);
4489b5c03e74SJoel Becker return ret;
4490b5c03e74SJoel Becker }
4491b5c03e74SJoel Becker
4492b5c03e74SJoel Becker /*
4493b5c03e74SJoel Becker * prev_blkno points to the start of an existing extent. new_blkno
4494b5c03e74SJoel Becker * points to a newly allocated extent. Because we know each of our
4495b5c03e74SJoel Becker * clusters contains more than bucket, we can easily split one cluster
449601225596STao Ma * at a bucket boundary. So we take the last cluster of the existing
4497b5c03e74SJoel Becker * extent and split it down the middle. We move the last half of the
4498b5c03e74SJoel Becker * buckets in the last cluster of the existing extent over to the new
4499b5c03e74SJoel Becker * extent.
4500b5c03e74SJoel Becker *
4501b5c03e74SJoel Becker * first_bh is the buffer at prev_blkno so we can update the existing
4502b5c03e74SJoel Becker * extent's bucket count. header_bh is the bucket were we were hoping
4503b5c03e74SJoel Becker * to insert our xattr. If the bucket move places the target in the new
450401225596STao Ma * extent, we'll update first_bh and header_bh after modifying the old
450501225596STao Ma * extent.
450601225596STao Ma *
450741cb8148SJoel Becker * first_hash will be set as the 1st xe's name_hash in the new extent.
450841cb8148SJoel Becker */
ocfs2_mv_xattr_bucket_cross_cluster(struct inode * inode,handle_t * handle,struct ocfs2_xattr_bucket * first,struct ocfs2_xattr_bucket * target,u64 new_blkno,u32 num_clusters,u32 * first_hash)450901225596STao Ma static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
451001225596STao Ma handle_t *handle,
451101225596STao Ma struct ocfs2_xattr_bucket *first,
451201225596STao Ma struct ocfs2_xattr_bucket *target,
4513c58b6032SJoel Becker u64 new_blkno,
451441cb8148SJoel Becker u32 num_clusters,
451541cb8148SJoel Becker u32 *first_hash)
451641cb8148SJoel Becker {
4517b5c03e74SJoel Becker int ret;
4518c58b6032SJoel Becker struct super_block *sb = inode->i_sb;
451941cb8148SJoel Becker int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(sb);
452041cb8148SJoel Becker int num_buckets = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb));
452101225596STao Ma int to_move = num_buckets / 2;
452241cb8148SJoel Becker u64 src_blkno;
452341cb8148SJoel Becker u64 last_cluster_blkno = bucket_blkno(first) +
452401225596STao Ma ((num_clusters - 1) * ocfs2_clusters_to_blocks(sb, 1));
4525402b4183STao Ma
4526402b4183STao Ma BUG_ON(le16_to_cpu(bucket_xh(first)->xh_num_buckets) < num_buckets);
4527402b4183STao Ma BUG_ON(OCFS2_XATTR_BUCKET_SIZE == OCFS2_SB(sb)->s_clustersize);
452801225596STao Ma
452941cb8148SJoel Becker trace_ocfs2_mv_xattr_bucket_cross_cluster(
4530c58b6032SJoel Becker (unsigned long long)last_cluster_blkno,
4531c58b6032SJoel Becker (unsigned long long)new_blkno);
4532b5c03e74SJoel Becker
4533b5c03e74SJoel Becker ret = ocfs2_mv_xattr_buckets(inode, handle, bucket_blkno(first),
4534b5c03e74SJoel Becker last_cluster_blkno, new_blkno,
4535b5c03e74SJoel Becker to_move, first_hash);
4536b5c03e74SJoel Becker if (ret) {
4537c58b6032SJoel Becker mlog_errno(ret);
4538c58b6032SJoel Becker goto out;
4539c58b6032SJoel Becker }
454001225596STao Ma
4541c58b6032SJoel Becker /* This is the first bucket that got moved */
454241cb8148SJoel Becker src_blkno = last_cluster_blkno + (to_move * blks_per_bucket);
454301225596STao Ma
454441cb8148SJoel Becker /*
4545c58b6032SJoel Becker * If the target bucket was part of the moved buckets, we need to
4546c58b6032SJoel Becker * update first and target.
454741cb8148SJoel Becker */
454841cb8148SJoel Becker if (bucket_blkno(target) >= src_blkno) {
454941cb8148SJoel Becker /* Find the block for the new target bucket */
455041cb8148SJoel Becker src_blkno = new_blkno +
4551b5c03e74SJoel Becker (bucket_blkno(target) - src_blkno);
4552b5c03e74SJoel Becker
4553c58b6032SJoel Becker ocfs2_xattr_bucket_relse(first);
4554c58b6032SJoel Becker ocfs2_xattr_bucket_relse(target);
4555b5c03e74SJoel Becker
455641cb8148SJoel Becker /*
4557b5c03e74SJoel Becker * These shouldn't fail - the buffers are in the
4558b5c03e74SJoel Becker * journal from ocfs2_cp_xattr_bucket().
4559b5c03e74SJoel Becker */
4560b5c03e74SJoel Becker ret = ocfs2_read_xattr_bucket(first, new_blkno);
456141cb8148SJoel Becker if (ret) {
456241cb8148SJoel Becker mlog_errno(ret);
4563b5c03e74SJoel Becker goto out;
456401225596STao Ma }
456501225596STao Ma ret = ocfs2_read_xattr_bucket(target, src_blkno);
456601225596STao Ma if (ret)
456701225596STao Ma mlog_errno(ret);
456801225596STao Ma
456901225596STao Ma }
457001225596STao Ma
457101225596STao Ma out:
457280bcaf34STao Ma return ret;
457380bcaf34STao Ma }
457480bcaf34STao Ma
457580bcaf34STao Ma /*
457680bcaf34STao Ma * Find the suitable pos when we divide a bucket into 2.
457780bcaf34STao Ma * We have to make sure the xattrs with the same hash value exist
457880bcaf34STao Ma * in the same bucket.
457980bcaf34STao Ma *
458001225596STao Ma * If this ocfs2_xattr_header covers more than one hash value, find a
458180bcaf34STao Ma * place where the hash value changes. Try to find the most even split.
458280bcaf34STao Ma * The most common case is that all entries have different hash values,
458380bcaf34STao Ma * and the first check we make will find a place to split.
458480bcaf34STao Ma */
ocfs2_xattr_find_divide_pos(struct ocfs2_xattr_header * xh)458580bcaf34STao Ma static int ocfs2_xattr_find_divide_pos(struct ocfs2_xattr_header *xh)
458680bcaf34STao Ma {
458780bcaf34STao Ma struct ocfs2_xattr_entry *entries = xh->xh_entries;
458880bcaf34STao Ma int count = le16_to_cpu(xh->xh_count);
458980bcaf34STao Ma int delta, middle = count / 2;
459080bcaf34STao Ma
459180bcaf34STao Ma /*
459280bcaf34STao Ma * We start at the middle. Each step gets farther away in both
459380bcaf34STao Ma * directions. We therefore hit the change in hash value
459480bcaf34STao Ma * nearest to the middle. Note that this loop does not execute for
459580bcaf34STao Ma * count < 2.
459680bcaf34STao Ma */
459780bcaf34STao Ma for (delta = 0; delta < middle; delta++) {
459880bcaf34STao Ma /* Let's check delta earlier than middle */
459980bcaf34STao Ma if (cmp_xe(&entries[middle - delta - 1],
460080bcaf34STao Ma &entries[middle - delta]))
460180bcaf34STao Ma return middle - delta;
460280bcaf34STao Ma
460380bcaf34STao Ma /* For even counts, don't walk off the end */
460480bcaf34STao Ma if ((middle + delta + 1) == count)
460580bcaf34STao Ma continue;
460680bcaf34STao Ma
460780bcaf34STao Ma /* Now try delta past middle */
460880bcaf34STao Ma if (cmp_xe(&entries[middle + delta],
460980bcaf34STao Ma &entries[middle + delta + 1]))
461080bcaf34STao Ma return middle + delta + 1;
461180bcaf34STao Ma }
461280bcaf34STao Ma
461380bcaf34STao Ma /* Every entry had the same hash */
461480bcaf34STao Ma return count;
461580bcaf34STao Ma }
461680bcaf34STao Ma
461780bcaf34STao Ma /*
461880bcaf34STao Ma * Move some xattrs in old bucket(blk) to new bucket(new_blk).
461980bcaf34STao Ma * first_hash will record the 1st hash of the new bucket.
462080bcaf34STao Ma *
462180bcaf34STao Ma * Normally half of the xattrs will be moved. But we have to make
462280bcaf34STao Ma * sure that the xattrs with the same hash value are stored in the
462380bcaf34STao Ma * same bucket. If all the xattrs in this bucket have the same hash
462401225596STao Ma * value, the new bucket will be initialized as an empty one and the
462501225596STao Ma * first_hash will be initialized as (hash_value+1).
462601225596STao Ma */
ocfs2_divide_xattr_bucket(struct inode * inode,handle_t * handle,u64 blk,u64 new_blk,u32 * first_hash,int new_bucket_head)462701225596STao Ma static int ocfs2_divide_xattr_bucket(struct inode *inode,
462801225596STao Ma handle_t *handle,
462901225596STao Ma u64 blk,
463001225596STao Ma u64 new_blk,
4631199799a3SJoel Becker u32 *first_hash,
4632ba937127SJoel Becker int new_bucket_head)
463301225596STao Ma {
463401225596STao Ma int ret, i;
463501225596STao Ma int count, start, len, name_value_len = 0, name_offset = 0;
463601225596STao Ma struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL;
4637402b4183STao Ma struct ocfs2_xattr_header *xh;
4638402b4183STao Ma struct ocfs2_xattr_entry *xe;
463901225596STao Ma int blocksize = inode->i_sb->s_blocksize;
4640ba937127SJoel Becker
4641ba937127SJoel Becker trace_ocfs2_divide_xattr_bucket_begin((unsigned long long)blk,
4642ba937127SJoel Becker (unsigned long long)new_blk);
4643ba937127SJoel Becker
4644ba937127SJoel Becker s_bucket = ocfs2_xattr_bucket_new(inode);
4645ba937127SJoel Becker t_bucket = ocfs2_xattr_bucket_new(inode);
4646ba937127SJoel Becker if (!s_bucket || !t_bucket) {
464701225596STao Ma ret = -ENOMEM;
4648ba937127SJoel Becker mlog_errno(ret);
464901225596STao Ma goto out;
465001225596STao Ma }
465101225596STao Ma
465201225596STao Ma ret = ocfs2_read_xattr_bucket(s_bucket, blk);
465301225596STao Ma if (ret) {
4654ba937127SJoel Becker mlog_errno(ret);
465501225596STao Ma goto out;
465601225596STao Ma }
465701225596STao Ma
465801225596STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, s_bucket,
465901225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
466001225596STao Ma if (ret) {
4661784b816aSJoel Becker mlog_errno(ret);
4662784b816aSJoel Becker goto out;
4663784b816aSJoel Becker }
4664784b816aSJoel Becker
46659c339255SWengang Wang /*
466601225596STao Ma * Even if !new_bucket_head, we're overwriting t_bucket. Thus,
466701225596STao Ma * there's no need to read it.
466801225596STao Ma */
466901225596STao Ma ret = ocfs2_init_xattr_bucket(t_bucket, new_blk, new_bucket_head);
467001225596STao Ma if (ret) {
46712b656c1dSJoel Becker mlog_errno(ret);
46722b656c1dSJoel Becker goto out;
46732b656c1dSJoel Becker }
46742b656c1dSJoel Becker
46752b656c1dSJoel Becker /*
4676ba937127SJoel Becker * Hey, if we're overwriting t_bucket, what difference does
4677eb6ff239SJoel Becker * ACCESS_CREATE vs ACCESS_WRITE make? See the comment in the
4678eb6ff239SJoel Becker * same part of ocfs2_cp_xattr_bucket().
4679eb6ff239SJoel Becker */
468001225596STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket,
468101225596STao Ma new_bucket_head ?
468201225596STao Ma OCFS2_JOURNAL_ACCESS_CREATE :
468301225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
468401225596STao Ma if (ret) {
4685ba937127SJoel Becker mlog_errno(ret);
468680bcaf34STao Ma goto out;
468780bcaf34STao Ma }
468880bcaf34STao Ma
468980bcaf34STao Ma xh = bucket_xh(s_bucket);
469080bcaf34STao Ma count = le16_to_cpu(xh->xh_count);
469180bcaf34STao Ma start = ocfs2_xattr_find_divide_pos(xh);
469280bcaf34STao Ma
469380bcaf34STao Ma if (start == count) {
469480bcaf34STao Ma xe = &xh->xh_entries[start-1];
469580bcaf34STao Ma
469680bcaf34STao Ma /*
4697ba937127SJoel Becker * initialized a new empty bucket here.
4698ba937127SJoel Becker * The hash value is set as one larger than
469980bcaf34STao Ma * that of the last entry in the previous bucket.
4700ba937127SJoel Becker */
470180bcaf34STao Ma for (i = 0; i < t_bucket->bu_blocks; i++)
470280bcaf34STao Ma memset(bucket_block(t_bucket, i), 0, blocksize);
470380bcaf34STao Ma
470480bcaf34STao Ma xh = bucket_xh(t_bucket);
470580bcaf34STao Ma xh->xh_free_start = cpu_to_le16(blocksize);
470680bcaf34STao Ma xh->xh_entries[0].xe_name_hash = xe->xe_name_hash;
470780bcaf34STao Ma le32_add_cpu(&xh->xh_entries[0].xe_name_hash, 1);
470801225596STao Ma
4709ba937127SJoel Becker goto set_num_buckets;
471001225596STao Ma }
471101225596STao Ma
4712ba937127SJoel Becker /* copy the whole bucket to the new first. */
471301225596STao Ma ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket);
471401225596STao Ma
471501225596STao Ma /* update the new bucket. */
471601225596STao Ma xh = bucket_xh(t_bucket);
471701225596STao Ma
471801225596STao Ma /*
471901225596STao Ma * Calculate the total name/value len and xh_free_start for
472001225596STao Ma * the old bucket first.
472101225596STao Ma */
4722199799a3SJoel Becker name_offset = OCFS2_XATTR_BUCKET_SIZE;
472301225596STao Ma name_value_len = 0;
472401225596STao Ma for (i = 0; i < start; i++) {
472501225596STao Ma xe = &xh->xh_entries[i];
472601225596STao Ma name_value_len += namevalue_size_xe(xe);
472701225596STao Ma if (le16_to_cpu(xe->xe_name_offset) < name_offset)
472801225596STao Ma name_offset = le16_to_cpu(xe->xe_name_offset);
472901225596STao Ma }
473001225596STao Ma
473101225596STao Ma /*
473201225596STao Ma * Now begin the modification to the new bucket.
473301225596STao Ma *
473401225596STao Ma * In the new bucket, We just move the xattr entry to the beginning
473501225596STao Ma * and don't touch the name/value. So there will be some holes in the
473601225596STao Ma * bucket, and they will be removed when ocfs2_defrag_xattr_bucket is
4737402b4183STao Ma * called.
4738ff1ec20eSMark Fasheh */
4739ff1ec20eSMark Fasheh xe = &xh->xh_entries[start];
474001225596STao Ma len = sizeof(struct ocfs2_xattr_entry) * (count - start);
474101225596STao Ma trace_ocfs2_divide_xattr_bucket_move(len,
474201225596STao Ma (int)((char *)xe - (char *)xh),
474301225596STao Ma (int)((char *)xh->xh_entries - (char *)xh));
474401225596STao Ma memmove((char *)xh->xh_entries, (char *)xe, len);
474501225596STao Ma xe = &xh->xh_entries[count - start];
474601225596STao Ma len = sizeof(struct ocfs2_xattr_entry) * start;
474701225596STao Ma memset((char *)xe, 0, len);
474801225596STao Ma
474901225596STao Ma le16_add_cpu(&xh->xh_count, -start);
475001225596STao Ma le16_add_cpu(&xh->xh_name_value_len, -name_value_len);
475101225596STao Ma
475201225596STao Ma /* Calculate xh_free_start for the new bucket. */
475301225596STao Ma xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE);
475401225596STao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
475501225596STao Ma xe = &xh->xh_entries[i];
475601225596STao Ma if (le16_to_cpu(xe->xe_name_offset) <
475780bcaf34STao Ma le16_to_cpu(xh->xh_free_start))
475801225596STao Ma xh->xh_free_start = xe->xe_name_offset;
475901225596STao Ma }
476001225596STao Ma
476101225596STao Ma set_num_buckets:
476201225596STao Ma /* set xh->xh_num_buckets for the new xh. */
476301225596STao Ma if (new_bucket_head)
4764ba937127SJoel Becker xh->xh_num_buckets = cpu_to_le16(1);
476501225596STao Ma else
476601225596STao Ma xh->xh_num_buckets = 0;
476701225596STao Ma
476801225596STao Ma ocfs2_xattr_bucket_journal_dirty(handle, t_bucket);
476901225596STao Ma
477001225596STao Ma /* store the first_hash of the new bucket. */
477180bcaf34STao Ma if (first_hash)
477280bcaf34STao Ma *first_hash = le32_to_cpu(xh->xh_entries[0].xe_name_hash);
477380bcaf34STao Ma
477401225596STao Ma /*
477580bcaf34STao Ma * Now only update the 1st block of the old bucket. If we
477680bcaf34STao Ma * just added a new empty bucket, there is no need to modify
477780bcaf34STao Ma * it.
4778ba937127SJoel Becker */
477901225596STao Ma if (start == count)
478001225596STao Ma goto out;
478101225596STao Ma
478201225596STao Ma xh = bucket_xh(s_bucket);
478301225596STao Ma memset(&xh->xh_entries[start], 0,
478401225596STao Ma sizeof(struct ocfs2_xattr_entry) * (count - start));
4785ba937127SJoel Becker xh->xh_count = cpu_to_le16(start);
478601225596STao Ma xh->xh_free_start = cpu_to_le16(name_offset);
478701225596STao Ma xh->xh_name_value_len = cpu_to_le16(name_value_len);
4788ba937127SJoel Becker
4789ba937127SJoel Becker ocfs2_xattr_bucket_journal_dirty(handle, s_bucket);
479001225596STao Ma
479101225596STao Ma out:
479201225596STao Ma ocfs2_xattr_bucket_free(s_bucket);
479301225596STao Ma ocfs2_xattr_bucket_free(t_bucket);
479401225596STao Ma
479501225596STao Ma return ret;
479601225596STao Ma }
479701225596STao Ma
479801225596STao Ma /*
479901225596STao Ma * Copy xattr from one bucket to another bucket.
480001225596STao Ma *
480101225596STao Ma * The caller must make sure that the journal transaction
480201225596STao Ma * has enough space for journaling.
480301225596STao Ma */
ocfs2_cp_xattr_bucket(struct inode * inode,handle_t * handle,u64 s_blkno,u64 t_blkno,int t_is_new)480401225596STao Ma static int ocfs2_cp_xattr_bucket(struct inode *inode,
480501225596STao Ma handle_t *handle,
48064980c6daSJoel Becker u64 s_blkno,
4807ba937127SJoel Becker u64 t_blkno,
480801225596STao Ma int t_is_new)
480901225596STao Ma {
481001225596STao Ma int ret;
4811402b4183STao Ma struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL;
4812402b4183STao Ma
4813de29c085SMark Fasheh BUG_ON(s_blkno == t_blkno);
481401225596STao Ma
4815ba937127SJoel Becker trace_ocfs2_cp_xattr_bucket((unsigned long long)s_blkno,
4816ba937127SJoel Becker (unsigned long long)t_blkno,
4817ba937127SJoel Becker t_is_new);
4818ba937127SJoel Becker
4819ba937127SJoel Becker s_bucket = ocfs2_xattr_bucket_new(inode);
4820ba937127SJoel Becker t_bucket = ocfs2_xattr_bucket_new(inode);
4821ba937127SJoel Becker if (!s_bucket || !t_bucket) {
482201225596STao Ma ret = -ENOMEM;
4823ba937127SJoel Becker mlog_errno(ret);
482401225596STao Ma goto out;
482501225596STao Ma }
482601225596STao Ma
4827784b816aSJoel Becker ret = ocfs2_read_xattr_bucket(s_bucket, s_blkno);
4828784b816aSJoel Becker if (ret)
4829784b816aSJoel Becker goto out;
4830784b816aSJoel Becker
48319c339255SWengang Wang /*
483201225596STao Ma * Even if !t_is_new, we're overwriting t_bucket. Thus,
483301225596STao Ma * there's no need to read it.
483401225596STao Ma */
48352b656c1dSJoel Becker ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno, t_is_new);
48362b656c1dSJoel Becker if (ret)
48372b656c1dSJoel Becker goto out;
4838874d65afSJoel Becker
4839874d65afSJoel Becker /*
4840874d65afSJoel Becker * Hey, if we're overwriting t_bucket, what difference does
4841874d65afSJoel Becker * ACCESS_CREATE vs ACCESS_WRITE make? Well, if we allocated a new
4842874d65afSJoel Becker * cluster to fill, we came here from
4843874d65afSJoel Becker * ocfs2_mv_xattr_buckets(), and it is really new -
48442b656c1dSJoel Becker * ACCESS_CREATE is required. But we also might have moved data
48452b656c1dSJoel Becker * out of t_bucket before extending back into it.
48462b656c1dSJoel Becker * ocfs2_add_new_xattr_bucket() can do this - its call to
48472b656c1dSJoel Becker * ocfs2_add_new_xattr_cluster() may have created a new extent
4848ba937127SJoel Becker * and copied out the end of the old extent. Then it re-extends
4849eb6ff239SJoel Becker * the old extent back to create space for new xattrs. That's
4850eb6ff239SJoel Becker * how we get here, and the bucket isn't really new.
485101225596STao Ma */
485201225596STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket,
485301225596STao Ma t_is_new ?
485401225596STao Ma OCFS2_JOURNAL_ACCESS_CREATE :
4855ba937127SJoel Becker OCFS2_JOURNAL_ACCESS_WRITE);
4856ba937127SJoel Becker if (ret)
485701225596STao Ma goto out;
485801225596STao Ma
4859ba937127SJoel Becker ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket);
4860ba937127SJoel Becker ocfs2_xattr_bucket_journal_dirty(handle, t_bucket);
486101225596STao Ma
486201225596STao Ma out:
486301225596STao Ma ocfs2_xattr_bucket_free(t_bucket);
486401225596STao Ma ocfs2_xattr_bucket_free(s_bucket);
486501225596STao Ma
4866874d65afSJoel Becker return ret;
4867874d65afSJoel Becker }
486854ecb6b6SJoel Becker
486954ecb6b6SJoel Becker /*
487054ecb6b6SJoel Becker * src_blk points to the start of an existing extent. last_blk points to
487154ecb6b6SJoel Becker * last cluster in that extent. to_blk points to a newly allocated
487254ecb6b6SJoel Becker * extent. We copy the buckets from the cluster at last_blk to the new
487301225596STao Ma * extent. If start_bucket is non-zero, we skip that many buckets before
487454ecb6b6SJoel Becker * we start copying. The new extent's xh_num_buckets gets set to the
487554ecb6b6SJoel Becker * number of buckets we copied. The old extent's xh_num_buckets shrinks
487654ecb6b6SJoel Becker * by the same amount.
487754ecb6b6SJoel Becker */
ocfs2_mv_xattr_buckets(struct inode * inode,handle_t * handle,u64 src_blk,u64 last_blk,u64 to_blk,unsigned int start_bucket,u32 * first_hash)487801225596STao Ma static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle,
487901225596STao Ma u64 src_blk, u64 last_blk, u64 to_blk,
488001225596STao Ma unsigned int start_bucket,
488115d60929SJoel Becker u32 *first_hash)
488201225596STao Ma {
488315d60929SJoel Becker int i, ret, credits;
488401225596STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4885402b4183STao Ma int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
4886402b4183STao Ma int num_buckets = ocfs2_xattr_buckets_per_cluster(osb);
488701225596STao Ma struct ocfs2_xattr_bucket *old_first, *new_first;
488854ecb6b6SJoel Becker
488954ecb6b6SJoel Becker trace_ocfs2_mv_xattr_buckets((unsigned long long)last_blk,
489054ecb6b6SJoel Becker (unsigned long long)to_blk);
489154ecb6b6SJoel Becker
489254ecb6b6SJoel Becker BUG_ON(start_bucket >= num_buckets);
489354ecb6b6SJoel Becker if (start_bucket) {
489415d60929SJoel Becker num_buckets -= start_bucket;
489515d60929SJoel Becker last_blk += (start_bucket * blks_per_bucket);
489615d60929SJoel Becker }
489715d60929SJoel Becker
489815d60929SJoel Becker /* The first bucket of the original extent */
489915d60929SJoel Becker old_first = ocfs2_xattr_bucket_new(inode);
490015d60929SJoel Becker /* The first bucket of the new extent */
490115d60929SJoel Becker new_first = ocfs2_xattr_bucket_new(inode);
490215d60929SJoel Becker if (!old_first || !new_first) {
490315d60929SJoel Becker ret = -ENOMEM;
4904874d65afSJoel Becker mlog_errno(ret);
490515d60929SJoel Becker goto out;
490615d60929SJoel Becker }
490715d60929SJoel Becker
490815d60929SJoel Becker ret = ocfs2_read_xattr_bucket(old_first, src_blk);
490915d60929SJoel Becker if (ret) {
491001225596STao Ma mlog_errno(ret);
491154ecb6b6SJoel Becker goto out;
491254ecb6b6SJoel Becker }
491301225596STao Ma
4914c901fb00STao Ma /*
491501225596STao Ma * We need to update the first bucket of the old extent and all
491601225596STao Ma * the buckets going to the new extent.
491701225596STao Ma */
491801225596STao Ma credits = ((num_buckets + 1) * blks_per_bucket);
491901225596STao Ma ret = ocfs2_extend_trans(handle, credits);
492001225596STao Ma if (ret) {
492115d60929SJoel Becker mlog_errno(ret);
492201225596STao Ma goto out;
492301225596STao Ma }
492401225596STao Ma
492501225596STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, old_first,
492601225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
492701225596STao Ma if (ret) {
492801225596STao Ma mlog_errno(ret);
492901225596STao Ma goto out;
4930874d65afSJoel Becker }
493115d60929SJoel Becker
493215d60929SJoel Becker for (i = 0; i < num_buckets; i++) {
493301225596STao Ma ret = ocfs2_cp_xattr_bucket(inode, handle,
493401225596STao Ma last_blk + (i * blks_per_bucket),
493501225596STao Ma to_blk + (i * blks_per_bucket),
493601225596STao Ma 1);
493701225596STao Ma if (ret) {
493801225596STao Ma mlog_errno(ret);
493915d60929SJoel Becker goto out;
494015d60929SJoel Becker }
494115d60929SJoel Becker }
494215d60929SJoel Becker
494315d60929SJoel Becker /*
494415d60929SJoel Becker * Get the new bucket ready before we dirty anything
494515d60929SJoel Becker * (This actually shouldn't fail, because we already dirtied
494601225596STao Ma * it once in ocfs2_cp_xattr_bucket()).
494701225596STao Ma */
494801225596STao Ma ret = ocfs2_read_xattr_bucket(new_first, to_blk);
494915d60929SJoel Becker if (ret) {
495001225596STao Ma mlog_errno(ret);
495101225596STao Ma goto out;
495201225596STao Ma }
495301225596STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, new_first,
495401225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
495501225596STao Ma if (ret) {
495615d60929SJoel Becker mlog_errno(ret);
495715d60929SJoel Becker goto out;
495815d60929SJoel Becker }
495901225596STao Ma
496015d60929SJoel Becker /* Now update the headers */
496115d60929SJoel Becker le16_add_cpu(&bucket_xh(old_first)->xh_num_buckets, -num_buckets);
496201225596STao Ma ocfs2_xattr_bucket_journal_dirty(handle, old_first);
496301225596STao Ma
496415d60929SJoel Becker bucket_xh(new_first)->xh_num_buckets = cpu_to_le16(num_buckets);
496515d60929SJoel Becker ocfs2_xattr_bucket_journal_dirty(handle, new_first);
496601225596STao Ma
496715d60929SJoel Becker if (first_hash)
496815d60929SJoel Becker *first_hash = le32_to_cpu(bucket_xh(new_first)->xh_entries[0].xe_name_hash);
496901225596STao Ma
497001225596STao Ma out:
497101225596STao Ma ocfs2_xattr_bucket_free(new_first);
497201225596STao Ma ocfs2_xattr_bucket_free(old_first);
497380bcaf34STao Ma return ret;
497401225596STao Ma }
497501225596STao Ma
497601225596STao Ma /*
497780bcaf34STao Ma * Move some xattrs in this cluster to the new cluster.
497801225596STao Ma * This function should only be called when bucket size == cluster size.
497901225596STao Ma * Otherwise ocfs2_mv_xattr_bucket_cross_cluster should be used instead.
498001225596STao Ma */
ocfs2_divide_xattr_cluster(struct inode * inode,handle_t * handle,u64 prev_blk,u64 new_blk,u32 * first_hash)498101225596STao Ma static int ocfs2_divide_xattr_cluster(struct inode *inode,
498201225596STao Ma handle_t *handle,
498301225596STao Ma u64 prev_blk,
4984c901fb00STao Ma u64 new_blk,
498501225596STao Ma u32 *first_hash)
498601225596STao Ma {
498701225596STao Ma u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
498801225596STao Ma int ret, credits = 2 * blk_per_bucket;
498901225596STao Ma
499001225596STao Ma BUG_ON(OCFS2_XATTR_BUCKET_SIZE < OCFS2_SB(inode->i_sb)->s_clustersize);
499101225596STao Ma
499201225596STao Ma ret = ocfs2_extend_trans(handle, credits);
499301225596STao Ma if (ret) {
499401225596STao Ma mlog_errno(ret);
499580bcaf34STao Ma return ret;
499601225596STao Ma }
499701225596STao Ma
499801225596STao Ma /* Move half of the xattr in start_blk to the next bucket. */
499901225596STao Ma return ocfs2_divide_xattr_bucket(inode, handle, prev_blk,
500001225596STao Ma new_blk, first_hash, 1);
500101225596STao Ma }
500201225596STao Ma
500301225596STao Ma /*
500401225596STao Ma * Move some xattrs from the old cluster to the new one since they are not
500501225596STao Ma * contiguous in ocfs2 xattr tree.
500601225596STao Ma *
500701225596STao Ma * new_blk starts a new separate cluster, and we will move some xattrs from
500801225596STao Ma * prev_blk to it. v_start will be set as the first name hash value in this
500901225596STao Ma * new cluster so that it can be used as e_cpos during tree insertion and
501001225596STao Ma * don't collide with our original b-tree operations. first_bh and header_bh
501101225596STao Ma * will also be updated since they will be used in ocfs2_extend_xattr_bucket
501201225596STao Ma * to extend the insert bucket.
501301225596STao Ma *
501401225596STao Ma * The problem is how much xattr should we move to the new one and when should
501501225596STao Ma * we update first_bh and header_bh?
501601225596STao Ma * 1. If cluster size > bucket size, that means the previous cluster has more
501701225596STao Ma * than 1 bucket, so just move half nums of bucket into the new cluster and
501801225596STao Ma * update the first_bh and header_bh if the insert bucket has been moved
501901225596STao Ma * to the new cluster.
502001225596STao Ma * 2. If cluster_size == bucket_size:
502101225596STao Ma * a) If the previous extent rec has more than one cluster and the insert
502201225596STao Ma * place isn't in the last cluster, copy the entire last cluster to the
502301225596STao Ma * new one. This time, we don't need to upate the first_bh and header_bh
502401225596STao Ma * since they will not be moved into the new cluster.
502501225596STao Ma * b) Otherwise, move the bottom half of the xattrs in the last cluster into
502601225596STao Ma * the new one. And we set the extend flag to zero if the insert place is
5027012ee910SJoel Becker * moved into the new allocated cluster since no extend is needed.
5028012ee910SJoel Becker */
ocfs2_adjust_xattr_cross_cluster(struct inode * inode,handle_t * handle,struct ocfs2_xattr_bucket * first,struct ocfs2_xattr_bucket * target,u64 new_blk,u32 prev_clusters,u32 * v_start,int * extend)502901225596STao Ma static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode,
503001225596STao Ma handle_t *handle,
503101225596STao Ma struct ocfs2_xattr_bucket *first,
503201225596STao Ma struct ocfs2_xattr_bucket *target,
503301225596STao Ma u64 new_blk,
503492cf3adfSJoel Becker u32 prev_clusters,
503501225596STao Ma u32 *v_start,
5036402b4183STao Ma int *extend)
5037402b4183STao Ma {
5038402b4183STao Ma int ret;
503901225596STao Ma
504041cb8148SJoel Becker trace_ocfs2_adjust_xattr_cross_cluster(
504101225596STao Ma (unsigned long long)bucket_blkno(first),
504201225596STao Ma (unsigned long long)new_blk, prev_clusters);
504341cb8148SJoel Becker
504401225596STao Ma if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) {
504501225596STao Ma ret = ocfs2_mv_xattr_bucket_cross_cluster(inode,
504601225596STao Ma handle,
5047012ee910SJoel Becker first, target,
504841cb8148SJoel Becker new_blk,
504941cb8148SJoel Becker prev_clusters,
505092cf3adfSJoel Becker v_start);
505192cf3adfSJoel Becker if (ret)
505292cf3adfSJoel Becker mlog_errno(ret);
505392cf3adfSJoel Becker } else {
505401225596STao Ma /* The start of the last cluster in the first extent */
5055012ee910SJoel Becker u64 last_blk = bucket_blkno(first) +
5056874d65afSJoel Becker ((prev_clusters - 1) *
505792cf3adfSJoel Becker ocfs2_clusters_to_blocks(inode->i_sb, 1));
505854ecb6b6SJoel Becker
505901225596STao Ma if (prev_clusters > 1 && bucket_blkno(target) != last_blk) {
5060012ee910SJoel Becker ret = ocfs2_mv_xattr_buckets(inode, handle,
5061012ee910SJoel Becker bucket_blkno(first),
5062012ee910SJoel Becker last_blk, new_blk, 0,
506380bcaf34STao Ma v_start);
506401225596STao Ma if (ret)
506501225596STao Ma mlog_errno(ret);
5066012ee910SJoel Becker } else {
5067012ee910SJoel Becker ret = ocfs2_divide_xattr_cluster(inode, handle,
506801225596STao Ma last_blk, new_blk,
506992cf3adfSJoel Becker v_start);
507001225596STao Ma if (ret)
507101225596STao Ma mlog_errno(ret);
507201225596STao Ma
507301225596STao Ma if ((bucket_blkno(target) == last_blk) && extend)
507401225596STao Ma *extend = 0;
507501225596STao Ma }
507601225596STao Ma }
507701225596STao Ma
507801225596STao Ma return ret;
507901225596STao Ma }
508001225596STao Ma
508101225596STao Ma /*
508201225596STao Ma * Add a new cluster for xattr storage.
508301225596STao Ma *
508401225596STao Ma * If the new cluster is contiguous with the previous one, it will be
508501225596STao Ma * appended to the same extent record, and num_clusters will be updated.
508601225596STao Ma * If not, we will insert a new extent for it and move some xattrs in
508701225596STao Ma * the last cluster into the new allocated one.
508801225596STao Ma * We also need to limit the maximum size of a btree leaf, otherwise we'll
508901225596STao Ma * lose the benefits of hashing because we'll have to search large leaves.
509001225596STao Ma * So now the maximum size is OCFS2_MAX_XATTR_TREE_LEAF_SIZE(or clustersize,
509101225596STao Ma * if it's bigger).
509201225596STao Ma *
509301225596STao Ma * first_bh is the first block of the previous extent rec and header_bh
509401225596STao Ma * indicates the bucket we will insert the new xattrs. They will be updated
5095ed29c0caSJoel Becker * when the header_bh is moved into the new cluster.
5096ed29c0caSJoel Becker */
ocfs2_add_new_xattr_cluster(struct inode * inode,struct buffer_head * root_bh,struct ocfs2_xattr_bucket * first,struct ocfs2_xattr_bucket * target,u32 * num_clusters,u32 prev_cpos,int * extend,struct ocfs2_xattr_set_ctxt * ctxt)509701225596STao Ma static int ocfs2_add_new_xattr_cluster(struct inode *inode,
509801225596STao Ma struct buffer_head *root_bh,
509978f30c31STao Ma struct ocfs2_xattr_bucket *first,
510078f30c31STao Ma struct ocfs2_xattr_bucket *target,
510101225596STao Ma u32 *num_clusters,
510285db90e7STao Ma u32 prev_cpos,
510301225596STao Ma int *extend,
510401225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
510501225596STao Ma {
510601225596STao Ma int ret;
510785db90e7STao Ma u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
510801225596STao Ma u32 prev_clusters = *num_clusters;
5109f99b9b7cSJoel Becker u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0;
511001225596STao Ma u64 block;
5111402b4183STao Ma handle_t *handle = ctxt->handle;
511201225596STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5113402b4183STao Ma struct ocfs2_extent_tree et;
5114402b4183STao Ma
511501225596STao Ma trace_ocfs2_add_new_xattr_cluster_begin(
51165e404e9eSJoel Becker (unsigned long long)OCFS2_I(inode)->ip_blkno,
5117f99b9b7cSJoel Becker (unsigned long long)bucket_blkno(first),
51180cf2f763SJoel Becker prev_cpos, prev_clusters);
511901225596STao Ma
512001225596STao Ma ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh);
512101225596STao Ma
512201225596STao Ma ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), root_bh,
512301225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
512401225596STao Ma if (ret < 0) {
51251ed9b777SJoel Becker mlog_errno(ret);
512601225596STao Ma goto leave;
512701225596STao Ma }
512801225596STao Ma
512901225596STao Ma ret = __ocfs2_claim_clusters(handle, ctxt->data_ac, 1,
513001225596STao Ma clusters_to_add, &bit_off, &num_bits);
513101225596STao Ma if (ret < 0) {
513201225596STao Ma if (ret != -ENOSPC)
513301225596STao Ma mlog_errno(ret);
513401225596STao Ma goto leave;
513501225596STao Ma }
5136402b4183STao Ma
513701225596STao Ma BUG_ON(num_bits > clusters_to_add);
5138ed29c0caSJoel Becker
513901225596STao Ma block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
514001225596STao Ma trace_ocfs2_add_new_xattr_cluster((unsigned long long)block, num_bits);
514101225596STao Ma
514201225596STao Ma if (bucket_blkno(first) + (prev_clusters * bpc) == block &&
514301225596STao Ma (prev_clusters + num_bits) << osb->s_clustersize_bits <=
514401225596STao Ma OCFS2_MAX_XATTR_TREE_LEAF_SIZE) {
514501225596STao Ma /*
514601225596STao Ma * If this cluster is contiguous with the old one and
514701225596STao Ma * adding this new cluster, we don't surpass the limit of
514801225596STao Ma * OCFS2_MAX_XATTR_TREE_LEAF_SIZE, cool. We will let it be
514901225596STao Ma * initialized and used like other buckets in the previous
515001225596STao Ma * cluster.
515101225596STao Ma * So add it as a contiguous one. The caller will handle
515201225596STao Ma * its init process.
515301225596STao Ma */
515401225596STao Ma v_start = prev_cpos + prev_clusters;
5155012ee910SJoel Becker *num_clusters = prev_clusters + num_bits;
5156012ee910SJoel Becker } else {
515701225596STao Ma ret = ocfs2_adjust_xattr_cross_cluster(inode,
515801225596STao Ma handle,
515901225596STao Ma first,
516001225596STao Ma target,
516101225596STao Ma block,
516201225596STao Ma prev_clusters,
516301225596STao Ma &v_start,
516401225596STao Ma extend);
516501225596STao Ma if (ret) {
516601225596STao Ma mlog_errno(ret);
5167402b4183STao Ma goto leave;
5168402b4183STao Ma }
5169cc79d8c1SJoel Becker }
517078f30c31STao Ma
517101225596STao Ma trace_ocfs2_add_new_xattr_cluster_insert((unsigned long long)block,
517201225596STao Ma v_start, num_bits);
517301225596STao Ma ret = ocfs2_insert_extent(handle, &et, v_start, block,
517401225596STao Ma num_bits, 0, ctxt->meta_ac);
517501225596STao Ma if (ret < 0) {
5176ec20cec7SJoel Becker mlog_errno(ret);
517701225596STao Ma goto leave;
517801225596STao Ma }
517901225596STao Ma
518001225596STao Ma ocfs2_journal_dirty(handle, root_bh);
518101225596STao Ma
518201225596STao Ma leave:
518392de109aSJoel Becker return ret;
518492de109aSJoel Becker }
518592de109aSJoel Becker
518692de109aSJoel Becker /*
518792de109aSJoel Becker * We are given an extent. 'first' is the bucket at the very front of
518892de109aSJoel Becker * the extent. The extent has space for an additional bucket past
518992de109aSJoel Becker * bucket_xh(first)->xh_num_buckets. 'target_blkno' is the block number
519001225596STao Ma * of the target bucket. We wish to shift every bucket past the target
519101225596STao Ma * down one, filling in that additional space. When we get back to the
519285db90e7STao Ma * target, we split the target between itself and the now-empty bucket
519392de109aSJoel Becker * at target+1 (aka, target_blkno + blks_per_bucket).
519492de109aSJoel Becker */
ocfs2_extend_xattr_bucket(struct inode * inode,handle_t * handle,struct ocfs2_xattr_bucket * first,u64 target_blk,u32 num_clusters)519501225596STao Ma static int ocfs2_extend_xattr_bucket(struct inode *inode,
519601225596STao Ma handle_t *handle,
519701225596STao Ma struct ocfs2_xattr_bucket *first,
519801225596STao Ma u64 target_blk,
519901225596STao Ma u32 num_clusters)
520092de109aSJoel Becker {
520192de109aSJoel Becker int ret, credits;
520201225596STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5203402b4183STao Ma u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
5204402b4183STao Ma u64 end_blk;
5205402b4183STao Ma u16 new_bucket = le16_to_cpu(bucket_xh(first)->xh_num_buckets);
520601225596STao Ma
520792de109aSJoel Becker trace_ocfs2_extend_xattr_bucket((unsigned long long)target_blk,
520892de109aSJoel Becker (unsigned long long)bucket_blkno(first),
520992de109aSJoel Becker num_clusters, new_bucket);
521001225596STao Ma
521192de109aSJoel Becker /* The extent must have room for an additional bucket */
521292de109aSJoel Becker BUG_ON(new_bucket >=
521301225596STao Ma (num_clusters * ocfs2_xattr_buckets_per_cluster(osb)));
521401225596STao Ma
521592de109aSJoel Becker /* end_blk points to the last existing bucket */
521692de109aSJoel Becker end_blk = bucket_blkno(first) + ((new_bucket - 1) * blk_per_bucket);
521792de109aSJoel Becker
521892de109aSJoel Becker /*
521992de109aSJoel Becker * end_blk is the start of the last existing bucket.
522001225596STao Ma * Thus, (end_blk - target_blk) covers the target bucket and
5221c901fb00STao Ma * every bucket after it up to, but not including, the last
522285db90e7STao Ma * existing bucket. Then we add the last existing bucket, the
522385db90e7STao Ma * new bucket, and the first bucket (3 * blk_per_bucket).
522401225596STao Ma */
522501225596STao Ma credits = (end_blk - target_blk) + (3 * blk_per_bucket);
522601225596STao Ma ret = ocfs2_extend_trans(handle, credits);
522701225596STao Ma if (ret) {
522892de109aSJoel Becker mlog_errno(ret);
522901225596STao Ma goto out;
523001225596STao Ma }
523101225596STao Ma
523285db90e7STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, first,
523301225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
523401225596STao Ma if (ret) {
523592de109aSJoel Becker mlog_errno(ret);
523601225596STao Ma goto out;
523701225596STao Ma }
523801225596STao Ma
523985db90e7STao Ma while (end_blk != target_blk) {
524001225596STao Ma ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk,
524101225596STao Ma end_blk + blk_per_bucket, 0);
524201225596STao Ma if (ret)
524392de109aSJoel Becker goto out;
524492de109aSJoel Becker end_blk -= blk_per_bucket;
524592de109aSJoel Becker }
524601225596STao Ma
524792de109aSJoel Becker /* Move half of the xattr in target_blkno to the next bucket. */
524892de109aSJoel Becker ret = ocfs2_divide_xattr_bucket(inode, handle, target_blk,
524901225596STao Ma target_blk + blk_per_bucket, NULL, 0);
525001225596STao Ma
525101225596STao Ma le16_add_cpu(&bucket_xh(first)->xh_num_buckets, 1);
525201225596STao Ma ocfs2_xattr_bucket_journal_dirty(handle, first);
525301225596STao Ma
525401225596STao Ma out:
525591f2033fSJoel Becker return ret;
525691f2033fSJoel Becker }
525791f2033fSJoel Becker
525801225596STao Ma /*
525991f2033fSJoel Becker * Add new xattr bucket in an extent record and adjust the buckets
526091f2033fSJoel Becker * accordingly. xb_bh is the ocfs2_xattr_block, and target is the
526191f2033fSJoel Becker * bucket we want to insert into.
526291f2033fSJoel Becker *
526391f2033fSJoel Becker * In the easy case, we will move all the buckets after target down by
526491f2033fSJoel Becker * one. Half of target's xattrs will be moved to the next bucket.
526591f2033fSJoel Becker *
526601225596STao Ma * If current cluster is full, we'll allocate a new one. This may not
526701225596STao Ma * be contiguous. The underlying calls will make sure that there is
526801225596STao Ma * space for the insert, shifting buckets around if necessary.
526991f2033fSJoel Becker * 'target' may be moved by those calls.
527078f30c31STao Ma */
ocfs2_add_new_xattr_bucket(struct inode * inode,struct buffer_head * xb_bh,struct ocfs2_xattr_bucket * target,struct ocfs2_xattr_set_ctxt * ctxt)527101225596STao Ma static int ocfs2_add_new_xattr_bucket(struct inode *inode,
527201225596STao Ma struct buffer_head *xb_bh,
527301225596STao Ma struct ocfs2_xattr_bucket *target,
527401225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
527501225596STao Ma {
527691f2033fSJoel Becker struct ocfs2_xattr_block *xb =
527791f2033fSJoel Becker (struct ocfs2_xattr_block *)xb_bh->b_data;
5278ed29c0caSJoel Becker struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root;
527901225596STao Ma struct ocfs2_extent_list *el = &xb_root->xt_list;
528001225596STao Ma u32 name_hash =
528101225596STao Ma le32_to_cpu(bucket_xh(target)->xh_entries[0].xe_name_hash);
528292de109aSJoel Becker struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
528391f2033fSJoel Becker int ret, num_buckets, extend = 1;
528401225596STao Ma u64 p_blkno;
5285402b4183STao Ma u32 e_cpos, num_clusters;
528691f2033fSJoel Becker /* The bucket at the front of the extent */
528701225596STao Ma struct ocfs2_xattr_bucket *first;
5288ed29c0caSJoel Becker
528992de109aSJoel Becker trace_ocfs2_add_new_xattr_bucket(
529091f2033fSJoel Becker (unsigned long long)bucket_blkno(target));
529192de109aSJoel Becker
529292de109aSJoel Becker /* The first bucket of the original extent */
529392de109aSJoel Becker first = ocfs2_xattr_bucket_new(inode);
529492de109aSJoel Becker if (!first) {
529592de109aSJoel Becker ret = -ENOMEM;
529601225596STao Ma mlog_errno(ret);
529701225596STao Ma goto out;
529801225596STao Ma }
529901225596STao Ma
530001225596STao Ma ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &e_cpos,
530101225596STao Ma &num_clusters, el);
530201225596STao Ma if (ret) {
5303ed29c0caSJoel Becker mlog_errno(ret);
5304ed29c0caSJoel Becker goto out;
5305ed29c0caSJoel Becker }
5306ed29c0caSJoel Becker
5307ed29c0caSJoel Becker ret = ocfs2_read_xattr_bucket(first, p_blkno);
5308ed29c0caSJoel Becker if (ret) {
530901225596STao Ma mlog_errno(ret);
5310ed29c0caSJoel Becker goto out;
5311ed29c0caSJoel Becker }
5312ed29c0caSJoel Becker
5313ed29c0caSJoel Becker num_buckets = ocfs2_xattr_buckets_per_cluster(osb) * num_clusters;
5314ed29c0caSJoel Becker if (num_buckets == le16_to_cpu(bucket_xh(first)->xh_num_buckets)) {
531501225596STao Ma /*
531601225596STao Ma * This can move first+target if the target bucket moves
5317ed29c0caSJoel Becker * to the new extent.
5318ed29c0caSJoel Becker */
531901225596STao Ma ret = ocfs2_add_new_xattr_cluster(inode,
532001225596STao Ma xb_bh,
532178f30c31STao Ma first,
532278f30c31STao Ma target,
532301225596STao Ma &num_clusters,
532401225596STao Ma e_cpos,
532501225596STao Ma &extend,
532601225596STao Ma ctxt);
532701225596STao Ma if (ret) {
532801225596STao Ma mlog_errno(ret);
532992de109aSJoel Becker goto out;
533001225596STao Ma }
533185db90e7STao Ma }
5332ed29c0caSJoel Becker
5333ed29c0caSJoel Becker if (extend) {
533401225596STao Ma ret = ocfs2_extend_xattr_bucket(inode,
533501225596STao Ma ctxt->handle,
533601225596STao Ma first,
533792de109aSJoel Becker bucket_blkno(target),
533892de109aSJoel Becker num_clusters);
533901225596STao Ma if (ret)
534092de109aSJoel Becker mlog_errno(ret);
5341ed29c0caSJoel Becker }
534201225596STao Ma
534301225596STao Ma out:
534401225596STao Ma ocfs2_xattr_bucket_free(first);
534501225596STao Ma
534601225596STao Ma return ret;
534701225596STao Ma }
534801225596STao Ma
534901225596STao Ma /*
535001225596STao Ma * Truncate the specified xe_off entry in xattr bucket.
535101225596STao Ma * bucket is indicated by header_bh and len is the new length.
535201225596STao Ma * Both the ocfs2_xattr_value_root and the entry will be updated here.
5353548b0f22SJoel Becker *
535401225596STao Ma * Copy the new updated xe and xe_value_root to new_xe and new_xv if needed.
535578f30c31STao Ma */
ocfs2_xattr_bucket_value_truncate(struct inode * inode,struct ocfs2_xattr_bucket * bucket,int xe_off,int len,struct ocfs2_xattr_set_ctxt * ctxt)535678f30c31STao Ma static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
535701225596STao Ma struct ocfs2_xattr_bucket *bucket,
535801225596STao Ma int xe_off,
535901225596STao Ma int len,
536001225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
5361548b0f22SJoel Becker {
536201225596STao Ma int ret, offset;
5363b3e5d379SJoel Becker u64 value_blk;
5364b3e5d379SJoel Becker struct ocfs2_xattr_entry *xe;
5365b3e5d379SJoel Becker struct ocfs2_xattr_header *xh = bucket_xh(bucket);
536601225596STao Ma size_t blocksize = inode->i_sb->s_blocksize;
536701225596STao Ma struct ocfs2_xattr_value_buf vb = {
536801225596STao Ma .vb_access = ocfs2_journal_access,
536901225596STao Ma };
537001225596STao Ma
537101225596STao Ma xe = &xh->xh_entries[xe_off];
537201225596STao Ma
537301225596STao Ma BUG_ON(!xe || ocfs2_xattr_is_local(xe));
537401225596STao Ma
537501225596STao Ma offset = le16_to_cpu(xe->xe_name_offset) +
537601225596STao Ma OCFS2_XATTR_SIZE(xe->xe_name_len);
537701225596STao Ma
537801225596STao Ma value_blk = offset / blocksize;
5379b3e5d379SJoel Becker
5380b3e5d379SJoel Becker /* We don't allow ocfs2_xattr_value to be stored in different block. */
538101225596STao Ma BUG_ON(value_blk != (offset + OCFS2_XATTR_ROOT_SIZE - 1) / blocksize);
5382b3e5d379SJoel Becker
5383b3e5d379SJoel Becker vb.vb_bh = bucket->bu_bhs[value_blk];
538401225596STao Ma BUG_ON(!vb.vb_bh);
5385548b0f22SJoel Becker
5386548b0f22SJoel Becker vb.vb_xv = (struct ocfs2_xattr_value_root *)
5387548b0f22SJoel Becker (vb.vb_bh->b_data + offset % blocksize);
5388548b0f22SJoel Becker
5389548b0f22SJoel Becker /*
5390548b0f22SJoel Becker * From here on out we have to dirty the bucket. The generic
5391548b0f22SJoel Becker * value calls only modify one of the bucket's bhs, but we need
5392402b4183STao Ma * to send the bucket at once. So if they error, they *could* have
5393402b4183STao Ma * modified something. We have to assume they did, and dirty
5394b3e5d379SJoel Becker * the whole bucket. This leaves us in a consistent state.
539501225596STao Ma */
539601225596STao Ma trace_ocfs2_xattr_bucket_value_truncate(
5397554e7f9eSTao Ma (unsigned long long)bucket_blkno(bucket), xe_off, len);
5398554e7f9eSTao Ma ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt);
5399554e7f9eSTao Ma if (ret) {
5400554e7f9eSTao Ma mlog_errno(ret);
5401554e7f9eSTao Ma goto out;
5402554e7f9eSTao Ma }
5403554e7f9eSTao Ma
5404554e7f9eSTao Ma ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
540501225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
540601225596STao Ma if (ret) {
5407548b0f22SJoel Becker mlog_errno(ret);
5408548b0f22SJoel Becker goto out;
5409548b0f22SJoel Becker }
541001225596STao Ma
541101225596STao Ma xe->xe_value_size = cpu_to_le64(len);
541201225596STao Ma
541301225596STao Ma ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket);
541401225596STao Ma
541501225596STao Ma out:
541601225596STao Ma return ret;
541701225596STao Ma }
541801225596STao Ma
ocfs2_rm_xattr_cluster(struct inode * inode,struct buffer_head * root_bh,u64 blkno,u32 cpos,u32 len,void * para)541947bca495STao Ma static int ocfs2_rm_xattr_cluster(struct inode *inode,
542047bca495STao Ma struct buffer_head *root_bh,
542101225596STao Ma u64 blkno,
542201225596STao Ma u32 cpos,
542301225596STao Ma u32 len,
542401225596STao Ma void *para)
542501225596STao Ma {
542601225596STao Ma int ret;
542701225596STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
542801225596STao Ma struct inode *tl_inode = osb->osb_tl_inode;
542901225596STao Ma handle_t *handle;
5430f99b9b7cSJoel Becker struct ocfs2_xattr_block *xb =
5431f99b9b7cSJoel Becker (struct ocfs2_xattr_block *)root_bh->b_data;
543247bca495STao Ma struct ocfs2_alloc_context *meta_ac = NULL;
5433ce9c5a54STao Ma struct ocfs2_cached_dealloc_ctxt dealloc;
543447bca495STao Ma struct ocfs2_extent_tree et;
543547bca495STao Ma
543647bca495STao Ma ret = ocfs2_iterate_xattr_buckets(inode, blkno, len,
543747bca495STao Ma ocfs2_delete_xattr_in_bucket, para);
543847bca495STao Ma if (ret) {
54395e404e9eSJoel Becker mlog_errno(ret);
544001225596STao Ma return ret;
544101225596STao Ma }
544201225596STao Ma
5443402b4183STao Ma ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh);
5444402b4183STao Ma
5445402b4183STao Ma ocfs2_init_dealloc_ctxt(&dealloc);
544601225596STao Ma
54478cb471e8SJoel Becker trace_ocfs2_rm_xattr_cluster(
54488cb471e8SJoel Becker (unsigned long long)OCFS2_I(inode)->ip_blkno,
544901225596STao Ma (unsigned long long)blkno, cpos, len);
5450f99b9b7cSJoel Becker
545101225596STao Ma ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), blkno,
545201225596STao Ma len);
545301225596STao Ma
545401225596STao Ma ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
545501225596STao Ma if (ret) {
54565955102cSAl Viro mlog_errno(ret);
545701225596STao Ma return ret;
545801225596STao Ma }
545901225596STao Ma
546001225596STao Ma inode_lock(tl_inode);
546101225596STao Ma
546201225596STao Ma if (ocfs2_truncate_log_needs_flush(osb)) {
546301225596STao Ma ret = __ocfs2_flush_truncate_log(osb);
546401225596STao Ma if (ret < 0) {
546501225596STao Ma mlog_errno(ret);
5466a90714c1SJan Kara goto out;
5467d3264799STao Ma }
546801225596STao Ma }
546901225596STao Ma
547001225596STao Ma handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(osb->sb));
547101225596STao Ma if (IS_ERR(handle)) {
547201225596STao Ma ret = -ENOMEM;
54730cf2f763SJoel Becker mlog_errno(ret);
547401225596STao Ma goto out;
547501225596STao Ma }
547601225596STao Ma
547701225596STao Ma ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), root_bh,
547801225596STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
547901225596STao Ma if (ret) {
5480dbdcf6a4SJoel Becker mlog_errno(ret);
5481f99b9b7cSJoel Becker goto out_commit;
548201225596STao Ma }
548301225596STao Ma
548401225596STao Ma ret = ocfs2_remove_extent(handle, &et, cpos, len, meta_ac,
548501225596STao Ma &dealloc);
548601225596STao Ma if (ret) {
548701225596STao Ma mlog_errno(ret);
5488ec20cec7SJoel Becker goto out_commit;
548901225596STao Ma }
549001225596STao Ma
549101225596STao Ma le32_add_cpu(&xb->xb_attrs.xb_root.xt_clusters, -len);
549201225596STao Ma ocfs2_journal_dirty(handle, root_bh);
54936fdb702dSDarrick J. Wong
549401225596STao Ma ret = ocfs2_truncate_log_append(osb, handle, blkno, len);
549501225596STao Ma if (ret)
549601225596STao Ma mlog_errno(ret);
549701225596STao Ma ocfs2_update_inode_fsync_trans(handle, inode, 0);
549801225596STao Ma
549901225596STao Ma out_commit:
55005955102cSAl Viro ocfs2_commit_trans(osb, handle);
550101225596STao Ma out:
550201225596STao Ma ocfs2_schedule_truncate_log_flush(osb, 1);
550301225596STao Ma
550401225596STao Ma inode_unlock(tl_inode);
550501225596STao Ma
550601225596STao Ma if (meta_ac)
550701225596STao Ma ocfs2_free_alloc_context(meta_ac);
550801225596STao Ma
550901225596STao Ma ocfs2_run_deallocs(osb, &dealloc);
551001225596STao Ma
551180bcaf34STao Ma return ret;
551280bcaf34STao Ma }
551380bcaf34STao Ma
551480bcaf34STao Ma /*
551580bcaf34STao Ma * check whether the xattr bucket is filled up with the same hash value.
551601225596STao Ma * If we want to insert the xattr with the same hash, return -ENOSPC.
551780bcaf34STao Ma * If we want to insert a xattr with different hash value, go ahead
551880bcaf34STao Ma * and ocfs2_divide_xattr_bucket will handle this.
551901225596STao Ma */
ocfs2_check_xattr_bucket_collision(struct inode * inode,struct ocfs2_xattr_bucket * bucket,const char * name)55203e632946SJoel Becker static int ocfs2_check_xattr_bucket_collision(struct inode *inode,
552180bcaf34STao Ma struct ocfs2_xattr_bucket *bucket,
552280bcaf34STao Ma const char *name)
552380bcaf34STao Ma {
552480bcaf34STao Ma struct ocfs2_xattr_header *xh = bucket_xh(bucket);
552501225596STao Ma u32 name_hash = ocfs2_xattr_name_hash(inode, name, strlen(name));
552601225596STao Ma
552701225596STao Ma if (name_hash != le32_to_cpu(xh->xh_entries[0].xe_name_hash))
552801225596STao Ma return 0;
552901225596STao Ma
55309c7759aaSJoel Becker if (xh->xh_entries[le16_to_cpu(xh->xh_count) - 1].xe_name_hash ==
553101225596STao Ma xh->xh_entries[0].xe_name_hash) {
553201225596STao Ma mlog(ML_ERROR, "Too much hash collision in xattr bucket %llu, "
553301225596STao Ma "hash = %u\n",
553401225596STao Ma (unsigned long long)bucket_blkno(bucket),
553501225596STao Ma le32_to_cpu(xh->xh_entries[0].xe_name_hash));
553601225596STao Ma return -ENOSPC;
553701225596STao Ma }
5538c5d95df5SJoel Becker
5539c5d95df5SJoel Becker return 0;
5540c5d95df5SJoel Becker }
5541c5d95df5SJoel Becker
5542c5d95df5SJoel Becker /*
554301225596STao Ma * Try to set the entry in the current bucket. If we fail, the caller
554478f30c31STao Ma * will handle getting us another bucket.
554578f30c31STao Ma */
ocfs2_xattr_set_entry_bucket(struct inode * inode,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xs,struct ocfs2_xattr_set_ctxt * ctxt)554601225596STao Ma static int ocfs2_xattr_set_entry_bucket(struct inode *inode,
5547c5d95df5SJoel Becker struct ocfs2_xattr_info *xi,
5548c5d95df5SJoel Becker struct ocfs2_xattr_search *xs,
554901225596STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
5550402b4183STao Ma {
555101225596STao Ma int ret;
5552c5d95df5SJoel Becker struct ocfs2_xa_loc loc;
5553c5d95df5SJoel Becker
5554c5d95df5SJoel Becker trace_ocfs2_xattr_set_entry_bucket(xi->xi_name);
5555c5d95df5SJoel Becker
5556c5d95df5SJoel Becker ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
5557c5d95df5SJoel Becker xs->not_found ? NULL : xs->here);
5558c5d95df5SJoel Becker ret = ocfs2_xa_set(&loc, xi, ctxt);
5559c5d95df5SJoel Becker if (!ret) {
5560c5d95df5SJoel Becker xs->here = loc.xl_entry;
5561c5d95df5SJoel Becker goto out;
556201225596STao Ma }
556301225596STao Ma if (ret != -ENOSPC) {
5564c5d95df5SJoel Becker mlog_errno(ret);
556585db90e7STao Ma goto out;
556685db90e7STao Ma }
556701225596STao Ma
556801225596STao Ma /* Ok, we need space. Let's try defragmenting the bucket. */
556901225596STao Ma ret = ocfs2_defrag_xattr_bucket(inode, ctxt->handle,
557001225596STao Ma xs->bucket);
557101225596STao Ma if (ret) {
5572c5d95df5SJoel Becker mlog_errno(ret);
5573c5d95df5SJoel Becker goto out;
5574c5d95df5SJoel Becker }
5575c5d95df5SJoel Becker
5576c5d95df5SJoel Becker ret = ocfs2_xa_set(&loc, xi, ctxt);
5577c5d95df5SJoel Becker if (!ret) {
5578c5d95df5SJoel Becker xs->here = loc.xl_entry;
557901225596STao Ma goto out;
558001225596STao Ma }
5581c5d95df5SJoel Becker if (ret != -ENOSPC)
5582c5d95df5SJoel Becker mlog_errno(ret);
558301225596STao Ma
558401225596STao Ma
5585c5d95df5SJoel Becker out:
5586c5d95df5SJoel Becker return ret;
5587c5d95df5SJoel Becker }
5588c5d95df5SJoel Becker
ocfs2_xattr_set_entry_index_block(struct inode * inode,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xs,struct ocfs2_xattr_set_ctxt * ctxt)5589c5d95df5SJoel Becker static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
5590c5d95df5SJoel Becker struct ocfs2_xattr_info *xi,
5591c5d95df5SJoel Becker struct ocfs2_xattr_search *xs,
5592402b4183STao Ma struct ocfs2_xattr_set_ctxt *ctxt)
5593c5d95df5SJoel Becker {
5594c5d95df5SJoel Becker int ret;
5595c5d95df5SJoel Becker
5596c5d95df5SJoel Becker trace_ocfs2_xattr_set_entry_index_block(xi->xi_name);
5597c5d95df5SJoel Becker
5598c5d95df5SJoel Becker ret = ocfs2_xattr_set_entry_bucket(inode, xi, xs, ctxt);
5599c5d95df5SJoel Becker if (!ret)
5600c5d95df5SJoel Becker goto out;
5601c5d95df5SJoel Becker if (ret != -ENOSPC) {
5602c5d95df5SJoel Becker mlog_errno(ret);
560301225596STao Ma goto out;
560401225596STao Ma }
560501225596STao Ma
560601225596STao Ma /* Ack, need more space. Let's try to get another bucket! */
560701225596STao Ma
560801225596STao Ma /*
560901225596STao Ma * We do not allow for overlapping ranges between buckets. And
561080bcaf34STao Ma * the maximum number of collisions we will allow for then is
5611ba937127SJoel Becker * one bucket's worth, so check it here whether we need to
56126b240ff6SJoel Becker * add a new bucket for the insert.
561301225596STao Ma */
561401225596STao Ma ret = ocfs2_check_xattr_bucket_collision(inode,
561501225596STao Ma xs->bucket,
561601225596STao Ma xi->xi_name);
561701225596STao Ma if (ret) {
561801225596STao Ma mlog_errno(ret);
561901225596STao Ma goto out;
562091f2033fSJoel Becker }
562178f30c31STao Ma
562201225596STao Ma ret = ocfs2_add_new_xattr_bucket(inode,
562301225596STao Ma xs->xattr_bh,
562401225596STao Ma xs->bucket,
562501225596STao Ma ctxt);
562601225596STao Ma if (ret) {
562791f2033fSJoel Becker mlog_errno(ret);
562891f2033fSJoel Becker goto out;
562991f2033fSJoel Becker }
563091f2033fSJoel Becker
563191f2033fSJoel Becker /*
563291f2033fSJoel Becker * ocfs2_add_new_xattr_bucket() will have updated
563391f2033fSJoel Becker * xs->bucket if it moved, but it will not have updated
5634ba937127SJoel Becker * any of the other search fields. Thus, we drop it and
563501225596STao Ma * re-search. Everything should be cached, so it'll be
56366b240ff6SJoel Becker * quick.
56376b240ff6SJoel Becker */
563801225596STao Ma ocfs2_xattr_bucket_relse(xs->bucket);
563901225596STao Ma ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh,
564001225596STao Ma xi->xi_name_index,
564101225596STao Ma xi->xi_name, xs);
5642c5d95df5SJoel Becker if (ret && ret != -ENODATA)
5643c5d95df5SJoel Becker goto out;
5644c5d95df5SJoel Becker xs->not_found = ret;
5645c5d95df5SJoel Becker
5646c5d95df5SJoel Becker /* Ok, we have a new bucket, let's try again */
564701225596STao Ma ret = ocfs2_xattr_set_entry_bucket(inode, xi, xs, ctxt);
564801225596STao Ma if (ret && (ret != -ENOSPC))
564901225596STao Ma mlog_errno(ret);
5650a3944256STao Ma
5651a3944256STao Ma out:
5652a3944256STao Ma return ret;
5653a3944256STao Ma }
5654a3944256STao Ma
ocfs2_delete_xattr_in_bucket(struct inode * inode,struct ocfs2_xattr_bucket * bucket,void * para)5655ce9c5a54STao Ma static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
56563e632946SJoel Becker struct ocfs2_xattr_bucket *bucket,
5657a3944256STao Ma void *para)
5658a3944256STao Ma {
565978f30c31STao Ma int ret = 0, ref_credits;
566078f30c31STao Ma struct ocfs2_xattr_header *xh = bucket_xh(bucket);
5661548b0f22SJoel Becker u16 i;
5662548b0f22SJoel Becker struct ocfs2_xattr_entry *xe;
5663ce9c5a54STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5664ce9c5a54STao Ma struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,};
5665ce9c5a54STao Ma int credits = ocfs2_remove_extent_credits(osb->sb) +
566678f30c31STao Ma ocfs2_blocks_per_xattr_bucket(inode->i_sb);
566778f30c31STao Ma struct ocfs2_xattr_value_root *xv;
5668a3944256STao Ma struct ocfs2_rm_xattr_bucket_para *args =
5669a3944256STao Ma (struct ocfs2_rm_xattr_bucket_para *)para;
5670a3944256STao Ma
5671a3944256STao Ma ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
5672a3944256STao Ma
5673a3944256STao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
5674ce9c5a54STao Ma xe = &xh->xh_entries[i];
5675ce9c5a54STao Ma if (ocfs2_xattr_is_local(xe))
5676023d4ea3SJoseph Qi continue;
5677023d4ea3SJoseph Qi
5678023d4ea3SJoseph Qi ret = ocfs2_get_xattr_tree_value_root(inode->i_sb, bucket,
5679023d4ea3SJoseph Qi i, &xv, NULL);
5680ce9c5a54STao Ma if (ret) {
5681ce9c5a54STao Ma mlog_errno(ret);
5682ce9c5a54STao Ma break;
5683ce9c5a54STao Ma }
5684ce9c5a54STao Ma
5685ce9c5a54STao Ma ret = ocfs2_lock_xattr_remove_allocators(inode, xv,
5686ce9c5a54STao Ma args->ref_ci,
5687ce9c5a54STao Ma args->ref_root_bh,
568888c3b062STao Ma &ctxt.meta_ac,
568988c3b062STao Ma &ref_credits);
569088c3b062STao Ma
569188c3b062STao Ma ctxt.handle = ocfs2_start_trans(osb, credits + ref_credits);
569288c3b062STao Ma if (IS_ERR(ctxt.handle)) {
569388c3b062STao Ma ret = PTR_ERR(ctxt.handle);
5694548b0f22SJoel Becker mlog_errno(ret);
569578f30c31STao Ma break;
569688c3b062STao Ma }
569788c3b062STao Ma
5698ce9c5a54STao Ma ret = ocfs2_xattr_bucket_value_truncate(inode, bucket,
5699ce9c5a54STao Ma i, 0, &ctxt);
5700ce9c5a54STao Ma
5701ce9c5a54STao Ma ocfs2_commit_trans(osb, ctxt.handle);
5702a3944256STao Ma if (ctxt.meta_ac) {
5703a3944256STao Ma ocfs2_free_alloc_context(ctxt.meta_ac);
5704a3944256STao Ma ctxt.meta_ac = NULL;
5705a3944256STao Ma }
5706a3944256STao Ma if (ret) {
5707a3944256STao Ma mlog_errno(ret);
5708ce9c5a54STao Ma break;
5709ce9c5a54STao Ma }
571078f30c31STao Ma }
571178f30c31STao Ma
5712a3944256STao Ma if (ctxt.meta_ac)
5713a3944256STao Ma ocfs2_free_alloc_context(ctxt.meta_ac);
5714a3944256STao Ma ocfs2_schedule_truncate_log_flush(osb, 1);
571599219aeaSMark Fasheh ocfs2_run_deallocs(osb, &ctxt.dealloc);
5716492a8a33STao Ma return ret;
5717492a8a33STao Ma }
5718492a8a33STao Ma
5719492a8a33STao Ma /*
5720492a8a33STao Ma * Whenever we modify a xattr value root in the bucket(e.g, CoW
5721492a8a33STao Ma * or change the extent record flag), we need to recalculate
5722492a8a33STao Ma * the metaecc for the whole bucket. So it is done here.
5723492a8a33STao Ma *
5724492a8a33STao Ma * Note:
5725492a8a33STao Ma * We have to give the extra credits for the caller.
5726492a8a33STao Ma */
ocfs2_xattr_bucket_post_refcount(struct inode * inode,handle_t * handle,void * para)5727492a8a33STao Ma static int ocfs2_xattr_bucket_post_refcount(struct inode *inode,
5728492a8a33STao Ma handle_t *handle,
5729492a8a33STao Ma void *para)
5730492a8a33STao Ma {
5731492a8a33STao Ma int ret;
5732492a8a33STao Ma struct ocfs2_xattr_bucket *bucket =
5733492a8a33STao Ma (struct ocfs2_xattr_bucket *)para;
5734492a8a33STao Ma
5735492a8a33STao Ma ret = ocfs2_xattr_bucket_journal_access(handle, bucket,
5736492a8a33STao Ma OCFS2_JOURNAL_ACCESS_WRITE);
5737492a8a33STao Ma if (ret) {
5738492a8a33STao Ma mlog_errno(ret);
5739492a8a33STao Ma return ret;
5740492a8a33STao Ma }
5741492a8a33STao Ma
5742492a8a33STao Ma ocfs2_xattr_bucket_journal_dirty(handle, bucket);
5743492a8a33STao Ma
5744492a8a33STao Ma return 0;
5745492a8a33STao Ma }
5746492a8a33STao Ma
5747492a8a33STao Ma /*
5748492a8a33STao Ma * Special action we need if the xattr value is refcounted.
5749492a8a33STao Ma *
5750492a8a33STao Ma * 1. If the xattr is refcounted, lock the tree.
5751492a8a33STao Ma * 2. CoW the xattr if we are setting the new value and the value
5752492a8a33STao Ma * will be stored outside.
5753492a8a33STao Ma * 3. In other case, decrease_refcount will work for us, so just
5754492a8a33STao Ma * lock the refcount tree, calculate the meta and credits is OK.
5755492a8a33STao Ma *
5756492a8a33STao Ma * We have to do CoW before ocfs2_init_xattr_set_ctxt since
5757492a8a33STao Ma * currently CoW is a completed transaction, while this function
5758492a8a33STao Ma * will also lock the allocators and let us deadlock. So we will
5759492a8a33STao Ma * CoW the whole xattr value.
5760492a8a33STao Ma */
ocfs2_prepare_refcount_xattr(struct inode * inode,struct ocfs2_dinode * di,struct ocfs2_xattr_info * xi,struct ocfs2_xattr_search * xis,struct ocfs2_xattr_search * xbs,struct ocfs2_refcount_tree ** ref_tree,int * meta_add,int * credits)5761492a8a33STao Ma static int ocfs2_prepare_refcount_xattr(struct inode *inode,
5762492a8a33STao Ma struct ocfs2_dinode *di,
5763492a8a33STao Ma struct ocfs2_xattr_info *xi,
5764492a8a33STao Ma struct ocfs2_xattr_search *xis,
5765492a8a33STao Ma struct ocfs2_xattr_search *xbs,
5766492a8a33STao Ma struct ocfs2_refcount_tree **ref_tree,
5767492a8a33STao Ma int *meta_add,
5768492a8a33STao Ma int *credits)
5769492a8a33STao Ma {
5770492a8a33STao Ma int ret = 0;
5771492a8a33STao Ma struct ocfs2_xattr_block *xb;
5772492a8a33STao Ma struct ocfs2_xattr_entry *xe;
5773492a8a33STao Ma char *base;
5774492a8a33STao Ma u32 p_cluster, num_clusters;
5775492a8a33STao Ma unsigned int ext_flags;
5776492a8a33STao Ma int name_offset, name_len;
5777492a8a33STao Ma struct ocfs2_xattr_value_buf vb;
5778492a8a33STao Ma struct ocfs2_xattr_bucket *bucket = NULL;
5779492a8a33STao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5780492a8a33STao Ma struct ocfs2_post_refcount refcount;
5781492a8a33STao Ma struct ocfs2_post_refcount *p = NULL;
5782492a8a33STao Ma struct buffer_head *ref_root_bh = NULL;
5783492a8a33STao Ma
5784492a8a33STao Ma if (!xis->not_found) {
5785492a8a33STao Ma xe = xis->here;
5786492a8a33STao Ma name_offset = le16_to_cpu(xe->xe_name_offset);
5787492a8a33STao Ma name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
5788492a8a33STao Ma base = xis->base;
5789492a8a33STao Ma vb.vb_bh = xis->inode_bh;
5790492a8a33STao Ma vb.vb_access = ocfs2_journal_access_di;
5791492a8a33STao Ma } else {
5792492a8a33STao Ma int i, block_off = 0;
5793492a8a33STao Ma xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
5794492a8a33STao Ma xe = xbs->here;
5795492a8a33STao Ma name_offset = le16_to_cpu(xe->xe_name_offset);
5796fd68a894STao Ma name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
5797492a8a33STao Ma i = xbs->here - xbs->header->xh_entries;
5798492a8a33STao Ma
5799492a8a33STao Ma if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
5800492a8a33STao Ma ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb,
5801492a8a33STao Ma bucket_xh(xbs->bucket),
5802492a8a33STao Ma i, &block_off,
5803492a8a33STao Ma &name_offset);
5804492a8a33STao Ma if (ret) {
5805492a8a33STao Ma mlog_errno(ret);
5806492a8a33STao Ma goto out;
5807492a8a33STao Ma }
5808492a8a33STao Ma base = bucket_block(xbs->bucket, block_off);
5809492a8a33STao Ma vb.vb_bh = xbs->bucket->bu_bhs[block_off];
5810492a8a33STao Ma vb.vb_access = ocfs2_journal_access;
5811492a8a33STao Ma
5812492a8a33STao Ma if (ocfs2_meta_ecc(osb)) {
5813492a8a33STao Ma /*create parameters for ocfs2_post_refcount. */
5814492a8a33STao Ma bucket = xbs->bucket;
5815492a8a33STao Ma refcount.credits = bucket->bu_blocks;
5816492a8a33STao Ma refcount.para = bucket;
5817492a8a33STao Ma refcount.func =
5818492a8a33STao Ma ocfs2_xattr_bucket_post_refcount;
5819492a8a33STao Ma p = &refcount;
5820492a8a33STao Ma }
5821492a8a33STao Ma } else {
5822492a8a33STao Ma base = xbs->base;
5823492a8a33STao Ma vb.vb_bh = xbs->xattr_bh;
5824492a8a33STao Ma vb.vb_access = ocfs2_journal_access_xb;
5825492a8a33STao Ma }
5826492a8a33STao Ma }
5827492a8a33STao Ma
5828492a8a33STao Ma if (ocfs2_xattr_is_local(xe))
5829492a8a33STao Ma goto out;
5830492a8a33STao Ma
5831492a8a33STao Ma vb.vb_xv = (struct ocfs2_xattr_value_root *)
5832492a8a33STao Ma (base + name_offset + name_len);
5833492a8a33STao Ma
5834492a8a33STao Ma ret = ocfs2_xattr_get_clusters(inode, 0, &p_cluster,
5835492a8a33STao Ma &num_clusters, &vb.vb_xv->xr_list,
5836492a8a33STao Ma &ext_flags);
5837492a8a33STao Ma if (ret) {
5838492a8a33STao Ma mlog_errno(ret);
5839492a8a33STao Ma goto out;
5840492a8a33STao Ma }
5841492a8a33STao Ma
5842492a8a33STao Ma /*
5843492a8a33STao Ma * We just need to check the 1st extent record, since we always
5844492a8a33STao Ma * CoW the whole xattr. So there shouldn't be a xattr with
5845492a8a33STao Ma * some REFCOUNT extent recs after the 1st one.
5846492a8a33STao Ma */
5847492a8a33STao Ma if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
5848492a8a33STao Ma goto out;
5849492a8a33STao Ma
5850492a8a33STao Ma ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
5851492a8a33STao Ma 1, ref_tree, &ref_root_bh);
5852492a8a33STao Ma if (ret) {
5853492a8a33STao Ma mlog_errno(ret);
5854492a8a33STao Ma goto out;
5855492a8a33STao Ma }
5856492a8a33STao Ma
5857492a8a33STao Ma /*
5858492a8a33STao Ma * If we are deleting the xattr or the new size will be stored inside,
5859492a8a33STao Ma * cool, leave it there, the xattr truncate process will remove them
5860492a8a33STao Ma * for us(it still needs the refcount tree lock and the meta, credits).
58616b240ff6SJoel Becker * And the worse case is that every cluster truncate will split the
5862492a8a33STao Ma * refcount tree, and make the original extent become 3. So we will need
5863492a8a33STao Ma * 2 * cluster more extent recs at most.
5864492a8a33STao Ma */
5865492a8a33STao Ma if (!xi->xi_value || xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE) {
5866492a8a33STao Ma
5867492a8a33STao Ma ret = ocfs2_refcounted_xattr_delete_need(inode,
5868492a8a33STao Ma &(*ref_tree)->rf_ci,
5869492a8a33STao Ma ref_root_bh, vb.vb_xv,
5870492a8a33STao Ma meta_add, credits);
5871492a8a33STao Ma if (ret)
5872492a8a33STao Ma mlog_errno(ret);
5873492a8a33STao Ma goto out;
5874492a8a33STao Ma }
5875492a8a33STao Ma
5876492a8a33STao Ma ret = ocfs2_refcount_cow_xattr(inode, di, &vb,
5877492a8a33STao Ma *ref_tree, ref_root_bh, 0,
5878492a8a33STao Ma le32_to_cpu(vb.vb_xv->xr_clusters), p);
5879492a8a33STao Ma if (ret)
5880492a8a33STao Ma mlog_errno(ret);
5881492a8a33STao Ma
5882492a8a33STao Ma out:
5883492a8a33STao Ma brelse(ref_root_bh);
58840129241eSTao Ma return ret;
58850129241eSTao Ma }
58860129241eSTao Ma
58870129241eSTao Ma /*
58880129241eSTao Ma * Add the REFCOUNTED flags for all the extent rec in ocfs2_xattr_value_root.
58890129241eSTao Ma * The physical clusters will be added to refcount tree.
58900129241eSTao Ma */
ocfs2_xattr_value_attach_refcount(struct inode * inode,struct ocfs2_xattr_value_root * xv,struct ocfs2_extent_tree * value_et,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh,struct ocfs2_cached_dealloc_ctxt * dealloc,struct ocfs2_post_refcount * refcount)58910129241eSTao Ma static int ocfs2_xattr_value_attach_refcount(struct inode *inode,
58920129241eSTao Ma struct ocfs2_xattr_value_root *xv,
58930129241eSTao Ma struct ocfs2_extent_tree *value_et,
58940129241eSTao Ma struct ocfs2_caching_info *ref_ci,
58950129241eSTao Ma struct buffer_head *ref_root_bh,
58960129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc,
58970129241eSTao Ma struct ocfs2_post_refcount *refcount)
58980129241eSTao Ma {
58990129241eSTao Ma int ret = 0;
59000129241eSTao Ma u32 clusters = le32_to_cpu(xv->xr_clusters);
59010129241eSTao Ma u32 cpos, p_cluster, num_clusters;
59020129241eSTao Ma struct ocfs2_extent_list *el = &xv->xr_list;
59030129241eSTao Ma unsigned int ext_flags;
59040129241eSTao Ma
590517caf955SJoseph Qi cpos = 0;
590617caf955SJoseph Qi while (cpos < clusters) {
590717caf955SJoseph Qi ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
590817caf955SJoseph Qi &num_clusters, el, &ext_flags);
59090129241eSTao Ma if (ret) {
59100129241eSTao Ma mlog_errno(ret);
59110129241eSTao Ma break;
59120129241eSTao Ma }
59130129241eSTao Ma
59140129241eSTao Ma cpos += num_clusters;
59150129241eSTao Ma if ((ext_flags & OCFS2_EXT_REFCOUNTED))
59160129241eSTao Ma continue;
59170129241eSTao Ma
59180129241eSTao Ma BUG_ON(!p_cluster);
59190129241eSTao Ma
59200129241eSTao Ma ret = ocfs2_add_refcount_flag(inode, value_et,
59210129241eSTao Ma ref_ci, ref_root_bh,
59220129241eSTao Ma cpos - num_clusters,
59230129241eSTao Ma p_cluster, num_clusters,
59240129241eSTao Ma dealloc, refcount);
59250129241eSTao Ma if (ret) {
59260129241eSTao Ma mlog_errno(ret);
59270129241eSTao Ma break;
59280129241eSTao Ma }
59290129241eSTao Ma }
59300129241eSTao Ma
59310129241eSTao Ma return ret;
59320129241eSTao Ma }
59330129241eSTao Ma
59340129241eSTao Ma /*
59350129241eSTao Ma * Given a normal ocfs2_xattr_header, refcount all the entries which
59360129241eSTao Ma * have value stored outside.
59370129241eSTao Ma * Used for xattrs stored in inode and ocfs2_xattr_block.
59380129241eSTao Ma */
ocfs2_xattr_attach_refcount_normal(struct inode * inode,struct ocfs2_xattr_value_buf * vb,struct ocfs2_xattr_header * header,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh,struct ocfs2_cached_dealloc_ctxt * dealloc)59390129241eSTao Ma static int ocfs2_xattr_attach_refcount_normal(struct inode *inode,
59400129241eSTao Ma struct ocfs2_xattr_value_buf *vb,
59410129241eSTao Ma struct ocfs2_xattr_header *header,
59420129241eSTao Ma struct ocfs2_caching_info *ref_ci,
59430129241eSTao Ma struct buffer_head *ref_root_bh,
59440129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc)
59450129241eSTao Ma {
59460129241eSTao Ma
59470129241eSTao Ma struct ocfs2_xattr_entry *xe;
59480129241eSTao Ma struct ocfs2_xattr_value_root *xv;
59490129241eSTao Ma struct ocfs2_extent_tree et;
59500129241eSTao Ma int i, ret = 0;
59510129241eSTao Ma
59520129241eSTao Ma for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
59530129241eSTao Ma xe = &header->xh_entries[i];
59540129241eSTao Ma
59550129241eSTao Ma if (ocfs2_xattr_is_local(xe))
59560129241eSTao Ma continue;
59570129241eSTao Ma
59580129241eSTao Ma xv = (struct ocfs2_xattr_value_root *)((void *)header +
59590129241eSTao Ma le16_to_cpu(xe->xe_name_offset) +
59600129241eSTao Ma OCFS2_XATTR_SIZE(xe->xe_name_len));
59610129241eSTao Ma
59620129241eSTao Ma vb->vb_xv = xv;
59630129241eSTao Ma ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
59640129241eSTao Ma
59650129241eSTao Ma ret = ocfs2_xattr_value_attach_refcount(inode, xv, &et,
59660129241eSTao Ma ref_ci, ref_root_bh,
59670129241eSTao Ma dealloc, NULL);
59680129241eSTao Ma if (ret) {
59690129241eSTao Ma mlog_errno(ret);
59700129241eSTao Ma break;
59710129241eSTao Ma }
59720129241eSTao Ma }
59730129241eSTao Ma
59740129241eSTao Ma return ret;
59750129241eSTao Ma }
59760129241eSTao Ma
ocfs2_xattr_inline_attach_refcount(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)59770129241eSTao Ma static int ocfs2_xattr_inline_attach_refcount(struct inode *inode,
59780129241eSTao Ma struct buffer_head *fe_bh,
59790129241eSTao Ma struct ocfs2_caching_info *ref_ci,
59800129241eSTao Ma struct buffer_head *ref_root_bh,
59810129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc)
59820129241eSTao Ma {
59830129241eSTao Ma struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data;
59840129241eSTao Ma struct ocfs2_xattr_header *header = (struct ocfs2_xattr_header *)
59850129241eSTao Ma (fe_bh->b_data + inode->i_sb->s_blocksize -
59860129241eSTao Ma le16_to_cpu(di->i_xattr_inline_size));
59870129241eSTao Ma struct ocfs2_xattr_value_buf vb = {
59880129241eSTao Ma .vb_bh = fe_bh,
59890129241eSTao Ma .vb_access = ocfs2_journal_access_di,
59900129241eSTao Ma };
59910129241eSTao Ma
59920129241eSTao Ma return ocfs2_xattr_attach_refcount_normal(inode, &vb, header,
59930129241eSTao Ma ref_ci, ref_root_bh, dealloc);
59940129241eSTao Ma }
59950129241eSTao Ma
59960129241eSTao Ma struct ocfs2_xattr_tree_value_refcount_para {
59970129241eSTao Ma struct ocfs2_caching_info *ref_ci;
59980129241eSTao Ma struct buffer_head *ref_root_bh;
59990129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc;
60000129241eSTao Ma };
60010129241eSTao Ma
ocfs2_get_xattr_tree_value_root(struct super_block * sb,struct ocfs2_xattr_bucket * bucket,int offset,struct ocfs2_xattr_value_root ** xv,struct buffer_head ** bh)60020129241eSTao Ma static int ocfs2_get_xattr_tree_value_root(struct super_block *sb,
60030129241eSTao Ma struct ocfs2_xattr_bucket *bucket,
60040129241eSTao Ma int offset,
60050129241eSTao Ma struct ocfs2_xattr_value_root **xv,
60060129241eSTao Ma struct buffer_head **bh)
60070129241eSTao Ma {
60080129241eSTao Ma int ret, block_off, name_offset;
60090129241eSTao Ma struct ocfs2_xattr_header *xh = bucket_xh(bucket);
60100129241eSTao Ma struct ocfs2_xattr_entry *xe = &xh->xh_entries[offset];
60110129241eSTao Ma void *base;
60120129241eSTao Ma
60130129241eSTao Ma ret = ocfs2_xattr_bucket_get_name_value(sb,
60140129241eSTao Ma bucket_xh(bucket),
60150129241eSTao Ma offset,
60160129241eSTao Ma &block_off,
60170129241eSTao Ma &name_offset);
60180129241eSTao Ma if (ret) {
60190129241eSTao Ma mlog_errno(ret);
60200129241eSTao Ma goto out;
60210129241eSTao Ma }
60220129241eSTao Ma
60230129241eSTao Ma base = bucket_block(bucket, block_off);
60240129241eSTao Ma
60250129241eSTao Ma *xv = (struct ocfs2_xattr_value_root *)(base + name_offset +
60260129241eSTao Ma OCFS2_XATTR_SIZE(xe->xe_name_len));
60270129241eSTao Ma
60280129241eSTao Ma if (bh)
60290129241eSTao Ma *bh = bucket->bu_bhs[block_off];
60300129241eSTao Ma out:
60310129241eSTao Ma return ret;
60320129241eSTao Ma }
60330129241eSTao Ma
60340129241eSTao Ma /*
60350129241eSTao Ma * For a given xattr bucket, refcount all the entries which
60360129241eSTao Ma * have value stored outside.
60370129241eSTao Ma */
ocfs2_xattr_bucket_value_refcount(struct inode * inode,struct ocfs2_xattr_bucket * bucket,void * para)60380129241eSTao Ma static int ocfs2_xattr_bucket_value_refcount(struct inode *inode,
60390129241eSTao Ma struct ocfs2_xattr_bucket *bucket,
60400129241eSTao Ma void *para)
60410129241eSTao Ma {
60420129241eSTao Ma int i, ret = 0;
60430129241eSTao Ma struct ocfs2_extent_tree et;
60440129241eSTao Ma struct ocfs2_xattr_tree_value_refcount_para *ref =
60450129241eSTao Ma (struct ocfs2_xattr_tree_value_refcount_para *)para;
60460129241eSTao Ma struct ocfs2_xattr_header *xh =
60470129241eSTao Ma (struct ocfs2_xattr_header *)bucket->bu_bhs[0]->b_data;
60480129241eSTao Ma struct ocfs2_xattr_entry *xe;
60490129241eSTao Ma struct ocfs2_xattr_value_buf vb = {
60500129241eSTao Ma .vb_access = ocfs2_journal_access,
60510129241eSTao Ma };
60520129241eSTao Ma struct ocfs2_post_refcount refcount = {
60530129241eSTao Ma .credits = bucket->bu_blocks,
60540129241eSTao Ma .para = bucket,
60550129241eSTao Ma .func = ocfs2_xattr_bucket_post_refcount,
60560129241eSTao Ma };
60570129241eSTao Ma struct ocfs2_post_refcount *p = NULL;
60580129241eSTao Ma
6059402b4183STao Ma /* We only need post_refcount if we support metaecc. */
60600129241eSTao Ma if (ocfs2_meta_ecc(OCFS2_SB(inode->i_sb)))
60610129241eSTao Ma p = &refcount;
60620129241eSTao Ma
60630129241eSTao Ma trace_ocfs2_xattr_bucket_value_refcount(
60640129241eSTao Ma (unsigned long long)bucket_blkno(bucket),
60650129241eSTao Ma le16_to_cpu(xh->xh_count));
60660129241eSTao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
60670129241eSTao Ma xe = &xh->xh_entries[i];
60680129241eSTao Ma
60690129241eSTao Ma if (ocfs2_xattr_is_local(xe))
60700129241eSTao Ma continue;
60710129241eSTao Ma
60720129241eSTao Ma ret = ocfs2_get_xattr_tree_value_root(inode->i_sb, bucket, i,
60730129241eSTao Ma &vb.vb_xv, &vb.vb_bh);
60740129241eSTao Ma if (ret) {
60750129241eSTao Ma mlog_errno(ret);
60760129241eSTao Ma break;
60770129241eSTao Ma }
60780129241eSTao Ma
60790129241eSTao Ma ocfs2_init_xattr_value_extent_tree(&et,
60800129241eSTao Ma INODE_CACHE(inode), &vb);
60810129241eSTao Ma
60820129241eSTao Ma ret = ocfs2_xattr_value_attach_refcount(inode, vb.vb_xv,
60830129241eSTao Ma &et, ref->ref_ci,
60840129241eSTao Ma ref->ref_root_bh,
60850129241eSTao Ma ref->dealloc, p);
60860129241eSTao Ma if (ret) {
60870129241eSTao Ma mlog_errno(ret);
60880129241eSTao Ma break;
60890129241eSTao Ma }
60900129241eSTao Ma }
60910129241eSTao Ma
60920129241eSTao Ma return ret;
60930129241eSTao Ma
60940129241eSTao Ma }
60950129241eSTao Ma
ocfs2_refcount_xattr_tree_rec(struct inode * inode,struct buffer_head * root_bh,u64 blkno,u32 cpos,u32 len,void * para)60960129241eSTao Ma static int ocfs2_refcount_xattr_tree_rec(struct inode *inode,
60970129241eSTao Ma struct buffer_head *root_bh,
60980129241eSTao Ma u64 blkno, u32 cpos, u32 len, void *para)
60990129241eSTao Ma {
61000129241eSTao Ma return ocfs2_iterate_xattr_buckets(inode, blkno, len,
61010129241eSTao Ma ocfs2_xattr_bucket_value_refcount,
61020129241eSTao Ma para);
61030129241eSTao Ma }
61040129241eSTao Ma
ocfs2_xattr_block_attach_refcount(struct inode * inode,struct buffer_head * blk_bh,struct ocfs2_caching_info * ref_ci,struct buffer_head * ref_root_bh,struct ocfs2_cached_dealloc_ctxt * dealloc)61050129241eSTao Ma static int ocfs2_xattr_block_attach_refcount(struct inode *inode,
61060129241eSTao Ma struct buffer_head *blk_bh,
61070129241eSTao Ma struct ocfs2_caching_info *ref_ci,
61080129241eSTao Ma struct buffer_head *ref_root_bh,
61090129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc)
61100129241eSTao Ma {
61110129241eSTao Ma int ret = 0;
61120129241eSTao Ma struct ocfs2_xattr_block *xb =
61130129241eSTao Ma (struct ocfs2_xattr_block *)blk_bh->b_data;
61140129241eSTao Ma
61150129241eSTao Ma if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
61160129241eSTao Ma struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header;
61170129241eSTao Ma struct ocfs2_xattr_value_buf vb = {
61180129241eSTao Ma .vb_bh = blk_bh,
61190129241eSTao Ma .vb_access = ocfs2_journal_access_xb,
61200129241eSTao Ma };
61210129241eSTao Ma
61220129241eSTao Ma ret = ocfs2_xattr_attach_refcount_normal(inode, &vb, header,
61230129241eSTao Ma ref_ci, ref_root_bh,
61240129241eSTao Ma dealloc);
61250129241eSTao Ma } else {
61260129241eSTao Ma struct ocfs2_xattr_tree_value_refcount_para para = {
61270129241eSTao Ma .ref_ci = ref_ci,
61280129241eSTao Ma .ref_root_bh = ref_root_bh,
61290129241eSTao Ma .dealloc = dealloc,
61300129241eSTao Ma };
61310129241eSTao Ma
61320129241eSTao Ma ret = ocfs2_iterate_xattr_index_block(inode, blk_bh,
61330129241eSTao Ma ocfs2_refcount_xattr_tree_rec,
61340129241eSTao Ma ¶);
61350129241eSTao Ma }
61360129241eSTao Ma
61370129241eSTao Ma return ret;
61380129241eSTao Ma }
61390129241eSTao Ma
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)61400129241eSTao Ma int ocfs2_xattr_attach_refcount_tree(struct inode *inode,
61410129241eSTao Ma struct buffer_head *fe_bh,
61420129241eSTao Ma struct ocfs2_caching_info *ref_ci,
61430129241eSTao Ma struct buffer_head *ref_root_bh,
61440129241eSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc)
61450129241eSTao Ma {
61460129241eSTao Ma int ret = 0;
61470129241eSTao Ma struct ocfs2_inode_info *oi = OCFS2_I(inode);
61480129241eSTao Ma struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data;
61490129241eSTao Ma struct buffer_head *blk_bh = NULL;
61500129241eSTao Ma
61510129241eSTao Ma if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
61520129241eSTao Ma ret = ocfs2_xattr_inline_attach_refcount(inode, fe_bh,
61530129241eSTao Ma ref_ci, ref_root_bh,
61540129241eSTao Ma dealloc);
61550129241eSTao Ma if (ret) {
61560129241eSTao Ma mlog_errno(ret);
61570129241eSTao Ma goto out;
61580129241eSTao Ma }
61590129241eSTao Ma }
61600129241eSTao Ma
61610129241eSTao Ma if (!di->i_xattr_loc)
61620129241eSTao Ma goto out;
61630129241eSTao Ma
61640129241eSTao Ma ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc),
61650129241eSTao Ma &blk_bh);
61660129241eSTao Ma if (ret < 0) {
61670129241eSTao Ma mlog_errno(ret);
61680129241eSTao Ma goto out;
61690129241eSTao Ma }
61700129241eSTao Ma
61710129241eSTao Ma ret = ocfs2_xattr_block_attach_refcount(inode, blk_bh, ref_ci,
61720129241eSTao Ma ref_root_bh, dealloc);
61730129241eSTao Ma if (ret)
61740129241eSTao Ma mlog_errno(ret);
61750129241eSTao Ma
61760129241eSTao Ma brelse(blk_bh);
61770129241eSTao Ma out:
61780fe9b66cSTao Ma
61790129241eSTao Ma return ret;
61802999d12fSTao Ma }
61812999d12fSTao Ma
61822999d12fSTao Ma typedef int (should_xattr_reflinked)(struct ocfs2_xattr_entry *xe);
61832999d12fSTao Ma /*
61842999d12fSTao Ma * Store the information we need in xattr reflink.
61852999d12fSTao Ma * old_bh and new_bh are inode bh for the old and new inode.
61862999d12fSTao Ma */
61872999d12fSTao Ma struct ocfs2_xattr_reflink {
61882999d12fSTao Ma struct inode *old_inode;
61892999d12fSTao Ma struct inode *new_inode;
61902999d12fSTao Ma struct buffer_head *old_bh;
61910fe9b66cSTao Ma struct buffer_head *new_bh;
61922999d12fSTao Ma struct ocfs2_caching_info *ref_ci;
61932999d12fSTao Ma struct buffer_head *ref_root_bh;
61942999d12fSTao Ma struct ocfs2_cached_dealloc_ctxt *dealloc;
61952999d12fSTao Ma should_xattr_reflinked *xattr_reflinked;
61962999d12fSTao Ma };
61972999d12fSTao Ma
61982999d12fSTao Ma /*
61992999d12fSTao Ma * Given a xattr header and xe offset,
62002999d12fSTao Ma * return the proper xv and the corresponding bh.
62012999d12fSTao Ma * xattr in inode, block and xattr tree have different implementaions.
62022999d12fSTao Ma */
62032999d12fSTao Ma typedef int (get_xattr_value_root)(struct super_block *sb,
62042999d12fSTao Ma struct buffer_head *bh,
62052999d12fSTao Ma struct ocfs2_xattr_header *xh,
62062999d12fSTao Ma int offset,
62072999d12fSTao Ma struct ocfs2_xattr_value_root **xv,
62082999d12fSTao Ma struct buffer_head **ret_bh,
62092999d12fSTao Ma void *para);
62102999d12fSTao Ma
62112999d12fSTao Ma /*
62122999d12fSTao Ma * Calculate all the xattr value root metadata stored in this xattr header and
62132999d12fSTao Ma * credits we need if we create them from the scratch.
62142999d12fSTao Ma * We use get_xattr_value_root so that all types of xattr container can use it.
62152999d12fSTao Ma */
ocfs2_value_metas_in_xattr_header(struct super_block * sb,struct buffer_head * bh,struct ocfs2_xattr_header * xh,int * metas,int * credits,int * num_recs,get_xattr_value_root * func,void * para)62162999d12fSTao Ma static int ocfs2_value_metas_in_xattr_header(struct super_block *sb,
62172999d12fSTao Ma struct buffer_head *bh,
62182999d12fSTao Ma struct ocfs2_xattr_header *xh,
62192999d12fSTao Ma int *metas, int *credits,
62202999d12fSTao Ma int *num_recs,
62212999d12fSTao Ma get_xattr_value_root *func,
62222999d12fSTao Ma void *para)
62232999d12fSTao Ma {
62242999d12fSTao Ma int i, ret = 0;
62252999d12fSTao Ma struct ocfs2_xattr_value_root *xv;
62262999d12fSTao Ma struct ocfs2_xattr_entry *xe;
62272999d12fSTao Ma
62282999d12fSTao Ma for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
62292999d12fSTao Ma xe = &xh->xh_entries[i];
62302999d12fSTao Ma if (ocfs2_xattr_is_local(xe))
62312999d12fSTao Ma continue;
62322999d12fSTao Ma
62332999d12fSTao Ma ret = func(sb, bh, xh, i, &xv, NULL, para);
62342999d12fSTao Ma if (ret) {
62352999d12fSTao Ma mlog_errno(ret);
62362999d12fSTao Ma break;
62372999d12fSTao Ma }
62382999d12fSTao Ma
623906f9da6eSGoldwyn Rodrigues *metas += le16_to_cpu(xv->xr_list.l_tree_depth) *
62402999d12fSTao Ma le16_to_cpu(xv->xr_list.l_next_free_rec);
62412999d12fSTao Ma
62422999d12fSTao Ma *credits += ocfs2_calc_extend_credits(sb,
62432999d12fSTao Ma &def_xv.xv.xr_list);
62442999d12fSTao Ma
62452999d12fSTao Ma /*
62468ff6af88STao Ma * If the value is a tree with depth > 1, We don't go deep
62472999d12fSTao Ma * to the extent block, so just calculate a maximum record num.
62482999d12fSTao Ma */
62492999d12fSTao Ma if (!xv->xr_list.l_tree_depth)
62502999d12fSTao Ma *num_recs += le16_to_cpu(xv->xr_list.l_next_free_rec);
62512999d12fSTao Ma else
62522999d12fSTao Ma *num_recs += ocfs2_clusters_for_bytes(sb,
62532999d12fSTao Ma XATTR_SIZE_MAX);
62542999d12fSTao Ma }
62552999d12fSTao Ma
62562999d12fSTao Ma return ret;
62572999d12fSTao Ma }
62582999d12fSTao Ma
62592999d12fSTao Ma /* Used by xattr inode and block to return the right xv and buffer_head. */
ocfs2_get_xattr_value_root(struct super_block * sb,struct buffer_head * bh,struct ocfs2_xattr_header * xh,int offset,struct ocfs2_xattr_value_root ** xv,struct buffer_head ** ret_bh,void * para)62602999d12fSTao Ma static int ocfs2_get_xattr_value_root(struct super_block *sb,
62612999d12fSTao Ma struct buffer_head *bh,
62622999d12fSTao Ma struct ocfs2_xattr_header *xh,
62632999d12fSTao Ma int offset,
62642999d12fSTao Ma struct ocfs2_xattr_value_root **xv,
62652999d12fSTao Ma struct buffer_head **ret_bh,
62662999d12fSTao Ma void *para)
62672999d12fSTao Ma {
62682999d12fSTao Ma struct ocfs2_xattr_entry *xe = &xh->xh_entries[offset];
62692999d12fSTao Ma
62702999d12fSTao Ma *xv = (struct ocfs2_xattr_value_root *)((void *)xh +
62712999d12fSTao Ma le16_to_cpu(xe->xe_name_offset) +
62722999d12fSTao Ma OCFS2_XATTR_SIZE(xe->xe_name_len));
62732999d12fSTao Ma
62742999d12fSTao Ma if (ret_bh)
62752999d12fSTao Ma *ret_bh = bh;
62762999d12fSTao Ma
62772999d12fSTao Ma return 0;
62782999d12fSTao Ma }
62792999d12fSTao Ma
62802999d12fSTao Ma /*
62812999d12fSTao Ma * Lock the meta_ac and caculate how much credits we need for reflink xattrs.
62822999d12fSTao Ma * It is only used for inline xattr and xattr block.
62832999d12fSTao Ma */
ocfs2_reflink_lock_xattr_allocators(struct ocfs2_super * osb,struct ocfs2_xattr_header * xh,struct buffer_head * ref_root_bh,int * credits,struct ocfs2_alloc_context ** meta_ac)62842999d12fSTao Ma static int ocfs2_reflink_lock_xattr_allocators(struct ocfs2_super *osb,
62852999d12fSTao Ma struct ocfs2_xattr_header *xh,
62862999d12fSTao Ma struct buffer_head *ref_root_bh,
62872999d12fSTao Ma int *credits,
62882999d12fSTao Ma struct ocfs2_alloc_context **meta_ac)
62892999d12fSTao Ma {
62902999d12fSTao Ma int ret, meta_add = 0, num_recs = 0;
62912999d12fSTao Ma struct ocfs2_refcount_block *rb =
62922999d12fSTao Ma (struct ocfs2_refcount_block *)ref_root_bh->b_data;
62932999d12fSTao Ma
62942999d12fSTao Ma *credits = 0;
62952999d12fSTao Ma
62962999d12fSTao Ma ret = ocfs2_value_metas_in_xattr_header(osb->sb, NULL, xh,
62972999d12fSTao Ma &meta_add, credits, &num_recs,
62982999d12fSTao Ma ocfs2_get_xattr_value_root,
62992999d12fSTao Ma NULL);
63002999d12fSTao Ma if (ret) {
63012999d12fSTao Ma mlog_errno(ret);
63022999d12fSTao Ma goto out;
63032999d12fSTao Ma }
63042999d12fSTao Ma
63052999d12fSTao Ma /*
63062999d12fSTao Ma * We need to add/modify num_recs in refcount tree, so just calculate
63072999d12fSTao Ma * an approximate number we need for refcount tree change.
63082999d12fSTao Ma * Sometimes we need to split the tree, and after split, half recs
63092999d12fSTao Ma * will be moved to the new block, and a new block can only provide
63102999d12fSTao Ma * half number of recs. So we multiple new blocks by 2.
63112999d12fSTao Ma */
63122999d12fSTao Ma num_recs = num_recs / ocfs2_refcount_recs_per_rb(osb->sb) * 2;
63132999d12fSTao Ma meta_add += num_recs;
63142999d12fSTao Ma *credits += num_recs + num_recs * OCFS2_EXPAND_REFCOUNT_TREE_CREDITS;
63152999d12fSTao Ma if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL)
63162999d12fSTao Ma *credits += le16_to_cpu(rb->rf_list.l_tree_depth) *
63172999d12fSTao Ma le16_to_cpu(rb->rf_list.l_next_free_rec) + 1;
63182999d12fSTao Ma else
63192999d12fSTao Ma *credits += 1;
63202999d12fSTao Ma
63212999d12fSTao Ma ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add, meta_ac);
63222999d12fSTao Ma if (ret)
63232999d12fSTao Ma mlog_errno(ret);
63242999d12fSTao Ma
63252999d12fSTao Ma out:
63262999d12fSTao Ma return ret;
63272999d12fSTao Ma }
63282999d12fSTao Ma
63292999d12fSTao Ma /*
63302999d12fSTao Ma * Given a xattr header, reflink all the xattrs in this container.
63312999d12fSTao Ma * It can be used for inode, block and bucket.
63320fe9b66cSTao Ma *
63330fe9b66cSTao Ma * NOTE:
63340fe9b66cSTao Ma * Before we call this function, the caller has memcpy the xattr in
63352999d12fSTao Ma * old_xh to the new_xh.
63362999d12fSTao Ma *
63372999d12fSTao Ma * If args.xattr_reflinked is set, call it to decide whether the xe should
63382999d12fSTao Ma * be reflinked or not. If not, remove it from the new xattr header.
63392999d12fSTao Ma */
ocfs2_reflink_xattr_header(handle_t * handle,struct ocfs2_xattr_reflink * args,struct buffer_head * old_bh,struct ocfs2_xattr_header * xh,struct buffer_head * new_bh,struct ocfs2_xattr_header * new_xh,struct ocfs2_xattr_value_buf * vb,struct ocfs2_alloc_context * meta_ac,get_xattr_value_root * func,void * para)63402999d12fSTao Ma static int ocfs2_reflink_xattr_header(handle_t *handle,
63412999d12fSTao Ma struct ocfs2_xattr_reflink *args,
63422999d12fSTao Ma struct buffer_head *old_bh,
63432999d12fSTao Ma struct ocfs2_xattr_header *xh,
63442999d12fSTao Ma struct buffer_head *new_bh,
63452999d12fSTao Ma struct ocfs2_xattr_header *new_xh,
63462999d12fSTao Ma struct ocfs2_xattr_value_buf *vb,
63470fe9b66cSTao Ma struct ocfs2_alloc_context *meta_ac,
63482999d12fSTao Ma get_xattr_value_root *func,
63492999d12fSTao Ma void *para)
63500fe9b66cSTao Ma {
63512999d12fSTao Ma int ret = 0, i, j;
63522999d12fSTao Ma struct super_block *sb = args->old_inode->i_sb;
63532999d12fSTao Ma struct buffer_head *value_bh;
63542999d12fSTao Ma struct ocfs2_xattr_entry *xe, *last;
63552999d12fSTao Ma struct ocfs2_xattr_value_root *xv, *new_xv;
6356402b4183STao Ma struct ocfs2_extent_tree data_et;
6357402b4183STao Ma u32 clusters, cpos, p_cluster, num_clusters;
63580fe9b66cSTao Ma unsigned int ext_flags = 0;
63590fe9b66cSTao Ma
63600fe9b66cSTao Ma trace_ocfs2_reflink_xattr_header((unsigned long long)old_bh->b_blocknr,
63612999d12fSTao Ma le16_to_cpu(xh->xh_count));
63622999d12fSTao Ma
63630fe9b66cSTao Ma last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)];
63640fe9b66cSTao Ma for (i = 0, j = 0; i < le16_to_cpu(xh->xh_count); i++, j++) {
63650fe9b66cSTao Ma xe = &xh->xh_entries[i];
63660fe9b66cSTao Ma
63670fe9b66cSTao Ma if (args->xattr_reflinked && !args->xattr_reflinked(xe)) {
63680fe9b66cSTao Ma xe = &new_xh->xh_entries[j];
63690fe9b66cSTao Ma
63700fe9b66cSTao Ma le16_add_cpu(&new_xh->xh_count, -1);
63710fe9b66cSTao Ma if (new_xh->xh_count) {
63720fe9b66cSTao Ma memmove(xe, xe + 1,
63730fe9b66cSTao Ma (void *)last - (void *)xe);
63740fe9b66cSTao Ma memset(last, 0,
63750fe9b66cSTao Ma sizeof(struct ocfs2_xattr_entry));
63760fe9b66cSTao Ma }
63770fe9b66cSTao Ma
63780fe9b66cSTao Ma /*
63790fe9b66cSTao Ma * We don't want j to increase in the next round since
63800fe9b66cSTao Ma * it is already moved ahead.
63810fe9b66cSTao Ma */
63822999d12fSTao Ma j--;
63832999d12fSTao Ma continue;
63842999d12fSTao Ma }
63852999d12fSTao Ma
63862999d12fSTao Ma if (ocfs2_xattr_is_local(xe))
63872999d12fSTao Ma continue;
63882999d12fSTao Ma
63892999d12fSTao Ma ret = func(sb, old_bh, xh, i, &xv, NULL, para);
63902999d12fSTao Ma if (ret) {
63910fe9b66cSTao Ma mlog_errno(ret);
63922999d12fSTao Ma break;
63932999d12fSTao Ma }
63942999d12fSTao Ma
63952999d12fSTao Ma ret = func(sb, new_bh, new_xh, j, &new_xv, &value_bh, para);
63962999d12fSTao Ma if (ret) {
63972999d12fSTao Ma mlog_errno(ret);
63982999d12fSTao Ma break;
63992999d12fSTao Ma }
64002999d12fSTao Ma
64012999d12fSTao Ma /*
64022999d12fSTao Ma * For the xattr which has l_tree_depth = 0, all the extent
64032999d12fSTao Ma * recs have already be copied to the new xh with the
64042999d12fSTao Ma * propriate OCFS2_EXT_REFCOUNTED flag we just need to
64052999d12fSTao Ma * increase the refount count int the refcount tree.
64062999d12fSTao Ma *
64072999d12fSTao Ma * For the xattr which has l_tree_depth > 0, we need
640832ed0bd7Salex chen * to initialize it to the empty default value root,
64092999d12fSTao Ma * and then insert the extents one by one.
64102999d12fSTao Ma */
64112999d12fSTao Ma if (xv->xr_list.l_tree_depth) {
64122999d12fSTao Ma memcpy(new_xv, &def_xv, OCFS2_XATTR_ROOT_SIZE);
64132999d12fSTao Ma vb->vb_xv = new_xv;
64142999d12fSTao Ma vb->vb_bh = value_bh;
64152999d12fSTao Ma ocfs2_init_xattr_value_extent_tree(&data_et,
64162999d12fSTao Ma INODE_CACHE(args->new_inode), vb);
64172999d12fSTao Ma }
64182999d12fSTao Ma
64192999d12fSTao Ma clusters = le32_to_cpu(xv->xr_clusters);
64202999d12fSTao Ma cpos = 0;
64212999d12fSTao Ma while (cpos < clusters) {
64222999d12fSTao Ma ret = ocfs2_xattr_get_clusters(args->old_inode,
64232999d12fSTao Ma cpos,
64242999d12fSTao Ma &p_cluster,
64252999d12fSTao Ma &num_clusters,
64262999d12fSTao Ma &xv->xr_list,
64272999d12fSTao Ma &ext_flags);
64282999d12fSTao Ma if (ret) {
64292999d12fSTao Ma mlog_errno(ret);
64302999d12fSTao Ma goto out;
64312999d12fSTao Ma }
64322999d12fSTao Ma
64332999d12fSTao Ma BUG_ON(!p_cluster);
64342999d12fSTao Ma
64352999d12fSTao Ma if (xv->xr_list.l_tree_depth) {
64362999d12fSTao Ma ret = ocfs2_insert_extent(handle,
64372999d12fSTao Ma &data_et, cpos,
64382999d12fSTao Ma ocfs2_clusters_to_blocks(
64392999d12fSTao Ma args->old_inode->i_sb,
64402999d12fSTao Ma p_cluster),
64412999d12fSTao Ma num_clusters, ext_flags,
64422999d12fSTao Ma meta_ac);
64432999d12fSTao Ma if (ret) {
64442999d12fSTao Ma mlog_errno(ret);
64452999d12fSTao Ma goto out;
64462999d12fSTao Ma }
64472999d12fSTao Ma }
64482999d12fSTao Ma
64492999d12fSTao Ma ret = ocfs2_increase_refcount(handle, args->ref_ci,
64502999d12fSTao Ma args->ref_root_bh,
64512999d12fSTao Ma p_cluster, num_clusters,
64522999d12fSTao Ma meta_ac, args->dealloc);
64532999d12fSTao Ma if (ret) {
64542999d12fSTao Ma mlog_errno(ret);
64552999d12fSTao Ma goto out;
64562999d12fSTao Ma }
64572999d12fSTao Ma
64582999d12fSTao Ma cpos += num_clusters;
64592999d12fSTao Ma }
64602999d12fSTao Ma }
64612999d12fSTao Ma
64622999d12fSTao Ma out:
64632999d12fSTao Ma return ret;
64642999d12fSTao Ma }
64652999d12fSTao Ma
ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink * args)64662999d12fSTao Ma static int ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink *args)
64672999d12fSTao Ma {
64682999d12fSTao Ma int ret = 0, credits = 0;
64692999d12fSTao Ma handle_t *handle;
64702999d12fSTao Ma struct ocfs2_super *osb = OCFS2_SB(args->old_inode->i_sb);
64712999d12fSTao Ma struct ocfs2_dinode *di = (struct ocfs2_dinode *)args->old_bh->b_data;
64722999d12fSTao Ma int inline_size = le16_to_cpu(di->i_xattr_inline_size);
64732999d12fSTao Ma int header_off = osb->sb->s_blocksize - inline_size;
64742999d12fSTao Ma struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)
64752999d12fSTao Ma (args->old_bh->b_data + header_off);
64762999d12fSTao Ma struct ocfs2_xattr_header *new_xh = (struct ocfs2_xattr_header *)
64772999d12fSTao Ma (args->new_bh->b_data + header_off);
64782999d12fSTao Ma struct ocfs2_alloc_context *meta_ac = NULL;
64792999d12fSTao Ma struct ocfs2_inode_info *new_oi;
64802999d12fSTao Ma struct ocfs2_dinode *new_di;
64812999d12fSTao Ma struct ocfs2_xattr_value_buf vb = {
64822999d12fSTao Ma .vb_bh = args->new_bh,
64832999d12fSTao Ma .vb_access = ocfs2_journal_access_di,
64842999d12fSTao Ma };
64852999d12fSTao Ma
64862999d12fSTao Ma ret = ocfs2_reflink_lock_xattr_allocators(osb, xh, args->ref_root_bh,
64872999d12fSTao Ma &credits, &meta_ac);
64882999d12fSTao Ma if (ret) {
64892999d12fSTao Ma mlog_errno(ret);
64902999d12fSTao Ma goto out;
64912999d12fSTao Ma }
64922999d12fSTao Ma
64932999d12fSTao Ma handle = ocfs2_start_trans(osb, credits);
64942999d12fSTao Ma if (IS_ERR(handle)) {
64952999d12fSTao Ma ret = PTR_ERR(handle);
64962999d12fSTao Ma mlog_errno(ret);
64972999d12fSTao Ma goto out;
64982999d12fSTao Ma }
64992999d12fSTao Ma
65002999d12fSTao Ma ret = ocfs2_journal_access_di(handle, INODE_CACHE(args->new_inode),
65012999d12fSTao Ma args->new_bh, OCFS2_JOURNAL_ACCESS_WRITE);
65022999d12fSTao Ma if (ret) {
65032999d12fSTao Ma mlog_errno(ret);
65042999d12fSTao Ma goto out_commit;
65052999d12fSTao Ma }
65062999d12fSTao Ma
65072999d12fSTao Ma memcpy(args->new_bh->b_data + header_off,
65082999d12fSTao Ma args->old_bh->b_data + header_off, inline_size);
65092999d12fSTao Ma
65102999d12fSTao Ma new_di = (struct ocfs2_dinode *)args->new_bh->b_data;
65112999d12fSTao Ma new_di->i_xattr_inline_size = cpu_to_le16(inline_size);
65122999d12fSTao Ma
65132999d12fSTao Ma ret = ocfs2_reflink_xattr_header(handle, args, args->old_bh, xh,
65142999d12fSTao Ma args->new_bh, new_xh, &vb, meta_ac,
65152999d12fSTao Ma ocfs2_get_xattr_value_root, NULL);
65162999d12fSTao Ma if (ret) {
65172999d12fSTao Ma mlog_errno(ret);
6518ef962df0SJunxiao Bi goto out_commit;
6519ef962df0SJunxiao Bi }
6520ef962df0SJunxiao Bi
6521ef962df0SJunxiao Bi new_oi = OCFS2_I(args->new_inode);
6522ef962df0SJunxiao Bi
6523ef962df0SJunxiao Bi spin_lock(&new_oi->ip_lock);
6524ef962df0SJunxiao Bi new_oi->ip_dyn_features |= OCFS2_HAS_XATTR_FL | OCFS2_INLINE_XATTR_FL;
6525ef962df0SJunxiao Bi new_di->i_dyn_features = cpu_to_le16(new_oi->ip_dyn_features);
6526ef962df0SJunxiao Bi spin_unlock(&new_oi->ip_lock);
6527ef962df0SJunxiao Bi
65282999d12fSTao Ma ocfs2_journal_dirty(handle, args->new_bh);
65292999d12fSTao Ma
65302999d12fSTao Ma out_commit:
65312999d12fSTao Ma ocfs2_commit_trans(osb, handle);
65322999d12fSTao Ma
65332999d12fSTao Ma out:
65342999d12fSTao Ma if (meta_ac)
65352999d12fSTao Ma ocfs2_free_alloc_context(meta_ac);
65362999d12fSTao Ma return ret;
65372999d12fSTao Ma }
65382999d12fSTao Ma
ocfs2_create_empty_xattr_block(struct inode * inode,struct buffer_head * fe_bh,struct buffer_head ** ret_bh,int indexed)65392999d12fSTao Ma static int ocfs2_create_empty_xattr_block(struct inode *inode,
65402999d12fSTao Ma struct buffer_head *fe_bh,
65412999d12fSTao Ma struct buffer_head **ret_bh,
65422999d12fSTao Ma int indexed)
65432999d12fSTao Ma {
65442999d12fSTao Ma int ret;
65452999d12fSTao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
65462999d12fSTao Ma struct ocfs2_xattr_set_ctxt ctxt;
65472999d12fSTao Ma
65482999d12fSTao Ma memset(&ctxt, 0, sizeof(ctxt));
65492999d12fSTao Ma ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &ctxt.meta_ac);
65502999d12fSTao Ma if (ret < 0) {
6551b2317968STao Ma mlog_errno(ret);
65522999d12fSTao Ma return ret;
6553b2317968STao Ma }
6554b2317968STao Ma
65552999d12fSTao Ma ctxt.handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS);
65562999d12fSTao Ma if (IS_ERR(ctxt.handle)) {
65572999d12fSTao Ma ret = PTR_ERR(ctxt.handle);
65582999d12fSTao Ma mlog_errno(ret);
65592999d12fSTao Ma goto out;
6560d3981544SJoel Becker }
6561d3981544SJoel Becker
6562d3981544SJoel Becker trace_ocfs2_create_empty_xattr_block(
65632999d12fSTao Ma (unsigned long long)fe_bh->b_blocknr, indexed);
65642999d12fSTao Ma ret = ocfs2_create_xattr_block(inode, fe_bh, &ctxt, indexed,
65652999d12fSTao Ma ret_bh);
65662999d12fSTao Ma if (ret)
6567402b4183STao Ma mlog_errno(ret);
65682999d12fSTao Ma
6569d3981544SJoel Becker ocfs2_commit_trans(osb, ctxt.handle);
6570d3981544SJoel Becker out:
65712999d12fSTao Ma ocfs2_free_alloc_context(ctxt.meta_ac);
65722999d12fSTao Ma return ret;
65732999d12fSTao Ma }
6574d3981544SJoel Becker
ocfs2_reflink_xattr_block(struct ocfs2_xattr_reflink * args,struct buffer_head * blk_bh,struct buffer_head * new_blk_bh)65752999d12fSTao Ma static int ocfs2_reflink_xattr_block(struct ocfs2_xattr_reflink *args,
6576b2317968STao Ma struct buffer_head *blk_bh,
65772999d12fSTao Ma struct buffer_head *new_blk_bh)
65782999d12fSTao Ma {
65792999d12fSTao Ma int ret = 0, credits = 0;
65802999d12fSTao Ma handle_t *handle;
65812999d12fSTao Ma struct ocfs2_inode_info *new_oi = OCFS2_I(args->new_inode);
65822999d12fSTao Ma struct ocfs2_dinode *new_di;
65832999d12fSTao Ma struct ocfs2_super *osb = OCFS2_SB(args->new_inode->i_sb);
65842999d12fSTao Ma int header_off = offsetof(struct ocfs2_xattr_block, xb_attrs.xb_header);
65852999d12fSTao Ma struct ocfs2_xattr_block *xb =
65862999d12fSTao Ma (struct ocfs2_xattr_block *)blk_bh->b_data;
65872999d12fSTao Ma struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header;
65882999d12fSTao Ma struct ocfs2_xattr_block *new_xb =
65892999d12fSTao Ma (struct ocfs2_xattr_block *)new_blk_bh->b_data;
65902999d12fSTao Ma struct ocfs2_xattr_header *new_xh = &new_xb->xb_attrs.xb_header;
65912999d12fSTao Ma struct ocfs2_alloc_context *meta_ac;
65922999d12fSTao Ma struct ocfs2_xattr_value_buf vb = {
65932999d12fSTao Ma .vb_bh = new_blk_bh,
65942999d12fSTao Ma .vb_access = ocfs2_journal_access_xb,
65952999d12fSTao Ma };
65962999d12fSTao Ma
65972999d12fSTao Ma ret = ocfs2_reflink_lock_xattr_allocators(osb, xh, args->ref_root_bh,
65982999d12fSTao Ma &credits, &meta_ac);
65992999d12fSTao Ma if (ret) {
66002999d12fSTao Ma mlog_errno(ret);
66012999d12fSTao Ma return ret;
66022999d12fSTao Ma }
66032999d12fSTao Ma
66042999d12fSTao Ma /* One more credits in case we need to add xattr flags in new inode. */
66052999d12fSTao Ma handle = ocfs2_start_trans(osb, credits + 1);
66062999d12fSTao Ma if (IS_ERR(handle)) {
66072999d12fSTao Ma ret = PTR_ERR(handle);
66082999d12fSTao Ma mlog_errno(ret);
66092999d12fSTao Ma goto out;
66102999d12fSTao Ma }
66112999d12fSTao Ma
66122999d12fSTao Ma if (!(new_oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) {
66132999d12fSTao Ma ret = ocfs2_journal_access_di(handle,
66142999d12fSTao Ma INODE_CACHE(args->new_inode),
66152999d12fSTao Ma args->new_bh,
66162999d12fSTao Ma OCFS2_JOURNAL_ACCESS_WRITE);
66172999d12fSTao Ma if (ret) {
66182999d12fSTao Ma mlog_errno(ret);
66192999d12fSTao Ma goto out_commit;
66202999d12fSTao Ma }
66212999d12fSTao Ma }
66222999d12fSTao Ma
66232999d12fSTao Ma ret = ocfs2_journal_access_xb(handle, INODE_CACHE(args->new_inode),
66242999d12fSTao Ma new_blk_bh, OCFS2_JOURNAL_ACCESS_WRITE);
66252999d12fSTao Ma if (ret) {
66262999d12fSTao Ma mlog_errno(ret);
66272999d12fSTao Ma goto out_commit;
66282999d12fSTao Ma }
66292999d12fSTao Ma
66302999d12fSTao Ma memcpy(new_blk_bh->b_data + header_off, blk_bh->b_data + header_off,
66312999d12fSTao Ma osb->sb->s_blocksize - header_off);
66322999d12fSTao Ma
66332999d12fSTao Ma ret = ocfs2_reflink_xattr_header(handle, args, blk_bh, xh,
66342999d12fSTao Ma new_blk_bh, new_xh, &vb, meta_ac,
66352999d12fSTao Ma ocfs2_get_xattr_value_root, NULL);
66362999d12fSTao Ma if (ret) {
66372999d12fSTao Ma mlog_errno(ret);
66382999d12fSTao Ma goto out_commit;
66392999d12fSTao Ma }
66402999d12fSTao Ma
66412999d12fSTao Ma ocfs2_journal_dirty(handle, new_blk_bh);
66422999d12fSTao Ma
66432999d12fSTao Ma if (!(new_oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) {
66442999d12fSTao Ma new_di = (struct ocfs2_dinode *)args->new_bh->b_data;
66452999d12fSTao Ma spin_lock(&new_oi->ip_lock);
66462999d12fSTao Ma new_oi->ip_dyn_features |= OCFS2_HAS_XATTR_FL;
66472999d12fSTao Ma new_di->i_dyn_features = cpu_to_le16(new_oi->ip_dyn_features);
66482999d12fSTao Ma spin_unlock(&new_oi->ip_lock);
66492999d12fSTao Ma
66502999d12fSTao Ma ocfs2_journal_dirty(handle, args->new_bh);
66512999d12fSTao Ma }
66522999d12fSTao Ma
66532999d12fSTao Ma out_commit:
66542999d12fSTao Ma ocfs2_commit_trans(osb, handle);
66552999d12fSTao Ma
66562999d12fSTao Ma out:
66572999d12fSTao Ma ocfs2_free_alloc_context(meta_ac);
66582999d12fSTao Ma return ret;
66592999d12fSTao Ma }
66602999d12fSTao Ma
66612999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args {
66622999d12fSTao Ma struct ocfs2_xattr_reflink *reflink;
66632999d12fSTao Ma struct buffer_head *old_blk_bh;
66642999d12fSTao Ma struct buffer_head *new_blk_bh;
66652999d12fSTao Ma struct ocfs2_xattr_bucket *old_bucket;
66662999d12fSTao Ma struct ocfs2_xattr_bucket *new_bucket;
66672999d12fSTao Ma };
66682999d12fSTao Ma
66692999d12fSTao Ma /*
66702999d12fSTao Ma * NOTE:
66712999d12fSTao Ma * We have to handle the case that both old bucket and new bucket
66722999d12fSTao Ma * will call this function to get the right ret_bh.
66732999d12fSTao Ma * So The caller must give us the right bh.
66742999d12fSTao Ma */
ocfs2_get_reflink_xattr_value_root(struct super_block * sb,struct buffer_head * bh,struct ocfs2_xattr_header * xh,int offset,struct ocfs2_xattr_value_root ** xv,struct buffer_head ** ret_bh,void * para)66752999d12fSTao Ma static int ocfs2_get_reflink_xattr_value_root(struct super_block *sb,
66762999d12fSTao Ma struct buffer_head *bh,
66772999d12fSTao Ma struct ocfs2_xattr_header *xh,
66782999d12fSTao Ma int offset,
66792999d12fSTao Ma struct ocfs2_xattr_value_root **xv,
66802999d12fSTao Ma struct buffer_head **ret_bh,
66812999d12fSTao Ma void *para)
66822999d12fSTao Ma {
66832999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args *args =
66842999d12fSTao Ma (struct ocfs2_reflink_xattr_tree_args *)para;
66852999d12fSTao Ma struct ocfs2_xattr_bucket *bucket;
66862999d12fSTao Ma
66872999d12fSTao Ma if (bh == args->old_bucket->bu_bhs[0])
66882999d12fSTao Ma bucket = args->old_bucket;
66892999d12fSTao Ma else
66902999d12fSTao Ma bucket = args->new_bucket;
66912999d12fSTao Ma
66922999d12fSTao Ma return ocfs2_get_xattr_tree_value_root(sb, bucket, offset,
66932999d12fSTao Ma xv, ret_bh);
66942999d12fSTao Ma }
66952999d12fSTao Ma
66962999d12fSTao Ma struct ocfs2_value_tree_metas {
66972999d12fSTao Ma int num_metas;
66982999d12fSTao Ma int credits;
66992999d12fSTao Ma int num_recs;
67002999d12fSTao Ma };
67012999d12fSTao Ma
ocfs2_value_tree_metas_in_bucket(struct super_block * sb,struct buffer_head * bh,struct ocfs2_xattr_header * xh,int offset,struct ocfs2_xattr_value_root ** xv,struct buffer_head ** ret_bh,void * para)67022999d12fSTao Ma static int ocfs2_value_tree_metas_in_bucket(struct super_block *sb,
67032999d12fSTao Ma struct buffer_head *bh,
67042999d12fSTao Ma struct ocfs2_xattr_header *xh,
67052999d12fSTao Ma int offset,
67062999d12fSTao Ma struct ocfs2_xattr_value_root **xv,
67072999d12fSTao Ma struct buffer_head **ret_bh,
67082999d12fSTao Ma void *para)
67092999d12fSTao Ma {
67102999d12fSTao Ma struct ocfs2_xattr_bucket *bucket =
67112999d12fSTao Ma (struct ocfs2_xattr_bucket *)para;
67122999d12fSTao Ma
67132999d12fSTao Ma return ocfs2_get_xattr_tree_value_root(sb, bucket, offset,
67142999d12fSTao Ma xv, ret_bh);
67152999d12fSTao Ma }
67162999d12fSTao Ma
ocfs2_calc_value_tree_metas(struct inode * inode,struct ocfs2_xattr_bucket * bucket,void * para)67172999d12fSTao Ma static int ocfs2_calc_value_tree_metas(struct inode *inode,
67182999d12fSTao Ma struct ocfs2_xattr_bucket *bucket,
67192999d12fSTao Ma void *para)
67202999d12fSTao Ma {
67212999d12fSTao Ma struct ocfs2_value_tree_metas *metas =
67222999d12fSTao Ma (struct ocfs2_value_tree_metas *)para;
67232999d12fSTao Ma struct ocfs2_xattr_header *xh =
67242999d12fSTao Ma (struct ocfs2_xattr_header *)bucket->bu_bhs[0]->b_data;
67252999d12fSTao Ma
67262999d12fSTao Ma /* Add the credits for this bucket first. */
67272999d12fSTao Ma metas->credits += bucket->bu_blocks;
67282999d12fSTao Ma return ocfs2_value_metas_in_xattr_header(inode->i_sb, bucket->bu_bhs[0],
67292999d12fSTao Ma xh, &metas->num_metas,
67302999d12fSTao Ma &metas->credits, &metas->num_recs,
67312999d12fSTao Ma ocfs2_value_tree_metas_in_bucket,
67322999d12fSTao Ma bucket);
67332999d12fSTao Ma }
67342999d12fSTao Ma
67352999d12fSTao Ma /*
67362999d12fSTao Ma * Given a xattr extent rec starting from blkno and having len clusters,
67372999d12fSTao Ma * iterate all the buckets calculate how much metadata we need for reflinking
67382999d12fSTao Ma * all the ocfs2_xattr_value_root and lock the allocators accordingly.
67392999d12fSTao Ma */
ocfs2_lock_reflink_xattr_rec_allocators(struct ocfs2_reflink_xattr_tree_args * args,struct ocfs2_extent_tree * xt_et,u64 blkno,u32 len,int * credits,struct ocfs2_alloc_context ** meta_ac,struct ocfs2_alloc_context ** data_ac)67402999d12fSTao Ma static int ocfs2_lock_reflink_xattr_rec_allocators(
67412999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args *args,
67422999d12fSTao Ma struct ocfs2_extent_tree *xt_et,
67432999d12fSTao Ma u64 blkno, u32 len, int *credits,
67442999d12fSTao Ma struct ocfs2_alloc_context **meta_ac,
67452999d12fSTao Ma struct ocfs2_alloc_context **data_ac)
67462999d12fSTao Ma {
67472999d12fSTao Ma int ret, num_free_extents;
67482999d12fSTao Ma struct ocfs2_value_tree_metas metas;
67492999d12fSTao Ma struct ocfs2_super *osb = OCFS2_SB(args->reflink->old_inode->i_sb);
67502999d12fSTao Ma struct ocfs2_refcount_block *rb;
67512999d12fSTao Ma
67522999d12fSTao Ma memset(&metas, 0, sizeof(metas));
67532999d12fSTao Ma
67542999d12fSTao Ma ret = ocfs2_iterate_xattr_buckets(args->reflink->old_inode, blkno, len,
67552999d12fSTao Ma ocfs2_calc_value_tree_metas, &metas);
67562999d12fSTao Ma if (ret) {
67572999d12fSTao Ma mlog_errno(ret);
67582999d12fSTao Ma goto out;
67592999d12fSTao Ma }
67602999d12fSTao Ma
67612999d12fSTao Ma *credits = metas.credits;
67622999d12fSTao Ma
67632999d12fSTao Ma /*
67642999d12fSTao Ma * Calculate we need for refcount tree change.
67652999d12fSTao Ma *
67662999d12fSTao Ma * We need to add/modify num_recs in refcount tree, so just calculate
67672999d12fSTao Ma * an approximate number we need for refcount tree change.
67682999d12fSTao Ma * Sometimes we need to split the tree, and after split, half recs
67692999d12fSTao Ma * will be moved to the new block, and a new block can only provide
67702999d12fSTao Ma * half number of recs. So we multiple new blocks by 2.
67712999d12fSTao Ma * In the end, we have to add credits for modifying the already
67722999d12fSTao Ma * existed refcount block.
67732999d12fSTao Ma */
67742999d12fSTao Ma rb = (struct ocfs2_refcount_block *)args->reflink->ref_root_bh->b_data;
67752999d12fSTao Ma metas.num_recs =
67762999d12fSTao Ma (metas.num_recs + ocfs2_refcount_recs_per_rb(osb->sb) - 1) /
67772999d12fSTao Ma ocfs2_refcount_recs_per_rb(osb->sb) * 2;
67782999d12fSTao Ma metas.num_metas += metas.num_recs;
67792999d12fSTao Ma *credits += metas.num_recs +
67802999d12fSTao Ma metas.num_recs * OCFS2_EXPAND_REFCOUNT_TREE_CREDITS;
67812999d12fSTao Ma if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL)
67822999d12fSTao Ma *credits += le16_to_cpu(rb->rf_list.l_tree_depth) *
67832999d12fSTao Ma le16_to_cpu(rb->rf_list.l_next_free_rec) + 1;
67842999d12fSTao Ma else
67852999d12fSTao Ma *credits += 1;
67862999d12fSTao Ma
67872999d12fSTao Ma /* count in the xattr tree change. */
67882999d12fSTao Ma num_free_extents = ocfs2_num_free_extents(xt_et);
67892999d12fSTao Ma if (num_free_extents < 0) {
67902999d12fSTao Ma ret = num_free_extents;
67912999d12fSTao Ma mlog_errno(ret);
67922999d12fSTao Ma goto out;
6793964f14a0SJun Piao }
67942999d12fSTao Ma
67952999d12fSTao Ma if (num_free_extents < len)
67962999d12fSTao Ma metas.num_metas += ocfs2_extend_meta_needed(xt_et->et_root_el);
67972999d12fSTao Ma
67982999d12fSTao Ma *credits += ocfs2_calc_extend_credits(osb->sb,
67992999d12fSTao Ma xt_et->et_root_el);
68002999d12fSTao Ma
68012999d12fSTao Ma if (metas.num_metas) {
68022999d12fSTao Ma ret = ocfs2_reserve_new_metadata_blocks(osb, metas.num_metas,
68032999d12fSTao Ma meta_ac);
680406f9da6eSGoldwyn Rodrigues if (ret) {
68052999d12fSTao Ma mlog_errno(ret);
68062999d12fSTao Ma goto out;
68072999d12fSTao Ma }
68082999d12fSTao Ma }
68092999d12fSTao Ma
68102999d12fSTao Ma if (len) {
68112999d12fSTao Ma ret = ocfs2_reserve_clusters(osb, len, data_ac);
68122999d12fSTao Ma if (ret)
68132999d12fSTao Ma mlog_errno(ret);
68142999d12fSTao Ma }
68152999d12fSTao Ma out:
68162999d12fSTao Ma if (ret) {
68172999d12fSTao Ma if (*meta_ac) {
68182999d12fSTao Ma ocfs2_free_alloc_context(*meta_ac);
68192999d12fSTao Ma *meta_ac = NULL;
68202999d12fSTao Ma }
68212999d12fSTao Ma }
68222999d12fSTao Ma
68232999d12fSTao Ma return ret;
68246cae6d31SJoseph Qi }
68252999d12fSTao Ma
ocfs2_reflink_xattr_bucket(handle_t * handle,u64 blkno,u64 new_blkno,u32 clusters,u32 * cpos,int num_buckets,struct ocfs2_alloc_context * meta_ac,struct ocfs2_alloc_context * data_ac,struct ocfs2_reflink_xattr_tree_args * args)68262999d12fSTao Ma static int ocfs2_reflink_xattr_bucket(handle_t *handle,
68272999d12fSTao Ma u64 blkno, u64 new_blkno, u32 clusters,
68282999d12fSTao Ma u32 *cpos, int num_buckets,
68292999d12fSTao Ma struct ocfs2_alloc_context *meta_ac,
68302999d12fSTao Ma struct ocfs2_alloc_context *data_ac,
6831121a39bbSTao Ma struct ocfs2_reflink_xattr_tree_args *args)
68322999d12fSTao Ma {
6833121a39bbSTao Ma int i, j, ret = 0;
68342999d12fSTao Ma struct super_block *sb = args->reflink->old_inode->i_sb;
68352999d12fSTao Ma int bpb = args->old_bucket->bu_blocks;
68362999d12fSTao Ma struct ocfs2_xattr_value_buf vb = {
68372999d12fSTao Ma .vb_access = ocfs2_journal_access,
68382999d12fSTao Ma };
68392999d12fSTao Ma
68402999d12fSTao Ma for (i = 0; i < num_buckets; i++, blkno += bpb, new_blkno += bpb) {
68412999d12fSTao Ma ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno);
68422999d12fSTao Ma if (ret) {
68432999d12fSTao Ma mlog_errno(ret);
68442999d12fSTao Ma break;
68452999d12fSTao Ma }
68462999d12fSTao Ma
68472999d12fSTao Ma ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno, 1);
68482999d12fSTao Ma if (ret) {
68492999d12fSTao Ma mlog_errno(ret);
68502999d12fSTao Ma break;
68512999d12fSTao Ma }
68529c339255SWengang Wang
68532999d12fSTao Ma ret = ocfs2_xattr_bucket_journal_access(handle,
68542999d12fSTao Ma args->new_bucket,
68552999d12fSTao Ma OCFS2_JOURNAL_ACCESS_CREATE);
68562999d12fSTao Ma if (ret) {
68572999d12fSTao Ma mlog_errno(ret);
68582999d12fSTao Ma break;
68592999d12fSTao Ma }
68602999d12fSTao Ma
68612999d12fSTao Ma for (j = 0; j < bpb; j++)
68622999d12fSTao Ma memcpy(bucket_block(args->new_bucket, j),
68632999d12fSTao Ma bucket_block(args->old_bucket, j),
68642999d12fSTao Ma sb->s_blocksize);
68652999d12fSTao Ma
68662999d12fSTao Ma /*
68672999d12fSTao Ma * Record the start cpos so that we can use it to initialize
68682999d12fSTao Ma * our xattr tree we also set the xh_num_bucket for the new
68692999d12fSTao Ma * bucket.
68702999d12fSTao Ma */
6871121a39bbSTao Ma if (i == 0) {
6872121a39bbSTao Ma *cpos = le32_to_cpu(bucket_xh(args->new_bucket)->
6873121a39bbSTao Ma xh_entries[0].xe_name_hash);
6874121a39bbSTao Ma bucket_xh(args->new_bucket)->xh_num_buckets =
6875121a39bbSTao Ma cpu_to_le16(num_buckets);
6876121a39bbSTao Ma }
6877121a39bbSTao Ma
6878121a39bbSTao Ma ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
6879121a39bbSTao Ma
6880121a39bbSTao Ma ret = ocfs2_reflink_xattr_header(handle, args->reflink,
6881121a39bbSTao Ma args->old_bucket->bu_bhs[0],
6882121a39bbSTao Ma bucket_xh(args->old_bucket),
68832999d12fSTao Ma args->new_bucket->bu_bhs[0],
68842999d12fSTao Ma bucket_xh(args->new_bucket),
68852999d12fSTao Ma &vb, meta_ac,
68862999d12fSTao Ma ocfs2_get_reflink_xattr_value_root,
68872999d12fSTao Ma args);
68882999d12fSTao Ma if (ret) {
68892999d12fSTao Ma mlog_errno(ret);
68902999d12fSTao Ma break;
68912999d12fSTao Ma }
68922999d12fSTao Ma
68932999d12fSTao Ma /*
68942999d12fSTao Ma * Re-access and dirty the bucket to calculate metaecc.
68952999d12fSTao Ma * Because we may extend the transaction in reflink_xattr_header
68962999d12fSTao Ma * which will let the already accessed block gone.
68972999d12fSTao Ma */
68982999d12fSTao Ma ret = ocfs2_xattr_bucket_journal_access(handle,
68992999d12fSTao Ma args->new_bucket,
69002999d12fSTao Ma OCFS2_JOURNAL_ACCESS_WRITE);
69012999d12fSTao Ma if (ret) {
69022999d12fSTao Ma mlog_errno(ret);
69032999d12fSTao Ma break;
69042999d12fSTao Ma }
69052999d12fSTao Ma
69062999d12fSTao Ma ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
69072999d12fSTao Ma
69082999d12fSTao Ma ocfs2_xattr_bucket_relse(args->old_bucket);
69092999d12fSTao Ma ocfs2_xattr_bucket_relse(args->new_bucket);
69102999d12fSTao Ma }
69112999d12fSTao Ma
6912121a39bbSTao Ma ocfs2_xattr_bucket_relse(args->old_bucket);
69132999d12fSTao Ma ocfs2_xattr_bucket_relse(args->new_bucket);
69142999d12fSTao Ma return ret;
69152999d12fSTao Ma }
69162999d12fSTao Ma
ocfs2_reflink_xattr_buckets(handle_t * handle,struct inode * inode,struct ocfs2_reflink_xattr_tree_args * args,struct ocfs2_extent_tree * et,struct ocfs2_alloc_context * meta_ac,struct ocfs2_alloc_context * data_ac,u64 blkno,u32 cpos,u32 len)69172999d12fSTao Ma static int ocfs2_reflink_xattr_buckets(handle_t *handle,
69182999d12fSTao Ma struct inode *inode,
69192999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args *args,
69202999d12fSTao Ma struct ocfs2_extent_tree *et,
6921121a39bbSTao Ma struct ocfs2_alloc_context *meta_ac,
6922121a39bbSTao Ma struct ocfs2_alloc_context *data_ac,
6923121a39bbSTao Ma u64 blkno, u32 cpos, u32 len)
6924121a39bbSTao Ma {
6925121a39bbSTao Ma int ret, first_inserted = 0;
6926121a39bbSTao Ma u32 p_cluster, num_clusters, reflink_cpos = 0;
6927121a39bbSTao Ma u64 new_blkno;
6928121a39bbSTao Ma unsigned int num_buckets, reflink_buckets;
6929121a39bbSTao Ma unsigned int bpc =
6930121a39bbSTao Ma ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
6931121a39bbSTao Ma
6932121a39bbSTao Ma ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno);
6933121a39bbSTao Ma if (ret) {
6934121a39bbSTao Ma mlog_errno(ret);
6935121a39bbSTao Ma goto out;
6936121a39bbSTao Ma }
6937121a39bbSTao Ma num_buckets = le16_to_cpu(bucket_xh(args->old_bucket)->xh_num_buckets);
6938121a39bbSTao Ma ocfs2_xattr_bucket_relse(args->old_bucket);
6939121a39bbSTao Ma
6940121a39bbSTao Ma while (len && num_buckets) {
6941121a39bbSTao Ma ret = ocfs2_claim_clusters(handle, data_ac,
6942121a39bbSTao Ma 1, &p_cluster, &num_clusters);
6943121a39bbSTao Ma if (ret) {
6944121a39bbSTao Ma mlog_errno(ret);
6945121a39bbSTao Ma goto out;
6946121a39bbSTao Ma }
6947121a39bbSTao Ma
6948121a39bbSTao Ma new_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
6949121a39bbSTao Ma reflink_buckets = min(num_buckets, bpc * num_clusters);
6950121a39bbSTao Ma
6951121a39bbSTao Ma ret = ocfs2_reflink_xattr_bucket(handle, blkno,
6952121a39bbSTao Ma new_blkno, num_clusters,
6953121a39bbSTao Ma &reflink_cpos, reflink_buckets,
6954121a39bbSTao Ma meta_ac, data_ac, args);
6955121a39bbSTao Ma if (ret) {
6956121a39bbSTao Ma mlog_errno(ret);
6957121a39bbSTao Ma goto out;
6958121a39bbSTao Ma }
6959121a39bbSTao Ma
6960121a39bbSTao Ma /*
6961121a39bbSTao Ma * For the 1st allocated cluster, we make it use the same cpos
6962121a39bbSTao Ma * so that the xattr tree looks the same as the original one
6963121a39bbSTao Ma * in the most case.
6964121a39bbSTao Ma */
6965121a39bbSTao Ma if (!first_inserted) {
6966121a39bbSTao Ma reflink_cpos = cpos;
6967121a39bbSTao Ma first_inserted = 1;
6968121a39bbSTao Ma }
6969121a39bbSTao Ma ret = ocfs2_insert_extent(handle, et, reflink_cpos, new_blkno,
6970121a39bbSTao Ma num_clusters, 0, meta_ac);
6971121a39bbSTao Ma if (ret)
6972121a39bbSTao Ma mlog_errno(ret);
6973121a39bbSTao Ma
6974121a39bbSTao Ma trace_ocfs2_reflink_xattr_buckets((unsigned long long)new_blkno,
6975121a39bbSTao Ma num_clusters, reflink_cpos);
6976121a39bbSTao Ma
6977121a39bbSTao Ma len -= num_clusters;
6978121a39bbSTao Ma blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters);
6979402b4183STao Ma num_buckets -= reflink_buckets;
6980402b4183STao Ma }
6981121a39bbSTao Ma out:
6982121a39bbSTao Ma return ret;
6983121a39bbSTao Ma }
6984121a39bbSTao Ma
6985121a39bbSTao Ma /*
6986121a39bbSTao Ma * Create the same xattr extent record in the new inode's xattr tree.
6987121a39bbSTao Ma */
ocfs2_reflink_xattr_rec(struct inode * inode,struct buffer_head * root_bh,u64 blkno,u32 cpos,u32 len,void * para)6988121a39bbSTao Ma static int ocfs2_reflink_xattr_rec(struct inode *inode,
6989121a39bbSTao Ma struct buffer_head *root_bh,
69902999d12fSTao Ma u64 blkno,
69912999d12fSTao Ma u32 cpos,
69922999d12fSTao Ma u32 len,
69932999d12fSTao Ma void *para)
69942999d12fSTao Ma {
69952999d12fSTao Ma int ret, credits = 0;
69962999d12fSTao Ma handle_t *handle;
69972999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args *args =
69982999d12fSTao Ma (struct ocfs2_reflink_xattr_tree_args *)para;
69992999d12fSTao Ma struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
70002999d12fSTao Ma struct ocfs2_alloc_context *meta_ac = NULL;
70012999d12fSTao Ma struct ocfs2_alloc_context *data_ac = NULL;
70022999d12fSTao Ma struct ocfs2_extent_tree et;
70032999d12fSTao Ma
70042999d12fSTao Ma trace_ocfs2_reflink_xattr_rec((unsigned long long)blkno, len);
70052999d12fSTao Ma
70062999d12fSTao Ma ocfs2_init_xattr_tree_extent_tree(&et,
70072999d12fSTao Ma INODE_CACHE(args->reflink->new_inode),
70082999d12fSTao Ma args->new_blk_bh);
7009402b4183STao Ma
7010121a39bbSTao Ma ret = ocfs2_lock_reflink_xattr_rec_allocators(args, &et, blkno,
70112999d12fSTao Ma len, &credits,
70122999d12fSTao Ma &meta_ac, &data_ac);
70132999d12fSTao Ma if (ret) {
70142999d12fSTao Ma mlog_errno(ret);
70152999d12fSTao Ma goto out;
70162999d12fSTao Ma }
70172999d12fSTao Ma
70182999d12fSTao Ma handle = ocfs2_start_trans(osb, credits);
70192999d12fSTao Ma if (IS_ERR(handle)) {
70202999d12fSTao Ma ret = PTR_ERR(handle);
70212999d12fSTao Ma mlog_errno(ret);
70222999d12fSTao Ma goto out;
70232999d12fSTao Ma }
70242999d12fSTao Ma
70252999d12fSTao Ma ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et,
70262999d12fSTao Ma meta_ac, data_ac,
70272999d12fSTao Ma blkno, cpos, len);
70282999d12fSTao Ma if (ret)
70292999d12fSTao Ma mlog_errno(ret);
7030121a39bbSTao Ma
7031121a39bbSTao Ma ocfs2_commit_trans(osb, handle);
7032121a39bbSTao Ma
70332999d12fSTao Ma out:
70342999d12fSTao Ma if (meta_ac)
70352999d12fSTao Ma ocfs2_free_alloc_context(meta_ac);
70362999d12fSTao Ma if (data_ac)
70372999d12fSTao Ma ocfs2_free_alloc_context(data_ac);
70382999d12fSTao Ma return ret;
70392999d12fSTao Ma }
70402999d12fSTao Ma
70412999d12fSTao Ma /*
70422999d12fSTao Ma * Create reflinked xattr buckets.
70432999d12fSTao Ma * We will add bucket one by one, and refcount all the xattrs in the bucket
70442999d12fSTao Ma * if they are stored outside.
70452999d12fSTao Ma */
ocfs2_reflink_xattr_tree(struct ocfs2_xattr_reflink * args,struct buffer_head * blk_bh,struct buffer_head * new_blk_bh)70462999d12fSTao Ma static int ocfs2_reflink_xattr_tree(struct ocfs2_xattr_reflink *args,
70472999d12fSTao Ma struct buffer_head *blk_bh,
70482999d12fSTao Ma struct buffer_head *new_blk_bh)
70492999d12fSTao Ma {
70502999d12fSTao Ma int ret;
70512999d12fSTao Ma struct ocfs2_reflink_xattr_tree_args para;
70522999d12fSTao Ma
70532999d12fSTao Ma memset(¶, 0, sizeof(para));
70542999d12fSTao Ma para.reflink = args;
70552999d12fSTao Ma para.old_blk_bh = blk_bh;
70562999d12fSTao Ma para.new_blk_bh = new_blk_bh;
70572999d12fSTao Ma
70582999d12fSTao Ma para.old_bucket = ocfs2_xattr_bucket_new(args->old_inode);
70592999d12fSTao Ma if (!para.old_bucket) {
70602999d12fSTao Ma mlog_errno(-ENOMEM);
70612999d12fSTao Ma return -ENOMEM;
70622999d12fSTao Ma }
70632999d12fSTao Ma
70642999d12fSTao Ma para.new_bucket = ocfs2_xattr_bucket_new(args->new_inode);
70652999d12fSTao Ma if (!para.new_bucket) {
70662999d12fSTao Ma ret = -ENOMEM;
70672999d12fSTao Ma mlog_errno(ret);
70682999d12fSTao Ma goto out;
70692999d12fSTao Ma }
70702999d12fSTao Ma
70712999d12fSTao Ma ret = ocfs2_iterate_xattr_index_block(args->old_inode, blk_bh,
70722999d12fSTao Ma ocfs2_reflink_xattr_rec,
70732999d12fSTao Ma ¶);
70742999d12fSTao Ma if (ret)
70752999d12fSTao Ma mlog_errno(ret);
70762999d12fSTao Ma
70772999d12fSTao Ma out:
70782999d12fSTao Ma ocfs2_xattr_bucket_free(para.old_bucket);
70792999d12fSTao Ma ocfs2_xattr_bucket_free(para.new_bucket);
70802999d12fSTao Ma return ret;
70812999d12fSTao Ma }
70822999d12fSTao Ma
ocfs2_reflink_xattr_in_block(struct ocfs2_xattr_reflink * args,struct buffer_head * blk_bh)70832999d12fSTao Ma static int ocfs2_reflink_xattr_in_block(struct ocfs2_xattr_reflink *args,
70842999d12fSTao Ma struct buffer_head *blk_bh)
70852999d12fSTao Ma {
70862999d12fSTao Ma int ret, indexed = 0;
70872999d12fSTao Ma struct buffer_head *new_blk_bh = NULL;
70882999d12fSTao Ma struct ocfs2_xattr_block *xb =
70892999d12fSTao Ma (struct ocfs2_xattr_block *)blk_bh->b_data;
70902999d12fSTao Ma
70912999d12fSTao Ma
70922999d12fSTao Ma if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)
70932999d12fSTao Ma indexed = 1;
70942999d12fSTao Ma
70952999d12fSTao Ma ret = ocfs2_create_empty_xattr_block(args->new_inode, args->new_bh,
70962999d12fSTao Ma &new_blk_bh, indexed);
70972999d12fSTao Ma if (ret) {
70982999d12fSTao Ma mlog_errno(ret);
70992999d12fSTao Ma goto out;
71002999d12fSTao Ma }
71012999d12fSTao Ma
71022999d12fSTao Ma if (!indexed)
71032999d12fSTao Ma ret = ocfs2_reflink_xattr_block(args, blk_bh, new_blk_bh);
71042999d12fSTao Ma else
71052999d12fSTao Ma ret = ocfs2_reflink_xattr_tree(args, blk_bh, new_blk_bh);
71062999d12fSTao Ma if (ret)
71072decd65aSJeff Liu mlog_errno(ret);
71082999d12fSTao Ma
71092999d12fSTao Ma out:
71102999d12fSTao Ma brelse(new_blk_bh);
71112999d12fSTao Ma return ret;
71122999d12fSTao Ma }
71132999d12fSTao Ma
ocfs2_reflink_xattr_no_security(struct ocfs2_xattr_entry * xe)71142999d12fSTao Ma static int ocfs2_reflink_xattr_no_security(struct ocfs2_xattr_entry *xe)
71152999d12fSTao Ma {
71162999d12fSTao Ma int type = ocfs2_xattr_get_type(xe);
71172999d12fSTao Ma
71182999d12fSTao Ma return type != OCFS2_XATTR_INDEX_SECURITY &&
71190fe9b66cSTao Ma type != OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS &&
71200fe9b66cSTao Ma type != OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT;
71210fe9b66cSTao Ma }
71220fe9b66cSTao Ma
ocfs2_reflink_xattrs(struct inode * old_inode,struct buffer_head * old_bh,struct inode * new_inode,struct buffer_head * new_bh,bool preserve_security)71230fe9b66cSTao Ma int ocfs2_reflink_xattrs(struct inode *old_inode,
71240fe9b66cSTao Ma struct buffer_head *old_bh,
71250fe9b66cSTao Ma struct inode *new_inode,
71260fe9b66cSTao Ma struct buffer_head *new_bh,
71270fe9b66cSTao Ma bool preserve_security)
71282999d12fSTao Ma {
71292999d12fSTao Ma int ret;
71302999d12fSTao Ma struct ocfs2_xattr_reflink args;
71310fe9b66cSTao Ma struct ocfs2_inode_info *oi = OCFS2_I(old_inode);
71320fe9b66cSTao Ma struct ocfs2_dinode *di = (struct ocfs2_dinode *)old_bh->b_data;
71332999d12fSTao Ma struct buffer_head *blk_bh = NULL;
71342999d12fSTao Ma struct ocfs2_cached_dealloc_ctxt dealloc;
71352999d12fSTao Ma struct ocfs2_refcount_tree *ref_tree;
71362999d12fSTao Ma struct buffer_head *ref_root_bh = NULL;
71372999d12fSTao Ma
71382999d12fSTao Ma ret = ocfs2_lock_refcount_tree(OCFS2_SB(old_inode->i_sb),
71392999d12fSTao Ma le64_to_cpu(di->i_refcount_loc),
71402999d12fSTao Ma 1, &ref_tree, &ref_root_bh);
71412999d12fSTao Ma if (ret) {
71422999d12fSTao Ma mlog_errno(ret);
71432999d12fSTao Ma goto out;
71442999d12fSTao Ma }
71452999d12fSTao Ma
71462999d12fSTao Ma ocfs2_init_dealloc_ctxt(&dealloc);
71472999d12fSTao Ma
71482999d12fSTao Ma args.old_inode = old_inode;
71492999d12fSTao Ma args.new_inode = new_inode;
71502999d12fSTao Ma args.old_bh = old_bh;
71512999d12fSTao Ma args.new_bh = new_bh;
71522999d12fSTao Ma args.ref_ci = &ref_tree->rf_ci;
71532999d12fSTao Ma args.ref_root_bh = ref_root_bh;
71542999d12fSTao Ma args.dealloc = &dealloc;
71552999d12fSTao Ma if (preserve_security)
71562999d12fSTao Ma args.xattr_reflinked = NULL;
71572999d12fSTao Ma else
71582999d12fSTao Ma args.xattr_reflinked = ocfs2_reflink_xattr_no_security;
71592999d12fSTao Ma
71600fe9b66cSTao Ma if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
71610fe9b66cSTao Ma ret = ocfs2_reflink_xattr_inline(&args);
71620fe9b66cSTao Ma if (ret) {
71630fe9b66cSTao Ma mlog_errno(ret);
71642999d12fSTao Ma goto out_unlock;
71652999d12fSTao Ma }
71662999d12fSTao Ma }
71672999d12fSTao Ma
71682999d12fSTao Ma if (!di->i_xattr_loc)
71692999d12fSTao Ma goto out_unlock;
71702999d12fSTao Ma
71712999d12fSTao Ma ret = ocfs2_read_xattr_block(old_inode, le64_to_cpu(di->i_xattr_loc),
71722999d12fSTao Ma &blk_bh);
71732999d12fSTao Ma if (ret < 0) {
71742999d12fSTao Ma mlog_errno(ret);
71752999d12fSTao Ma goto out_unlock;
71762999d12fSTao Ma }
71772999d12fSTao Ma
71782999d12fSTao Ma ret = ocfs2_reflink_xattr_in_block(&args, blk_bh);
71792999d12fSTao Ma if (ret)
71802999d12fSTao Ma mlog_errno(ret);
71812999d12fSTao Ma
71822999d12fSTao Ma brelse(blk_bh);
71832999d12fSTao Ma
71842999d12fSTao Ma out_unlock:
71852999d12fSTao Ma ocfs2_unlock_refcount_tree(OCFS2_SB(old_inode->i_sb),
71862999d12fSTao Ma ref_tree, 1);
71872999d12fSTao Ma brelse(ref_root_bh);
71882999d12fSTao Ma
71892999d12fSTao Ma if (ocfs2_dealloc_has_cluster(&dealloc)) {
71902999d12fSTao Ma ocfs2_schedule_truncate_log_flush(OCFS2_SB(old_inode->i_sb), 1);
71912999d12fSTao Ma ocfs2_run_deallocs(OCFS2_SB(old_inode->i_sb), &dealloc);
71922999d12fSTao Ma }
71932999d12fSTao Ma
71942999d12fSTao Ma out:
71952999d12fSTao Ma return ret;
71962999d12fSTao Ma }
71972999d12fSTao Ma
71982999d12fSTao Ma /*
71992999d12fSTao Ma * Initialize security and acl for a already created inode.
72002999d12fSTao Ma * Used for reflink a non-preserve-security file.
72012999d12fSTao Ma *
72022999d12fSTao Ma * It uses common api like ocfs2_xattr_set, so the caller
72032999d12fSTao Ma * must not hold any lock expect i_rwsem.
72040fe9b66cSTao Ma */
ocfs2_init_security_and_acl(struct inode * dir,struct inode * inode,const struct qstr * qstr)72050fe9b66cSTao Ma int ocfs2_init_security_and_acl(struct inode *dir,
72060fe9b66cSTao Ma struct inode *inode,
72070fe9b66cSTao Ma const struct qstr *qstr)
7208*137cebf9Shongnanli {
72090fe9b66cSTao Ma int ret = 0;
72100fe9b66cSTao Ma struct buffer_head *dir_bh = NULL;
72112a7dba39SEric Paris
7212c25a1e06SJunxiao Bi ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
72130fe9b66cSTao Ma if (ret) {
7214702e5bc6SChristoph Hellwig mlog_errno(ret);
7215c25a1e06SJunxiao Bi goto leave;
72160fe9b66cSTao Ma }
72179d8f13baSMimi Zohar
721832918dd9SJeff Liu ret = ocfs2_inode_lock(dir, &dir_bh, 0);
72190fe9b66cSTao Ma if (ret) {
72200fe9b66cSTao Ma mlog_errno(ret);
72210fe9b66cSTao Ma goto leave;
72220fe9b66cSTao Ma }
72230fe9b66cSTao Ma ret = ocfs2_init_acl(NULL, inode, dir, NULL, dir_bh, NULL, NULL);
72240fe9b66cSTao Ma if (ret)
72250fe9b66cSTao Ma mlog_errno(ret);
72260fe9b66cSTao Ma
72270fe9b66cSTao Ma ocfs2_inode_unlock(dir, 0);
7228c25a1e06SJunxiao Bi brelse(dir_bh);
7229c25a1e06SJunxiao Bi leave:
7230c25a1e06SJunxiao Bi return ret;
72310fe9b66cSTao Ma }
72320fe9b66cSTao Ma
72330fe9b66cSTao Ma /*
72340fe9b66cSTao Ma * 'security' attributes support
72350fe9b66cSTao Ma */
ocfs2_xattr_security_get(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size)72360fe9b66cSTao Ma static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
72371046cb11SAndreas Gruenbacher struct dentry *unused, struct inode *inode,
72380fe9b66cSTao Ma const char *name, void *buffer, size_t size)
7239923f7f31STiger Yang {
7240923f7f31STiger Yang return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY,
7241d9a82a04SAndreas Gruenbacher name, buffer, size);
7242b296821aSAl Viro }
7243b296821aSAl Viro
ocfs2_xattr_security_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)7244923f7f31STiger Yang static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
7245b296821aSAl Viro struct mnt_idmap *idmap,
7246431547b3SChristoph Hellwig struct dentry *unused, struct inode *inode,
7247923f7f31STiger Yang const char *name, const void *value,
7248923f7f31STiger Yang size_t size, int flags)
7249d9a82a04SAndreas Gruenbacher {
7250e65ce2a5SChristian Brauner return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
725159301226SAl Viro name, value, size, flags);
725259301226SAl Viro }
725359301226SAl Viro
ocfs2_initxattrs(struct inode * inode,const struct xattr * xattr_array,void * fs_info)7254923f7f31STiger Yang static int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
725559301226SAl Viro void *fs_info)
7256431547b3SChristoph Hellwig {
7257923f7f31STiger Yang struct ocfs2_security_xattr_info *si = fs_info;
7258923f7f31STiger Yang const struct xattr *xattr;
7259b519ea6dSJoseph Qi int err = 0;
72609d8f13baSMimi Zohar
72619d8f13baSMimi Zohar if (si) {
72629d8f13baSMimi Zohar si->value = kmemdup(xattr_array->value, xattr_array->value_len,
72639d8f13baSMimi Zohar GFP_KERNEL);
72649d8f13baSMimi Zohar if (!si->value)
72659d8f13baSMimi Zohar return -ENOMEM;
72669d8f13baSMimi Zohar
72679d8f13baSMimi Zohar si->name = xattr_array->name;
72689d8f13baSMimi Zohar si->value_len = xattr_array->value_len;
72699d8f13baSMimi Zohar return 0;
72709d8f13baSMimi Zohar }
72719d8f13baSMimi Zohar
72729d8f13baSMimi Zohar for (xattr = xattr_array; xattr->name != NULL; xattr++) {
72739d8f13baSMimi Zohar err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
72749d8f13baSMimi Zohar xattr->name, xattr->value,
7275534eadddSTiger Yang xattr->value_len, XATTR_CREATE);
7276534eadddSTiger Yang if (err)
72772a7dba39SEric Paris break;
7278534eadddSTiger Yang }
7279534eadddSTiger Yang return err;
728038d59ef6STiger Yang }
728138d59ef6STiger Yang
ocfs2_init_security_get(struct inode * inode,struct inode * dir,const struct qstr * qstr,struct ocfs2_security_xattr_info * si)728238d59ef6STiger Yang int ocfs2_init_security_get(struct inode *inode,
72839d8f13baSMimi Zohar struct inode *dir,
72849d8f13baSMimi Zohar const struct qstr *qstr,
72859d8f13baSMimi Zohar struct ocfs2_security_xattr_info *si)
72869d8f13baSMimi Zohar {
72879d8f13baSMimi Zohar int ret;
72889d8f13baSMimi Zohar
72899d8f13baSMimi Zohar /* check whether ocfs2 support feature xattr */
7290534eadddSTiger Yang if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
7291534eadddSTiger Yang return -EOPNOTSUPP;
7292534eadddSTiger Yang if (si) {
7293534eadddSTiger Yang ret = security_inode_init_security(inode, dir, qstr,
7294534eadddSTiger Yang &ocfs2_initxattrs, si);
7295534eadddSTiger Yang /*
7296534eadddSTiger Yang * security_inode_init_security() does not return -EOPNOTSUPP,
7297534eadddSTiger Yang * we have to check the xattr ourselves.
7298534eadddSTiger Yang */
7299534eadddSTiger Yang if (!ret && !si->name)
7300534eadddSTiger Yang si->enable = 0;
7301534eadddSTiger Yang
7302534eadddSTiger Yang return ret;
7303534eadddSTiger Yang }
7304534eadddSTiger Yang
7305537d81caSStephen Hemminger return security_inode_init_security(inode, dir, qstr,
7306923f7f31STiger Yang &ocfs2_initxattrs, NULL);
7307923f7f31STiger Yang }
7308923f7f31STiger Yang
ocfs2_init_security_set(handle_t * handle,struct inode * inode,struct buffer_head * di_bh,struct ocfs2_security_xattr_info * si,struct ocfs2_alloc_context * xattr_ac,struct ocfs2_alloc_context * data_ac)7309923f7f31STiger Yang int ocfs2_init_security_set(handle_t *handle,
7310923f7f31STiger Yang struct inode *inode,
7311923f7f31STiger Yang struct buffer_head *di_bh,
731299219aeaSMark Fasheh struct ocfs2_security_xattr_info *si,
731399219aeaSMark Fasheh struct ocfs2_alloc_context *xattr_ac,
7314d9a82a04SAndreas Gruenbacher struct ocfs2_alloc_context *data_ac)
7315b296821aSAl Viro {
7316b296821aSAl Viro return ocfs2_xattr_set_handle(handle, inode, di_bh,
731799219aeaSMark Fasheh OCFS2_XATTR_INDEX_SECURITY,
7318b296821aSAl Viro si->name, si->value, si->value_len, 0,
7319431547b3SChristoph Hellwig xattr_ac, data_ac);
732099219aeaSMark Fasheh }
732199219aeaSMark Fasheh
7322d9a82a04SAndreas Gruenbacher const struct xattr_handler ocfs2_xattr_security_handler = {
7323e65ce2a5SChristian Brauner .prefix = XATTR_SECURITY_PREFIX,
732459301226SAl Viro .get = ocfs2_xattr_security_get,
732559301226SAl Viro .set = ocfs2_xattr_security_set,
732659301226SAl Viro };
732799219aeaSMark Fasheh
732859301226SAl Viro /*
7329431547b3SChristoph Hellwig * 'trusted' attributes support
733099219aeaSMark Fasheh */
ocfs2_xattr_trusted_get(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size)733199219aeaSMark Fasheh static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
7332537d81caSStephen Hemminger struct dentry *unused, struct inode *inode,
733399219aeaSMark Fasheh const char *name, void *buffer, size_t size)
733499219aeaSMark Fasheh {
733599219aeaSMark Fasheh return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED,
733699219aeaSMark Fasheh name, buffer, size);
733799219aeaSMark Fasheh }
733899219aeaSMark Fasheh
ocfs2_xattr_trusted_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)733999219aeaSMark Fasheh static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
734099219aeaSMark Fasheh struct mnt_idmap *idmap,
7341d9a82a04SAndreas Gruenbacher struct dentry *unused, struct inode *inode,
734284d86e6dSAndreas Gruenbacher const char *name, const void *value,
7343b296821aSAl Viro size_t size, int flags)
734499219aeaSMark Fasheh {
7345b296821aSAl Viro return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_TRUSTED,
734699219aeaSMark Fasheh name, value, size, flags);
734799219aeaSMark Fasheh }
734899219aeaSMark Fasheh
7349b296821aSAl Viro const struct xattr_handler ocfs2_xattr_trusted_handler = {
735099219aeaSMark Fasheh .prefix = XATTR_TRUSTED_PREFIX,
735199219aeaSMark Fasheh .get = ocfs2_xattr_trusted_get,
735299219aeaSMark Fasheh .set = ocfs2_xattr_trusted_set,
7353d9a82a04SAndreas Gruenbacher };
7354e65ce2a5SChristian Brauner
735559301226SAl Viro /*
735659301226SAl Viro * 'user' attributes support
735759301226SAl Viro */
ocfs2_xattr_user_get(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size)735899219aeaSMark Fasheh static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
735959301226SAl Viro struct dentry *unused, struct inode *inode,
736099219aeaSMark Fasheh const char *name, void *buffer, size_t size)
736199219aeaSMark Fasheh {
736299219aeaSMark Fasheh struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
736399219aeaSMark Fasheh
736459301226SAl Viro if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
7365431547b3SChristoph Hellwig return -EOPNOTSUPP;
736699219aeaSMark Fasheh return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_USER, name,
736799219aeaSMark Fasheh buffer, size);
7368537d81caSStephen Hemminger }
736999219aeaSMark Fasheh
ocfs2_xattr_user_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)737099219aeaSMark Fasheh static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
737199219aeaSMark Fasheh struct mnt_idmap *idmap,
737299219aeaSMark Fasheh struct dentry *unused, struct inode *inode,
7373 const char *name, const void *value,
7374 size_t size, int flags)
7375 {
7376 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
7377
7378 if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
7379 return -EOPNOTSUPP;
7380
7381 return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_USER,
7382 name, value, size, flags);
7383 }
7384
7385 const struct xattr_handler ocfs2_xattr_user_handler = {
7386 .prefix = XATTR_USER_PREFIX,
7387 .get = ocfs2_xattr_user_get,
7388 .set = ocfs2_xattr_user_set,
7389 };
7390