[Top][All Lists]
[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 ();
}
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/04
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/04
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/04
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/04
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/04
- smbfs smbnetfs.c,
Ludovic Courtès <=
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/05
- smbfs smbnetfs.c, Ludovic Courtès, 2012/03/14