aboutsummaryrefslogtreecommitdiffstats
path: root/fs/kernfs/dir.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2015-05-13 17:09:29 -0400
committerEric W. Biederman <ebiederm@xmission.com>2015-07-01 11:36:43 -0400
commitea015218f2f7ace2dad9cedd21ed95bdba2886d7 (patch)
tree9ab4dc58398a5ef08b174871a9cc587680261b65 /fs/kernfs/dir.c
parenteb6d38d5427b3ad42f5268da0f1dd31bb0af1264 (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.c38
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 */
789struct 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
779static struct dentry *kernfs_iop_lookup(struct inode *dir, 814static 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;