aboutsummaryrefslogtreecommitdiffstats
path: root/fs/kernfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/kernfs')
-rw-r--r--fs/kernfs/dir.c9
-rw-r--r--fs/kernfs/file.c19
-rw-r--r--fs/kernfs/inode.c14
3 files changed, 28 insertions, 14 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 78f3403300af..ac127cd008bf 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -232,9 +232,6 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
232 struct rb_node **node = &kn->parent->dir.children.rb_node; 232 struct rb_node **node = &kn->parent->dir.children.rb_node;
233 struct rb_node *parent = NULL; 233 struct rb_node *parent = NULL;
234 234
235 if (kernfs_type(kn) == KERNFS_DIR)
236 kn->parent->dir.subdirs++;
237
238 while (*node) { 235 while (*node) {
239 struct kernfs_node *pos; 236 struct kernfs_node *pos;
240 int result; 237 int result;
@@ -249,9 +246,15 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
249 else 246 else
250 return -EEXIST; 247 return -EEXIST;
251 } 248 }
249
252 /* add new node and rebalance the tree */ 250 /* add new node and rebalance the tree */
253 rb_link_node(&kn->rb, parent, node); 251 rb_link_node(&kn->rb, parent, node);
254 rb_insert_color(&kn->rb, &kn->parent->dir.children); 252 rb_insert_color(&kn->rb, &kn->parent->dir.children);
253
254 /* successfully added, account subdir number */
255 if (kernfs_type(kn) == KERNFS_DIR)
256 kn->parent->dir.subdirs++;
257
255 return 0; 258 return 0;
256} 259}
257 260
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 8034706a7af8..5e9a80cfc3d8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -484,6 +484,8 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma)
484 484
485 ops = kernfs_ops(of->kn); 485 ops = kernfs_ops(of->kn);
486 rc = ops->mmap(of, vma); 486 rc = ops->mmap(of, vma);
487 if (rc)
488 goto out_put;
487 489
488 /* 490 /*
489 * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup() 491 * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup()
@@ -608,6 +610,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn,
608static int kernfs_fop_open(struct inode *inode, struct file *file) 610static int kernfs_fop_open(struct inode *inode, struct file *file)
609{ 611{
610 struct kernfs_node *kn = file->f_path.dentry->d_fsdata; 612 struct kernfs_node *kn = file->f_path.dentry->d_fsdata;
613 struct kernfs_root *root = kernfs_root(kn);
611 const struct kernfs_ops *ops; 614 const struct kernfs_ops *ops;
612 struct kernfs_open_file *of; 615 struct kernfs_open_file *of;
613 bool has_read, has_write, has_mmap; 616 bool has_read, has_write, has_mmap;
@@ -622,14 +625,16 @@ static int kernfs_fop_open(struct inode *inode, struct file *file)
622 has_write = ops->write || ops->mmap; 625 has_write = ops->write || ops->mmap;
623 has_mmap = ops->mmap; 626 has_mmap = ops->mmap;
624 627
625 /* check perms and supported operations */ 628 /* see the flag definition for details */
626 if ((file->f_mode & FMODE_WRITE) && 629 if (root->flags & KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK) {
627 (!(inode->i_mode & S_IWUGO) || !has_write)) 630 if ((file->f_mode & FMODE_WRITE) &&
628 goto err_out; 631 (!(inode->i_mode & S_IWUGO) || !has_write))
632 goto err_out;
629 633
630 if ((file->f_mode & FMODE_READ) && 634 if ((file->f_mode & FMODE_READ) &&
631 (!(inode->i_mode & S_IRUGO) || !has_read)) 635 (!(inode->i_mode & S_IRUGO) || !has_read))
632 goto err_out; 636 goto err_out;
637 }
633 638
634 /* allocate a kernfs_open_file for the file */ 639 /* allocate a kernfs_open_file for the file */
635 error = -ENOMEM; 640 error = -ENOMEM;
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index abb0f1f53d93..985217626e66 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -48,14 +48,18 @@ void __init kernfs_inode_init(void)
48 48
49static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) 49static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
50{ 50{
51 static DEFINE_MUTEX(iattr_mutex);
52 struct kernfs_iattrs *ret;
51 struct iattr *iattrs; 53 struct iattr *iattrs;
52 54
55 mutex_lock(&iattr_mutex);
56
53 if (kn->iattr) 57 if (kn->iattr)
54 return kn->iattr; 58 goto out_unlock;
55 59
56 kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); 60 kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL);
57 if (!kn->iattr) 61 if (!kn->iattr)
58 return NULL; 62 goto out_unlock;
59 iattrs = &kn->iattr->ia_iattr; 63 iattrs = &kn->iattr->ia_iattr;
60 64
61 /* assign default attributes */ 65 /* assign default attributes */
@@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
65 iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; 69 iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
66 70
67 simple_xattrs_init(&kn->iattr->xattrs); 71 simple_xattrs_init(&kn->iattr->xattrs);
68 72out_unlock:
69 return kn->iattr; 73 ret = kn->iattr;
74 mutex_unlock(&iattr_mutex);
75 return ret;
70} 76}
71 77
72static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) 78static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)