Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 019
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/list.h> 022 #include <sos/list.h>
023 #include <sos/kmem_slab.h> 023 #include <sos/kmem_slab.h>
024 #include <sos/kmalloc.h> 024 #include <sos/kmalloc.h>
025 025
026 #include "fs_nscache.h" 026 #include "fs_nscache.h"
027 027
028 028
029 029
030 030
031 031
032 032
033 033
034 struct sos_fs_nscache_node 034 struct sos_fs_nscache_node
035 { 035 {
036 036
037 struct sos_fs_node *fs_node; 037 struct sos_fs_node *fs_node;
038 038
039 struct sos_fs_pathname name; 039 struct sos_fs_pathname name;
040 040
041 041
042 042
043 sos_count_t ref_cnt; 043 sos_count_t ref_cnt;
044 044
045 045
046 046
047 047
048 048
049 049
050 050
051 struct sos_fs_nscache_node *mounted_root; 051 struct sos_fs_nscache_node *mounted_root;
052 052
053 053
054 struct sos_fs_nscache_node *mountpoint; 054 struct sos_fs_nscache_node *mountpoint;
055 055
056 056
057 struct sos_fs_nscache_node *parent; 057 struct sos_fs_nscache_node *parent;
058 058
059 059
060 struct sos_fs_nscache_node *children; 060 struct sos_fs_nscache_node *children;
061 061
062 062
063 struct sos_fs_nscache_node *siblings_prev, * 063 struct sos_fs_nscache_node *siblings_prev, *siblings_next;
064 }; 064 };
065 065
066 066
067 067
068 static struct sos_kslab_cache * cache_of_nscac 068 static struct sos_kslab_cache * cache_of_nscache_nodes;
069 069
070 070
071 sos_ret_t sos_fs_nscache_subsystem_setup() 071 sos_ret_t sos_fs_nscache_subsystem_setup()
072 { 072 {
073 cache_of_nscache_nodes 073 cache_of_nscache_nodes
074 = sos_kmem_cache_create("fs_nscache", 074 = sos_kmem_cache_create("fs_nscache",
075 sizeof(struct sos_ 075 sizeof(struct sos_fs_nscache_node),
076 3, 0, 076 3, 0,
077 SOS_KSLAB_CREATE_M 077 SOS_KSLAB_CREATE_MAP | SOS_KSLAB_CREATE_ZERO);
078 if (! cache_of_nscache_nodes) 078 if (! cache_of_nscache_nodes)
079 return -SOS_ENOMEM; 079 return -SOS_ENOMEM;
080 080
081 return SOS_OK; 081 return SOS_OK;
082 }; 082 };
083 083
084 084
085 sos_bool_t 085 sos_bool_t
086 sos_fs_pathname_eat_slashes(const struct sos_f 086 sos_fs_pathname_eat_slashes(const struct sos_fs_pathname * path,
087 struct sos_fs_path 087 struct sos_fs_pathname * result)
088 { 088 {
089 sos_bool_t retval = FALSE; 089 sos_bool_t retval = FALSE;
090 090
091 result->contents = path->contents; 091 result->contents = path->contents;
092 result->length = path->length; 092 result->length = path->length;
093 while (result->length > 0) 093 while (result->length > 0)
094 { 094 {
095 if (*result->contents != '/') 095 if (*result->contents != '/')
096 break; 096 break;
097 097
098 result->contents ++; 098 result->contents ++;
099 result->length --; 099 result->length --;
100 retval = TRUE; 100 retval = TRUE;
101 } 101 }
102 102
103 if(result->length <= 0) 103 if(result->length <= 0)
104 result->contents = NULL; 104 result->contents = NULL;
105 105
106 return retval; 106 return retval;
107 } 107 }
108 108
109 109
110 static sos_bool_t 110 static sos_bool_t
111 sos_fs_pathname_eat_non_slashes(const struct s 111 sos_fs_pathname_eat_non_slashes(const struct sos_fs_pathname * path,
112 struct sos_fs_ 112 struct sos_fs_pathname * result)
113 { 113 {
114 sos_bool_t retval = FALSE; 114 sos_bool_t retval = FALSE;
115 115
116 result->contents = path->contents; 116 result->contents = path->contents;
117 result->length = path->length; 117 result->length = path->length;
118 while (result->length > 0) 118 while (result->length > 0)
119 { 119 {
120 if (*result->contents == '/') 120 if (*result->contents == '/')
121 break; 121 break;
122 122
123 result->contents ++; 123 result->contents ++;
124 result->length --; 124 result->length --;
125 retval = TRUE; 125 retval = TRUE;
126 } 126 }
127 127
128 if(result->length <= 0) 128 if(result->length <= 0)
129 result->contents = NULL; 129 result->contents = NULL;
130 130
131 return retval; 131 return retval;
132 } 132 }
133 133
134 134
135 sos_bool_t 135 sos_bool_t
136 sos_fs_pathname_split_path(const struct sos_fs 136 sos_fs_pathname_split_path(const struct sos_fs_pathname * path,
137 struct sos_fs_pathn 137 struct sos_fs_pathname * result_first_component,
138 struct sos_fs_pathn 138 struct sos_fs_pathname * result_remaining_path)
139 { 139 {
140 result_first_component->contents = path->con 140 result_first_component->contents = path->contents;
141 result_first_component->length = path->len 141 result_first_component->length = path->length;
142 142
143 143
144 sos_fs_pathname_eat_slashes(result_first_com 144 sos_fs_pathname_eat_slashes(result_first_component,
145 result_first_com 145 result_first_component);
146 146
147 147
148 sos_fs_pathname_eat_non_slashes(result_first 148 sos_fs_pathname_eat_non_slashes(result_first_component,
149 result_remai 149 result_remaining_path);
150 SOS_ASSERT_FATAL(result_remaining_path->leng 150 SOS_ASSERT_FATAL(result_remaining_path->length >= 0);
151 result_first_component->length -= result_rem 151 result_first_component->length -= result_remaining_path->length;
152 152
153 153
154 return (result_remaining_path->length > 0); 154 return (result_remaining_path->length > 0);
155 } 155 }
156 156
157 157
158 sos_bool_t fs_pathname_iseq(const struct sos_f 158 sos_bool_t fs_pathname_iseq(const struct sos_fs_pathname * p1,
159 const struct sos_f 159 const struct sos_fs_pathname * p2)
160 { 160 {
161 if (!p1->contents) 161 if (!p1->contents)
162 SOS_ASSERT_FATAL(p1->length == 0); 162 SOS_ASSERT_FATAL(p1->length == 0);
163 if (!p2->contents) 163 if (!p2->contents)
164 SOS_ASSERT_FATAL(p2->length == 0); 164 SOS_ASSERT_FATAL(p2->length == 0);
165 165
166 if (p1->length != p2->length) 166 if (p1->length != p2->length)
167 return FALSE; 167 return FALSE;
168 168
169 if (p1->length == 0) 169 if (p1->length == 0)
170 return TRUE; 170 return TRUE;
171 171
172 return (0 == memcmp(p1->contents, p2->conten 172 return (0 == memcmp(p1->contents, p2->contents, p1->length));
173 } 173 }
174 174
175 175
176 #define fs_pathname_isstr(str,path) \ 176 #define fs_pathname_isstr(str,path) \
177 ({ struct sos_fs_pathname _s; _s.contents = 177 ({ struct sos_fs_pathname _s; _s.contents = str; _s.length = sizeof(str)-1; \
178 fs_pathname_iseq(&_s, (path)); }) 178 fs_pathname_iseq(&_s, (path)); })
179 179
180 180
181 struct sos_fs_node * 181 struct sos_fs_node *
182 sos_fs_nscache_get_fs_node(const struct sos_fs 182 sos_fs_nscache_get_fs_node(const struct sos_fs_nscache_node * nsnode)
183 { 183 {
184 return nsnode->fs_node; 184 return nsnode->fs_node;
185 } 185 }
186 186
187 187
188 sos_ret_t 188 sos_ret_t
189 sos_fs_nscache_get_parent(const struct sos_fs_ 189 sos_fs_nscache_get_parent(const struct sos_fs_nscache_node * nsnode,
190 struct sos_fs_nscach 190 struct sos_fs_nscache_node ** result_parent)
191 { 191 {
192 *result_parent = nsnode->parent; 192 *result_parent = nsnode->parent;
193 if (*result_parent) 193 if (*result_parent)
194 return SOS_OK; 194 return SOS_OK;
195 return -SOS_ENOENT; 195 return -SOS_ENOENT;
196 } 196 }
197 197
198 198
199 sos_ret_t 199 sos_ret_t
200 sos_fs_nscache_get_name(const struct sos_fs_ns 200 sos_fs_nscache_get_name(const struct sos_fs_nscache_node * nsnode,
201 struct sos_fs_pathname 201 struct sos_fs_pathname * result_pathname)
202 { 202 {
203 result_pathname->contents = nsnode->name.con 203 result_pathname->contents = nsnode->name.contents;
204 result_pathname->length = nsnode->name.len 204 result_pathname->length = nsnode->name.length;
205 return SOS_OK; 205 return SOS_OK;
206 } 206 }
207 207
208 208
209 sos_ret_t 209 sos_ret_t
210 sos_fs_nscache_get_ref_cnt(const struct sos_fs 210 sos_fs_nscache_get_ref_cnt(const struct sos_fs_nscache_node * nsnode)
211 { 211 {
212 return nsnode->ref_cnt; 212 return nsnode->ref_cnt;
213 } 213 }
214 214
215 215
216 sos_ret_t 216 sos_ret_t
217 sos_fs_nscache_lookup(struct sos_fs_nscache_no 217 sos_fs_nscache_lookup(struct sos_fs_nscache_node * cur_nsnode,
218 const struct sos_fs_path 218 const struct sos_fs_pathname * node_name,
219 const struct sos_fs_nsca 219 const struct sos_fs_nscache_node * root_nsnode,
220 struct sos_fs_nscache_no 220 struct sos_fs_nscache_node ** result_nsnode)
221 { 221 {
222 if (fs_pathname_isstr(".", node_name)) 222 if (fs_pathname_isstr(".", node_name))
223 { 223 {
224 *result_nsnode = cur_nsnode; 224 *result_nsnode = cur_nsnode;
225 } 225 }
226 else if (fs_pathname_isstr("..", node_name)) 226 else if (fs_pathname_isstr("..", node_name))
227 { 227 {
228 228
229 if (cur_nsnode == root_nsnode) 229 if (cur_nsnode == root_nsnode)
230 { 230 {
231 231
232 *result_nsnode = cur_nsnode; 232 *result_nsnode = cur_nsnode;
233 } 233 }
234 else 234 else
235 { 235 {
236 236
237 237
238 for ( ; cur_nsnode->mountpoint ; cur 238 for ( ; cur_nsnode->mountpoint ; cur_nsnode = cur_nsnode->mountpoint)
239 ; 239 ;
240 240
241 241
242 SOS_ASSERT_FATAL(NULL != cur_nsnode- 242 SOS_ASSERT_FATAL(NULL != cur_nsnode->parent);
243 *result_nsnode = cur_nsnode->parent; 243 *result_nsnode = cur_nsnode->parent;
244 } 244 }
245 245
246 246
247 sos_fs_nscache_ref_node(*result_nsnode); 247 sos_fs_nscache_ref_node(*result_nsnode);
248 return SOS_OK; 248 return SOS_OK;
249 } 249 }
250 else 250 else
251 { 251 {
252 252
253 253
254 int nb_children; 254 int nb_children;
255 struct sos_fs_nscache_node * child; 255 struct sos_fs_nscache_node * child;
256 256
257 257
258 list_foreach_named(cur_nsnode->children, 258 list_foreach_named(cur_nsnode->children,
259 child, nb_children, 259 child, nb_children,
260 siblings_prev, siblin 260 siblings_prev, siblings_next)
261 { 261 {
262 struct sos_fs_node * fs_node = cur_n 262 struct sos_fs_node * fs_node = cur_nsnode->fs_node;
263 263
264 if (fs_node->fs->nsnode_same_name) 264 if (fs_node->fs->nsnode_same_name)
265 { 265 {
266 if (fs_node->fs-> 266 if (fs_node->fs->
267 nsnode_same_name(child->na 267 nsnode_same_name(child->name.contents,
268 child->na 268 child->name.length,
269 node_name 269 node_name->contents,
270 node_name 270 node_name->length))
271 break; 271 break;
272 } 272 }
273 else 273 else
274 if (fs_pathname_iseq(& child->name 274 if (fs_pathname_iseq(& child->name,
275 node_name)) 275 node_name))
276 break; 276 break;
277 } 277 }
278 278
279 279
280 if (! list_foreach_early_break(cur_nsnod 280 if (! list_foreach_early_break(cur_nsnode->children,
281 child, nb 281 child, nb_children))
282 return -SOS_ENOENT; 282 return -SOS_ENOENT;
283 283
284 284
285 *result_nsnode = child; 285 *result_nsnode = child;
286 } 286 }
287 287
288 288
289 for ( ; (*result_nsnode)->mounted_root ; 289 for ( ; (*result_nsnode)->mounted_root ;
290 *result_nsnode = (*result_nsnode)->mou 290 *result_nsnode = (*result_nsnode)->mounted_root)
291 ; 291 ;
292 292
293 293
294 sos_fs_nscache_ref_node(*result_nsnode); 294 sos_fs_nscache_ref_node(*result_nsnode);
295 295
296 return SOS_OK; 296 return SOS_OK;
297 } 297 }
298 298
299 299
300 sos_ret_t sos_fs_nscache_ref_node(struct sos_f 300 sos_ret_t sos_fs_nscache_ref_node(struct sos_fs_nscache_node * nsnode)
301 { 301 {
302 SOS_ASSERT_FATAL(nsnode->ref_cnt > 0); 302 SOS_ASSERT_FATAL(nsnode->ref_cnt > 0);
303 nsnode->ref_cnt ++; 303 nsnode->ref_cnt ++;
304 return SOS_OK; 304 return SOS_OK;
305 } 305 }
306 306
307 307
308 308
309 sos_ret_t _sos_fs_nscache_unref_node(struct so 309 sos_ret_t _sos_fs_nscache_unref_node(struct sos_fs_nscache_node ** nsnode)
310 { 310 {
311 struct sos_fs_nscache_node * to_delete = NUL 311 struct sos_fs_nscache_node * to_delete = NULL, *node;
312 312
313 node = *nsnode; 313 node = *nsnode;
314 *nsnode = NULL; 314 *nsnode = NULL;
315 315
316 while (node) 316 while (node)
317 { 317 {
318 318
319 SOS_ASSERT_FATAL(node->ref_cnt > 0); 319 SOS_ASSERT_FATAL(node->ref_cnt > 0);
320 node->ref_cnt --; 320 node->ref_cnt --;
321 321
322 322
323 if (node->ref_cnt > 0) 323 if (node->ref_cnt > 0)
324 break; 324 break;
325 325
326 if (node->parent) 326 if (node->parent)
327 { 327 {
328 struct sos_fs_nscache_node * parent 328 struct sos_fs_nscache_node * parent = node->parent;
329 329
330 SOS_ASSERT_FATAL(node->parent->ref_c 330 SOS_ASSERT_FATAL(node->parent->ref_cnt >= 1);
331 331
332 list_delete_named(parent->children, 332 list_delete_named(parent->children, node,
333 siblings_prev, sib 333 siblings_prev, siblings_next);
334 334
335 335
336 } 336 }
337 337
338 338
339 list_add_tail_named(to_delete, node, sib 339 list_add_tail_named(to_delete, node, siblings_prev, siblings_next);
340 340
341 341
342 node = node->parent; 342 node = node->parent;
343 } 343 }
344 344
345 345
346 while (! list_is_empty_named(to_delete, sibl 346 while (! list_is_empty_named(to_delete, siblings_prev, siblings_next))
347 { 347 {
348 node = list_pop_head_named(to_delete, si 348 node = list_pop_head_named(to_delete, siblings_prev, siblings_next);
349 sos_fs_unref_fsnode(node->fs_node); 349 sos_fs_unref_fsnode(node->fs_node);
350 sos_kfree((sos_vaddr_t)node); 350 sos_kfree((sos_vaddr_t)node);
351 } 351 }
352 352
353 return SOS_OK; 353 return SOS_OK;
354 } 354 }
355 355
356 356
357 sos_ret_t 357 sos_ret_t
358 sos_fs_nscache_add_new_child_node(struct sos_f 358 sos_fs_nscache_add_new_child_node(struct sos_fs_nscache_node * parent,
359 const struct 359 const struct sos_fs_pathname * node_name,
360 struct sos_f 360 struct sos_fs_node * fsnode,
361 struct sos_f 361 struct sos_fs_nscache_node ** result_nsnode)
362 { 362 {
363 struct sos_fs_nscache_node * nsnode; 363 struct sos_fs_nscache_node * nsnode;
364 364
365 365
366 nsnode = (struct sos_fs_nscache_node*) 366 nsnode = (struct sos_fs_nscache_node*)
367 sos_kmem_cache_alloc(cache_of_nscache_node 367 sos_kmem_cache_alloc(cache_of_nscache_nodes,
368 SOS_KSLAB_ALLOC_ATOMI 368 SOS_KSLAB_ALLOC_ATOMIC);
369 if (! nsnode) 369 if (! nsnode)
370 return -SOS_ENOMEM; 370 return -SOS_ENOMEM;
371 371
372 372
373 if (node_name && (node_name->length > 0)) 373 if (node_name && (node_name->length > 0))
374 { 374 {
375 char * contents = (char*) sos_kmalloc(no 375 char * contents = (char*) sos_kmalloc(node_name->length,
376 SO 376 SOS_KMALLOC_ATOMIC);
377 if (! contents) 377 if (! contents)
378 { 378 {
379 sos_kfree((sos_vaddr_t)nsnode); 379 sos_kfree((sos_vaddr_t)nsnode);
380 return -SOS_ENOMEM; 380 return -SOS_ENOMEM;
381 } 381 }
382 382
383 memcpy(contents, node_name->contents, no 383 memcpy(contents, node_name->contents, node_name->length);
384 nsnode->name.contents = contents; 384 nsnode->name.contents = contents;
385 nsnode->name.length = node_name->lengt 385 nsnode->name.length = node_name->length;
386 } 386 }
387 387
388 388
389 nsnode->ref_cnt = 1; 389 nsnode->ref_cnt = 1;
390 sos_fs_ref_fsnode(fsnode); 390 sos_fs_ref_fsnode(fsnode);
391 nsnode->fs_node = fsnode; 391 nsnode->fs_node = fsnode;
392 392
393 393
394 nsnode->parent = parent; 394 nsnode->parent = parent;
395 if (parent) 395 if (parent)
396 { 396 {
397 sos_fs_nscache_ref_node(parent); 397 sos_fs_nscache_ref_node(parent);
398 list_add_head_named(parent->children, ns 398 list_add_head_named(parent->children, nsnode,
399 siblings_prev, sibli 399 siblings_prev, siblings_next);
400 } 400 }
401 401
402 *result_nsnode = nsnode; 402 *result_nsnode = nsnode;
403 return SOS_OK; 403 return SOS_OK;
404 } 404 }
405 405
406 406
407 sos_ret_t 407 sos_ret_t
408 sos_fs_nscache_add_existing_child_node(struct 408 sos_fs_nscache_add_existing_child_node(struct sos_fs_nscache_node * parent,
409 const s 409 const struct sos_fs_pathname * node_name,
410 struct 410 struct sos_fs_nscache_node * nsnode)
411 { 411 {
412 SOS_ASSERT_FATAL(nsnode->parent == NULL); 412 SOS_ASSERT_FATAL(nsnode->parent == NULL);
413 413
414 414
415 if (NULL != nsnode->name.contents) 415 if (NULL != nsnode->name.contents)
416 { 416 {
417 sos_kfree((sos_vaddr_t)nsnode->name.cont 417 sos_kfree((sos_vaddr_t)nsnode->name.contents);
418 } 418 }
419 memset(& nsnode->name, 0x0, sizeof(struct so 419 memset(& nsnode->name, 0x0, sizeof(struct sos_fs_pathname));
420 420
421 421
422 if (node_name && (node_name->length > 0)) 422 if (node_name && (node_name->length > 0))
423 { 423 {
424 char * contents = (char*) sos_kmalloc(no 424 char * contents = (char*) sos_kmalloc(node_name->length,
425 SO 425 SOS_KMALLOC_ATOMIC);
426 if (! contents) 426 if (! contents)
427 { 427 {
428 sos_kfree((sos_vaddr_t)nsnode); 428 sos_kfree((sos_vaddr_t)nsnode);
429 return -SOS_ENOMEM; 429 return -SOS_ENOMEM;
430 } 430 }
431 431
432 memcpy(contents, node_name->contents, no 432 memcpy(contents, node_name->contents, node_name->length);
433 nsnode->name.contents = contents; 433 nsnode->name.contents = contents;
434 nsnode->name.length = node_name->lengt 434 nsnode->name.length = node_name->length;
435 } 435 }
436 436
437 437
438 438
439 nsnode->parent = parent; 439 nsnode->parent = parent;
440 if (parent) 440 if (parent)
441 { 441 {
442 sos_fs_nscache_ref_node(parent); 442 sos_fs_nscache_ref_node(parent);
443 list_add_head_named(parent->children, ns 443 list_add_head_named(parent->children, nsnode,
444 siblings_prev, sibli 444 siblings_prev, siblings_next);
445 } 445 }
446 return SOS_OK; 446 return SOS_OK;
447 } 447 }
448 448
449 449
450 sos_ret_t 450 sos_ret_t
451 sos_fs_nscache_disconnect_node(struct sos_fs_n 451 sos_fs_nscache_disconnect_node(struct sos_fs_nscache_node * nsnode)
452 { 452 {
453 if (! nsnode->parent) 453 if (! nsnode->parent)
454 return SOS_OK; 454 return SOS_OK;
455 455
456 list_delete_named(nsnode->parent->children, 456 list_delete_named(nsnode->parent->children, nsnode,
457 siblings_prev, siblings_ne 457 siblings_prev, siblings_next);
458 sos_fs_nscache_unref_node(nsnode->parent); 458 sos_fs_nscache_unref_node(nsnode->parent);
459 nsnode->parent = NULL; 459 nsnode->parent = NULL;
460 460
461 return SOS_OK; 461 return SOS_OK;
462 } 462 }
463 463
464 464
465 sos_ret_t 465 sos_ret_t
466 sos_fs_nscache_register_opened_file(struct sos 466 sos_fs_nscache_register_opened_file(struct sos_fs_nscache_node * nsnode,
467 struct sos 467 struct sos_fs_opened_file * of)
468 { 468 {
469 of->direntry = nsnode; 469 of->direntry = nsnode;
470 sos_fs_nscache_ref_node(nsnode); 470 sos_fs_nscache_ref_node(nsnode);
471 return SOS_OK; 471 return SOS_OK;
472 } 472 }
473 473
474 474
475 sos_ret_t 475 sos_ret_t
476 sos_fs_nscache_mount(struct sos_fs_nscache_nod 476 sos_fs_nscache_mount(struct sos_fs_nscache_node * mountpoint,
477 struct sos_fs_nscache_nod 477 struct sos_fs_nscache_node * mounted_root)
478 { 478 {
479 SOS_ASSERT_FATAL(NULL == mountpoint->mounted 479 SOS_ASSERT_FATAL(NULL == mountpoint->mounted_root);
480 SOS_ASSERT_FATAL(NULL == mounted_root->mount 480 SOS_ASSERT_FATAL(NULL == mounted_root->mountpoint);
481 mountpoint->mounted_root = mounted_root; 481 mountpoint->mounted_root = mounted_root;
482 mounted_root->mountpoint = mountpoint; 482 mounted_root->mountpoint = mountpoint;
483 sos_fs_nscache_ref_node(mountpoint); 483 sos_fs_nscache_ref_node(mountpoint);
484 sos_fs_nscache_ref_node(mounted_root); 484 sos_fs_nscache_ref_node(mounted_root);
485 485
486 return SOS_OK; 486 return SOS_OK;
487 } 487 }
488 488
489 489
490 sos_ret_t 490 sos_ret_t
491 sos_fs_nscache_umount(struct sos_fs_nscache_no 491 sos_fs_nscache_umount(struct sos_fs_nscache_node * mounted_root)
492 { 492 {
493 struct sos_fs_manager_instance *fs; 493 struct sos_fs_manager_instance *fs;
494 494
495 SOS_ASSERT_FATAL(NULL != mounted_root->mount 495 SOS_ASSERT_FATAL(NULL != mounted_root->mountpoint);
496 SOS_ASSERT_FATAL(mounted_root->mountpoint->m 496 SOS_ASSERT_FATAL(mounted_root->mountpoint->mounted_root == mounted_root);
497 497
498 498
499 SOS_ASSERT_FATAL(NULL == mounted_root->mount 499 SOS_ASSERT_FATAL(NULL == mounted_root->mounted_root);
500 500
501 501
502 502
503 SOS_ASSERT_FATAL(mounted_root->ref_cnt >= 3) 503 SOS_ASSERT_FATAL(mounted_root->ref_cnt >= 3);
504 if (mounted_root->ref_cnt != 3) 504 if (mounted_root->ref_cnt != 3)
505 return -SOS_EBUSY; 505 return -SOS_EBUSY;
506 506
507 fs = mounted_root->fs_node->fs; 507 fs = mounted_root->fs_node->fs;
508 SOS_ASSERT_FATAL(NULL != fs); 508 SOS_ASSERT_FATAL(NULL != fs);
509 SOS_ASSERT_FATAL(fs->root == mounted_root); 509 SOS_ASSERT_FATAL(fs->root == mounted_root);
510 510
511 511
512 mounted_root->mountpoint->mounted_root = NUL 512 mounted_root->mountpoint->mounted_root = NULL;
513 sos_fs_nscache_unref_node(mounted_root->moun 513 sos_fs_nscache_unref_node(mounted_root->mountpoint);
514 mounted_root->mountpoint = NULL; 514 mounted_root->mountpoint = NULL;
515 sos_fs_nscache_unref_node(mounted_root); 515 sos_fs_nscache_unref_node(mounted_root);
516 516
517 517
518 sos_fs_nscache_unref_node(fs->root); 518 sos_fs_nscache_unref_node(fs->root);
519 519
520 return SOS_OK; 520 return SOS_OK;
521 } 521 }
522 522
523 sos_bool_t 523 sos_bool_t
524 sos_fs_nscache_is_mountnode(const struct sos_f 524 sos_fs_nscache_is_mountnode(const struct sos_fs_nscache_node * nsnode)
525 { 525 {
526 return ( (NULL != nsnode->mounted_root) || ( 526 return ( (NULL != nsnode->mounted_root) || (NULL != nsnode->mountpoint) );
527 } 527 }