@@ -181,48 +181,82 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
181181 return aa_findn_ns (root , name , strlen (name ));
182182}
183183
184+ static struct aa_ns * __aa_create_ns (struct aa_ns * parent , const char * name ,
185+ struct dentry * dir )
186+ {
187+ struct aa_ns * ns ;
188+ int error ;
189+
190+ AA_BUG (!parent );
191+ AA_BUG (!name );
192+ AA_BUG (!mutex_is_locked (& parent -> lock ));
193+
194+ ns = alloc_ns (parent -> base .hname , name );
195+ if (!ns )
196+ return NULL ;
197+ mutex_lock (& ns -> lock );
198+ error = __aa_fs_ns_mkdir (ns , ns_subns_dir (parent ), name );
199+ if (error ) {
200+ AA_ERROR ("Failed to create interface for ns %s\n" ,
201+ ns -> base .name );
202+ mutex_unlock (& ns -> lock );
203+ aa_free_ns (ns );
204+ return ERR_PTR (error );
205+ }
206+ ns -> parent = aa_get_ns (parent );
207+ list_add_rcu (& ns -> base .list , & parent -> sub_ns );
208+ /* add list ref */
209+ aa_get_ns (ns );
210+ mutex_unlock (& ns -> lock );
211+
212+ return ns ;
213+ }
214+
184215/**
185- * aa_prepare_ns - find an existing or create a new namespace of @name
186- * @name: the namespace to find or add (MAYBE NULL)
216+ * aa_create_ns - create an ns, fail if it already exists
217+ * @parent: the parent of the namespace being created
218+ * @name: the name of the namespace
219+ * @dir: if not null the dir to put the ns entries in
187220 *
188- * Returns: refcounted ns or NULL if failed to create one
221+ * Returns: the a refcounted ns that has been add or an ERR_PTR
189222 */
190- struct aa_ns * aa_prepare_ns (const char * name )
223+ struct aa_ns * __aa_find_or_create_ns (struct aa_ns * parent , const char * name ,
224+ struct dentry * dir )
191225{
192- struct aa_ns * ns , * root ;
226+ struct aa_ns * ns ;
193227
194- root = aa_current_profile () -> ns ;
228+ AA_BUG (! mutex_is_locked ( & parent -> lock )) ;
195229
196- mutex_lock (& root -> lock );
230+ /* try and find the specified ns */
231+ /* released by caller */
232+ ns = aa_get_ns (__aa_find_ns (& parent -> sub_ns , name ));
233+ if (!ns )
234+ ns = __aa_create_ns (parent , name , dir );
235+ else
236+ ns = ERR_PTR (- EEXIST );
197237
198- /* if name isn't specified the profile is loaded to the current ns */
199- if (!name ) {
200- /* released by caller */
201- ns = aa_get_ns (root );
202- goto out ;
203- }
238+ /* return ref */
239+ return ns ;
240+ }
204241
242+ /**
243+ * aa_prepare_ns - find an existing or create a new namespace of @name
244+ * @parent: ns to treat as parent
245+ * @name: the namespace to find or add (NOT NULL)
246+ *
247+ * Returns: refcounted namespace or PTR_ERR if failed to create one
248+ */
249+ struct aa_ns * aa_prepare_ns (struct aa_ns * parent , const char * name )
250+ {
251+ struct aa_ns * ns ;
252+
253+ mutex_lock (& parent -> lock );
205254 /* try and find the specified ns and if it doesn't exist create it */
206255 /* released by caller */
207- ns = aa_get_ns (__aa_find_ns (& root -> sub_ns , name ));
208- if (!ns ) {
209- ns = alloc_ns (root -> base .hname , name );
210- if (!ns )
211- goto out ;
212- if (__aa_fs_ns_mkdir (ns , ns_subns_dir (root ), name )) {
213- AA_ERROR ("Failed to create interface for ns %s\n" ,
214- ns -> base .name );
215- aa_free_ns (ns );
216- ns = NULL ;
217- goto out ;
218- }
219- ns -> parent = aa_get_ns (root );
220- list_add_rcu (& ns -> base .list , & root -> sub_ns );
221- /* add list ref */
222- aa_get_ns (ns );
223- }
224- out :
225- mutex_unlock (& root -> lock );
256+ ns = aa_get_ns (__aa_find_ns (& parent -> sub_ns , name ));
257+ if (!ns )
258+ ns = __aa_create_ns (parent , name , NULL );
259+ mutex_unlock (& parent -> lock );
226260
227261 /* return ref */
228262 return ns ;
0 commit comments