/* * inode->i_mutex: don't care */ struct posix_acl * ext2_get_acl(struct inode *inode, int type) { int name_index; char *value = NULL; struct posix_acl *acl; int retval; switch (type) { case ACL_TYPE_ACCESS: name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: BUG(); } retval = ext2_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { value = kmalloc(retval, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); retval = ext2_xattr_get(inode, name_index, "", value, retval); } if (retval > 0) acl = ext2_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; else acl = ERR_PTR(retval); kfree(value); return acl; }
/* * inode->i_sem: don't care */ static struct posix_acl * ext2_get_acl(struct inode *inode, int type) { struct ext2_inode_info *ei = EXT2_I(inode); int name_index; char *value = NULL; struct posix_acl *acl; int retval; if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; switch(type) { case ACL_TYPE_ACCESS: acl = ext2_iget_acl(inode, &ei->i_acl); if (acl != EXT2_ACL_NOT_CACHED) return acl; name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: acl = ext2_iget_acl(inode, &ei->i_default_acl); if (acl != EXT2_ACL_NOT_CACHED) return acl; name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } retval = ext2_xattr_get(inode, name_index, "", NULL, 0); if (retval > 0) { value = kmalloc(retval, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); retval = ext2_xattr_get(inode, name_index, "", value, retval); } if (retval > 0) acl = ext2_acl_from_disk(value, retval); else if (retval == -ENODATA || retval == -ENOSYS) acl = NULL; else acl = ERR_PTR(retval); if (value) kfree(value); if (!IS_ERR(acl)) { switch(type) { case ACL_TYPE_ACCESS: ext2_iset_acl(inode, &ei->i_acl, acl); break; case ACL_TYPE_DEFAULT: ext2_iset_acl(inode, &ei->i_default_acl, acl); break; } } return acl; }
void ext2_delete_from_parent(struct inode * inode) { int *value, *new_value, retval, count, *temp, *temp1; unsigned long parent_ino; struct inode * parent_inode; // ext2_debug("%lu: Looking for parent\n", inode->i_ino); retval = ext2_xattr_get(inode, 10, "parent", NULL, 0); if(retval > 0) { // ext2_debug("%lu: retval > 0\n", inode->i_ino); retval = ext2_xattr_get(inode, 10, "parent", &parent_ino, sizeof(unsigned long)); // ext2_debug("%lu: Found parent %lu\n", inode->i_ino, parent_ino); parent_inode = iget(inode->i_sb, parent_ino); if(!parent_inode) return; retval = ext2_xattr_get(parent_inode, 11, "children", NULL, 0); if (retval > 0) { value = (int *)kmalloc(retval, GFP_KERNEL); new_value = (int *)kmalloc(retval, GFP_KERNEL); temp = value; temp1 = new_value; retval = ext2_xattr_get(parent_inode, 11, "children", value, retval); count = 0; while(*value) { if(*value != (int)(inode->i_ino)) { *new_value = *value; new_value++; count++; } else { // ext2_debug("%lu: deleting %d from parent list\n", parent_inode->i_ino, *value); } value++; } // ext2_debug("%lu: parent has %d children left\n", parent_inode->i_ino, count); *new_value = 0; ext2_xattr_set(parent_inode, 11, "children", temp1, (count+1)*sizeof(int), 0); if(!count) { // delete inode } cleanup: kfree(temp); kfree(temp1); iput(parent_inode); /* This should take care of dropping root when it has no children */ } } else { // ext2_debug("no parent found\n"); return; } }
static int ext2_xattr_security_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *buffer, size_t size) { return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name, buffer, size); }
static int ext2_xattr_trusted_get(const struct xattr_handler *handler, struct dentry *dentry, const char *name, void *buffer, size_t size) { return ext2_xattr_get(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name, buffer, size); }
static int ext2_xattr_security_get(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { if (strcmp(name, "") == 0) return -EINVAL; return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name, buffer, size); }
static int ext2_xattr_trusted_get(struct inode *inode, const char *name, void *buffer, size_t size) { if (strcmp(name, "") == 0) return -EINVAL; return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, buffer, size); }
static int ext2_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size) { if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); }
int ext2_inode_has_parent(struct inode *inode) { int retval, *value; retval = ext2_xattr_get(inode, 10, "parent", NULL, 0); if(retval > 0) { value = kmalloc(retval, GFP_KERNEL); if (!value) return -ENOMEM; ext2_xattr_get(inode, 10, "parent", value, retval); if(!value) { return 0; } // ext2_debug ("%lu: parent inode number = %d\n", inode->i_ino, *value); retval = *value; kfree(value); return retval; } return 0; }
static int ext2_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size) { int error; if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; error = permission(inode, MAY_READ, NULL); if (error) return error; return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); }
int ext2_inode_has_children(struct inode *inode) { int retval; retval = ext2_xattr_get(inode, 11, "children", NULL, 0); if(retval > 0 && retval > sizeof(int)) { // ext2_debug("retval is %d\n", retval); // ext2_debug("size of int %d\n", sizeof(int)); return 1; } else { // ext2_debug("no children, retval = %d\n", retval); return 0; } }