diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-05-13 17:09:29 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2015-07-01 11:36:43 -0400 |
commit | ea015218f2f7ace2dad9cedd21ed95bdba2886d7 (patch) | |
tree | 9ab4dc58398a5ef08b174871a9cc587680261b65 /fs/kernfs/dir.c | |
parent | eb6d38d5427b3ad42f5268da0f1dd31bb0af1264 (diff) |
kernfs: Add support for always empty directories.
Add a new function kernfs_create_empty_dir that can be used to create
directory that can not be modified.
Update the code to use make_empty_dir_inode when reporting a
permanently empty directory to the vfs.
Update the code to not allow adding to permanently empty directories.
Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/kernfs/dir.c')
-rw-r--r-- | fs/kernfs/dir.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index f131fc23ffc4..47dc636d80ed 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -585,6 +585,9 @@ int kernfs_add_one(struct kernfs_node *kn) | |||
585 | goto out_unlock; | 585 | goto out_unlock; |
586 | 586 | ||
587 | ret = -ENOENT; | 587 | ret = -ENOENT; |
588 | if (parent->flags & KERNFS_EMPTY_DIR) | ||
589 | goto out_unlock; | ||
590 | |||
588 | if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent)) | 591 | if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent)) |
589 | goto out_unlock; | 592 | goto out_unlock; |
590 | 593 | ||
@@ -776,6 +779,38 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, | |||
776 | return ERR_PTR(rc); | 779 | return ERR_PTR(rc); |
777 | } | 780 | } |
778 | 781 | ||
782 | /** | ||
783 | * kernfs_create_empty_dir - create an always empty directory | ||
784 | * @parent: parent in which to create a new directory | ||
785 | * @name: name of the new directory | ||
786 | * | ||
787 | * Returns the created node on success, ERR_PTR() value on failure. | ||
788 | */ | ||
789 | struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, | ||
790 | const char *name) | ||
791 | { | ||
792 | struct kernfs_node *kn; | ||
793 | int rc; | ||
794 | |||
795 | /* allocate */ | ||
796 | kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR); | ||
797 | if (!kn) | ||
798 | return ERR_PTR(-ENOMEM); | ||
799 | |||
800 | kn->flags |= KERNFS_EMPTY_DIR; | ||
801 | kn->dir.root = parent->dir.root; | ||
802 | kn->ns = NULL; | ||
803 | kn->priv = NULL; | ||
804 | |||
805 | /* link in */ | ||
806 | rc = kernfs_add_one(kn); | ||
807 | if (!rc) | ||
808 | return kn; | ||
809 | |||
810 | kernfs_put(kn); | ||
811 | return ERR_PTR(rc); | ||
812 | } | ||
813 | |||
779 | static struct dentry *kernfs_iop_lookup(struct inode *dir, | 814 | static struct dentry *kernfs_iop_lookup(struct inode *dir, |
780 | struct dentry *dentry, | 815 | struct dentry *dentry, |
781 | unsigned int flags) | 816 | unsigned int flags) |
@@ -1247,7 +1282,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent, | |||
1247 | mutex_lock(&kernfs_mutex); | 1282 | mutex_lock(&kernfs_mutex); |
1248 | 1283 | ||
1249 | error = -ENOENT; | 1284 | error = -ENOENT; |
1250 | if (!kernfs_active(kn) || !kernfs_active(new_parent)) | 1285 | if (!kernfs_active(kn) || !kernfs_active(new_parent) || |
1286 | (new_parent->flags & KERNFS_EMPTY_DIR)) | ||
1251 | goto out; | 1287 | goto out; |
1252 | 1288 | ||
1253 | error = 0; | 1289 | error = 0; |