static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { struct kernfs_iattrs *attrs; struct iattr *iattrs; unsigned int ia_valid = iattr->ia_valid; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; iattrs = &attrs->ia_iattr; if (ia_valid & ATTR_UID) iattrs->ia_uid = iattr->ia_uid; if (ia_valid & ATTR_GID) iattrs->ia_gid = iattr->ia_gid; if (ia_valid & ATTR_ATIME) iattrs->ia_atime = iattr->ia_atime; if (ia_valid & ATTR_MTIME) iattrs->ia_mtime = iattr->ia_mtime; if (ia_valid & ATTR_CTIME) iattrs->ia_ctime = iattr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = iattr->ia_mode; iattrs->ia_mode = kn->mode = mode; } return 0; }
static int kernfs_security_xattr_set(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) { struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; void *secdata; u32 secdata_len = 0; int error; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; error = security_inode_setsecurity(inode, suffix, value, size, flags); if (error) return error; error = security_inode_getsecctx(inode, &secdata, &secdata_len); if (error) return error; mutex_lock(&kernfs_mutex); error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); return error; }
ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_list(&attrs->xattrs, buf, size); }
int kernfs_iop_removexattr(struct dentry *dentry, const char *name) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_remove(&attrs->xattrs, name); }
ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) { struct kernfs_node *kn = kernfs_dentry_node(dentry); struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size); }
ssize_t kernfs_iop_getxattr(struct dentry *dentry, const char *name, void *buf, size_t size) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_get(&attrs->xattrs, name, buf, size); }
ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode, const char *name, void *buf, size_t size) { struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_get(&attrs->xattrs, name, buf, size); }
static int kernfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *suffix, void *value, size_t size) { const char *name = xattr_full_name(handler, suffix); struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; return simple_xattr_get(&attrs->xattrs, name, value, size); }
static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, u32 *secdata_len) { struct kernfs_iattrs *attrs; void *old_secdata; size_t old_secdata_len; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; old_secdata = attrs->ia_secdata; old_secdata_len = attrs->ia_secdata_len; attrs->ia_secdata = *secdata; attrs->ia_secdata_len = *secdata_len; *secdata = old_secdata; *secdata_len = old_secdata_len; return 0; }
int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; void *secdata; int error; u32 secdata_len = 0; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) { const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; error = security_inode_setsecurity(dentry->d_inode, suffix, value, size, flags); if (error) return error; error = security_inode_getsecctx(dentry->d_inode, &secdata, &secdata_len); if (error) return error; mutex_lock(&kernfs_mutex); error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); return error; } else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { return simple_xattr_set(&attrs->xattrs, name, value, size, flags); } return -EINVAL; }