/** * Remove an attribute from the table. * * The key is only used for lookups, only the hashed elements need to be * filled in. * * @return TRUE if we found the attribute and removed it. */ static bool xattr_table_remove_key(xattr_table_t *xat, const struct xattr *key) { struct xattr *old; xattr_table_check(xat); g_assert(key != NULL); old = xattr_table_lookup_key(xat, key); if (old != NULL) { hash_list_remove(xat->hl, old); xattr_free(old); return TRUE; } else { return FALSE; } }
/** * Insert an attribute to the table. * * If the attribute already existed, the value is replaced so that the * older position is kept. Otherwsie, the new attribute is appended to the * list of existing attributes. * * @return TRUE when we create a new attribute, FALSE if we replaced the * value of an existing one. */ static bool xattr_table_insert(xattr_table_t *xat, struct xattr *xa) { struct xattr *old; xattr_table_check(xat); g_assert(xa != NULL); old = xattr_table_lookup_key(xat, xa); if (old != NULL) { HFREE_NULL(old->value); old->value = xa->value; xa->value = NULL; xattr_free(xa); return FALSE; } else { hash_list_append(xat->hl, xa); return TRUE; } }
/*Not Working Yet*/ static int copyup_xattrs(struct dentry *old_hidden_dentry, struct dentry *new_hidden_dentry) { int err = 0; ssize_t list_size = -1; char *name_list = NULL; char *attr_value = NULL; char *name_list_orig = NULL; print_entry_location(); PASSERT(old_hidden_dentry); PASSERT(old_hidden_dentry->d_inode); PASSERT(old_hidden_dentry->d_inode->i_op); PASSERT(new_hidden_dentry); PASSERT(new_hidden_dentry->d_inode); PASSERT(new_hidden_dentry->d_inode->i_op); if (!old_hidden_dentry->d_inode->i_op->getxattr || !old_hidden_dentry->d_inode->i_op->listxattr || !new_hidden_dentry->d_inode->i_op->setxattr) { err = -ENOTSUPP; goto out; } list_size = old_hidden_dentry->d_inode->i_op->listxattr(old_hidden_dentry, NULL, 0); if (list_size <= 0) { err = list_size; goto out; } name_list = xattr_alloc(list_size + 1, XATTR_LIST_MAX); if (!name_list || IS_ERR(name_list)) { err = PTR_ERR(name_list); goto out; } list_size = old_hidden_dentry->d_inode->i_op->listxattr(old_hidden_dentry, name_list, list_size); attr_value = xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX); if (!attr_value || IS_ERR(attr_value)) { err = PTR_ERR(name_list); goto out; } name_list_orig = name_list; while (*name_list) { ssize_t size; down(&old_hidden_dentry->d_inode->i_sem); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) err = security_inode_getxattr(old_hidden_dentry, name_list); if (err) size = err; else #endif size = old_hidden_dentry->d_inode->i_op-> getxattr(old_hidden_dentry, name_list, attr_value, XATTR_SIZE_MAX); up(&old_hidden_dentry->d_inode->i_sem); if (size < 0) { err = size; goto out; } if (size > XATTR_SIZE_MAX) { err = -E2BIG; goto out; } down(&new_hidden_dentry->d_inode->i_sem); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) err = security_inode_setxattr(old_hidden_dentry, name_list, attr_value, size, 0); if (!err) { #endif err = new_hidden_dentry->d_inode->i_op-> setxattr(new_hidden_dentry, name_list, attr_value, size, 0); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) if (!err) security_inode_post_setxattr(old_hidden_dentry, name_list, attr_value, size, 0); } #endif up(&new_hidden_dentry->d_inode->i_sem); if (err < 0) goto out; name_list += strlen(name_list) + 1; } out: name_list = name_list_orig; if (name_list) xattr_free(name_list, list_size + 1); if (attr_value) xattr_free(attr_value, XATTR_SIZE_MAX); /* It is no big deal if this fails, we just roll with the punches. */ if (err == -ENOTSUPP) err = 0; return err; }