Hi! Ludovic Courtès <[EMAIL PROTECTED]> wrote: > If I remember well, "find -name \*" doesn't work with shadowfs which is a > libnetfs-based translator. I encountered the same problem with another > libnetfs translator, even though something like "ls -R" does work fine. I > tried to look at the code of find but 1) I didn't manage to compile it and 2) > the code seems quite hard to read. ;)
Moritz told me that find uses an optimization that causes it to ignore some directories in Shadowfs: The "struct stat" for a directory contains the number of links to the directory, which also tells us the number of subdirectories, as we have a ".." link from each subdir plus two other links ("." and the link to it in its parent directory). Thus, if find has processed st_nlink-2 subdirs, it assumes there are no more. And Shadowfs simply returned the struct stat for one of its underlying directories. You can work around this by using the "-noleaf" option of find, but I also made a patch for the old Shadowfs (see below). But the new Shadowfs will be very different internally, and I'm waiting for Moritz to release it so I can start doing some work on it (Hello Moritz!). Cheers, GNU/Wolfgang Now here's my patch (note that Shadowfs probably should calculate more of the fields for the stat structure and do caching of the information, which the new version will do): diff -rup shadowfs-0.1.9-/fs.h shadowfs-0.1.9/fs.h --- shadowfs-0.1.9-/fs.h Mon Oct 22 16:15:32 2001 +++ shadowfs-0.1.9/fs.h Thu May 2 22:57:38 2002 @@ -16,6 +16,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __SHADOWFS_FS_H__ +#define __SHADOWFS_FS_H__ + #include <hurd.h> struct dirent_chain @@ -35,3 +38,5 @@ error_t find_writable_fs (struct node *d error_t create_dir_on_writable_fs (struct node *dir, char *name); error_t do_copy_on_write (struct node *dir, mach_port_t port, char *name, int flags, mach_port_t *the_port); + +#endif diff -rup shadowfs-0.1.9-/main.c shadowfs-0.1.9/main.c --- shadowfs-0.1.9-/main.c Mon Oct 22 16:15:32 2001 +++ shadowfs-0.1.9/main.c Thu May 2 23:14:50 2002 @@ -34,7 +34,7 @@ const char *argp_program_version = STANDARD_HURD_VERSION (shadowfs); const char *argp_program_bug_address = "Moritz Schulte <[EMAIL PROTECTED]>"; const char *args_doc = "FILESYSTEMS ..."; -const char *doc = "Hurd Shadowfs translator v" SHADOWFS_VERSION; +const char *doc = "The Hurd Shadowfs translator v" SHADOWFS_VERSION; /* General state information for the shadowfs. */ int shadowfs_flags = 0; diff -rup shadowfs-0.1.9-/netfs.c shadowfs-0.1.9/netfs.c --- shadowfs-0.1.9-/netfs.c Mon Oct 22 16:15:32 2001 +++ shadowfs-0.1.9/netfs.c Sat May 4 01:50:51 2002 @@ -1,6 +1,7 @@ /* Shadowfs - a shadowfs translator for GNU/Hurd Copyright (C) 2001 Moritz Schulte <[EMAIL PROTECTED]> - + Copyright (C) 2002 Wolfgang Jaehrling <[EMAIL PROTECTED]> + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -18,9 +19,12 @@ #define _GNU_SOURCE +#include <hurd.h> #include <hurd/netfs.h> #include <hurd/paths.h> +#include <hurd/io.h> #include <error.h> +#include <errno.h> #include <argz.h> #include <stdio.h> #include <stddef.h> @@ -286,10 +290,80 @@ netfs_validate_stat (struct node *np, st error_t err = 0; if (np != netfs_root_node) - /* The last port is the one we take the stat information from. */ - err = io_stat ((np->nn->ports + np->nn->nports - 1)->port, - &np->nn_stat); + { + struct dirent_chain *dirent_chain; + + /* The last port is the one we take the stat information from. */ + err = io_stat ((np->nn->ports + np->nn->nports - 1)->port, + &np->nn_stat); + /* We need to fix the link count, as we might have more + subdirectories. */ + if (! err) + { + err = shadowfs_readdir (np, &dirent_chain); + if (! err) + { + int link_cnt = 0; + struct dirent_chain *dec; + + /* Delete the entire chain. */ + void free_dirent_chain (void) + { + struct dirent_chain *prev; + + for (; dirent_chain; (prev = dirent_chain, + dirent_chain = dirent_chain->next, + free (prev->dirent), + free (prev))) + ; + } + + /* Find file we wish to io_stat (). */ + file_t shadowfs_lookup (const char *name) + { + int i; + + for (i = 0; i < np->nn->nports; i++) + { + file_t port + = file_name_lookup_under (np->nn->ports[i].port, + name, O_NORW, 0); + + if (port) + return port; + if (errno != ENOENT) + { + err = errno; + return MACH_PORT_NULL; + } + } + err = EIEIO; + return MACH_PORT_NULL; + } + + /* Count directories. */ + for (dec = dirent_chain; dec; dec = dec->next) + { + struct stat stat; + file_t port = shadowfs_lookup (dec->dirent->d_name); + + if (! port) + break; + err = io_stat (port, &stat); + if (err) + break; + mach_port_deallocate (mach_task_self (), port); + + if (stat.st_mode & S_IFDIR) + link_cnt++; + } + free_dirent_chain (); + if (! err) + np->nn_stat.st_nlink = link_cnt; + } + } + } return err; } @@ -695,6 +769,7 @@ netfs_node_norefs (struct node *np) The number of entries in the array is stored in *AMT and the number of bytes in *DATACNT. If the supplied buffer is not large enough to hold the data, it should be grown. */ +/* FIXME: The above argument names are wrong. --wj */ error_t netfs_get_dirents (struct iouser *cred, struct node *dir, int first_entry, int num_entries, char **data, @@ -713,6 +788,7 @@ netfs_get_dirents (struct iouser *cred, if (num_entries == -1 || count < num_entries) { size_t new_size = size + len; + if (max_data_len > 0 && new_size > max_data_len) return 0; size = new_size; diff -rup shadowfs-0.1.9-/node.h shadowfs-0.1.9/node.h --- shadowfs-0.1.9-/node.h Mon Oct 22 16:15:32 2001 +++ shadowfs-0.1.9/node.h Sat May 4 02:02:55 2002 @@ -16,8 +16,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __SHADOWFS_NODE_H__ +#define __SHADOWFS_NODE_H__ + error_t shadowfs_make_node (struct node *dir, char *name, struct node **the_node); error_t make_root_node (struct node **root_node); error_t shadowfs_free_node (struct node *node); error_t add_port_to_node (struct node *node, mach_port_t port, int flags); + +#endif Only in shadowfs-0.1.9: node.h~ diff -rup shadowfs-0.1.9-/shadowfs.h shadowfs-0.1.9/shadowfs.h --- shadowfs-0.1.9-/shadowfs.h Mon Oct 22 16:15:32 2001 +++ shadowfs-0.1.9/shadowfs.h Sat May 4 02:03:16 2002 @@ -16,6 +16,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __SHADOWFS_SHADOWFS_H +#define __SHADOWFS_SHADOWFS_H + #include <dirent.h> #include "version.h" @@ -64,3 +67,5 @@ struct netnode int nports; /* The number of ports in PORTS. */ struct node *dir; /* The parent directory. */ }; + +#endif _______________________________________________ Help-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/help-hurd