SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/fs_nscache.c (Article 8) and /sos/fs_nscache.c (Article 9)


001 /* Copyright (C) 2005      David Decotigny        001 /* Copyright (C) 2005      David Decotigny
002    Copyright (C) 2000-2005 The KOS Team (Thoma    002    Copyright (C) 2000-2005 The KOS Team (Thomas Petazzoni, David
003                            Decotigny, Julien M    003                            Decotigny, Julien Munier)
004                                                   004 
005    This program is free software; you can redi    005    This program is free software; you can redistribute it and/or
006    modify it under the terms of the GNU Genera    006    modify it under the terms of the GNU General Public License
007    as published by the Free Software Foundatio    007    as published by the Free Software Foundation; either version 2
008    of the License, or (at your option) any lat    008    of the License, or (at your option) any later version.
009                                                   009    
010    This program is distributed in the hope tha    010    This program is distributed in the hope that it will be useful,
011    but WITHOUT ANY WARRANTY; without even the     011    but WITHOUT ANY WARRANTY; without even the implied warranty of
012    MERCHANTABILITY or FITNESS FOR A PARTICULAR    012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013    GNU General Public License for more details    013    GNU General Public License for more details.
014                                                   014    
015    You should have received a copy of the GNU     015    You should have received a copy of the GNU General Public License
016    along with this program; if not, write to t    016    along with this program; if not, write to the Free Software
017    Foundation, Inc., 59 Temple Place - Suite 3    017    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
018    USA.                                           018    USA. 
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  * A so-called "dentry" / "nsnode" structure.     030  * A so-called "dentry" / "nsnode" structure. Used to make the
031  * "in-memory" representation of the file syst    031  * "in-memory" representation of the file system files/dir/devices
032  * that have been used up to now                  032  * that have been used up to now
033  */                                               033  */
034 struct sos_fs_nscache_node                        034 struct sos_fs_nscache_node
035 {                                                 035 {
036   /** The reference to the associated sos_fs_n    036   /** The reference to the associated sos_fs_node */
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   /** Number of references to that node, refer    041   /** Number of references to that node, reference from parent (if
042       any) is EXCLUDED */                         042       any) is EXCLUDED */
043   sos_count_t ref_cnt;                            043   sos_count_t ref_cnt;
044                                                   044 
045   /*                                              045   /*
046    * Ued to chain the mounted filesystem          046    * Ued to chain the mounted filesystem
047    */                                             047    */
048                                                   048 
049   /** If this node is a mountpoint (a file sys    049   /** If this node is a mountpoint (a file system is mounted on it):
050       reference to the filesystem mounted on i    050       reference to the filesystem mounted on it */
051   struct sos_fs_nscache_node *mounted_root;       051   struct sos_fs_nscache_node *mounted_root;
052   /** If this node is the root of a mounted fi    052   /** If this node is the root of a mounted filesystem: reference to
053       the mountpoint where it is mounted on */    053       the mountpoint where it is mounted on */
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   /** List of the already known children */       059   /** List of the already known children */
060   struct sos_fs_nscache_node *children;           060   struct sos_fs_nscache_node *children;
061                                                   061   
062   /** Other children for the same parent */       062   /** Other children for the same parent */
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 /** The cache of nscache_node objects */          067 /** The cache of nscache_node objects */
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   /* Skip any leading slash */                    143   /* Skip any leading slash */
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   /* Extract the first component */               147   /* Extract the first component */
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   /* Return true if there is something left (a    153   /* Return true if there is something left (at least one slash) */
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       /* Effectively go up only if we did not     228       /* Effectively go up only if we did not reach a root node */
229       if (cur_nsnode == root_nsnode) /* did re    229       if (cur_nsnode == root_nsnode) /* did reach chroot */
230         {                                         230         {
231           /* Simply stay here */                  231           /* Simply stay here */
232           *result_nsnode = cur_nsnode;            232           *result_nsnode = cur_nsnode;
233         }                                         233         }
234       else                                        234       else
235         {                                         235         {
236           /* If current node is a mounted FS,     236           /* If current node is a mounted FS, rewind the mountpoint
237              chain */                             237              chain */
238           for ( ; cur_nsnode->mountpoint ; cur    238           for ( ; cur_nsnode->mountpoint ; cur_nsnode = cur_nsnode->mountpoint)
239             /* nop */ ;                           239             /* nop */ ;
240                                                   240 
241           /* Now go up to parent */               241           /* Now go up to parent */
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       /* Update the nscache_node result */        246       /* Update the nscache_node result */
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       /* Normal lookup: we iterate over the li    252       /* Normal lookup: we iterate over the list of children nscache
253          nodes */                                 253          nodes */
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       /* Lookup the child node with the correc    257       /* Lookup the child node with the correct name, if any */
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       /* Did not find it ! */                     279       /* Did not find it ! */
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       /* Yes, found it ! */                       284       /* Yes, found it ! */
285       *result_nsnode = child;                     285       *result_nsnode = child;
286     }                                             286     }
287                                                   287 
288   /* Found it. Now, Follow the mountpoint chai    288   /* Found it. Now, Follow the mountpoint chain, if any */
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     /* nop */ ;                                   291     /* nop */ ;
292                                                   292 
293   /* Update the nscache_node result */            293   /* Update the nscache_node result */
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 /* Eventually collapses a whole list of nsnode    308 /* Eventually collapses a whole list of nsnodes (non recursive) */
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       /* Unreference this node */                 318       /* Unreference this node */
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       /* Is it a good candidate for deletion ?    322       /* Is it a good candidate for deletion ? */
323       if (node->ref_cnt > 0)                      323       if (node->ref_cnt > 0)
324         break; /* No */                           324         break; /* No */
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           /* The parent lost one child: next i    334           /* The parent lost one child: next iteration will decrement
335              ths parent's ref cnt */              335              ths parent's ref cnt */
336         }                                         336         }
337                                                   337 
338       /* Add to the list of elements to suppre    338       /* Add to the list of elements to suppress */
339       list_add_tail_named(to_delete, node, sib    339       list_add_tail_named(to_delete, node, siblings_prev, siblings_next);
340                                                   340 
341       /* Now look if parent (if any) can be de    341       /* Now look if parent (if any) can be destroyed */
342       node = node->parent;                        342       node = node->parent;
343     }                                             343     }
344                                                   344 
345   /* Now destroy all the elements gathered */     345   /* Now destroy all the elements gathered */
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   /* Allocate a new nscache node from slab */     365   /* Allocate a new nscache node from slab */
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   /* Allocate a new memory chunk to hold the n    372   /* Allocate a new memory chunk to hold the node's name */
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   /* Now initialize the new node's fields */      388   /* Now initialize the new node's fields */
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   /* Register this node as a child of its pare    393   /* Register this node as a child of its parent, if any */
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   /* If the node already had a name, suppress     414   /* If the node already had a name, suppress it */
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   /* Allocate a new memory chunk to hold the n    421   /* Allocate a new memory chunk to hold the node's name */
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   /* Register this node as a child of its pare    438   /* Register this node as a child of its parent, if any */
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   /* No FS should be mounted on the mounted ro    498   /* No FS should be mounted on the mounted root to umount */
499   SOS_ASSERT_FATAL(NULL == mounted_root->mount    499   SOS_ASSERT_FATAL(NULL == mounted_root->mounted_root);
500                                                   500 
501   /* The mounted root should have its own refe    501   /* The mounted root should have its own reference, plus a reference
502      from the mountpoint and from the fs insta    502      from the mountpoint and from the fs instance */
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   /* Undo the mountpoint <-> mounted_root mutu    511   /* Undo the mountpoint <-> mounted_root mutual reference */
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   /* Undo the fs->root -> mounted_root referen    517   /* Undo the fs->root -> mounted_root reference */
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 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]