static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); size_t size = 0; char *value = NULL; int rc, xprefix; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; switch (type) { case ACL_TYPE_ACCESS: xprefix = JFFS2_XPREFIX_ACL_ACCESS; if (acl) { mode_t mode = inode->i_mode; rc = posix_acl_equiv_mode(acl, &mode); if (rc < 0) return rc; if (inode->i_mode != mode) { inode->i_mode = mode; jffs2_dirty_inode(inode); } if (rc == 0) acl = NULL; } break; case ACL_TYPE_DEFAULT: xprefix = JFFS2_XPREFIX_ACL_DEFAULT; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; default: return -EINVAL; } if (acl) { value = jffs2_acl_to_medium(acl, &size); if (IS_ERR(value)) return PTR_ERR(value); } rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0); if (!value && rc == -ENODATA) rc = 0; if (value) kfree(value); if (!rc) { switch(type) { case ACL_TYPE_ACCESS: jffs2_iset_acl(inode, &f->i_acl_access, acl); break; case ACL_TYPE_DEFAULT: jffs2_iset_acl(inode, &f->i_acl_default, acl); break; } } return rc; }
static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *acl) { char *value = NULL; size_t size = 0; int rc; if (acl) { value = jffs2_acl_to_medium(acl, &size); if (IS_ERR(value)) return PTR_ERR(value); } rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0); if (!value && rc == -ENODATA) rc = 0; kfree(value); return rc; }