aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs/symlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/configfs/symlink.c')
-rw-r--r--fs/configfs/symlink.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index 61a886dbd601..bf74973b0492 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -76,6 +76,9 @@ static int create_link(struct config_item *parent_item,
76 struct configfs_symlink *sl; 76 struct configfs_symlink *sl;
77 int ret; 77 int ret;
78 78
79 ret = -ENOENT;
80 if (!configfs_dirent_is_ready(target_sd))
81 goto out;
79 ret = -ENOMEM; 82 ret = -ENOMEM;
80 sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); 83 sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
81 if (sl) { 84 if (sl) {
@@ -100,6 +103,7 @@ static int create_link(struct config_item *parent_item,
100 } 103 }
101 } 104 }
102 105
106out:
103 return ret; 107 return ret;
104} 108}
105 109
@@ -129,6 +133,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
129{ 133{
130 int ret; 134 int ret;
131 struct nameidata nd; 135 struct nameidata nd;
136 struct configfs_dirent *sd;
132 struct config_item *parent_item; 137 struct config_item *parent_item;
133 struct config_item *target_item; 138 struct config_item *target_item;
134 struct config_item_type *type; 139 struct config_item_type *type;
@@ -137,9 +142,19 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
137 if (dentry->d_parent == configfs_sb->s_root) 142 if (dentry->d_parent == configfs_sb->s_root)
138 goto out; 143 goto out;
139 144
145 sd = dentry->d_parent->d_fsdata;
146 /*
147 * Fake invisibility if dir belongs to a group/default groups hierarchy
148 * being attached
149 */
150 ret = -ENOENT;
151 if (!configfs_dirent_is_ready(sd))
152 goto out;
153
140 parent_item = configfs_get_config_item(dentry->d_parent); 154 parent_item = configfs_get_config_item(dentry->d_parent);
141 type = parent_item->ci_type; 155 type = parent_item->ci_type;
142 156
157 ret = -EPERM;
143 if (!type || !type->ct_item_ops || 158 if (!type || !type->ct_item_ops ||
144 !type->ct_item_ops->allow_link) 159 !type->ct_item_ops->allow_link)
145 goto out_put; 160 goto out_put;