diff options
-rw-r--r-- | fs/kernfs/dir.c | 38 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 2 | ||||
-rw-r--r-- | include/linux/kernfs.h | 3 |
3 files changed, 42 insertions, 1 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index fffca9517321..2d48d28e1640 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -592,6 +592,9 @@ int kernfs_add_one(struct kernfs_node *kn) | |||
592 | goto out_unlock; | 592 | goto out_unlock; |
593 | 593 | ||
594 | ret = -ENOENT; | 594 | ret = -ENOENT; |
595 | if (parent->flags & KERNFS_EMPTY_DIR) | ||
596 | goto out_unlock; | ||
597 | |||
595 | if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent)) | 598 | if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent)) |
596 | goto out_unlock; | 599 | goto out_unlock; |
597 | 600 | ||
@@ -783,6 +786,38 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, | |||
783 | return ERR_PTR(rc); | 786 | return ERR_PTR(rc); |
784 | } | 787 | } |
785 | 788 | ||
789 | /** | ||
790 | * kernfs_create_empty_dir - create an always empty directory | ||
791 | * @parent: parent in which to create a new directory | ||
792 | * @name: name of the new directory | ||
793 | * | ||
794 | * Returns the created node on success, ERR_PTR() value on failure. | ||
795 | */ | ||
796 | struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, | ||
797 | const char *name) | ||
798 | { | ||
799 | struct kernfs_node *kn; | ||
800 | int rc; | ||
801 | |||
802 | /* allocate */ | ||
803 | kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR); | ||
804 | if (!kn) | ||
805 | return ERR_PTR(-ENOMEM); | ||
806 | |||
807 | kn->flags |= KERNFS_EMPTY_DIR; | ||
808 | kn->dir.root = parent->dir.root; | ||
809 | kn->ns = NULL; | ||
810 | kn->priv = NULL; | ||
811 | |||
812 | /* link in */ | ||
813 | rc = kernfs_add_one(kn); | ||
814 | if (!rc) | ||
815 | return kn; | ||
816 | |||
817 | kernfs_put(kn); | ||
818 | return ERR_PTR(rc); | ||
819 | } | ||
820 | |||
786 | static struct dentry *kernfs_iop_lookup(struct inode *dir, | 821 | static struct dentry *kernfs_iop_lookup(struct inode *dir, |
787 | struct dentry *dentry, | 822 | struct dentry *dentry, |
788 | unsigned int flags) | 823 | unsigned int flags) |
@@ -1254,7 +1289,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, | |||
1254 | mutex_lock(&kernfs_mutex); | 1289 | mutex_lock(&kernfs_mutex); |
1255 | 1290 | ||
1256 | error = -ENOENT; | 1291 | error = -ENOENT; |
1257 | if (!kernfs_active(kn) || !kernfs_active(new_parent)) | 1292 | if (!kernfs_active(kn) || !kernfs_active(new_parent) || |
1293 | (new_parent->flags & KERNFS_EMPTY_DIR)) | ||
1258 | goto out; | 1294 | goto out; |
1259 | 1295 | ||
1260 | error = 0; | 1296 | error = 0; |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 2da8493a380b..756dd56aaf60 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -296,6 +296,8 @@ static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode) | |||
296 | case KERNFS_DIR: | 296 | case KERNFS_DIR: |
297 | inode->i_op = &kernfs_dir_iops; | 297 | inode->i_op = &kernfs_dir_iops; |
298 | inode->i_fop = &kernfs_dir_fops; | 298 | inode->i_fop = &kernfs_dir_fops; |
299 | if (kn->flags & KERNFS_EMPTY_DIR) | ||
300 | make_empty_dir_inode(inode); | ||
299 | break; | 301 | break; |
300 | case KERNFS_FILE: | 302 | case KERNFS_FILE: |
301 | inode->i_size = kn->attr.size; | 303 | inode->i_size = kn->attr.size; |
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index 71ecdab1671b..29d1896c3ba5 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
@@ -45,6 +45,7 @@ enum kernfs_node_flag { | |||
45 | KERNFS_LOCKDEP = 0x0100, | 45 | KERNFS_LOCKDEP = 0x0100, |
46 | KERNFS_SUICIDAL = 0x0400, | 46 | KERNFS_SUICIDAL = 0x0400, |
47 | KERNFS_SUICIDED = 0x0800, | 47 | KERNFS_SUICIDED = 0x0800, |
48 | KERNFS_EMPTY_DIR = 0x1000, | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | /* @flags for kernfs_create_root() */ | 51 | /* @flags for kernfs_create_root() */ |
@@ -285,6 +286,8 @@ void kernfs_destroy_root(struct kernfs_root *root); | |||
285 | struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, | 286 | struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, |
286 | const char *name, umode_t mode, | 287 | const char *name, umode_t mode, |
287 | void *priv, const void *ns); | 288 | void *priv, const void *ns); |
289 | struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, | ||
290 | const char *name); | ||
288 | struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, | 291 | struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, |
289 | const char *name, | 292 | const char *name, |
290 | umode_t mode, loff_t size, | 293 | umode_t mode, loff_t size, |