hurdextras-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

smbfs smbnetfs.c


From: Ludovic Courtès
Subject: smbfs smbnetfs.c
Date: Mon, 05 Mar 2012 21:15:21 +0000

CVSROOT:        /sources/hurdextras
Module name:    smbfs
Changes by:     Ludovic Courtès <civodul>       12/03/05 21:15:21

Modified files:
        .              : smbnetfs.c 

Log message:
        Revamp node management to have per-directory search lists.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/smbfs/smbnetfs.c?cvsroot=hurdextras&r1=1.11&r2=1.12

Patches:
Index: smbnetfs.c
===================================================================
RCS file: /sources/hurdextras/smbfs/smbnetfs.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- smbnetfs.c  4 Mar 2012 21:24:09 -0000       1.11
+++ smbnetfs.c  5 Mar 2012 21:15:21 -0000       1.12
@@ -50,172 +50,159 @@
 char *netfs_server_version = "0.1";
 int netfs_maxsymlinks = 0;
 
+/* A node in the SMB file system.  */
 struct netnode
 {
-  struct node *node;
-  char *filename;
-  struct netnode *parent;
-  struct netnode *next;
+  struct node *node;                           /* corresponding node */
+  char *file_name;                             /* base name */
+  char *abs_file_name;                         /* absolute SMB path */
+  struct node *dir;                            /* parent directory */
+  struct node *entries;                                /* entries, if a 
directory */
 };
 
-static struct netnode  *nodes;
-
-/* Free the memory used by the nodes.  */
-static void
-clear_nodes ()
-{
-  if (!nodes)
-    return;
-  struct netnode *pt = nodes;
-  struct netnode *pt2 = 0;
-
-  for (;;)
-    {
-      pt2 = pt;
-      if (pt2)
-        {
-          pt = pt->next;
-          free (pt2->node);
-          free (pt2->filename);
-          free (pt2);
-        }
-      else
-        break;
-    }
-  nodes = 0;
-}
-
-static void
-append_node_to_list (struct netnode *n)
+/* Initialize *NODE with a new node within directory DIR.  */
+static error_t
+create_node (struct node *dir, struct node **node)
 {
-  n->next = nodes;
-  nodes = n;
-}
-
-/* Create a new node and initialize it with default values.  */
-static int
-create_node (struct node **node)
-{
-  struct netnode *n = malloc (sizeof (struct netnode));
+  struct netnode *n;
 
-  if(!n)
+  n = calloc (1, sizeof *n);
+  if (!n)
        return ENOMEM;
 
+  n->dir = dir;
   *node = n->node = netfs_make_node (n);
   if (!(*node))
     {
       free (n);
       return ENOMEM;
     }  
-  append_node_to_list (n);
-  return 0;
-}
 
-static struct netnode *
-search_node (char *filename, struct node *dir)
-{
-  struct netnode *pt = nodes;
+  if (dir != NULL)
+    {
+      /* Increase DIR's reference counter.  */
+      netfs_nref (dir);
 
-  while (pt)
+      (*node)->next = NULL;
+
+      if (dir->nn->entries != NULL)
     {
-      if ((pt->parent)  && (dir == pt->parent->node)
-          && !strcmp (pt->filename, filename))
-            return pt;
+         /* Insert *NODE at the end.  */
+         struct node *e;
+
+         for (e = dir->nn->entries;
+              e->next != NULL;
+              e = e->next);
 
-      pt = pt->next;
+         (*node)->prevp = &e->next;
+         e->next = *node;
+       }
+      else
+       {
+         /* *NODE is the first entry in DIR.  */
+         (*node)->prevp = &dir->nn->entries;
+         dir->nn->entries = *node;
+       }
     }
 
   return 0;
 }
 
-static void
-remove_node (struct node *np)
+/* Return the node named FILENAME in DIR, or NULL on failure.  */
+static struct netnode *
+search_node (const char *filename, struct node *dir)
 {
-  struct netnode *pt;
-  struct netnode *prevpt;
+  struct node *entry;
 
-  for ( pt=nodes, prevpt=0 ; pt ; pt=pt->next )
+  for (entry = dir->nn->entries;
+       entry != NULL;
+       entry = entry->next)
     {
-      if (pt->node == np)
-        {
-          free (pt->node);
-          free (pt->filename);
-          free (pt);
+      if (strcmp (entry->nn->file_name, filename) == 0)
+       return entry->nn;
+    }
 
-          if (prevpt)
-            prevpt->next = pt->next;
-          else
-            nodes = pt->next;
+  return 0;
+}
 
-          break;
-        }
-      else
-        prevpt = pt;
-    }
+/* Remove NODE and free any associated resources.  */
+static void
+remove_node (struct node *node)
+{
+  *node->prevp = node->next;
+  node->next = NULL;
+  node->prevp = NULL;
+  if (node->nn->file_name != NULL)
+    free (node->nn->file_name);
+  if (node->nn->abs_file_name != NULL)
+    free (node->nn->abs_file_name);
+  free (node->nn);
+  node->nn = NULL;
 }
 
+/* Create the file system's root node.  */
 static void
 create_root_node ()
 {
   struct node *node;
-  int err = create_node (&node);
+  int err = create_node (NULL, &node);
   if (err)
     return;
 
   netfs_root_node = node;
-  node->nn->parent = 0;
-  node->nn->filename = strdup (credentials.share);
+  node->nn->abs_file_name = strdup (credentials.share);
 
   netfs_validate_stat (node, 0);
 }
 
 
-static int
+/* Add FILENAME in directory NAME and set *NN to the resulting node.  */
+static error_t
 add_node (char *filename, struct node *top ,struct netnode** nn)
 {
   int err;
   struct netnode *n;
   struct node *newnode;
-  io_statbuf_t  st;
 
   n = search_node (filename, top);
-  if (n)
+  if (n == NULL)
     {
-      *nn = n;
-      return 0;
-    }
-    
-  err = create_node (&newnode);
+      /* Nothing known about FILENAME, so create a new node.  */
+      err = create_node (top, &newnode);
   if (err)
     return err;
+
   n = newnode->nn;
   n->node = newnode;
-
-  if (top)
-    n->parent = top->nn;
+      n->dir = top;
+      n->file_name = strdup (filename);
+      asprintf (&n->abs_file_name, "%s/%s",
+               top->nn->abs_file_name, filename);
+      if (n->file_name == NULL || n->abs_file_name == NULL)
+       {
+         netfs_nput (newnode);
+         return ENOMEM;
+       }
+    }
   else
-    n->parent = 0;
-
-  asprintf (&n->filename, "%s/%s", top->nn->filename, filename);
+    /* A node already exists for FILENAME.  */
+    newnode = n->node;
 
+  /* Make sure FILENAME actually exists.  */
   mutex_lock (&smb_mutex);  
-  err = smbc_stat (n->filename, &st);
+  err = smbc_stat (n->abs_file_name, &n->node->nn_stat);
   mutex_unlock (&smb_mutex);  
     
-  if (err)
-    return errno;
-  
-  /* Consider only directories and regular files.  */
-  if (((st.st_mode &  S_IFDIR) == 0)  && ((st.st_mode &  S_IFREG) == 0))
-    err=-1;
-  if(err)
+  if (err != 0)
     { 
-      remove_node (newnode);
-      return errno;
+      /* FILENAME cannot be accessed, so forget about NEWNODE.  */
+      err = errno;
+      netfs_nput (newnode);
     }
-    
+  else
   *nn = n;
-  return 0;
+
+  return err;
 }
 
 /* Return a zeroed stat buffer for CRED.  */
@@ -245,7 +232,7 @@
 netfs_validate_stat (struct node * np, struct iouser *cred)
 {
   mutex_lock (&smb_mutex);    
-  int err = smbc_stat (np->nn->filename, &np->nn_stat);
+  int err = smbc_stat (np->nn->abs_file_name, &np->nn_stat);
   mutex_unlock (&smb_mutex);
   if (err)
     return errno;
@@ -271,7 +258,7 @@
 {
   int err;
   mutex_lock (&smb_mutex);    
-  err=smbc_chmod (np->nn->filename,mode);
+  err = smbc_chmod (np->nn->abs_file_name, mode);
   mutex_unlock (&smb_mutex);  
 
   if (err)
@@ -323,7 +310,7 @@
     maptime_read (maptime, &tv);
 
   mutex_lock (&smb_mutex);    
-  err = smbc_utimes (np->nn->filename, &tv);
+  err = smbc_utimes (np->nn->abs_file_name, &tv);
   mutex_unlock (&smb_mutex);
 
   if(err)
@@ -338,7 +325,7 @@
   int fd, ret, saved_errno;
 
   mutex_lock (&smb_mutex);
-  fd = smbc_open (np->nn->filename, O_WRONLY, 0);
+  fd = smbc_open (np->nn->abs_file_name, O_WRONLY, 0);
   mutex_unlock (&smb_mutex);
 
   if (fd < 0)
@@ -388,9 +375,9 @@
     }
   else if (strcmp (name, "..") == 0)   /*Parent directory */
     {
-      if (dir->nn->parent)
+      if (dir->nn->dir)
         {
-          *np = dir->nn->parent->node;
+          *np = dir->nn->dir;
           if (*np)
             {
               netfs_nref (*np);
@@ -410,8 +397,7 @@
     }
 
   mutex_unlock (&dir->lock);
-  
-  err = add_node (name, dir,&n);
+  err = add_node (name, dir, &n);
 
   if(err)
     return err;
@@ -430,10 +416,7 @@
 {
   char *filename;
 
-  if (dir->nn->filename)
-    asprintf (&filename, "%s/%s", dir->nn->filename, name);
-  else
-    asprintf (&filename, "%s/%s", credentials.share, name);
+  asprintf (&filename, "%s/%s", dir->nn->abs_file_name, name);
 
   if (!filename)
     return ENOMEM;
@@ -458,19 +441,11 @@
   char *filename;              /* Origin file name.  */
   char *filename2;             /* Destination file name.  */
 
-  if (fromdir->nn->filename)
-    asprintf (&filename, "%s/%s", fromdir->nn->filename,fromname);
-  else
-    asprintf (&filename, "%s/%s", credentials.share, fromname);
-
+  asprintf (&filename, "%s/%s", fromdir->nn->abs_file_name, fromname);
   if (!filename)
     return ENOMEM;
 
-  if (todir->nn->filename)
-    asprintf (&filename2, "%s/%s", todir->nn->filename, toname);
-  else
-    asprintf (&filename2, "%s/%s", credentials.share, toname);
-
+  asprintf (&filename2, "%s/%s", todir->nn->abs_file_name, toname);
   if (!filename2)
     {
       free (filename);
@@ -493,11 +468,7 @@
   char *filename;
   error_t err;
 
-  if (dir->nn->filename)
-    asprintf (&filename, "%s/%s", dir->nn->filename,name);
-  else
-    asprintf (&filename, "%s/%s", credentials.share, name);
-
+  asprintf (&filename, "%s/%s", dir->nn->abs_file_name,name);
   if (!filename)
     return ENOMEM;
 
@@ -515,11 +486,7 @@
   char *filename;
   error_t err;
 
-  if (dir->nn->filename)
-    asprintf (&filename, "%s/%s", dir->nn->filename,    name);
-  else
-    asprintf (&filename, "%s/%s", credentials.share, name);
-
+  asprintf (&filename, "%s/%s", dir->nn->abs_file_name, name);
   if (!filename)
     return ENOMEM;
 
@@ -556,11 +523,7 @@
   int fd;
   *np = 0;
 
-  if (dir->nn->filename)
-    asprintf (&filename, "%s/%s", dir->nn->filename,name);
-  else
-    asprintf (&filename, "%s/%s", credentials.share, name);
-
+  asprintf (&filename, "%s/%s", dir->nn->abs_file_name, name);
   if (!filename)
     return ENOMEM;
 
@@ -603,7 +566,7 @@
   io_statbuf_t  nn_stat;
   
   mutex_lock (&smb_mutex);
-  err = smbc_stat (np->nn->filename, &nn_stat);
+  err = smbc_stat (np->nn->abs_file_name, &nn_stat);
   mutex_unlock (&smb_mutex);
    
   if (err)
@@ -627,7 +590,7 @@
   int ret = 0;
 
   mutex_lock (&smb_mutex);
-  fd = smbc_open (np->nn->filename, O_RDONLY, 0);
+  fd = smbc_open (np->nn->abs_file_name, O_RDONLY, 0);
   mutex_unlock (&smb_mutex);
 
   if (fd < 0)
@@ -677,7 +640,7 @@
   int fd;
 
   mutex_lock (&smb_mutex);
-  fd = smbc_open (np->nn->filename, O_WRONLY, 0);
+  fd = smbc_open (np->nn->abs_file_name, O_WRONLY, 0);
   mutex_unlock (&smb_mutex);
 
   if (fd < 0)
@@ -763,7 +726,7 @@
     return ENOTDIR;
 
   mutex_lock (&smb_mutex);
-  dd = smbc_opendir (dir->nn->filename);
+  dd = smbc_opendir (dir->nn->abs_file_name);
   mutex_unlock (&smb_mutex);
   
   if (dd < 0)
@@ -900,7 +863,7 @@
         if (!strcmp (dirent->name, "."))
           {
             mutex_lock (&smb_mutex);
-            err = smbc_stat (dir->nn->filename, &st);
+            err = smbc_stat (dir->nn->abs_file_name, &st);
             mutex_unlock (&smb_mutex);
           }
         else if (!strcmp (dirent->name, ".."))
@@ -913,7 +876,7 @@
            char *stat_file_name;
 
             asprintf (&stat_file_name, "%s/%s",
-                     dir->nn->filename, dirent->name);
+                     dir->nn->abs_file_name, dirent->name);
            if (stat_file_name == NULL)
              return ENOMEM;
 
@@ -954,7 +917,6 @@
 smbfs_init ()
 {
   int err;
-  nodes = 0;
   err = maptime_map (0, 0, &maptime);
 
   if(err)
@@ -967,5 +929,4 @@
 smbfs_terminate ()
 {
   mutex_init (&smb_mutex);
-  clear_nodes ();
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]