> One possible solution would be to mark the archive as dirty whenever any > command is issued to change it. That flag would go to struct archive in > extfs.h.
I'm attaching an implementation of the above. I wrote it in 10 minites and the testing shows that it doesn't work properly. But it can be a good starting point if you want to work on this. -- Regards, Pavel Roskin
--- extfs.c +++ extfs.c @@ -82,6 +82,7 @@ static struct entry * find_entry (struct entry *dir, char *name, int make_dirs, int make_file); static int extfs_which (vfs *me, char *path); static void remove_entry (struct entry *e); +static void extfs_free (vfsid id); static struct archive *first_archive = NULL; static int my_errno = 0; @@ -414,7 +415,8 @@ get_path_mangle (char *inname, struct ar { char *local, *archive_name, *op; int result = -1; - struct archive *parc; + struct archive *p; + struct archive *parc = NULL; struct vfs_stamping *parent; vfs *v; int fstype; @@ -437,32 +439,42 @@ get_path_mangle (char *inname, struct ar * All filesystems should have some local archive, at least * it can be '/'. */ - for (parc = first_archive; parc != NULL; parc = parc->next) - if (parc->name) { - if (!strcmp (parc->name, archive_name)) { - vfs_stamp (&vfs_extfs_ops, (vfsid) parc); - goto return_success; + for (p = first_archive; p != NULL; p = p->next) + if (p->name) { + if (!strcmp (p->name, archive_name)) { + vfs_stamp (&vfs_extfs_ops, (vfsid) p); + parc = p; } } - result = do_not_open ? -1 : read_archive (fstype, archive_name, &parc); - if (result == -1) - ERRNOR (EIO, NULL); - - if (archive_name) { - v = vfs_type (archive_name); - if (v == &vfs_local_ops) { - parent = NULL; - } else { - parent = g_new (struct vfs_stamping, 1); - parent->v = v; - parent->next = 0; - parent->id = (*v->getid) (v, archive_name, &(parent->parent)); + if (parc && parc->dirty) { + extfs_free ((vfsid) parc); + parc = NULL; + } + + if (!parc) { + result = + do_not_open ? -1 : read_archive (fstype, archive_name, &parc); + if (result == -1) + ERRNOR (EIO, NULL); + + if (archive_name) { + v = vfs_type (archive_name); + if (v == &vfs_local_ops) { + parent = NULL; + } else { + parent = g_new (struct vfs_stamping, 1); + parent->v = v; + parent->next = 0; + parent->id = + (*v->getid) (v, archive_name, &(parent->parent)); + } + vfs_add_noncurrent_stamps (&vfs_extfs_ops, (vfsid) parc, + parent); + vfs_rm_parents (parent); } - vfs_add_noncurrent_stamps (&vfs_extfs_ops, (vfsid) parc, parent); - vfs_rm_parents (parent); } - return_success: + *archive = parc; return local; } @@ -702,6 +714,7 @@ static int extfs_close (void *data) /* Commit the file if it has changed */ if (file->has_changed) { + file->archive->dirty = 1; if (extfs_cmd (" copyin ", file->archive, file->entry, file->entry->inode->local_filename)) errno_code = EIO; @@ -1028,6 +1041,7 @@ static int extfs_unlink (vfs *me, char * return -1; if (S_ISDIR (entry->inode->mode)) ERRNOR (EISDIR, -1); + archive->dirty = 1; if (extfs_cmd (" rm ", archive, entry, "")){ my_errno = EIO; return -1; @@ -1054,6 +1068,7 @@ static int extfs_mkdir (vfs *me, char *p return -1; if (!S_ISDIR (entry->inode->mode)) ERRNOR (ENOTDIR, -1); + archive->dirty = 1; if (extfs_cmd (" mkdir ", archive, entry, "")){ my_errno = EIO; remove_entry (entry); @@ -1078,6 +1093,7 @@ static int extfs_rmdir (vfs *me, char *p return -1; if (!S_ISDIR (entry->inode->mode)) ERRNOR (ENOTDIR, -1); + archive->dirty = 1; if (extfs_cmd (" rmdir ", archive, entry, "")){ my_errno = EIO; return -1; --- extfs.h +++ extfs.h @@ -25,6 +25,7 @@ struct stat local_stat; dev_t rdev; int fd_usage; + int dirty; ino_t __inode_counter; struct entry *root_entry; struct entry *current_dir;