diff options
Diffstat (limited to 'fs/kernfs')
-rw-r--r-- | fs/kernfs/dir.c | 9 | ||||
-rw-r--r-- | fs/kernfs/file.c | 19 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 14 |
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, | |||
608 | static int kernfs_fop_open(struct inode *inode, struct file *file) | 610 | static 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 | ||
49 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | 49 | static 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 | 72 | out_unlock: | |
69 | return kn->iattr; | 73 | ret = kn->iattr; |
74 | mutex_unlock(&iattr_mutex); | ||
75 | return ret; | ||
70 | } | 76 | } |
71 | 77 | ||
72 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) | 78 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) |