ocfs2: Optionally limit extent size in ocfs2_insert_extent()
[deliverable/linux.git] / fs / ocfs2 / xattr.c
CommitLineData
f56654c4
TM
1/* -*- mode: c; c-basic-offset: 8; -*-
2 * vim: noexpandtab sw=8 ts=8 sts=0:
3 *
4 * xattr.c
5 *
6 * Copyright (C) 2008 Oracle. All rights reserved.
7 *
cf1d6c76
TY
8 * CREDITS:
9 * Lots of code in this file is taken from ext3.
10 *
f56654c4
TM
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 021110-1307, USA.
25 */
26
cf1d6c76
TY
27#include <linux/capability.h>
28#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/slab.h>
31#include <linux/highmem.h>
32#include <linux/pagemap.h>
33#include <linux/uio.h>
34#include <linux/sched.h>
35#include <linux/splice.h>
36#include <linux/mount.h>
37#include <linux/writeback.h>
38#include <linux/falloc.h>
39
f56654c4
TM
40#define MLOG_MASK_PREFIX ML_XATTR
41#include <cluster/masklog.h>
42
43#include "ocfs2.h"
44#include "alloc.h"
45#include "dlmglue.h"
46#include "file.h"
cf1d6c76
TY
47#include "symlink.h"
48#include "sysfile.h"
f56654c4
TM
49#include "inode.h"
50#include "journal.h"
51#include "ocfs2_fs.h"
52#include "suballoc.h"
53#include "uptodate.h"
54#include "buffer_head_io.h"
0c044f0b 55#include "super.h"
cf1d6c76
TY
56#include "xattr.h"
57
58
59struct ocfs2_xattr_def_value_root {
60 struct ocfs2_xattr_value_root xv;
61 struct ocfs2_extent_rec er;
62};
63
0c044f0b
TM
64struct ocfs2_xattr_bucket {
65 struct buffer_head *bhs[OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET];
66 struct ocfs2_xattr_header *xh;
67};
68
cf1d6c76
TY
69#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
70#define OCFS2_XATTR_INLINE_SIZE 80
71
72static struct ocfs2_xattr_def_value_root def_xv = {
73 .xv.xr_list.l_count = cpu_to_le16(1),
74};
75
76struct xattr_handler *ocfs2_xattr_handlers[] = {
77 &ocfs2_xattr_user_handler,
78 &ocfs2_xattr_trusted_handler,
79 NULL
80};
81
82static struct xattr_handler *ocfs2_xattr_handler_map[] = {
83 [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
84 [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
85};
86
87struct ocfs2_xattr_info {
88 int name_index;
89 const char *name;
90 const void *value;
91 size_t value_len;
92};
93
94struct ocfs2_xattr_search {
95 struct buffer_head *inode_bh;
96 /*
97 * xattr_bh point to the block buffer head which has extended attribute
98 * when extended attribute in inode, xattr_bh is equal to inode_bh.
99 */
100 struct buffer_head *xattr_bh;
101 struct ocfs2_xattr_header *header;
589dc260 102 struct ocfs2_xattr_bucket bucket;
cf1d6c76
TY
103 void *base;
104 void *end;
105 struct ocfs2_xattr_entry *here;
106 int not_found;
107};
108
589dc260
TM
109static int ocfs2_xattr_bucket_get_name_value(struct inode *inode,
110 struct ocfs2_xattr_header *xh,
111 int index,
112 int *block_off,
113 int *new_offset);
114
115static int ocfs2_xattr_index_block_find(struct inode *inode,
116 struct buffer_head *root_bh,
117 int name_index,
118 const char *name,
119 struct ocfs2_xattr_search *xs);
120
0c044f0b
TM
121static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
122 struct ocfs2_xattr_tree_root *xt,
123 char *buffer,
124 size_t buffer_size);
125
cf1d6c76
TY
126static inline struct xattr_handler *ocfs2_xattr_handler(int name_index)
127{
128 struct xattr_handler *handler = NULL;
129
130 if (name_index > 0 && name_index < OCFS2_XATTR_MAX)
131 handler = ocfs2_xattr_handler_map[name_index];
132
133 return handler;
134}
135
136static inline u32 ocfs2_xattr_name_hash(struct inode *inode,
137 char *prefix,
138 int prefix_len,
139 char *name,
140 int name_len)
141{
142 /* Get hash value of uuid from super block */
143 u32 hash = OCFS2_SB(inode->i_sb)->uuid_hash;
144 int i;
145
146 /* hash extended attribute prefix */
147 for (i = 0; i < prefix_len; i++) {
148 hash = (hash << OCFS2_HASH_SHIFT) ^
149 (hash >> (8*sizeof(hash) - OCFS2_HASH_SHIFT)) ^
150 *prefix++;
151 }
152 /* hash extended attribute name */
153 for (i = 0; i < name_len; i++) {
154 hash = (hash << OCFS2_HASH_SHIFT) ^
155 (hash >> (8*sizeof(hash) - OCFS2_HASH_SHIFT)) ^
156 *name++;
157 }
158
159 return hash;
160}
161
162/*
163 * ocfs2_xattr_hash_entry()
164 *
165 * Compute the hash of an extended attribute.
166 */
167static void ocfs2_xattr_hash_entry(struct inode *inode,
168 struct ocfs2_xattr_header *header,
169 struct ocfs2_xattr_entry *entry)
170{
171 u32 hash = 0;
172 struct xattr_handler *handler =
173 ocfs2_xattr_handler(ocfs2_xattr_get_type(entry));
174 char *prefix = handler->prefix;
175 char *name = (char *)header + le16_to_cpu(entry->xe_name_offset);
176 int prefix_len = strlen(handler->prefix);
177
178 hash = ocfs2_xattr_name_hash(inode, prefix, prefix_len, name,
179 entry->xe_name_len);
180 entry->xe_name_hash = cpu_to_le32(hash);
181
182 return;
183}
f56654c4
TM
184
185static int ocfs2_xattr_extend_allocation(struct inode *inode,
186 u32 clusters_to_add,
187 struct buffer_head *xattr_bh,
188 struct ocfs2_xattr_value_root *xv)
189{
190 int status = 0;
191 int restart_func = 0;
192 int credits = 0;
193 handle_t *handle = NULL;
194 struct ocfs2_alloc_context *data_ac = NULL;
195 struct ocfs2_alloc_context *meta_ac = NULL;
196 enum ocfs2_alloc_restarted why;
197 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
198 struct ocfs2_extent_list *root_el = &xv->xr_list;
199 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
200
201 mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add);
202
203restart_all:
204
205 status = ocfs2_lock_allocators(inode, xattr_bh, root_el,
206 clusters_to_add, 0, &data_ac,
207 &meta_ac, OCFS2_XATTR_VALUE_EXTENT, xv);
208 if (status) {
209 mlog_errno(status);
210 goto leave;
211 }
212
213 credits = ocfs2_calc_extend_credits(osb->sb, root_el, clusters_to_add);
214 handle = ocfs2_start_trans(osb, credits);
215 if (IS_ERR(handle)) {
216 status = PTR_ERR(handle);
217 handle = NULL;
218 mlog_errno(status);
219 goto leave;
220 }
221
222restarted_transaction:
223 status = ocfs2_journal_access(handle, inode, xattr_bh,
224 OCFS2_JOURNAL_ACCESS_WRITE);
225 if (status < 0) {
226 mlog_errno(status);
227 goto leave;
228 }
229
230 prev_clusters = le32_to_cpu(xv->xr_clusters);
231 status = ocfs2_add_clusters_in_btree(osb,
232 inode,
233 &logical_start,
234 clusters_to_add,
235 0,
236 xattr_bh,
237 root_el,
238 handle,
239 data_ac,
240 meta_ac,
241 &why,
242 OCFS2_XATTR_VALUE_EXTENT,
243 xv);
244 if ((status < 0) && (status != -EAGAIN)) {
245 if (status != -ENOSPC)
246 mlog_errno(status);
247 goto leave;
248 }
249
250 status = ocfs2_journal_dirty(handle, xattr_bh);
251 if (status < 0) {
252 mlog_errno(status);
253 goto leave;
254 }
255
256 clusters_to_add -= le32_to_cpu(xv->xr_clusters) - prev_clusters;
257
258 if (why != RESTART_NONE && clusters_to_add) {
259 if (why == RESTART_META) {
260 mlog(0, "restarting function.\n");
261 restart_func = 1;
262 } else {
263 BUG_ON(why != RESTART_TRANS);
264
265 mlog(0, "restarting transaction.\n");
266 /* TODO: This can be more intelligent. */
267 credits = ocfs2_calc_extend_credits(osb->sb,
268 root_el,
269 clusters_to_add);
270 status = ocfs2_extend_trans(handle, credits);
271 if (status < 0) {
272 /* handle still has to be committed at
273 * this point. */
274 status = -ENOMEM;
275 mlog_errno(status);
276 goto leave;
277 }
278 goto restarted_transaction;
279 }
280 }
281
282leave:
283 if (handle) {
284 ocfs2_commit_trans(osb, handle);
285 handle = NULL;
286 }
287 if (data_ac) {
288 ocfs2_free_alloc_context(data_ac);
289 data_ac = NULL;
290 }
291 if (meta_ac) {
292 ocfs2_free_alloc_context(meta_ac);
293 meta_ac = NULL;
294 }
295 if ((!status) && restart_func) {
296 restart_func = 0;
297 goto restart_all;
298 }
299
300 return status;
301}
302
303static int __ocfs2_remove_xattr_range(struct inode *inode,
304 struct buffer_head *root_bh,
305 struct ocfs2_xattr_value_root *xv,
306 u32 cpos, u32 phys_cpos, u32 len,
307 struct ocfs2_cached_dealloc_ctxt *dealloc)
308{
309 int ret;
310 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
311 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
312 struct inode *tl_inode = osb->osb_tl_inode;
313 handle_t *handle;
314 struct ocfs2_alloc_context *meta_ac = NULL;
315
316 ret = ocfs2_lock_allocators(inode, root_bh, &xv->xr_list,
317 0, 1, NULL, &meta_ac,
318 OCFS2_XATTR_VALUE_EXTENT, xv);
319 if (ret) {
320 mlog_errno(ret);
321 return ret;
322 }
323
324 mutex_lock(&tl_inode->i_mutex);
325
326 if (ocfs2_truncate_log_needs_flush(osb)) {
327 ret = __ocfs2_flush_truncate_log(osb);
328 if (ret < 0) {
329 mlog_errno(ret);
330 goto out;
331 }
332 }
333
334 handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
335 if (IS_ERR(handle)) {
336 ret = PTR_ERR(handle);
337 mlog_errno(ret);
338 goto out;
339 }
340
341 ret = ocfs2_journal_access(handle, inode, root_bh,
342 OCFS2_JOURNAL_ACCESS_WRITE);
343 if (ret) {
344 mlog_errno(ret);
345 goto out_commit;
346 }
347
348 ret = ocfs2_remove_extent(inode, root_bh, cpos, len, handle, meta_ac,
349 dealloc, OCFS2_XATTR_VALUE_EXTENT, xv);
350 if (ret) {
351 mlog_errno(ret);
352 goto out_commit;
353 }
354
355 le32_add_cpu(&xv->xr_clusters, -len);
356
357 ret = ocfs2_journal_dirty(handle, root_bh);
358 if (ret) {
359 mlog_errno(ret);
360 goto out_commit;
361 }
362
363 ret = ocfs2_truncate_log_append(osb, handle, phys_blkno, len);
364 if (ret)
365 mlog_errno(ret);
366
367out_commit:
368 ocfs2_commit_trans(osb, handle);
369out:
370 mutex_unlock(&tl_inode->i_mutex);
371
372 if (meta_ac)
373 ocfs2_free_alloc_context(meta_ac);
374
375 return ret;
376}
377
378static int ocfs2_xattr_shrink_size(struct inode *inode,
379 u32 old_clusters,
380 u32 new_clusters,
381 struct buffer_head *root_bh,
382 struct ocfs2_xattr_value_root *xv)
383{
384 int ret = 0;
385 u32 trunc_len, cpos, phys_cpos, alloc_size;
386 u64 block;
387 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
388 struct ocfs2_cached_dealloc_ctxt dealloc;
389
390 ocfs2_init_dealloc_ctxt(&dealloc);
391
392 if (old_clusters <= new_clusters)
393 return 0;
394
395 cpos = new_clusters;
396 trunc_len = old_clusters - new_clusters;
397 while (trunc_len) {
398 ret = ocfs2_xattr_get_clusters(inode, cpos, &phys_cpos,
399 &alloc_size, &xv->xr_list);
400 if (ret) {
401 mlog_errno(ret);
402 goto out;
403 }
404
405 if (alloc_size > trunc_len)
406 alloc_size = trunc_len;
407
408 ret = __ocfs2_remove_xattr_range(inode, root_bh, xv, cpos,
409 phys_cpos, alloc_size,
410 &dealloc);
411 if (ret) {
412 mlog_errno(ret);
413 goto out;
414 }
415
416 block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
417 ocfs2_remove_xattr_clusters_from_cache(inode, block,
418 alloc_size);
419 cpos += alloc_size;
420 trunc_len -= alloc_size;
421 }
422
423out:
424 ocfs2_schedule_truncate_log_flush(osb, 1);
425 ocfs2_run_deallocs(osb, &dealloc);
426
427 return ret;
428}
429
430static int ocfs2_xattr_value_truncate(struct inode *inode,
431 struct buffer_head *root_bh,
432 struct ocfs2_xattr_value_root *xv,
433 int len)
434{
435 int ret;
436 u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb, len);
437 u32 old_clusters = le32_to_cpu(xv->xr_clusters);
438
439 if (new_clusters == old_clusters)
440 return 0;
441
442 if (new_clusters > old_clusters)
443 ret = ocfs2_xattr_extend_allocation(inode,
444 new_clusters - old_clusters,
445 root_bh, xv);
446 else
447 ret = ocfs2_xattr_shrink_size(inode,
448 old_clusters, new_clusters,
449 root_bh, xv);
450
451 return ret;
452}
cf1d6c76
TY
453
454static int ocfs2_xattr_list_entries(struct inode *inode,
455 struct ocfs2_xattr_header *header,
456 char *buffer, size_t buffer_size)
457{
458 size_t rest = buffer_size;
459 int i;
460
461 for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) {
462 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
463 struct xattr_handler *handler =
464 ocfs2_xattr_handler(ocfs2_xattr_get_type(entry));
465
466 if (handler) {
467 size_t size = handler->list(inode, buffer, rest,
468 ((char *)header +
469 le16_to_cpu(entry->xe_name_offset)),
470 entry->xe_name_len);
471 if (buffer) {
472 if (size > rest)
473 return -ERANGE;
474 buffer += size;
475 }
476 rest -= size;
477 }
478 }
479
480 return buffer_size - rest;
481}
482
483static int ocfs2_xattr_ibody_list(struct inode *inode,
484 struct ocfs2_dinode *di,
485 char *buffer,
486 size_t buffer_size)
487{
488 struct ocfs2_xattr_header *header = NULL;
489 struct ocfs2_inode_info *oi = OCFS2_I(inode);
490 int ret = 0;
491
492 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
493 return ret;
494
495 header = (struct ocfs2_xattr_header *)
496 ((void *)di + inode->i_sb->s_blocksize -
497 le16_to_cpu(di->i_xattr_inline_size));
498
499 ret = ocfs2_xattr_list_entries(inode, header, buffer, buffer_size);
500
501 return ret;
502}
503
504static int ocfs2_xattr_block_list(struct inode *inode,
505 struct ocfs2_dinode *di,
506 char *buffer,
507 size_t buffer_size)
508{
509 struct buffer_head *blk_bh = NULL;
0c044f0b 510 struct ocfs2_xattr_block *xb;
cf1d6c76
TY
511 int ret = 0;
512
513 if (!di->i_xattr_loc)
514 return ret;
515
516 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
517 le64_to_cpu(di->i_xattr_loc),
518 &blk_bh, OCFS2_BH_CACHED, inode);
519 if (ret < 0) {
520 mlog_errno(ret);
521 return ret;
522 }
523 /*Verify the signature of xattr block*/
524 if (memcmp((void *)blk_bh->b_data, OCFS2_XATTR_BLOCK_SIGNATURE,
525 strlen(OCFS2_XATTR_BLOCK_SIGNATURE))) {
526 ret = -EFAULT;
527 goto cleanup;
528 }
529
0c044f0b 530 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
cf1d6c76 531
0c044f0b
TM
532 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
533 struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header;
534 ret = ocfs2_xattr_list_entries(inode, header,
535 buffer, buffer_size);
536 } else {
537 struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root;
538 ret = ocfs2_xattr_tree_list_index_block(inode, xt,
539 buffer, buffer_size);
540 }
cf1d6c76
TY
541cleanup:
542 brelse(blk_bh);
543
544 return ret;
545}
546
547ssize_t ocfs2_listxattr(struct dentry *dentry,
548 char *buffer,
549 size_t size)
550{
551 int ret = 0, i_ret = 0, b_ret = 0;
552 struct buffer_head *di_bh = NULL;
553 struct ocfs2_dinode *di = NULL;
554 struct ocfs2_inode_info *oi = OCFS2_I(dentry->d_inode);
555
556 if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
557 return ret;
558
559 ret = ocfs2_inode_lock(dentry->d_inode, &di_bh, 0);
560 if (ret < 0) {
561 mlog_errno(ret);
562 return ret;
563 }
564
565 di = (struct ocfs2_dinode *)di_bh->b_data;
566
567 down_read(&oi->ip_xattr_sem);
568 i_ret = ocfs2_xattr_ibody_list(dentry->d_inode, di, buffer, size);
569 if (i_ret < 0)
570 b_ret = 0;
571 else {
572 if (buffer) {
573 buffer += i_ret;
574 size -= i_ret;
575 }
576 b_ret = ocfs2_xattr_block_list(dentry->d_inode, di,
577 buffer, size);
578 if (b_ret < 0)
579 i_ret = 0;
580 }
581 up_read(&oi->ip_xattr_sem);
582 ocfs2_inode_unlock(dentry->d_inode, 0);
583
584 brelse(di_bh);
585
586 return i_ret + b_ret;
587}
588
589static int ocfs2_xattr_find_entry(int name_index,
590 const char *name,
591 struct ocfs2_xattr_search *xs)
592{
593 struct ocfs2_xattr_entry *entry;
594 size_t name_len;
595 int i, cmp = 1;
596
597 if (name == NULL)
598 return -EINVAL;
599
600 name_len = strlen(name);
601 entry = xs->here;
602 for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
603 cmp = name_index - ocfs2_xattr_get_type(entry);
604 if (!cmp)
605 cmp = name_len - entry->xe_name_len;
606 if (!cmp)
607 cmp = memcmp(name, (xs->base +
608 le16_to_cpu(entry->xe_name_offset)),
609 name_len);
610 if (cmp == 0)
611 break;
612 entry += 1;
613 }
614 xs->here = entry;
615
616 return cmp ? -ENODATA : 0;
617}
618
619static int ocfs2_xattr_get_value_outside(struct inode *inode,
589dc260 620 struct ocfs2_xattr_value_root *xv,
cf1d6c76
TY
621 void *buffer,
622 size_t len)
623{
624 u32 cpos, p_cluster, num_clusters, bpc, clusters;
625 u64 blkno;
626 int i, ret = 0;
627 size_t cplen, blocksize;
628 struct buffer_head *bh = NULL;
cf1d6c76
TY
629 struct ocfs2_extent_list *el;
630
cf1d6c76
TY
631 el = &xv->xr_list;
632 clusters = le32_to_cpu(xv->xr_clusters);
633 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
634 blocksize = inode->i_sb->s_blocksize;
635
636 cpos = 0;
637 while (cpos < clusters) {
638 ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
639 &num_clusters, el);
640 if (ret) {
641 mlog_errno(ret);
642 goto out;
643 }
644
645 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
646 /* Copy ocfs2_xattr_value */
647 for (i = 0; i < num_clusters * bpc; i++, blkno++) {
648 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), blkno,
649 &bh, OCFS2_BH_CACHED, inode);
650 if (ret) {
651 mlog_errno(ret);
652 goto out;
653 }
654
655 cplen = len >= blocksize ? blocksize : len;
656 memcpy(buffer, bh->b_data, cplen);
657 len -= cplen;
658 buffer += cplen;
659
660 brelse(bh);
661 bh = NULL;
662 if (len == 0)
663 break;
664 }
665 cpos += num_clusters;
666 }
667out:
668 return ret;
669}
670
671static int ocfs2_xattr_ibody_get(struct inode *inode,
672 int name_index,
673 const char *name,
674 void *buffer,
675 size_t buffer_size,
676 struct ocfs2_xattr_search *xs)
677{
678 struct ocfs2_inode_info *oi = OCFS2_I(inode);
679 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
589dc260 680 struct ocfs2_xattr_value_root *xv;
cf1d6c76
TY
681 size_t size;
682 int ret = 0;
683
684 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL))
685 return -ENODATA;
686
687 xs->end = (void *)di + inode->i_sb->s_blocksize;
688 xs->header = (struct ocfs2_xattr_header *)
689 (xs->end - le16_to_cpu(di->i_xattr_inline_size));
690 xs->base = (void *)xs->header;
691 xs->here = xs->header->xh_entries;
692
693 ret = ocfs2_xattr_find_entry(name_index, name, xs);
694 if (ret)
695 return ret;
696 size = le64_to_cpu(xs->here->xe_value_size);
697 if (buffer) {
698 if (size > buffer_size)
699 return -ERANGE;
700 if (ocfs2_xattr_is_local(xs->here)) {
701 memcpy(buffer, (void *)xs->base +
702 le16_to_cpu(xs->here->xe_name_offset) +
703 OCFS2_XATTR_SIZE(xs->here->xe_name_len), size);
704 } else {
589dc260
TM
705 xv = (struct ocfs2_xattr_value_root *)
706 (xs->base + le16_to_cpu(
707 xs->here->xe_name_offset) +
708 OCFS2_XATTR_SIZE(xs->here->xe_name_len));
709 ret = ocfs2_xattr_get_value_outside(inode, xv,
cf1d6c76
TY
710 buffer, size);
711 if (ret < 0) {
712 mlog_errno(ret);
713 return ret;
714 }
715 }
716 }
717
718 return size;
719}
720
721static int ocfs2_xattr_block_get(struct inode *inode,
722 int name_index,
723 const char *name,
724 void *buffer,
725 size_t buffer_size,
726 struct ocfs2_xattr_search *xs)
727{
728 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
729 struct buffer_head *blk_bh = NULL;
730 struct ocfs2_xattr_block *xb;
589dc260 731 struct ocfs2_xattr_value_root *xv;
cf1d6c76 732 size_t size;
589dc260 733 int ret = -ENODATA, name_offset, name_len, block_off, i;
cf1d6c76
TY
734
735 if (!di->i_xattr_loc)
736 return ret;
737
589dc260
TM
738 memset(&xs->bucket, 0, sizeof(xs->bucket));
739
cf1d6c76
TY
740 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
741 le64_to_cpu(di->i_xattr_loc),
742 &blk_bh, OCFS2_BH_CACHED, inode);
743 if (ret < 0) {
744 mlog_errno(ret);
745 return ret;
746 }
747 /*Verify the signature of xattr block*/
748 if (memcmp((void *)blk_bh->b_data, OCFS2_XATTR_BLOCK_SIGNATURE,
749 strlen(OCFS2_XATTR_BLOCK_SIGNATURE))) {
750 ret = -EFAULT;
751 goto cleanup;
752 }
753
754 xs->xattr_bh = blk_bh;
755 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
cf1d6c76 756
589dc260
TM
757 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
758 xs->header = &xb->xb_attrs.xb_header;
759 xs->base = (void *)xs->header;
760 xs->end = (void *)(blk_bh->b_data) + blk_bh->b_size;
761 xs->here = xs->header->xh_entries;
762
763 ret = ocfs2_xattr_find_entry(name_index, name, xs);
764 } else
765 ret = ocfs2_xattr_index_block_find(inode, blk_bh,
766 name_index,
767 name, xs);
768
cf1d6c76
TY
769 if (ret)
770 goto cleanup;
771 size = le64_to_cpu(xs->here->xe_value_size);
772 if (buffer) {
773 ret = -ERANGE;
774 if (size > buffer_size)
775 goto cleanup;
589dc260
TM
776
777 name_offset = le16_to_cpu(xs->here->xe_name_offset);
778 name_len = OCFS2_XATTR_SIZE(xs->here->xe_name_len);
779 i = xs->here - xs->header->xh_entries;
780
781 if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
782 ret = ocfs2_xattr_bucket_get_name_value(inode,
783 xs->bucket.xh,
784 i,
785 &block_off,
786 &name_offset);
787 xs->base = xs->bucket.bhs[block_off]->b_data;
788 }
cf1d6c76
TY
789 if (ocfs2_xattr_is_local(xs->here)) {
790 memcpy(buffer, (void *)xs->base +
589dc260 791 name_offset + name_len, size);
cf1d6c76 792 } else {
589dc260
TM
793 xv = (struct ocfs2_xattr_value_root *)
794 (xs->base + name_offset + name_len);
795 ret = ocfs2_xattr_get_value_outside(inode, xv,
cf1d6c76
TY
796 buffer, size);
797 if (ret < 0) {
798 mlog_errno(ret);
799 goto cleanup;
800 }
801 }
802 }
803 ret = size;
804cleanup:
589dc260
TM
805 for (i = 0; i < OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET; i++)
806 brelse(xs->bucket.bhs[i]);
807 memset(&xs->bucket, 0, sizeof(xs->bucket));
cf1d6c76 808
589dc260 809 brelse(blk_bh);
cf1d6c76
TY
810 return ret;
811}
812
813/* ocfs2_xattr_get()
814 *
815 * Copy an extended attribute into the buffer provided.
816 * Buffer is NULL to compute the size of buffer required.
817 */
818int ocfs2_xattr_get(struct inode *inode,
819 int name_index,
820 const char *name,
821 void *buffer,
822 size_t buffer_size)
823{
824 int ret;
825 struct ocfs2_dinode *di = NULL;
826 struct buffer_head *di_bh = NULL;
827 struct ocfs2_inode_info *oi = OCFS2_I(inode);
828 struct ocfs2_xattr_search xis = {
829 .not_found = -ENODATA,
830 };
831 struct ocfs2_xattr_search xbs = {
832 .not_found = -ENODATA,
833 };
834
835 if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
836 ret = -ENODATA;
837
838 ret = ocfs2_inode_lock(inode, &di_bh, 0);
839 if (ret < 0) {
840 mlog_errno(ret);
841 return ret;
842 }
843 xis.inode_bh = xbs.inode_bh = di_bh;
844 di = (struct ocfs2_dinode *)di_bh->b_data;
845
846 down_read(&oi->ip_xattr_sem);
847 ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer,
848 buffer_size, &xis);
849 if (ret == -ENODATA)
850 ret = ocfs2_xattr_block_get(inode, name_index, name, buffer,
851 buffer_size, &xbs);
852 up_read(&oi->ip_xattr_sem);
853 ocfs2_inode_unlock(inode, 0);
854
855 brelse(di_bh);
856
857 return ret;
858}
859
860static int __ocfs2_xattr_set_value_outside(struct inode *inode,
861 struct ocfs2_xattr_value_root *xv,
862 const void *value,
863 int value_len)
864{
865 int ret = 0, i, cp_len, credits;
866 u16 blocksize = inode->i_sb->s_blocksize;
867 u32 p_cluster, num_clusters;
868 u32 cpos = 0, bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
869 u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len);
870 u64 blkno;
871 struct buffer_head *bh = NULL;
872 handle_t *handle;
873
874 BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
875
876 credits = clusters * bpc;
877 handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb), credits);
878 if (IS_ERR(handle)) {
879 ret = PTR_ERR(handle);
880 mlog_errno(ret);
881 goto out;
882 }
883
884 while (cpos < clusters) {
885 ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
886 &num_clusters, &xv->xr_list);
887 if (ret) {
888 mlog_errno(ret);
889 goto out_commit;
890 }
891
892 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
893
894 for (i = 0; i < num_clusters * bpc; i++, blkno++) {
895 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), blkno,
896 &bh, OCFS2_BH_CACHED, inode);
897 if (ret) {
898 mlog_errno(ret);
899 goto out_commit;
900 }
901
902 ret = ocfs2_journal_access(handle,
903 inode,
904 bh,
905 OCFS2_JOURNAL_ACCESS_WRITE);
906 if (ret < 0) {
907 mlog_errno(ret);
908 goto out_commit;
909 }
910
911 cp_len = value_len > blocksize ? blocksize : value_len;
912 memcpy(bh->b_data, value, cp_len);
913 value_len -= cp_len;
914 value += cp_len;
915 if (cp_len < blocksize)
916 memset(bh->b_data + cp_len, 0,
917 blocksize - cp_len);
918
919 ret = ocfs2_journal_dirty(handle, bh);
920 if (ret < 0) {
921 mlog_errno(ret);
922 goto out_commit;
923 }
924 brelse(bh);
925 bh = NULL;
926
927 /*
928 * XXX: do we need to empty all the following
929 * blocks in this cluster?
930 */
931 if (!value_len)
932 break;
933 }
934 cpos += num_clusters;
935 }
936out_commit:
937 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
938out:
939 brelse(bh);
940
941 return ret;
942}
943
944static int ocfs2_xattr_cleanup(struct inode *inode,
945 struct ocfs2_xattr_info *xi,
946 struct ocfs2_xattr_search *xs,
947 size_t offs)
948{
949 handle_t *handle = NULL;
950 int ret = 0;
951 size_t name_len = strlen(xi->name);
952 void *val = xs->base + offs;
953 size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
954
955 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
956 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
957 if (IS_ERR(handle)) {
958 ret = PTR_ERR(handle);
959 mlog_errno(ret);
960 goto out;
961 }
962 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
963 OCFS2_JOURNAL_ACCESS_WRITE);
964 if (ret) {
965 mlog_errno(ret);
966 goto out_commit;
967 }
968 /* Decrease xattr count */
969 le16_add_cpu(&xs->header->xh_count, -1);
970 /* Remove the xattr entry and tree root which has already be set*/
971 memset((void *)xs->here, 0, sizeof(struct ocfs2_xattr_entry));
972 memset(val, 0, size);
973
974 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
975 if (ret < 0)
976 mlog_errno(ret);
977out_commit:
978 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
979out:
980 return ret;
981}
982
983static int ocfs2_xattr_update_entry(struct inode *inode,
984 struct ocfs2_xattr_info *xi,
985 struct ocfs2_xattr_search *xs,
986 size_t offs)
987{
988 handle_t *handle = NULL;
989 int ret = 0;
990
991 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
992 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
993 if (IS_ERR(handle)) {
994 ret = PTR_ERR(handle);
995 mlog_errno(ret);
996 goto out;
997 }
998 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
999 OCFS2_JOURNAL_ACCESS_WRITE);
1000 if (ret) {
1001 mlog_errno(ret);
1002 goto out_commit;
1003 }
1004
1005 xs->here->xe_name_offset = cpu_to_le16(offs);
1006 xs->here->xe_value_size = cpu_to_le64(xi->value_len);
1007 if (xi->value_len <= OCFS2_XATTR_INLINE_SIZE)
1008 ocfs2_xattr_set_local(xs->here, 1);
1009 else
1010 ocfs2_xattr_set_local(xs->here, 0);
1011 ocfs2_xattr_hash_entry(inode, xs->header, xs->here);
1012
1013 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
1014 if (ret < 0)
1015 mlog_errno(ret);
1016out_commit:
1017 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1018out:
1019 return ret;
1020}
1021
1022/*
1023 * ocfs2_xattr_set_value_outside()
1024 *
1025 * Set large size value in B tree.
1026 */
1027static int ocfs2_xattr_set_value_outside(struct inode *inode,
1028 struct ocfs2_xattr_info *xi,
1029 struct ocfs2_xattr_search *xs,
1030 size_t offs)
1031{
1032 size_t name_len = strlen(xi->name);
1033 void *val = xs->base + offs;
1034 struct ocfs2_xattr_value_root *xv = NULL;
1035 size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
1036 int ret = 0;
1037
1038 memset(val, 0, size);
1039 memcpy(val, xi->name, name_len);
1040 xv = (struct ocfs2_xattr_value_root *)
1041 (val + OCFS2_XATTR_SIZE(name_len));
1042 xv->xr_clusters = 0;
1043 xv->xr_last_eb_blk = 0;
1044 xv->xr_list.l_tree_depth = 0;
1045 xv->xr_list.l_count = cpu_to_le16(1);
1046 xv->xr_list.l_next_free_rec = 0;
1047
1048 ret = ocfs2_xattr_value_truncate(inode, xs->xattr_bh, xv,
1049 xi->value_len);
1050 if (ret < 0) {
1051 mlog_errno(ret);
1052 return ret;
1053 }
1054 ret = __ocfs2_xattr_set_value_outside(inode, xv, xi->value,
1055 xi->value_len);
1056 if (ret < 0) {
1057 mlog_errno(ret);
1058 return ret;
1059 }
1060 ret = ocfs2_xattr_update_entry(inode, xi, xs, offs);
1061 if (ret < 0)
1062 mlog_errno(ret);
1063
1064 return ret;
1065}
1066
1067/*
1068 * ocfs2_xattr_set_entry_local()
1069 *
1070 * Set, replace or remove extended attribute in local.
1071 */
1072static void ocfs2_xattr_set_entry_local(struct inode *inode,
1073 struct ocfs2_xattr_info *xi,
1074 struct ocfs2_xattr_search *xs,
1075 struct ocfs2_xattr_entry *last,
1076 size_t min_offs)
1077{
1078 size_t name_len = strlen(xi->name);
1079 int i;
1080
1081 if (xi->value && xs->not_found) {
1082 /* Insert the new xattr entry. */
1083 le16_add_cpu(&xs->header->xh_count, 1);
1084 ocfs2_xattr_set_type(last, xi->name_index);
1085 ocfs2_xattr_set_local(last, 1);
1086 last->xe_name_len = name_len;
1087 } else {
1088 void *first_val;
1089 void *val;
1090 size_t offs, size;
1091
1092 first_val = xs->base + min_offs;
1093 offs = le16_to_cpu(xs->here->xe_name_offset);
1094 val = xs->base + offs;
1095
1096 if (le64_to_cpu(xs->here->xe_value_size) >
1097 OCFS2_XATTR_INLINE_SIZE)
1098 size = OCFS2_XATTR_SIZE(name_len) +
1099 OCFS2_XATTR_ROOT_SIZE;
1100 else
1101 size = OCFS2_XATTR_SIZE(name_len) +
1102 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1103
1104 if (xi->value && size == OCFS2_XATTR_SIZE(name_len) +
1105 OCFS2_XATTR_SIZE(xi->value_len)) {
1106 /* The old and the new value have the
1107 same size. Just replace the value. */
1108 ocfs2_xattr_set_local(xs->here, 1);
1109 xs->here->xe_value_size = cpu_to_le64(xi->value_len);
1110 /* Clear value bytes. */
1111 memset(val + OCFS2_XATTR_SIZE(name_len),
1112 0,
1113 OCFS2_XATTR_SIZE(xi->value_len));
1114 memcpy(val + OCFS2_XATTR_SIZE(name_len),
1115 xi->value,
1116 xi->value_len);
1117 return;
1118 }
1119 /* Remove the old name+value. */
1120 memmove(first_val + size, first_val, val - first_val);
1121 memset(first_val, 0, size);
1122 xs->here->xe_name_hash = 0;
1123 xs->here->xe_name_offset = 0;
1124 ocfs2_xattr_set_local(xs->here, 1);
1125 xs->here->xe_value_size = 0;
1126
1127 min_offs += size;
1128
1129 /* Adjust all value offsets. */
1130 last = xs->header->xh_entries;
1131 for (i = 0 ; i < le16_to_cpu(xs->header->xh_count); i++) {
1132 size_t o = le16_to_cpu(last->xe_name_offset);
1133
1134 if (o < offs)
1135 last->xe_name_offset = cpu_to_le16(o + size);
1136 last += 1;
1137 }
1138
1139 if (!xi->value) {
1140 /* Remove the old entry. */
1141 last -= 1;
1142 memmove(xs->here, xs->here + 1,
1143 (void *)last - (void *)xs->here);
1144 memset(last, 0, sizeof(struct ocfs2_xattr_entry));
1145 le16_add_cpu(&xs->header->xh_count, -1);
1146 }
1147 }
1148 if (xi->value) {
1149 /* Insert the new name+value. */
1150 size_t size = OCFS2_XATTR_SIZE(name_len) +
1151 OCFS2_XATTR_SIZE(xi->value_len);
1152 void *val = xs->base + min_offs - size;
1153
1154 xs->here->xe_name_offset = cpu_to_le16(min_offs - size);
1155 memset(val, 0, size);
1156 memcpy(val, xi->name, name_len);
1157 memcpy(val + OCFS2_XATTR_SIZE(name_len),
1158 xi->value,
1159 xi->value_len);
1160 xs->here->xe_value_size = cpu_to_le64(xi->value_len);
1161 ocfs2_xattr_set_local(xs->here, 1);
1162 ocfs2_xattr_hash_entry(inode, xs->header, xs->here);
1163 }
1164
1165 return;
1166}
1167
1168/*
1169 * ocfs2_xattr_set_entry()
1170 *
1171 * Set extended attribute entry into inode or block.
1172 *
1173 * If extended attribute value size > OCFS2_XATTR_INLINE_SIZE,
1174 * We first insert tree root(ocfs2_xattr_value_root) with set_entry_local(),
1175 * then set value in B tree with set_value_outside().
1176 */
1177static int ocfs2_xattr_set_entry(struct inode *inode,
1178 struct ocfs2_xattr_info *xi,
1179 struct ocfs2_xattr_search *xs,
1180 int flag)
1181{
1182 struct ocfs2_xattr_entry *last;
1183 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1184 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1185 size_t min_offs = xs->end - xs->base, name_len = strlen(xi->name);
1186 size_t size_l = 0;
1187 handle_t *handle = NULL;
1188 int free, i, ret;
1189 struct ocfs2_xattr_info xi_l = {
1190 .name_index = xi->name_index,
1191 .name = xi->name,
1192 .value = xi->value,
1193 .value_len = xi->value_len,
1194 };
1195
1196 /* Compute min_offs, last and free space. */
1197 last = xs->header->xh_entries;
1198
1199 for (i = 0 ; i < le16_to_cpu(xs->header->xh_count); i++) {
1200 size_t offs = le16_to_cpu(last->xe_name_offset);
1201 if (offs < min_offs)
1202 min_offs = offs;
1203 last += 1;
1204 }
1205
1206 free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
1207 if (free < 0)
1208 return -EFAULT;
1209
1210 if (!xs->not_found) {
1211 size_t size = 0;
1212 if (ocfs2_xattr_is_local(xs->here))
1213 size = OCFS2_XATTR_SIZE(name_len) +
1214 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1215 else
1216 size = OCFS2_XATTR_SIZE(name_len) +
1217 OCFS2_XATTR_ROOT_SIZE;
1218 free += (size + sizeof(struct ocfs2_xattr_entry));
1219 }
1220 /* Check free space in inode or block */
1221 if (xi->value && xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
1222 if (free < sizeof(struct ocfs2_xattr_entry) +
1223 OCFS2_XATTR_SIZE(name_len) +
1224 OCFS2_XATTR_ROOT_SIZE) {
1225 ret = -ENOSPC;
1226 goto out;
1227 }
1228 size_l = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
1229 xi_l.value = (void *)&def_xv;
1230 xi_l.value_len = OCFS2_XATTR_ROOT_SIZE;
1231 } else if (xi->value) {
1232 if (free < sizeof(struct ocfs2_xattr_entry) +
1233 OCFS2_XATTR_SIZE(name_len) +
1234 OCFS2_XATTR_SIZE(xi->value_len)) {
1235 ret = -ENOSPC;
1236 goto out;
1237 }
1238 }
1239
1240 if (!xs->not_found) {
1241 /* For existing extended attribute */
1242 size_t size = OCFS2_XATTR_SIZE(name_len) +
1243 OCFS2_XATTR_SIZE(le64_to_cpu(xs->here->xe_value_size));
1244 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
1245 void *val = xs->base + offs;
1246
1247 if (ocfs2_xattr_is_local(xs->here) && size == size_l) {
1248 /* Replace existing local xattr with tree root */
1249 ret = ocfs2_xattr_set_value_outside(inode, xi, xs,
1250 offs);
1251 if (ret < 0)
1252 mlog_errno(ret);
1253 goto out;
1254 } else if (!ocfs2_xattr_is_local(xs->here)) {
1255 /* For existing xattr which has value outside */
1256 struct ocfs2_xattr_value_root *xv = NULL;
1257 xv = (struct ocfs2_xattr_value_root *)(val +
1258 OCFS2_XATTR_SIZE(name_len));
1259
1260 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
1261 /*
1262 * If new value need set outside also,
1263 * first truncate old value to new value,
1264 * then set new value with set_value_outside().
1265 */
1266 ret = ocfs2_xattr_value_truncate(inode,
1267 xs->xattr_bh,
1268 xv,
1269 xi->value_len);
1270 if (ret < 0) {
1271 mlog_errno(ret);
1272 goto out;
1273 }
1274
1275 ret = __ocfs2_xattr_set_value_outside(inode,
1276 xv,
1277 xi->value,
1278 xi->value_len);
1279 if (ret < 0) {
1280 mlog_errno(ret);
1281 goto out;
1282 }
1283
1284 ret = ocfs2_xattr_update_entry(inode,
1285 xi,
1286 xs,
1287 offs);
1288 if (ret < 0)
1289 mlog_errno(ret);
1290 goto out;
1291 } else {
1292 /*
1293 * If new value need set in local,
1294 * just trucate old value to zero.
1295 */
1296 ret = ocfs2_xattr_value_truncate(inode,
1297 xs->xattr_bh,
1298 xv,
1299 0);
1300 if (ret < 0)
1301 mlog_errno(ret);
1302 }
1303 }
1304 }
1305
1306 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1307 OCFS2_INODE_UPDATE_CREDITS);
1308 if (IS_ERR(handle)) {
1309 ret = PTR_ERR(handle);
1310 mlog_errno(ret);
1311 goto out;
1312 }
1313
1314 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
1315 OCFS2_JOURNAL_ACCESS_WRITE);
1316 if (ret) {
1317 mlog_errno(ret);
1318 goto out_commit;
1319 }
1320
1321 if (!(flag & OCFS2_INLINE_XATTR_FL)) {
1322 /*set extended attribue in external blcok*/
1323 ret = ocfs2_extend_trans(handle,
1324 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
1325 if (ret) {
1326 mlog_errno(ret);
1327 goto out_commit;
1328 }
1329 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
1330 OCFS2_JOURNAL_ACCESS_WRITE);
1331 if (ret) {
1332 mlog_errno(ret);
1333 goto out_commit;
1334 }
1335 }
1336
1337 /*
1338 * Set value in local, include set tree root in local.
1339 * This is the first step for value size >INLINE_SIZE.
1340 */
1341 ocfs2_xattr_set_entry_local(inode, &xi_l, xs, last, min_offs);
1342
1343 if (!(flag & OCFS2_INLINE_XATTR_FL)) {
1344 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
1345 if (ret < 0) {
1346 mlog_errno(ret);
1347 goto out_commit;
1348 }
1349 }
1350
1351 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) &&
1352 (flag & OCFS2_INLINE_XATTR_FL)) {
1353 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1354 unsigned int xattrsize = osb->s_xattr_inline_size;
1355
1356 /*
1357 * Adjust extent record count or inline data size
1358 * to reserve space for extended attribute.
1359 */
1360 if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1361 struct ocfs2_inline_data *idata = &di->id2.i_data;
1362 le16_add_cpu(&idata->id_count, -xattrsize);
1363 } else if (!(ocfs2_inode_is_fast_symlink(inode))) {
1364 struct ocfs2_extent_list *el = &di->id2.i_list;
1365 le16_add_cpu(&el->l_count, -(xattrsize /
1366 sizeof(struct ocfs2_extent_rec)));
1367 }
1368 di->i_xattr_inline_size = cpu_to_le16(xattrsize);
1369 }
1370 /* Update xattr flag */
1371 spin_lock(&oi->ip_lock);
1372 oi->ip_dyn_features |= flag;
1373 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
1374 spin_unlock(&oi->ip_lock);
1375 /* Update inode ctime */
1376 inode->i_ctime = CURRENT_TIME;
1377 di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
1378 di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
1379
1380 ret = ocfs2_journal_dirty(handle, xs->inode_bh);
1381 if (ret < 0)
1382 mlog_errno(ret);
1383
1384out_commit:
1385 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1386
1387 if (!ret && xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
1388 /*
1389 * Set value outside in B tree.
1390 * This is the second step for value size > INLINE_SIZE.
1391 */
1392 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
1393 ret = ocfs2_xattr_set_value_outside(inode, xi, xs, offs);
1394 if (ret < 0) {
1395 int ret2;
1396
1397 mlog_errno(ret);
1398 /*
1399 * If set value outside failed, we have to clean
1400 * the junk tree root we have already set in local.
1401 */
1402 ret2 = ocfs2_xattr_cleanup(inode, xi, xs, offs);
1403 if (ret2 < 0)
1404 mlog_errno(ret2);
1405 }
1406 }
1407out:
1408 return ret;
1409
1410}
1411
1412static int ocfs2_xattr_free_block(handle_t *handle,
1413 struct ocfs2_super *osb,
1414 struct ocfs2_xattr_block *xb)
1415{
1416 struct inode *xb_alloc_inode;
1417 struct buffer_head *xb_alloc_bh = NULL;
1418 u64 blk = le64_to_cpu(xb->xb_blkno);
1419 u16 bit = le16_to_cpu(xb->xb_suballoc_bit);
1420 u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
1421 int ret = 0;
1422
1423 xb_alloc_inode = ocfs2_get_system_file_inode(osb,
1424 EXTENT_ALLOC_SYSTEM_INODE,
1425 le16_to_cpu(xb->xb_suballoc_slot));
1426 if (!xb_alloc_inode) {
1427 ret = -ENOMEM;
1428 mlog_errno(ret);
1429 goto out;
1430 }
1431 mutex_lock(&xb_alloc_inode->i_mutex);
1432
1433 ret = ocfs2_inode_lock(xb_alloc_inode, &xb_alloc_bh, 1);
1434 if (ret < 0) {
1435 mlog_errno(ret);
1436 goto out_mutex;
1437 }
1438 ret = ocfs2_extend_trans(handle, OCFS2_SUBALLOC_FREE);
1439 if (ret < 0) {
1440 mlog_errno(ret);
1441 goto out_unlock;
1442 }
1443 ret = ocfs2_free_suballoc_bits(handle, xb_alloc_inode, xb_alloc_bh,
1444 bit, bg_blkno, 1);
1445 if (ret < 0)
1446 mlog_errno(ret);
1447out_unlock:
1448 ocfs2_inode_unlock(xb_alloc_inode, 1);
1449 brelse(xb_alloc_bh);
1450out_mutex:
1451 mutex_unlock(&xb_alloc_inode->i_mutex);
1452 iput(xb_alloc_inode);
1453out:
1454 return ret;
1455}
1456
1457static int ocfs2_remove_value_outside(struct inode*inode,
1458 struct buffer_head *bh,
1459 struct ocfs2_xattr_header *header)
1460{
1461 int ret = 0, i;
1462
1463 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
1464 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
1465
1466 if (!ocfs2_xattr_is_local(entry)) {
1467 struct ocfs2_xattr_value_root *xv;
1468 void *val;
1469
1470 val = (void *)header +
1471 le16_to_cpu(entry->xe_name_offset);
1472 xv = (struct ocfs2_xattr_value_root *)
1473 (val + OCFS2_XATTR_SIZE(entry->xe_name_len));
1474 ret = ocfs2_xattr_value_truncate(inode, bh, xv, 0);
1475 if (ret < 0) {
1476 mlog_errno(ret);
1477 return ret;
1478 }
1479 }
1480 }
1481
1482 return ret;
1483}
1484
1485static int ocfs2_xattr_ibody_remove(struct inode *inode,
1486 struct buffer_head *di_bh)
1487{
1488
1489 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1490 struct ocfs2_xattr_header *header;
1491 int ret;
1492
1493 header = (struct ocfs2_xattr_header *)
1494 ((void *)di + inode->i_sb->s_blocksize -
1495 le16_to_cpu(di->i_xattr_inline_size));
1496
1497 ret = ocfs2_remove_value_outside(inode, di_bh, header);
1498
1499 return ret;
1500}
1501
1502static int ocfs2_xattr_block_remove(struct inode *inode,
1503 struct buffer_head *blk_bh)
1504{
1505 struct ocfs2_xattr_block *xb;
1506 struct ocfs2_xattr_header *header;
1507 int ret = 0;
1508
1509 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1510 header = &(xb->xb_attrs.xb_header);
1511
1512 ret = ocfs2_remove_value_outside(inode, blk_bh, header);
1513
1514 return ret;
1515}
1516
1517/*
1518 * ocfs2_xattr_remove()
1519 *
1520 * Free extended attribute resources associated with this inode.
1521 */
1522int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)
1523{
1524 struct ocfs2_xattr_block *xb;
1525 struct buffer_head *blk_bh = NULL;
1526 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1527 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1528 struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
1529 handle_t *handle;
1530 int ret;
1531
1532 if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL))
1533 return 0;
1534
1535 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
1536 ret = ocfs2_xattr_ibody_remove(inode, di_bh);
1537 if (ret < 0) {
1538 mlog_errno(ret);
1539 goto out;
1540 }
1541 }
1542 if (di->i_xattr_loc) {
1543 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
1544 le64_to_cpu(di->i_xattr_loc),
1545 &blk_bh, OCFS2_BH_CACHED, inode);
1546 if (ret < 0) {
1547 mlog_errno(ret);
1548 return ret;
1549 }
1550 /*Verify the signature of xattr block*/
1551 if (memcmp((void *)blk_bh->b_data, OCFS2_XATTR_BLOCK_SIGNATURE,
1552 strlen(OCFS2_XATTR_BLOCK_SIGNATURE))) {
1553 ret = -EFAULT;
1554 goto out;
1555 }
1556
1557 ret = ocfs2_xattr_block_remove(inode, blk_bh);
1558 if (ret < 0) {
1559 mlog_errno(ret);
1560 goto out;
1561 }
1562 }
1563
1564 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1565 OCFS2_INODE_UPDATE_CREDITS);
1566 if (IS_ERR(handle)) {
1567 ret = PTR_ERR(handle);
1568 mlog_errno(ret);
1569 goto out;
1570 }
1571 ret = ocfs2_journal_access(handle, inode, di_bh,
1572 OCFS2_JOURNAL_ACCESS_WRITE);
1573 if (ret) {
1574 mlog_errno(ret);
1575 goto out_commit;
1576 }
1577
1578 if (di->i_xattr_loc) {
1579 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1580 ocfs2_xattr_free_block(handle, osb, xb);
1581 di->i_xattr_loc = cpu_to_le64(0);
1582 }
1583
1584 spin_lock(&oi->ip_lock);
1585 oi->ip_dyn_features &= ~(OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL);
1586 di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
1587 spin_unlock(&oi->ip_lock);
1588
1589 ret = ocfs2_journal_dirty(handle, di_bh);
1590 if (ret < 0)
1591 mlog_errno(ret);
1592out_commit:
1593 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1594out:
1595 brelse(blk_bh);
1596
1597 return ret;
1598}
1599
1600static int ocfs2_xattr_has_space_inline(struct inode *inode,
1601 struct ocfs2_dinode *di)
1602{
1603 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1604 unsigned int xattrsize = OCFS2_SB(inode->i_sb)->s_xattr_inline_size;
1605 int free;
1606
1607 if (xattrsize < OCFS2_MIN_XATTR_INLINE_SIZE)
1608 return 0;
1609
1610 if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1611 struct ocfs2_inline_data *idata = &di->id2.i_data;
1612 free = le16_to_cpu(idata->id_count) - le64_to_cpu(di->i_size);
1613 } else if (ocfs2_inode_is_fast_symlink(inode)) {
1614 free = ocfs2_fast_symlink_chars(inode->i_sb) -
1615 le64_to_cpu(di->i_size);
1616 } else {
1617 struct ocfs2_extent_list *el = &di->id2.i_list;
1618 free = (le16_to_cpu(el->l_count) -
1619 le16_to_cpu(el->l_next_free_rec)) *
1620 sizeof(struct ocfs2_extent_rec);
1621 }
1622 if (free >= xattrsize)
1623 return 1;
1624
1625 return 0;
1626}
1627
1628/*
1629 * ocfs2_xattr_ibody_find()
1630 *
1631 * Find extended attribute in inode block and
1632 * fill search info into struct ocfs2_xattr_search.
1633 */
1634static int ocfs2_xattr_ibody_find(struct inode *inode,
1635 int name_index,
1636 const char *name,
1637 struct ocfs2_xattr_search *xs)
1638{
1639 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1640 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1641 int ret;
1642 int has_space = 0;
1643
1644 if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE)
1645 return 0;
1646
1647 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
1648 down_read(&oi->ip_alloc_sem);
1649 has_space = ocfs2_xattr_has_space_inline(inode, di);
1650 up_read(&oi->ip_alloc_sem);
1651 if (!has_space)
1652 return 0;
1653 }
1654
1655 xs->xattr_bh = xs->inode_bh;
1656 xs->end = (void *)di + inode->i_sb->s_blocksize;
1657 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)
1658 xs->header = (struct ocfs2_xattr_header *)
1659 (xs->end - le16_to_cpu(di->i_xattr_inline_size));
1660 else
1661 xs->header = (struct ocfs2_xattr_header *)
1662 (xs->end - OCFS2_SB(inode->i_sb)->s_xattr_inline_size);
1663 xs->base = (void *)xs->header;
1664 xs->here = xs->header->xh_entries;
1665
1666 /* Find the named attribute. */
1667 if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) {
1668 ret = ocfs2_xattr_find_entry(name_index, name, xs);
1669 if (ret && ret != -ENODATA)
1670 return ret;
1671 xs->not_found = ret;
1672 }
1673
1674 return 0;
1675}
1676
1677/*
1678 * ocfs2_xattr_ibody_set()
1679 *
1680 * Set, replace or remove an extended attribute into inode block.
1681 *
1682 */
1683static int ocfs2_xattr_ibody_set(struct inode *inode,
1684 struct ocfs2_xattr_info *xi,
1685 struct ocfs2_xattr_search *xs)
1686{
1687 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1688 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1689 int ret;
1690
1691 if (inode->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE)
1692 return -ENOSPC;
1693
1694 down_write(&oi->ip_alloc_sem);
1695 if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
1696 if (!ocfs2_xattr_has_space_inline(inode, di)) {
1697 ret = -ENOSPC;
1698 goto out;
1699 }
1700 }
1701
1702 ret = ocfs2_xattr_set_entry(inode, xi, xs,
1703 (OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL));
1704out:
1705 up_write(&oi->ip_alloc_sem);
1706
1707 return ret;
1708}
1709
1710/*
1711 * ocfs2_xattr_block_find()
1712 *
1713 * Find extended attribute in external block and
1714 * fill search info into struct ocfs2_xattr_search.
1715 */
1716static int ocfs2_xattr_block_find(struct inode *inode,
1717 int name_index,
1718 const char *name,
1719 struct ocfs2_xattr_search *xs)
1720{
1721 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1722 struct buffer_head *blk_bh = NULL;
589dc260 1723 struct ocfs2_xattr_block *xb;
cf1d6c76
TY
1724 int ret = 0;
1725
1726 if (!di->i_xattr_loc)
1727 return ret;
1728
1729 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
1730 le64_to_cpu(di->i_xattr_loc),
1731 &blk_bh, OCFS2_BH_CACHED, inode);
1732 if (ret < 0) {
1733 mlog_errno(ret);
1734 return ret;
1735 }
1736 /*Verify the signature of xattr block*/
1737 if (memcmp((void *)blk_bh->b_data, OCFS2_XATTR_BLOCK_SIGNATURE,
1738 strlen(OCFS2_XATTR_BLOCK_SIGNATURE))) {
1739 ret = -EFAULT;
1740 goto cleanup;
1741 }
1742
1743 xs->xattr_bh = blk_bh;
589dc260
TM
1744 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
1745
1746 if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) {
1747 xs->header = &xb->xb_attrs.xb_header;
1748 xs->base = (void *)xs->header;
1749 xs->end = (void *)(blk_bh->b_data) + blk_bh->b_size;
1750 xs->here = xs->header->xh_entries;
1751
1752 ret = ocfs2_xattr_find_entry(name_index, name, xs);
1753 } else
1754 ret = ocfs2_xattr_index_block_find(inode, blk_bh,
1755 name_index,
1756 name, xs);
cf1d6c76 1757
cf1d6c76
TY
1758 if (ret && ret != -ENODATA) {
1759 xs->xattr_bh = NULL;
1760 goto cleanup;
1761 }
1762 xs->not_found = ret;
1763 return 0;
cf1d6c76
TY
1764cleanup:
1765 brelse(blk_bh);
1766
1767 return ret;
1768}
1769
1770/*
1771 * ocfs2_xattr_block_set()
1772 *
1773 * Set, replace or remove an extended attribute into external block.
1774 *
1775 */
1776static int ocfs2_xattr_block_set(struct inode *inode,
1777 struct ocfs2_xattr_info *xi,
1778 struct ocfs2_xattr_search *xs)
1779{
1780 struct buffer_head *new_bh = NULL;
1781 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1782 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1783 struct ocfs2_alloc_context *meta_ac = NULL;
1784 handle_t *handle = NULL;
1785 struct ocfs2_xattr_block *xblk = NULL;
1786 u16 suballoc_bit_start;
1787 u32 num_got;
1788 u64 first_blkno;
1789 int ret;
1790
1791 if (!xs->xattr_bh) {
1792 /*
1793 * Alloc one external block for extended attribute
1794 * outside of inode.
1795 */
1796 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
1797 if (ret < 0) {
1798 mlog_errno(ret);
1799 goto out;
1800 }
1801 handle = ocfs2_start_trans(osb,
1802 OCFS2_XATTR_BLOCK_CREATE_CREDITS);
1803 if (IS_ERR(handle)) {
1804 ret = PTR_ERR(handle);
1805 mlog_errno(ret);
1806 goto out;
1807 }
1808 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
1809 OCFS2_JOURNAL_ACCESS_CREATE);
1810 if (ret < 0) {
1811 mlog_errno(ret);
1812 goto out_commit;
1813 }
1814
1815 ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1,
1816 &suballoc_bit_start, &num_got,
1817 &first_blkno);
1818 if (ret < 0) {
1819 mlog_errno(ret);
1820 goto out_commit;
1821 }
1822
1823 new_bh = sb_getblk(inode->i_sb, first_blkno);
1824 ocfs2_set_new_buffer_uptodate(inode, new_bh);
1825
1826 ret = ocfs2_journal_access(handle, inode, new_bh,
1827 OCFS2_JOURNAL_ACCESS_CREATE);
1828 if (ret < 0) {
1829 mlog_errno(ret);
1830 goto out_commit;
1831 }
1832
1833 /* Initialize ocfs2_xattr_block */
1834 xs->xattr_bh = new_bh;
1835 xblk = (struct ocfs2_xattr_block *)new_bh->b_data;
1836 memset(xblk, 0, inode->i_sb->s_blocksize);
1837 strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
1838 xblk->xb_suballoc_slot = cpu_to_le16(osb->slot_num);
1839 xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
1840 xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation);
1841 xblk->xb_blkno = cpu_to_le64(first_blkno);
1842
1843 xs->header = &xblk->xb_attrs.xb_header;
1844 xs->base = (void *)xs->header;
1845 xs->end = (void *)xblk + inode->i_sb->s_blocksize;
1846 xs->here = xs->header->xh_entries;
1847
1848
1849 ret = ocfs2_journal_dirty(handle, new_bh);
1850 if (ret < 0) {
1851 mlog_errno(ret);
1852 goto out_commit;
1853 }
1854 di->i_xattr_loc = cpu_to_le64(first_blkno);
1855 ret = ocfs2_journal_dirty(handle, xs->inode_bh);
1856 if (ret < 0)
1857 mlog_errno(ret);
1858out_commit:
1859 ocfs2_commit_trans(osb, handle);
1860out:
1861 if (meta_ac)
1862 ocfs2_free_alloc_context(meta_ac);
1863 if (ret < 0)
1864 return ret;
1865 }
1866
1867 /* Set extended attribute into external block */
1868 ret = ocfs2_xattr_set_entry(inode, xi, xs, OCFS2_HAS_XATTR_FL);
1869
1870 return ret;
1871}
1872
1873/*
1874 * ocfs2_xattr_set()
1875 *
1876 * Set, replace or remove an extended attribute for this inode.
1877 * value is NULL to remove an existing extended attribute, else either
1878 * create or replace an extended attribute.
1879 */
1880int ocfs2_xattr_set(struct inode *inode,
1881 int name_index,
1882 const char *name,
1883 const void *value,
1884 size_t value_len,
1885 int flags)
1886{
1887 struct buffer_head *di_bh = NULL;
1888 struct ocfs2_dinode *di;
1889 int ret;
1890
1891 struct ocfs2_xattr_info xi = {
1892 .name_index = name_index,
1893 .name = name,
1894 .value = value,
1895 .value_len = value_len,
1896 };
1897
1898 struct ocfs2_xattr_search xis = {
1899 .not_found = -ENODATA,
1900 };
1901
1902 struct ocfs2_xattr_search xbs = {
1903 .not_found = -ENODATA,
1904 };
1905
1906 ret = ocfs2_inode_lock(inode, &di_bh, 1);
1907 if (ret < 0) {
1908 mlog_errno(ret);
1909 return ret;
1910 }
1911 xis.inode_bh = xbs.inode_bh = di_bh;
1912 di = (struct ocfs2_dinode *)di_bh->b_data;
1913
1914 down_write(&OCFS2_I(inode)->ip_xattr_sem);
1915 /*
1916 * Scan inode and external block to find the same name
1917 * extended attribute and collect search infomation.
1918 */
1919 ret = ocfs2_xattr_ibody_find(inode, name_index, name, &xis);
1920 if (ret)
1921 goto cleanup;
1922 if (xis.not_found) {
1923 ret = ocfs2_xattr_block_find(inode, name_index, name, &xbs);
1924 if (ret)
1925 goto cleanup;
1926 }
1927
1928 if (xis.not_found && xbs.not_found) {
1929 ret = -ENODATA;
1930 if (flags & XATTR_REPLACE)
1931 goto cleanup;
1932 ret = 0;
1933 if (!value)
1934 goto cleanup;
1935 } else {
1936 ret = -EEXIST;
1937 if (flags & XATTR_CREATE)
1938 goto cleanup;
1939 }
1940
1941 if (!value) {
1942 /* Remove existing extended attribute */
1943 if (!xis.not_found)
1944 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
1945 else if (!xbs.not_found)
1946 ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
1947 } else {
1948 /* We always try to set extended attribute into inode first*/
1949 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
1950 if (!ret && !xbs.not_found) {
1951 /*
1952 * If succeed and that extended attribute existing in
1953 * external block, then we will remove it.
1954 */
1955 xi.value = NULL;
1956 xi.value_len = 0;
1957 ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
1958 } else if (ret == -ENOSPC) {
1959 if (di->i_xattr_loc && !xbs.xattr_bh) {
1960 ret = ocfs2_xattr_block_find(inode, name_index,
1961 name, &xbs);
1962 if (ret)
1963 goto cleanup;
1964 }
1965 /*
1966 * If no space in inode, we will set extended attribute
1967 * into external block.
1968 */
1969 ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
1970 if (ret)
1971 goto cleanup;
1972 if (!xis.not_found) {
1973 /*
1974 * If succeed and that extended attribute
1975 * existing in inode, we will remove it.
1976 */
1977 xi.value = NULL;
1978 xi.value_len = 0;
1979 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
1980 }
1981 }
1982 }
1983cleanup:
1984 up_write(&OCFS2_I(inode)->ip_xattr_sem);
1985 ocfs2_inode_unlock(inode, 1);
1986 brelse(di_bh);
1987 brelse(xbs.xattr_bh);
1988
1989 return ret;
1990}
1991
589dc260
TM
1992static inline u32 ocfs2_xattr_hash_by_name(struct inode *inode,
1993 int name_index,
1994 const char *suffix_name)
1995{
1996 struct xattr_handler *handler = ocfs2_xattr_handler(name_index);
1997 char *prefix = handler->prefix;
1998 int prefix_len = strlen(handler->prefix);
1999
2000 return ocfs2_xattr_name_hash(inode, prefix, prefix_len,
2001 (char *)suffix_name, strlen(suffix_name));
2002}
2003
0c044f0b
TM
2004/*
2005 * Find the xattr extent rec which may contains name_hash.
2006 * e_cpos will be the first name hash of the xattr rec.
2007 * el must be the ocfs2_xattr_header.xb_attrs.xb_root.xt_list.
2008 */
2009static int ocfs2_xattr_get_rec(struct inode *inode,
2010 u32 name_hash,
2011 u64 *p_blkno,
2012 u32 *e_cpos,
2013 u32 *num_clusters,
2014 struct ocfs2_extent_list *el)
2015{
2016 int ret = 0, i;
2017 struct buffer_head *eb_bh = NULL;
2018 struct ocfs2_extent_block *eb;
2019 struct ocfs2_extent_rec *rec = NULL;
2020 u64 e_blkno = 0;
2021
2022 if (el->l_tree_depth) {
2023 ret = ocfs2_find_leaf(inode, el, name_hash, &eb_bh);
2024 if (ret) {
2025 mlog_errno(ret);
2026 goto out;
2027 }
2028
2029 eb = (struct ocfs2_extent_block *) eb_bh->b_data;
2030 el = &eb->h_list;
2031
2032 if (el->l_tree_depth) {
2033 ocfs2_error(inode->i_sb,
2034 "Inode %lu has non zero tree depth in "
2035 "xattr tree block %llu\n", inode->i_ino,
2036 (unsigned long long)eb_bh->b_blocknr);
2037 ret = -EROFS;
2038 goto out;
2039 }
2040 }
2041
2042 for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
2043 rec = &el->l_recs[i];
2044
2045 if (le32_to_cpu(rec->e_cpos) <= name_hash) {
2046 e_blkno = le64_to_cpu(rec->e_blkno);
2047 break;
2048 }
2049 }
2050
2051 if (!e_blkno) {
2052 ocfs2_error(inode->i_sb, "Inode %lu has bad extent "
2053 "record (%u, %u, 0) in xattr", inode->i_ino,
2054 le32_to_cpu(rec->e_cpos),
2055 ocfs2_rec_clusters(el, rec));
2056 ret = -EROFS;
2057 goto out;
2058 }
2059
2060 *p_blkno = le64_to_cpu(rec->e_blkno);
2061 *num_clusters = le16_to_cpu(rec->e_leaf_clusters);
2062 if (e_cpos)
2063 *e_cpos = le32_to_cpu(rec->e_cpos);
2064out:
2065 brelse(eb_bh);
2066 return ret;
2067}
2068
2069typedef int (xattr_bucket_func)(struct inode *inode,
2070 struct ocfs2_xattr_bucket *bucket,
2071 void *para);
2072
589dc260
TM
2073static int ocfs2_find_xe_in_bucket(struct inode *inode,
2074 struct buffer_head *header_bh,
2075 int name_index,
2076 const char *name,
2077 u32 name_hash,
2078 u16 *xe_index,
2079 int *found)
2080{
2081 int i, ret = 0, cmp = 1, block_off, new_offset;
2082 struct ocfs2_xattr_header *xh =
2083 (struct ocfs2_xattr_header *)header_bh->b_data;
2084 size_t name_len = strlen(name);
2085 struct ocfs2_xattr_entry *xe = NULL;
2086 struct buffer_head *name_bh = NULL;
2087 char *xe_name;
2088
2089 /*
2090 * We don't use binary search in the bucket because there
2091 * may be multiple entries with the same name hash.
2092 */
2093 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
2094 xe = &xh->xh_entries[i];
2095
2096 if (name_hash > le32_to_cpu(xe->xe_name_hash))
2097 continue;
2098 else if (name_hash < le32_to_cpu(xe->xe_name_hash))
2099 break;
2100
2101 cmp = name_index - ocfs2_xattr_get_type(xe);
2102 if (!cmp)
2103 cmp = name_len - xe->xe_name_len;
2104 if (cmp)
2105 continue;
2106
2107 ret = ocfs2_xattr_bucket_get_name_value(inode,
2108 xh,
2109 i,
2110 &block_off,
2111 &new_offset);
2112 if (ret) {
2113 mlog_errno(ret);
2114 break;
2115 }
2116
2117 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
2118 header_bh->b_blocknr + block_off,
2119 &name_bh, OCFS2_BH_CACHED, inode);
2120 if (ret) {
2121 mlog_errno(ret);
2122 break;
2123 }
2124 xe_name = name_bh->b_data + new_offset;
2125
2126 cmp = memcmp(name, xe_name, name_len);
2127 brelse(name_bh);
2128 name_bh = NULL;
2129
2130 if (cmp == 0) {
2131 *xe_index = i;
2132 *found = 1;
2133 ret = 0;
2134 break;
2135 }
2136 }
2137
2138 return ret;
2139}
2140
2141/*
2142 * Find the specified xattr entry in a series of buckets.
2143 * This series start from p_blkno and last for num_clusters.
2144 * The ocfs2_xattr_header.xh_num_buckets of the first bucket contains
2145 * the num of the valid buckets.
2146 *
2147 * Return the buffer_head this xattr should reside in. And if the xattr's
2148 * hash is in the gap of 2 buckets, return the lower bucket.
2149 */
2150static int ocfs2_xattr_bucket_find(struct inode *inode,
2151 int name_index,
2152 const char *name,
2153 u32 name_hash,
2154 u64 p_blkno,
2155 u32 first_hash,
2156 u32 num_clusters,
2157 struct ocfs2_xattr_search *xs)
2158{
2159 int ret, found = 0;
2160 struct buffer_head *bh = NULL;
2161 struct buffer_head *lower_bh = NULL;
2162 struct ocfs2_xattr_header *xh = NULL;
2163 struct ocfs2_xattr_entry *xe = NULL;
2164 u16 index = 0;
2165 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2166 int low_bucket = 0, bucket, high_bucket;
2167 u32 last_hash;
2168 u64 blkno;
2169
2170 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), p_blkno,
2171 &bh, OCFS2_BH_CACHED, inode);
2172 if (ret) {
2173 mlog_errno(ret);
2174 goto out;
2175 }
2176
2177 xh = (struct ocfs2_xattr_header *)bh->b_data;
2178 high_bucket = le16_to_cpu(xh->xh_num_buckets) - 1;
2179
2180 while (low_bucket <= high_bucket) {
2181 brelse(bh);
2182 bh = NULL;
2183 bucket = (low_bucket + high_bucket) / 2;
2184
2185 blkno = p_blkno + bucket * blk_per_bucket;
2186
2187 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), blkno,
2188 &bh, OCFS2_BH_CACHED, inode);
2189 if (ret) {
2190 mlog_errno(ret);
2191 goto out;
2192 }
2193
2194 xh = (struct ocfs2_xattr_header *)bh->b_data;
2195 xe = &xh->xh_entries[0];
2196 if (name_hash < le32_to_cpu(xe->xe_name_hash)) {
2197 high_bucket = bucket - 1;
2198 continue;
2199 }
2200
2201 /*
2202 * Check whether the hash of the last entry in our
2203 * bucket is larger than the search one.
2204 */
2205 xe = &xh->xh_entries[le16_to_cpu(xh->xh_count) - 1];
2206 last_hash = le32_to_cpu(xe->xe_name_hash);
2207
2208 /* record lower_bh which may be the insert place. */
2209 brelse(lower_bh);
2210 lower_bh = bh;
2211 bh = NULL;
2212
2213 if (name_hash > le32_to_cpu(xe->xe_name_hash)) {
2214 low_bucket = bucket + 1;
2215 continue;
2216 }
2217
2218 /* the searched xattr should reside in this bucket if exists. */
2219 ret = ocfs2_find_xe_in_bucket(inode, lower_bh,
2220 name_index, name, name_hash,
2221 &index, &found);
2222 if (ret) {
2223 mlog_errno(ret);
2224 goto out;
2225 }
2226 break;
2227 }
2228
2229 /*
2230 * Record the bucket we have found.
2231 * When the xattr's hash value is in the gap of 2 buckets, we will
2232 * always set it to the previous bucket.
2233 */
2234 if (!lower_bh) {
2235 /*
2236 * We can't find any bucket whose first name_hash is less
2237 * than the find name_hash.
2238 */
2239 BUG_ON(bh->b_blocknr != p_blkno);
2240 lower_bh = bh;
2241 bh = NULL;
2242 }
2243 xs->bucket.bhs[0] = lower_bh;
2244 xs->bucket.xh = (struct ocfs2_xattr_header *)
2245 xs->bucket.bhs[0]->b_data;
2246 lower_bh = NULL;
2247
2248 xs->header = xs->bucket.xh;
2249 xs->base = xs->bucket.bhs[0]->b_data;
2250 xs->end = xs->base + inode->i_sb->s_blocksize;
2251
2252 if (found) {
2253 /*
2254 * If we have found the xattr enty, read all the blocks in
2255 * this bucket.
2256 */
2257 ret = ocfs2_read_blocks(OCFS2_SB(inode->i_sb),
2258 xs->bucket.bhs[0]->b_blocknr + 1,
2259 blk_per_bucket - 1, &xs->bucket.bhs[1],
2260 OCFS2_BH_CACHED, inode);
2261 if (ret) {
2262 mlog_errno(ret);
2263 goto out;
2264 }
2265
2266 xs->here = &xs->header->xh_entries[index];
2267 mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name,
2268 (unsigned long long)xs->bucket.bhs[0]->b_blocknr, index);
2269 } else
2270 ret = -ENODATA;
2271
2272out:
2273 brelse(bh);
2274 brelse(lower_bh);
2275 return ret;
2276}
2277
2278static int ocfs2_xattr_index_block_find(struct inode *inode,
2279 struct buffer_head *root_bh,
2280 int name_index,
2281 const char *name,
2282 struct ocfs2_xattr_search *xs)
2283{
2284 int ret;
2285 struct ocfs2_xattr_block *xb =
2286 (struct ocfs2_xattr_block *)root_bh->b_data;
2287 struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root;
2288 struct ocfs2_extent_list *el = &xb_root->xt_list;
2289 u64 p_blkno = 0;
2290 u32 first_hash, num_clusters = 0;
2291 u32 name_hash = ocfs2_xattr_hash_by_name(inode, name_index, name);
2292
2293 if (le16_to_cpu(el->l_next_free_rec) == 0)
2294 return -ENODATA;
2295
2296 mlog(0, "find xattr %s, hash = %u, index = %d in xattr tree\n",
2297 name, name_hash, name_index);
2298
2299 ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &first_hash,
2300 &num_clusters, el);
2301 if (ret) {
2302 mlog_errno(ret);
2303 goto out;
2304 }
2305
2306 BUG_ON(p_blkno == 0 || num_clusters == 0 || first_hash > name_hash);
2307
2308 mlog(0, "find xattr extent rec %u clusters from %llu, the first hash "
2309 "in the rec is %u\n", num_clusters, p_blkno, first_hash);
2310
2311 ret = ocfs2_xattr_bucket_find(inode, name_index, name, name_hash,
2312 p_blkno, first_hash, num_clusters, xs);
2313
2314out:
2315 return ret;
2316}
2317
0c044f0b
TM
2318static int ocfs2_iterate_xattr_buckets(struct inode *inode,
2319 u64 blkno,
2320 u32 clusters,
2321 xattr_bucket_func *func,
2322 void *para)
2323{
2324 int i, j, ret = 0;
2325 int blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2326 u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
2327 u32 num_buckets = clusters * bpc;
2328 struct ocfs2_xattr_bucket bucket;
2329
2330 memset(&bucket, 0, sizeof(bucket));
2331
2332 mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n",
2333 clusters, blkno);
2334
2335 for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) {
2336 ret = ocfs2_read_blocks(OCFS2_SB(inode->i_sb),
2337 blkno, blk_per_bucket,
2338 bucket.bhs, OCFS2_BH_CACHED, inode);
2339 if (ret) {
2340 mlog_errno(ret);
2341 goto out;
2342 }
2343
2344 bucket.xh = (struct ocfs2_xattr_header *)bucket.bhs[0]->b_data;
2345 /*
2346 * The real bucket num in this series of blocks is stored
2347 * in the 1st bucket.
2348 */
2349 if (i == 0)
2350 num_buckets = le16_to_cpu(bucket.xh->xh_num_buckets);
2351
2352 mlog(0, "iterating xattr bucket %llu\n", blkno);
2353 if (func) {
2354 ret = func(inode, &bucket, para);
2355 if (ret) {
2356 mlog_errno(ret);
2357 break;
2358 }
2359 }
2360
2361 for (j = 0; j < blk_per_bucket; j++)
2362 brelse(bucket.bhs[j]);
2363 memset(&bucket, 0, sizeof(bucket));
2364 }
2365
2366out:
2367 for (j = 0; j < blk_per_bucket; j++)
2368 brelse(bucket.bhs[j]);
2369
2370 return ret;
2371}
2372
2373struct ocfs2_xattr_tree_list {
2374 char *buffer;
2375 size_t buffer_size;
2376};
2377
2378static int ocfs2_xattr_bucket_get_name_value(struct inode *inode,
2379 struct ocfs2_xattr_header *xh,
2380 int index,
2381 int *block_off,
2382 int *new_offset)
2383{
2384 u16 name_offset;
2385
2386 if (index < 0 || index >= le16_to_cpu(xh->xh_count))
2387 return -EINVAL;
2388
2389 name_offset = le16_to_cpu(xh->xh_entries[index].xe_name_offset);
2390
2391 *block_off = name_offset >> inode->i_sb->s_blocksize_bits;
2392 *new_offset = name_offset % inode->i_sb->s_blocksize;
2393
2394 return 0;
2395}
2396
2397static int ocfs2_list_xattr_bucket(struct inode *inode,
2398 struct ocfs2_xattr_bucket *bucket,
2399 void *para)
2400{
2401 int ret = 0;
2402 struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para;
2403 size_t size;
2404 int i, block_off, new_offset;
2405
2406 for (i = 0 ; i < le16_to_cpu(bucket->xh->xh_count); i++) {
2407 struct ocfs2_xattr_entry *entry = &bucket->xh->xh_entries[i];
2408 struct xattr_handler *handler =
2409 ocfs2_xattr_handler(ocfs2_xattr_get_type(entry));
2410
2411 if (handler) {
2412 ret = ocfs2_xattr_bucket_get_name_value(inode,
2413 bucket->xh,
2414 i,
2415 &block_off,
2416 &new_offset);
2417 if (ret)
2418 break;
2419 size = handler->list(inode, xl->buffer, xl->buffer_size,
2420 bucket->bhs[block_off]->b_data +
2421 new_offset,
2422 entry->xe_name_len);
2423 if (xl->buffer) {
2424 if (size > xl->buffer_size)
2425 return -ERANGE;
2426 xl->buffer += size;
2427 }
2428 xl->buffer_size -= size;
2429 }
2430 }
2431
2432 return ret;
2433}
2434
2435static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
2436 struct ocfs2_xattr_tree_root *xt,
2437 char *buffer,
2438 size_t buffer_size)
2439{
2440 struct ocfs2_extent_list *el = &xt->xt_list;
2441 int ret = 0;
2442 u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0;
2443 u64 p_blkno = 0;
2444 struct ocfs2_xattr_tree_list xl = {
2445 .buffer = buffer,
2446 .buffer_size = buffer_size,
2447 };
2448
2449 if (le16_to_cpu(el->l_next_free_rec) == 0)
2450 return 0;
2451
2452 while (name_hash > 0) {
2453 ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno,
2454 &e_cpos, &num_clusters, el);
2455 if (ret) {
2456 mlog_errno(ret);
2457 goto out;
2458 }
2459
2460 ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters,
2461 ocfs2_list_xattr_bucket,
2462 &xl);
2463 if (ret) {
2464 mlog_errno(ret);
2465 goto out;
2466 }
2467
2468 if (e_cpos == 0)
2469 break;
2470
2471 name_hash = e_cpos - 1;
2472 }
2473
2474 ret = buffer_size - xl.buffer_size;
2475out:
2476 return ret;
2477}
This page took 0.120743 seconds and 5 git commands to generate.