1603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim/** 2603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * xattr.c 3603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * 4603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Many parts of codes are copied from Linux kernel/fs/f2fs. 5603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * 6603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Copyright (C) 2015 Huawei Ltd. 7603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Witten by: 8603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Hou Pengyang <houpengyang@huawei.com> 9603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Liu Shuoran <liushuoran@huawei.com> 10603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Jaegeuk Kim <jaegeuk@kernel.org> 11603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * 12603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * This program is free software; you can redistribute it and/or modify 13603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * it under the terms of the GNU General Public License version 2 as 14603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * published by the Free Software Foundation. 15603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim */ 16603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim#include "fsck.h" 17603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim#include "node.h" 18603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim#include "xattr.h" 19603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 20603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim#define XATTR_CREATE 0x1 21603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim#define XATTR_REPLACE 0x2 22603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 23603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimstatic void *read_all_xattrs(struct f2fs_sb_info *sbi, struct f2fs_node *inode) 24603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim{ 25603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_xattr_header *header; 26603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim void *txattr_addr; 27603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim u64 inline_size = inline_xattr_size(&inode->i); 28603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 29603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim txattr_addr = calloc(inline_size + BLOCK_SZ, 1); 30603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(txattr_addr); 31603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 32603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (inline_size) 33603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memcpy(txattr_addr, inline_xattr_addr(&inode->i), inline_size); 34603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 35603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* Read from xattr node block. */ 36603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (inode->i.i_xattr_nid) { 37603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct node_info ni; 38603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int ret; 39603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 40603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim get_node_info(sbi, le32_to_cpu(inode->i.i_xattr_nid), &ni); 41603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ret = dev_read_block(txattr_addr + inline_size, ni.blk_addr); 42603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(ret >= 0); 43603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 44603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 45603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim header = XATTR_HDR(txattr_addr); 46603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 47603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* Never been allocated xattrs */ 48603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) { 49603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC); 50603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim header->h_refcount = cpu_to_le32(1); 51603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 52603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return txattr_addr; 53603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim} 54603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 55603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimstatic struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index, 56603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim size_t len, const char *name) 57603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim{ 58603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_xattr_entry *entry; 59603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim list_for_each_xattr(entry, base_addr) { 60603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (entry->e_name_index != index) 61603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim continue; 62603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (entry->e_name_len != len) 63603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim continue; 64603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (!memcmp(entry->e_name, name, len)) 65603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim break; 66603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 67603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return entry; 68603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim} 69603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 70603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimstatic void write_all_xattrs(struct f2fs_sb_info *sbi, 71603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_node *inode, __u32 hsize, void *txattr_addr) 72603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim{ 73603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim void *xattr_addr; 74603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct dnode_of_data dn; 75603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct node_info ni; 76603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_node *xattr_node; 77603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim nid_t new_nid = 0; 78603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim block_t blkaddr; 79603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim nid_t xnid = le32_to_cpu(inode->i.i_xattr_nid); 80603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim u64 inline_size = inline_xattr_size(&inode->i); 81603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int ret; 82603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 83603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(inode->i.i_inline & F2FS_INLINE_XATTR); 84603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memcpy(inline_xattr_addr(&inode->i), txattr_addr, inline_size); 85603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 86603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (hsize <= inline_size) 87603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return; 88603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 89603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (!xnid) { 90603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim f2fs_alloc_nid(sbi, &new_nid, 0); 91603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 92603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim set_new_dnode(&dn, inode, NULL, new_nid); 93603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* NAT entry would be updated by new_node_page. */ 94603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim blkaddr = new_node_block(sbi, &dn, XATTR_NODE_OFFSET); 95603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(dn.node_blk); 96603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim xattr_node = dn.node_blk; 97603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim inode->i.i_xattr_nid = cpu_to_le32(new_nid); 98603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } else { 99603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim set_new_dnode(&dn, inode, NULL, xnid); 100603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim get_node_info(sbi, xnid, &ni); 101603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim blkaddr = ni.blk_addr; 102603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim xattr_node = calloc(BLOCK_SZ, 1); 103603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(xattr_node); 104603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ret = dev_read_block(xattr_node, ni.blk_addr); 105603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(ret >= 0); 106603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 107603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 108603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* write to xattr node block */ 109603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim xattr_addr = (void *)xattr_node; 110603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memcpy(xattr_addr, txattr_addr + inline_size, 111603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim PAGE_SIZE - sizeof(struct node_footer)); 112603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 113603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ret = dev_write_block(xattr_node, blkaddr); 114603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(ret >= 0); 115603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim} 116603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 117603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimint f2fs_setxattr(struct f2fs_sb_info *sbi, nid_t ino, int index, const char *name, 118603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim const void *value, size_t size, int flags) 119603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim{ 120603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_node *inode; 121603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim void *base_addr; 122603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_xattr_entry *here, *last; 123603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct node_info ni; 124603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int error = 0; 125603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int len; 126603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int found, newsize; 127603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim __u32 new_hsize; 128603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int ret; 129603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 130603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (name == NULL) 131603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return -EINVAL; 132603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 133603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (value == NULL) 134603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return -EINVAL; 135603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 136603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim len = strlen(name); 137603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 138603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (len > F2FS_NAME_LEN || size > MAX_VALUE_LEN) 139603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return -ERANGE; 140603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 141603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (ino < 3) 142603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return -EINVAL; 143603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 144603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* Now We just support selinux */ 145603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(index == F2FS_XATTR_INDEX_SECURITY); 146603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 147603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim get_node_info(sbi, ino, &ni); 148603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim inode = calloc(BLOCK_SZ, 1); 149603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(inode); 150603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ret = dev_read_block(inode, ni.blk_addr); 151603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(ret >= 0); 152603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 153603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim base_addr = read_all_xattrs(sbi, inode); 154603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(base_addr); 155603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 156603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim here = __find_xattr(base_addr, index, len, name); 157603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 158603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; 159603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 160603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if ((flags & XATTR_REPLACE) && !found) { 161603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim error = -ENODATA; 162603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim goto exit; 163603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } else if ((flags & XATTR_CREATE) && found) { 164603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim error = -EEXIST; 165603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim goto exit; 166603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 167603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 168603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last = here; 169603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim while (!IS_XATTR_LAST_ENTRY(last)) 170603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last = XATTR_NEXT_ENTRY(last); 171603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 172603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size); 173603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 174603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 1. Check space */ 175603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (value) { 176603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int free; 177603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 178603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * If value is NULL, it is remove operation. 179603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * In case of update operation, we calculate free. 180603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim */ 181603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim free = MIN_OFFSET - ((char *)last - (char *)base_addr); 182603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (found) 183603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim free = free + ENTRY_SIZE(here); 184603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (free < newsize) { 185603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim error = -ENOSPC; 186603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim goto exit; 187603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 188603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 189603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 190603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 2. Remove old entry */ 191603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (found) { 192603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 193603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * If entry if sound, remove old entry. 194603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * If not found, remove operation is not needed 195603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim */ 196603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here); 197603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim int oldsize = ENTRY_SIZE(here); 198603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 199603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memmove(here, next, (char *)last - (char *)next); 200603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last = (struct f2fs_xattr_entry *)((char *)last - oldsize); 201603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memset(last, 0, oldsize); 202603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 203603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 204603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 205603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim new_hsize = (char *)last - (char *)base_addr; 206603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 207603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 3. Write new entry */ 208603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (value) { 209603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim char *pval; 210603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* 211603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * Before we come here, old entry is removed. 212603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim * We just write new entry. 213603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim */ 214603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memset(last, 0, newsize); 215603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last->e_name_index = index; 216603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last->e_name_len = len; 217603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memcpy(last->e_name, name, len); 218603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim pval = last->e_name + len; 219603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim memcpy(pval, value, size); 220603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim last->e_value_size = cpu_to_le16(size); 221603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim new_hsize += newsize; 222603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim } 223603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 224603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim write_all_xattrs(sbi, inode, new_hsize, base_addr); 225603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 226603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim /* inode need update */ 227603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ret = dev_write_block(inode, ni.blk_addr); 228603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim ASSERT(ret >= 0); 229603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimexit: 230603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim free(base_addr); 231603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return error; 232603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim} 233603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 234603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kimint inode_set_selinux(struct f2fs_sb_info *sbi, u32 ino, const char *secon) 235603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim{ 236603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim if (!secon) 237603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return 0; 238603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim 239603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim return f2fs_setxattr(sbi, ino, F2FS_XATTR_INDEX_SECURITY, 240603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim XATTR_SELINUX_SUFFIX, secon, strlen(secon), 1); 241603f8f9d3628e8b81fea301e5f543a9f0b0d902dJaegeuk Kim} 242