diff options
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r-- | fs/ocfs2/xattr.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 2e273c2cb831..3cc8385f9738 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -84,6 +84,10 @@ struct ocfs2_xattr_set_ctxt { | |||
84 | #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ | 84 | #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ |
85 | - sizeof(struct ocfs2_xattr_header) \ | 85 | - sizeof(struct ocfs2_xattr_header) \ |
86 | - sizeof(__u32)) | 86 | - sizeof(__u32)) |
87 | #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ | ||
88 | - sizeof(struct ocfs2_xattr_block) \ | ||
89 | - sizeof(struct ocfs2_xattr_header) \ | ||
90 | - sizeof(__u32)) | ||
87 | 91 | ||
88 | static struct ocfs2_xattr_def_value_root def_xv = { | 92 | static struct ocfs2_xattr_def_value_root def_xv = { |
89 | .xv.xr_list.l_count = cpu_to_le16(1), | 93 | .xv.xr_list.l_count = cpu_to_le16(1), |
@@ -402,6 +406,81 @@ int ocfs2_calc_security_init(struct inode *dir, | |||
402 | return ret; | 406 | return ret; |
403 | } | 407 | } |
404 | 408 | ||
409 | int ocfs2_calc_xattr_init(struct inode *dir, | ||
410 | struct buffer_head *dir_bh, | ||
411 | int mode, | ||
412 | struct ocfs2_security_xattr_info *si, | ||
413 | int *want_clusters, | ||
414 | int *xattr_credits, | ||
415 | struct ocfs2_alloc_context **xattr_ac) | ||
416 | { | ||
417 | int ret = 0; | ||
418 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | ||
419 | int s_size = 0; | ||
420 | int a_size = 0; | ||
421 | int acl_len = 0; | ||
422 | |||
423 | if (si->enable) | ||
424 | s_size = ocfs2_xattr_entry_real_size(strlen(si->name), | ||
425 | si->value_len); | ||
426 | |||
427 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { | ||
428 | acl_len = ocfs2_xattr_get_nolock(dir, dir_bh, | ||
429 | OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT, | ||
430 | "", NULL, 0); | ||
431 | if (acl_len > 0) { | ||
432 | a_size = ocfs2_xattr_entry_real_size(0, acl_len); | ||
433 | if (S_ISDIR(mode)) | ||
434 | a_size <<= 1; | ||
435 | } else if (acl_len != 0 && acl_len != -ENODATA) { | ||
436 | mlog_errno(ret); | ||
437 | return ret; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | if (!(s_size + a_size)) | ||
442 | return ret; | ||
443 | |||
444 | /* | ||
445 | * The max space of security xattr taken inline is | ||
446 | * 256(name) + 80(value) + 16(entry) = 352 bytes, | ||
447 | * The max space of acl xattr taken inline is | ||
448 | * 80(value) + 16(entry) * 2(if directory) = 192 bytes, | ||
449 | * when blocksize = 512, may reserve one more cluser for | ||
450 | * xattr bucket, otherwise reserve one metadata block | ||
451 | * for them is ok. | ||
452 | */ | ||
453 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || | ||
454 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { | ||
455 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); | ||
456 | if (ret) { | ||
457 | mlog_errno(ret); | ||
458 | return ret; | ||
459 | } | ||
460 | *xattr_credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS; | ||
461 | } | ||
462 | |||
463 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE && | ||
464 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_BLOCK(dir)) { | ||
465 | *want_clusters += 1; | ||
466 | *xattr_credits += ocfs2_blocks_per_xattr_bucket(dir->i_sb); | ||
467 | } | ||
468 | |||
469 | /* reserve clusters for xattr value which will be set in B tree*/ | ||
470 | if (si->enable && si->value_len > OCFS2_XATTR_INLINE_SIZE) | ||
471 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, | ||
472 | si->value_len); | ||
473 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL && | ||
474 | acl_len > OCFS2_XATTR_INLINE_SIZE) { | ||
475 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, acl_len); | ||
476 | if (S_ISDIR(mode)) | ||
477 | *want_clusters += ocfs2_clusters_for_bytes(dir->i_sb, | ||
478 | acl_len); | ||
479 | } | ||
480 | |||
481 | return ret; | ||
482 | } | ||
483 | |||
405 | static int ocfs2_xattr_extend_allocation(struct inode *inode, | 484 | static int ocfs2_xattr_extend_allocation(struct inode *inode, |
406 | u32 clusters_to_add, | 485 | u32 clusters_to_add, |
407 | struct buffer_head *xattr_bh, | 486 | struct buffer_head *xattr_bh, |