155716d26SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2b8441ed2STejun Heo /* 3b8441ed2STejun Heo * fs/kernfs/inode.c - kernfs inode implementation 4b8441ed2STejun Heo * 5b8441ed2STejun Heo * Copyright (c) 2001-3 Patrick Mochel 6b8441ed2STejun Heo * Copyright (c) 2007 SUSE Linux Products GmbH 7b8441ed2STejun Heo * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org> 8b8441ed2STejun Heo */ 9ffed24e2STejun Heo 10ffed24e2STejun Heo #include <linux/pagemap.h> 11ffed24e2STejun Heo #include <linux/backing-dev.h> 12ffed24e2STejun Heo #include <linux/capability.h> 13ffed24e2STejun Heo #include <linux/errno.h> 14ffed24e2STejun Heo #include <linux/slab.h> 15ffed24e2STejun Heo #include <linux/xattr.h> 16ffed24e2STejun Heo #include <linux/security.h> 17ffed24e2STejun Heo 18ffed24e2STejun Heo #include "kernfs-internal.h" 19ffed24e2STejun Heo 20a797bfc3STejun Heo static const struct address_space_operations kernfs_aops = { 21ffed24e2STejun Heo .readpage = simple_readpage, 22ffed24e2STejun Heo .write_begin = simple_write_begin, 23ffed24e2STejun Heo .write_end = simple_write_end, 24ffed24e2STejun Heo }; 25ffed24e2STejun Heo 26a797bfc3STejun Heo static const struct inode_operations kernfs_iops = { 27c637b8acSTejun Heo .permission = kernfs_iop_permission, 28c637b8acSTejun Heo .setattr = kernfs_iop_setattr, 29c637b8acSTejun Heo .getattr = kernfs_iop_getattr, 30c637b8acSTejun Heo .listxattr = kernfs_iop_listxattr, 31ffed24e2STejun Heo }; 32ffed24e2STejun Heo 33d0c9c153SOndrej Mosnacek static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, int alloc) 34ffed24e2STejun Heo { 354afddd60STejun Heo static DEFINE_MUTEX(iattr_mutex); 364afddd60STejun Heo struct kernfs_iattrs *ret; 37ffed24e2STejun Heo 384afddd60STejun Heo mutex_lock(&iattr_mutex); 394afddd60STejun Heo 40d0c9c153SOndrej Mosnacek if (kn->iattr || !alloc) 414afddd60STejun Heo goto out_unlock; 429a8049afSTejun Heo 4326e28d68SAyush Mittal kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL); 44adc5e8b5STejun Heo if (!kn->iattr) 454afddd60STejun Heo goto out_unlock; 46ffed24e2STejun Heo 47ffed24e2STejun Heo /* assign default attributes */ 4805895219SOndrej Mosnacek kn->iattr->ia_uid = GLOBAL_ROOT_UID; 4905895219SOndrej Mosnacek kn->iattr->ia_gid = GLOBAL_ROOT_GID; 503a3a5fecSDeepa Dinamani 5105895219SOndrej Mosnacek ktime_get_real_ts64(&kn->iattr->ia_atime); 5205895219SOndrej Mosnacek kn->iattr->ia_mtime = kn->iattr->ia_atime; 5305895219SOndrej Mosnacek kn->iattr->ia_ctime = kn->iattr->ia_atime; 54ffed24e2STejun Heo 55adc5e8b5STejun Heo simple_xattrs_init(&kn->iattr->xattrs); 564afddd60STejun Heo out_unlock: 574afddd60STejun Heo ret = kn->iattr; 584afddd60STejun Heo mutex_unlock(&iattr_mutex); 594afddd60STejun Heo return ret; 60ffed24e2STejun Heo } 61ffed24e2STejun Heo 62d0c9c153SOndrej Mosnacek static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) 63d0c9c153SOndrej Mosnacek { 64d0c9c153SOndrej Mosnacek return __kernfs_iattrs(kn, 1); 65d0c9c153SOndrej Mosnacek } 66d0c9c153SOndrej Mosnacek 67d0c9c153SOndrej Mosnacek static struct kernfs_iattrs *kernfs_iattrs_noalloc(struct kernfs_node *kn) 68d0c9c153SOndrej Mosnacek { 69d0c9c153SOndrej Mosnacek return __kernfs_iattrs(kn, 0); 70d0c9c153SOndrej Mosnacek } 71d0c9c153SOndrej Mosnacek 72488dee96SDmitry Torokhov int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) 73ffed24e2STejun Heo { 74c525aaddSTejun Heo struct kernfs_iattrs *attrs; 75ffed24e2STejun Heo unsigned int ia_valid = iattr->ia_valid; 76ffed24e2STejun Heo 77c525aaddSTejun Heo attrs = kernfs_iattrs(kn); 789a8049afSTejun Heo if (!attrs) 79ffed24e2STejun Heo return -ENOMEM; 809a8049afSTejun Heo 81ffed24e2STejun Heo if (ia_valid & ATTR_UID) 8205895219SOndrej Mosnacek attrs->ia_uid = iattr->ia_uid; 83ffed24e2STejun Heo if (ia_valid & ATTR_GID) 8405895219SOndrej Mosnacek attrs->ia_gid = iattr->ia_gid; 85ffed24e2STejun Heo if (ia_valid & ATTR_ATIME) 8605895219SOndrej Mosnacek attrs->ia_atime = iattr->ia_atime; 87ffed24e2STejun Heo if (ia_valid & ATTR_MTIME) 8805895219SOndrej Mosnacek attrs->ia_mtime = iattr->ia_mtime; 89ffed24e2STejun Heo if (ia_valid & ATTR_CTIME) 9005895219SOndrej Mosnacek attrs->ia_ctime = iattr->ia_ctime; 9105895219SOndrej Mosnacek if (ia_valid & ATTR_MODE) 9205895219SOndrej Mosnacek kn->mode = iattr->ia_mode; 93ffed24e2STejun Heo return 0; 94ffed24e2STejun Heo } 95ffed24e2STejun Heo 96ffed24e2STejun Heo /** 97ffed24e2STejun Heo * kernfs_setattr - set iattr on a node 98324a56e1STejun Heo * @kn: target node 99ffed24e2STejun Heo * @iattr: iattr to set 100ffed24e2STejun Heo * 101ffed24e2STejun Heo * Returns 0 on success, -errno on failure. 102ffed24e2STejun Heo */ 103324a56e1STejun Heo int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) 104ffed24e2STejun Heo { 105ffed24e2STejun Heo int ret; 106ffed24e2STejun Heo 107a797bfc3STejun Heo mutex_lock(&kernfs_mutex); 108324a56e1STejun Heo ret = __kernfs_setattr(kn, iattr); 109a797bfc3STejun Heo mutex_unlock(&kernfs_mutex); 110ffed24e2STejun Heo return ret; 111ffed24e2STejun Heo } 112ffed24e2STejun Heo 113c637b8acSTejun Heo int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr) 114ffed24e2STejun Heo { 1152b0143b5SDavid Howells struct inode *inode = d_inode(dentry); 116319ba91dSShaohua Li struct kernfs_node *kn = inode->i_private; 117ffed24e2STejun Heo int error; 118ffed24e2STejun Heo 119324a56e1STejun Heo if (!kn) 120ffed24e2STejun Heo return -EINVAL; 121ffed24e2STejun Heo 122a797bfc3STejun Heo mutex_lock(&kernfs_mutex); 12331051c85SJan Kara error = setattr_prepare(dentry, iattr); 124ffed24e2STejun Heo if (error) 125ffed24e2STejun Heo goto out; 126ffed24e2STejun Heo 127324a56e1STejun Heo error = __kernfs_setattr(kn, iattr); 128ffed24e2STejun Heo if (error) 129ffed24e2STejun Heo goto out; 130ffed24e2STejun Heo 131ffed24e2STejun Heo /* this ignores size changes */ 132ffed24e2STejun Heo setattr_copy(inode, iattr); 133ffed24e2STejun Heo 134ffed24e2STejun Heo out: 135a797bfc3STejun Heo mutex_unlock(&kernfs_mutex); 136ffed24e2STejun Heo return error; 137ffed24e2STejun Heo } 138ffed24e2STejun Heo 139c637b8acSTejun Heo ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) 1402322392bSTejun Heo { 141319ba91dSShaohua Li struct kernfs_node *kn = kernfs_dentry_node(dentry); 142c525aaddSTejun Heo struct kernfs_iattrs *attrs; 1432322392bSTejun Heo 144c525aaddSTejun Heo attrs = kernfs_iattrs(kn); 1452322392bSTejun Heo if (!attrs) 1462322392bSTejun Heo return -ENOMEM; 1472322392bSTejun Heo 148786534b9SAndreas Gruenbacher return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size); 149ffed24e2STejun Heo } 150ffed24e2STejun Heo 151ffed24e2STejun Heo static inline void set_default_inode_attr(struct inode *inode, umode_t mode) 152ffed24e2STejun Heo { 153ffed24e2STejun Heo inode->i_mode = mode; 1543a3a5fecSDeepa Dinamani inode->i_atime = inode->i_mtime = 155c2050a45SDeepa Dinamani inode->i_ctime = current_time(inode); 156ffed24e2STejun Heo } 157ffed24e2STejun Heo 15805895219SOndrej Mosnacek static inline void set_inode_attr(struct inode *inode, 15905895219SOndrej Mosnacek struct kernfs_iattrs *attrs) 160ffed24e2STejun Heo { 16105895219SOndrej Mosnacek inode->i_uid = attrs->ia_uid; 16205895219SOndrej Mosnacek inode->i_gid = attrs->ia_gid; 163f0f3588fSAl Viro inode->i_atime = attrs->ia_atime; 164f0f3588fSAl Viro inode->i_mtime = attrs->ia_mtime; 165f0f3588fSAl Viro inode->i_ctime = attrs->ia_ctime; 166ffed24e2STejun Heo } 167ffed24e2STejun Heo 168c637b8acSTejun Heo static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) 169ffed24e2STejun Heo { 170c525aaddSTejun Heo struct kernfs_iattrs *attrs = kn->iattr; 171ffed24e2STejun Heo 172adc5e8b5STejun Heo inode->i_mode = kn->mode; 1730ac6075aSOndrej Mosnacek if (attrs) 174324a56e1STejun Heo /* 175324a56e1STejun Heo * kernfs_node has non-default attributes get them from 176324a56e1STejun Heo * persistent copy in kernfs_node. 177ffed24e2STejun Heo */ 17805895219SOndrej Mosnacek set_inode_attr(inode, attrs); 179ffed24e2STejun Heo 180df23fc39STejun Heo if (kernfs_type(kn) == KERNFS_DIR) 181adc5e8b5STejun Heo set_nlink(inode, kn->dir.subdirs + 2); 182ffed24e2STejun Heo } 183ffed24e2STejun Heo 184a528d35eSDavid Howells int kernfs_iop_getattr(const struct path *path, struct kstat *stat, 185a528d35eSDavid Howells u32 request_mask, unsigned int query_flags) 186ffed24e2STejun Heo { 187a528d35eSDavid Howells struct inode *inode = d_inode(path->dentry); 188319ba91dSShaohua Li struct kernfs_node *kn = inode->i_private; 189ffed24e2STejun Heo 190a797bfc3STejun Heo mutex_lock(&kernfs_mutex); 191c637b8acSTejun Heo kernfs_refresh_inode(kn, inode); 192a797bfc3STejun Heo mutex_unlock(&kernfs_mutex); 193ffed24e2STejun Heo 194ffed24e2STejun Heo generic_fillattr(inode, stat); 195ffed24e2STejun Heo return 0; 196ffed24e2STejun Heo } 197ffed24e2STejun Heo 198c637b8acSTejun Heo static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode) 199ffed24e2STejun Heo { 200324a56e1STejun Heo kernfs_get(kn); 201324a56e1STejun Heo inode->i_private = kn; 202a797bfc3STejun Heo inode->i_mapping->a_ops = &kernfs_aops; 203a797bfc3STejun Heo inode->i_op = &kernfs_iops; 20467c0496eSTejun Heo inode->i_generation = kernfs_gen(kn); 205ffed24e2STejun Heo 206adc5e8b5STejun Heo set_default_inode_attr(inode, kn->mode); 207c637b8acSTejun Heo kernfs_refresh_inode(kn, inode); 208ffed24e2STejun Heo 209ffed24e2STejun Heo /* initialize inode according to type */ 210df23fc39STejun Heo switch (kernfs_type(kn)) { 211df23fc39STejun Heo case KERNFS_DIR: 212a797bfc3STejun Heo inode->i_op = &kernfs_dir_iops; 213a797bfc3STejun Heo inode->i_fop = &kernfs_dir_fops; 214ea015218SEric W. Biederman if (kn->flags & KERNFS_EMPTY_DIR) 215ea015218SEric W. Biederman make_empty_dir_inode(inode); 216ffed24e2STejun Heo break; 217df23fc39STejun Heo case KERNFS_FILE: 218adc5e8b5STejun Heo inode->i_size = kn->attr.size; 219a797bfc3STejun Heo inode->i_fop = &kernfs_file_fops; 220ffed24e2STejun Heo break; 221df23fc39STejun Heo case KERNFS_LINK: 222a797bfc3STejun Heo inode->i_op = &kernfs_symlink_iops; 223ffed24e2STejun Heo break; 224ffed24e2STejun Heo default: 225ffed24e2STejun Heo BUG(); 226ffed24e2STejun Heo } 227ffed24e2STejun Heo 228ffed24e2STejun Heo unlock_new_inode(inode); 229ffed24e2STejun Heo } 230ffed24e2STejun Heo 231ffed24e2STejun Heo /** 232c637b8acSTejun Heo * kernfs_get_inode - get inode for kernfs_node 233ffed24e2STejun Heo * @sb: super block 234324a56e1STejun Heo * @kn: kernfs_node to allocate inode for 235ffed24e2STejun Heo * 236324a56e1STejun Heo * Get inode for @kn. If such inode doesn't exist, a new inode is 237324a56e1STejun Heo * allocated and basics are initialized. New inode is returned 238324a56e1STejun Heo * locked. 239ffed24e2STejun Heo * 240ffed24e2STejun Heo * LOCKING: 241ffed24e2STejun Heo * Kernel thread context (may sleep). 242ffed24e2STejun Heo * 243ffed24e2STejun Heo * RETURNS: 244ffed24e2STejun Heo * Pointer to allocated inode on success, NULL on failure. 245ffed24e2STejun Heo */ 246c637b8acSTejun Heo struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn) 247ffed24e2STejun Heo { 248ffed24e2STejun Heo struct inode *inode; 249ffed24e2STejun Heo 25067c0496eSTejun Heo inode = iget_locked(sb, kernfs_ino(kn)); 251ffed24e2STejun Heo if (inode && (inode->i_state & I_NEW)) 252c637b8acSTejun Heo kernfs_init_inode(kn, inode); 253ffed24e2STejun Heo 254ffed24e2STejun Heo return inode; 255ffed24e2STejun Heo } 256ffed24e2STejun Heo 257ffed24e2STejun Heo /* 258c637b8acSTejun Heo * The kernfs_node serves as both an inode and a directory entry for 259c637b8acSTejun Heo * kernfs. To prevent the kernfs inode numbers from being freed 260c637b8acSTejun Heo * prematurely we take a reference to kernfs_node from the kernfs inode. A 261ffed24e2STejun Heo * super_operations.evict_inode() implementation is needed to drop that 262ffed24e2STejun Heo * reference upon inode destruction. 263ffed24e2STejun Heo */ 264c637b8acSTejun Heo void kernfs_evict_inode(struct inode *inode) 265ffed24e2STejun Heo { 266324a56e1STejun Heo struct kernfs_node *kn = inode->i_private; 267ffed24e2STejun Heo 26891b0abe3SJohannes Weiner truncate_inode_pages_final(&inode->i_data); 269ffed24e2STejun Heo clear_inode(inode); 270324a56e1STejun Heo kernfs_put(kn); 271ffed24e2STejun Heo } 272ffed24e2STejun Heo 273c637b8acSTejun Heo int kernfs_iop_permission(struct inode *inode, int mask) 274ffed24e2STejun Heo { 275324a56e1STejun Heo struct kernfs_node *kn; 276ffed24e2STejun Heo 277ffed24e2STejun Heo if (mask & MAY_NOT_BLOCK) 278ffed24e2STejun Heo return -ECHILD; 279ffed24e2STejun Heo 280324a56e1STejun Heo kn = inode->i_private; 281ffed24e2STejun Heo 282a797bfc3STejun Heo mutex_lock(&kernfs_mutex); 283c637b8acSTejun Heo kernfs_refresh_inode(kn, inode); 284a797bfc3STejun Heo mutex_unlock(&kernfs_mutex); 285ffed24e2STejun Heo 286ffed24e2STejun Heo return generic_permission(inode, mask); 287ffed24e2STejun Heo } 288e72a1a8bSAndreas Gruenbacher 2891537ad15SOndrej Mosnacek int kernfs_xattr_get(struct kernfs_node *kn, const char *name, 290b230d5abSOndrej Mosnacek void *value, size_t size) 291e72a1a8bSAndreas Gruenbacher { 2921537ad15SOndrej Mosnacek struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn); 293e72a1a8bSAndreas Gruenbacher if (!attrs) 294d0c9c153SOndrej Mosnacek return -ENODATA; 295e72a1a8bSAndreas Gruenbacher 296e72a1a8bSAndreas Gruenbacher return simple_xattr_get(&attrs->xattrs, name, value, size); 297e72a1a8bSAndreas Gruenbacher } 298e72a1a8bSAndreas Gruenbacher 2991537ad15SOndrej Mosnacek int kernfs_xattr_set(struct kernfs_node *kn, const char *name, 300b230d5abSOndrej Mosnacek const void *value, size_t size, int flags) 301e72a1a8bSAndreas Gruenbacher { 3021537ad15SOndrej Mosnacek struct kernfs_iattrs *attrs = kernfs_iattrs(kn); 303e72a1a8bSAndreas Gruenbacher if (!attrs) 304e72a1a8bSAndreas Gruenbacher return -ENOMEM; 305e72a1a8bSAndreas Gruenbacher 306e72a1a8bSAndreas Gruenbacher return simple_xattr_set(&attrs->xattrs, name, value, size, flags); 307e72a1a8bSAndreas Gruenbacher } 308e72a1a8bSAndreas Gruenbacher 3091537ad15SOndrej Mosnacek static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, 310b230d5abSOndrej Mosnacek struct dentry *unused, struct inode *inode, 311b230d5abSOndrej Mosnacek const char *suffix, void *value, size_t size) 312b230d5abSOndrej Mosnacek { 3131537ad15SOndrej Mosnacek const char *name = xattr_full_name(handler, suffix); 314b230d5abSOndrej Mosnacek struct kernfs_node *kn = inode->i_private; 315b230d5abSOndrej Mosnacek 3161537ad15SOndrej Mosnacek return kernfs_xattr_get(kn, name, value, size); 317b230d5abSOndrej Mosnacek } 318b230d5abSOndrej Mosnacek 3191537ad15SOndrej Mosnacek static int kernfs_vfs_xattr_set(const struct xattr_handler *handler, 320b230d5abSOndrej Mosnacek struct dentry *unused, struct inode *inode, 321b230d5abSOndrej Mosnacek const char *suffix, const void *value, 322b230d5abSOndrej Mosnacek size_t size, int flags) 323b230d5abSOndrej Mosnacek { 3241537ad15SOndrej Mosnacek const char *name = xattr_full_name(handler, suffix); 325b230d5abSOndrej Mosnacek struct kernfs_node *kn = inode->i_private; 326b230d5abSOndrej Mosnacek 3271537ad15SOndrej Mosnacek return kernfs_xattr_set(kn, name, value, size, flags); 328b230d5abSOndrej Mosnacek } 329b230d5abSOndrej Mosnacek 330b5a06234SBart Van Assche static const struct xattr_handler kernfs_trusted_xattr_handler = { 331e72a1a8bSAndreas Gruenbacher .prefix = XATTR_TRUSTED_PREFIX, 3321537ad15SOndrej Mosnacek .get = kernfs_vfs_xattr_get, 3331537ad15SOndrej Mosnacek .set = kernfs_vfs_xattr_set, 334e72a1a8bSAndreas Gruenbacher }; 335e72a1a8bSAndreas Gruenbacher 336b5a06234SBart Van Assche static const struct xattr_handler kernfs_security_xattr_handler = { 337e72a1a8bSAndreas Gruenbacher .prefix = XATTR_SECURITY_PREFIX, 3381537ad15SOndrej Mosnacek .get = kernfs_vfs_xattr_get, 3391537ad15SOndrej Mosnacek .set = kernfs_vfs_xattr_set, 340e72a1a8bSAndreas Gruenbacher }; 341e72a1a8bSAndreas Gruenbacher 342e72a1a8bSAndreas Gruenbacher const struct xattr_handler *kernfs_xattr_handlers[] = { 343e72a1a8bSAndreas Gruenbacher &kernfs_trusted_xattr_handler, 344e72a1a8bSAndreas Gruenbacher &kernfs_security_xattr_handler, 345e72a1a8bSAndreas Gruenbacher NULL 346e72a1a8bSAndreas Gruenbacher }; 347