* vfs.c: Split garbage collection code into ...
* gc.c: ... this. * vfs.h: Corresponding code moved ... * gc.h: ... here. * Makefile.am: Adjustments for the above.
Этот коммит содержится в:
родитель
7633c40204
Коммит
b33f2cbb47
@ -1,3 +1,11 @@
|
||||
2003-11-07 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* vfs.c: Split garbage collection code into ...
|
||||
* gc.c: ... this.
|
||||
* vfs.h: Corresponding code moved ...
|
||||
* gc.h: ... here.
|
||||
* Makefile.am: Adjustments for the above.
|
||||
|
||||
2003-11-05 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* vfs.c: Eliminate MC_OP. Reorder other MC_* macros for
|
||||
|
@ -16,6 +16,7 @@ BASICFILES = \
|
||||
cpio.c \
|
||||
direntry.c \
|
||||
extfs.c \
|
||||
gc.c \
|
||||
local.c \
|
||||
tar.c \
|
||||
sfs.c \
|
||||
@ -24,6 +25,7 @@ BASICFILES = \
|
||||
|
||||
VFSHDRS = \
|
||||
ftpfs.h \
|
||||
gc.h \
|
||||
local.h \
|
||||
mcfs.h \
|
||||
mcfsutil.h \
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include "utilvfs.h"
|
||||
#include "gc.h" /* vfs_rmstamp */
|
||||
#include "xdirentry.h"
|
||||
|
||||
enum {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "utilvfs.h"
|
||||
#include "gc.h" /* vfs_rmstamp */
|
||||
#include "xdirentry.h"
|
||||
|
||||
#define CALL(x) if (MEDATA->x) MEDATA->x
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "utilvfs.h"
|
||||
#include "../src/execute.h" /* For shell_execute */
|
||||
#include "vfs.h"
|
||||
#include "gc.h" /* vfs_rmstamp */
|
||||
|
||||
#undef ERRNOR
|
||||
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "xdirentry.h"
|
||||
#include "vfs.h"
|
||||
#include "gc.h" /* vfs_add_noncurrent_stamps */
|
||||
#include "tcputil.h"
|
||||
|
||||
#define FISH_DIRECTORY_TIMEOUT 30 * 60
|
||||
|
@ -72,6 +72,7 @@ What to do with this?
|
||||
|
||||
#include "xdirentry.h"
|
||||
#include "vfs.h"
|
||||
#include "gc.h" /* vfs_add_noncurrent_stamps */
|
||||
#include "tcputil.h"
|
||||
#include "../src/setup.h" /* for load_anon_passwd */
|
||||
#include "ftpfs.h"
|
||||
|
395
vfs/gc.c
Обычный файл
395
vfs/gc.c
Обычный файл
@ -0,0 +1,395 @@
|
||||
/* Virtual File System grabage collection code
|
||||
Copyright (C) 1995-2003 The Free Software Foundation
|
||||
|
||||
Written by: 1995 Miguel de Icaza
|
||||
1995 Jakub Jelinek
|
||||
1998 Pavel Machek
|
||||
2003 Pavel Roskin
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License
|
||||
as published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For atol() */
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h> /* is_digit() */
|
||||
|
||||
#include "utilvfs.h"
|
||||
#include "gc.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#include "../src/panel.h" /* get_current_panel() */
|
||||
#include "../src/layout.h" /* get_current_type() */
|
||||
|
||||
|
||||
int vfs_timeout = 60; /* VFS timeout in seconds */
|
||||
|
||||
static struct vfs_stamping *stamps;
|
||||
|
||||
|
||||
static void
|
||||
vfs_addstamp (struct vfs_class *v, vfsid id, struct vfs_stamping *parent)
|
||||
{
|
||||
if (!(v->flags & VFSF_LOCAL) && id != (vfsid) - 1) {
|
||||
struct vfs_stamping *stamp;
|
||||
struct vfs_stamping *last_stamp = NULL;
|
||||
|
||||
for (stamp = stamps; stamp != NULL; stamp = stamp->next) {
|
||||
if (stamp->v == v && stamp->id == id) {
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
return;
|
||||
}
|
||||
last_stamp = stamp;
|
||||
}
|
||||
stamp = g_new (struct vfs_stamping, 1);
|
||||
stamp->v = v;
|
||||
stamp->id = id;
|
||||
if (parent) {
|
||||
struct vfs_stamping *st = stamp;
|
||||
while (parent) {
|
||||
st->parent = g_new (struct vfs_stamping, 1);
|
||||
*st->parent = *parent;
|
||||
parent = parent->parent;
|
||||
st = st->parent;
|
||||
}
|
||||
st->parent = 0;
|
||||
} else
|
||||
stamp->parent = 0;
|
||||
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
stamp->next = 0;
|
||||
|
||||
if (stamps) {
|
||||
/* Add to the end */
|
||||
last_stamp->next = stamp;
|
||||
} else {
|
||||
/* Add first element */
|
||||
stamps = stamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_stamp (struct vfs_class *v, vfsid id)
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
|
||||
for (stamp = stamps; stamp != NULL; stamp = stamp->next)
|
||||
if (stamp->v == v && stamp->id == id) {
|
||||
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
if (stamp->parent != NULL)
|
||||
vfs_stamp (stamp->parent->v, stamp->parent->id);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vfs_rm_parents (struct vfs_stamping *stamp)
|
||||
{
|
||||
struct vfs_stamping *parent;
|
||||
|
||||
while (stamp) {
|
||||
parent = stamp->parent;
|
||||
g_free (stamp);
|
||||
stamp = parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_rmstamp (struct vfs_class *v, vfsid id, int removeparents)
|
||||
{
|
||||
struct vfs_stamping *stamp, *st1;
|
||||
|
||||
for (stamp = stamps, st1 = NULL; stamp != NULL;
|
||||
st1 = stamp, stamp = stamp->next)
|
||||
if (stamp->v == v && stamp->id == id) {
|
||||
if (stamp->parent != NULL) {
|
||||
if (removeparents)
|
||||
vfs_rmstamp (stamp->parent->v, stamp->parent->id, 1);
|
||||
vfs_rm_parents (stamp->parent);
|
||||
stamp->parent = NULL;
|
||||
continue; /* rescan the tree */
|
||||
}
|
||||
if (st1 == NULL) {
|
||||
stamps = stamp->next;
|
||||
} else {
|
||||
st1->next = stamp->next;
|
||||
}
|
||||
g_free (stamp);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vfsid
|
||||
vfs_ncs_getid (struct vfs_class *nvfs, const char *dir,
|
||||
struct vfs_stamping **par)
|
||||
{
|
||||
vfsid nvfsid;
|
||||
char *dir1;
|
||||
|
||||
dir1 = concat_dir_and_file (dir, "");
|
||||
nvfsid = (*nvfs->getid) (nvfs, dir1, par);
|
||||
g_free (dir1);
|
||||
return nvfsid;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_parent (struct vfs_class *nvfs, vfsid nvfsid,
|
||||
struct vfs_stamping *parent)
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
|
||||
for (stamp = parent; stamp; stamp = stamp->parent)
|
||||
if (stamp->v == nvfs && stamp->id == nvfsid)
|
||||
break;
|
||||
|
||||
return (stamp ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vfs_stamp_path (char *path)
|
||||
{
|
||||
struct vfs_class *vfs;
|
||||
vfsid id;
|
||||
struct vfs_stamping *par, *stamp;
|
||||
|
||||
vfs = vfs_get_class (path);
|
||||
id = vfs_ncs_getid (vfs, path, &par);
|
||||
vfs_addstamp (vfs, id, par);
|
||||
|
||||
for (stamp = par; stamp != NULL; stamp = stamp->parent)
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
vfs_rm_parents (par);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_vfs_add_noncurrent_stamps (struct vfs_class *oldvfs, vfsid oldvfsid,
|
||||
struct vfs_stamping *parent)
|
||||
{
|
||||
struct vfs_class *nvfs, *n2vfs, *n3vfs;
|
||||
vfsid nvfsid, n2vfsid, n3vfsid;
|
||||
struct vfs_stamping *par, *stamp;
|
||||
int f;
|
||||
|
||||
/* FIXME: As soon as we convert to multiple panels, this stuff
|
||||
has to change. It works like this: We do not time out the
|
||||
vfs's which are current in any panel and on the other
|
||||
side we add the old directory with all its parents which
|
||||
are not in any panel (if we find such one, we stop adding
|
||||
parents to the time-outing structure. */
|
||||
|
||||
/* There are three directories we have to take care of: current_dir,
|
||||
current_panel->cwd and other_panel->cwd. Athough most of the time either
|
||||
current_dir and current_panel->cwd or current_dir and other_panel->cwd are the
|
||||
same, it's possible that all three are different -- Norbert */
|
||||
|
||||
if (!current_panel)
|
||||
return;
|
||||
|
||||
nvfs = vfs_get_class (vfs_get_current_dir ());
|
||||
nvfsid = vfs_ncs_getid (nvfs, vfs_get_current_dir (), &par);
|
||||
vfs_rmstamp (nvfs, nvfsid, 1);
|
||||
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((nvfs == oldvfs && nvfsid == oldvfsid) || oldvfsid == (vfsid *) - 1
|
||||
|| f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_current_type () == view_listing) {
|
||||
n2vfs = vfs_get_class (current_panel->cwd);
|
||||
n2vfsid = vfs_ncs_getid (n2vfs, current_panel->cwd, &par);
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((n2vfs == oldvfs && n2vfsid == oldvfsid) || f)
|
||||
return;
|
||||
} else {
|
||||
n2vfs = (struct vfs_class *) -1;
|
||||
n2vfsid = (vfsid) - 1;
|
||||
}
|
||||
|
||||
if (get_other_type () == view_listing) {
|
||||
n3vfs = vfs_get_class (other_panel->cwd);
|
||||
n3vfsid = vfs_ncs_getid (n3vfs, other_panel->cwd, &par);
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((n3vfs == oldvfs && n3vfsid == oldvfsid) || f)
|
||||
return;
|
||||
} else {
|
||||
n3vfs = (struct vfs_class *) -1;
|
||||
n3vfsid = (vfsid) - 1;
|
||||
}
|
||||
|
||||
if ((*oldvfs->nothingisopen) (oldvfsid)) {
|
||||
#if 0 /* need setctl for this */
|
||||
if (oldvfs == &vfs_extfs_ops
|
||||
&& ((extfs_archive *) oldvfsid)->name == 0) {
|
||||
/* Free the resources immediatly when we leave a mtools fs
|
||||
('cd a:') instead of waiting for the vfs-timeout */
|
||||
(oldvfs->free) (oldvfsid);
|
||||
} else
|
||||
#endif
|
||||
vfs_addstamp (oldvfs, oldvfsid, parent);
|
||||
for (stamp = parent; stamp != NULL; stamp = stamp->parent) {
|
||||
if ((stamp->v == nvfs && stamp->id == nvfsid)
|
||||
|| (stamp->v == n2vfs && stamp->id == n2vfsid)
|
||||
|| (stamp->v == n3vfs && stamp->id == n3vfsid)
|
||||
|| stamp->id == (vfsid) - 1
|
||||
|| !(*stamp->v->nothingisopen) (stamp->id))
|
||||
break;
|
||||
#if 0
|
||||
if (stamp->v == &vfs_extfs_ops
|
||||
&& ((extfs_archive *) stamp->id)->name == 0) {
|
||||
(stamp->v->free) (stamp->id);
|
||||
vfs_rmstamp (stamp->v, stamp->id, 0);
|
||||
} else
|
||||
#endif
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_add_noncurrent_stamps (struct vfs_class *oldvfs, vfsid oldvfsid,
|
||||
struct vfs_stamping *parent)
|
||||
{
|
||||
_vfs_add_noncurrent_stamps (oldvfs, oldvfsid, parent);
|
||||
vfs_rm_parents (parent);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_add_current_stamps (void)
|
||||
{
|
||||
vfs_stamp_path (vfs_get_current_dir ());
|
||||
|
||||
if (current_panel) {
|
||||
if (get_current_type () == view_listing)
|
||||
vfs_stamp_path (current_panel->cwd);
|
||||
}
|
||||
|
||||
if (other_panel) {
|
||||
if (get_other_type () == view_listing)
|
||||
vfs_stamp_path (other_panel->cwd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Compare two timeval structures. Return 0 is t1 is less than t2. */
|
||||
static inline int
|
||||
timeoutcmp (struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return ((t1->tv_sec < t2->tv_sec)
|
||||
|| ((t1->tv_sec == t2->tv_sec)
|
||||
&& (t1->tv_usec <= t2->tv_usec)));
|
||||
}
|
||||
|
||||
|
||||
/* This is called from timeout handler with now = 0, or can be called
|
||||
with now = 1 to force freeing all filesystems that are not in use */
|
||||
void
|
||||
vfs_expire (int now)
|
||||
{
|
||||
static int locked = 0;
|
||||
struct timeval time;
|
||||
struct vfs_stamping *stamp, *st;
|
||||
|
||||
/* Avoid recursive invocation, e.g. when one of the free functions
|
||||
calls message */
|
||||
if (locked)
|
||||
return;
|
||||
locked = 1;
|
||||
|
||||
gettimeofday (&time, NULL);
|
||||
time.tv_sec -= vfs_timeout;
|
||||
|
||||
for (stamp = stamps; stamp != NULL;) {
|
||||
if (now || (timeoutcmp (&stamp->time, &time))) {
|
||||
st = stamp->next;
|
||||
(*stamp->v->free) (stamp->id);
|
||||
vfs_rmstamp (stamp->v, stamp->id, 0);
|
||||
stamp = st;
|
||||
} else
|
||||
stamp = stamp->next;
|
||||
}
|
||||
locked = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of seconds remaining to the vfs timeout.
|
||||
* FIXME: The code should be improved to actually return the number of
|
||||
* seconds until the next item times out.
|
||||
*/
|
||||
int
|
||||
vfs_timeouts ()
|
||||
{
|
||||
return stamps ? 10 : 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_timeout_handler (void)
|
||||
{
|
||||
vfs_expire (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_release_path (const char *dir)
|
||||
{
|
||||
struct vfs_class *oldvfs;
|
||||
vfsid oldvfsid;
|
||||
struct vfs_stamping *parent;
|
||||
|
||||
oldvfs = vfs_get_class (dir);
|
||||
oldvfsid = vfs_ncs_getid (oldvfs, dir, &parent);
|
||||
vfs_add_noncurrent_stamps (oldvfs, oldvfsid, parent);
|
||||
}
|
||||
|
||||
|
||||
/* Free all data */
|
||||
void
|
||||
vfs_gc_done (void)
|
||||
{
|
||||
struct vfs_stamping *stamp, *st;
|
||||
|
||||
for (stamp = stamps, stamps = 0; stamp != NULL;) {
|
||||
(*stamp->v->free) (stamp->id);
|
||||
st = stamp->next;
|
||||
g_free (stamp);
|
||||
stamp = st;
|
||||
}
|
||||
|
||||
if (stamps)
|
||||
vfs_rmstamp (stamps->v, stamps->id, 1);
|
||||
}
|
27
vfs/gc.h
Обычный файл
27
vfs/gc.h
Обычный файл
@ -0,0 +1,27 @@
|
||||
#ifndef __GC_H
|
||||
#define __GC_H
|
||||
|
||||
struct vfs_stamping {
|
||||
struct vfs_class *v;
|
||||
vfsid id;
|
||||
struct vfs_stamping *parent;
|
||||
struct vfs_stamping *next;
|
||||
struct timeval time;
|
||||
};
|
||||
|
||||
extern int vfs_timeout;
|
||||
|
||||
void vfs_stamp (struct vfs_class *, vfsid);
|
||||
void vfs_rmstamp (struct vfs_class *, vfsid, int);
|
||||
void vfs_add_noncurrent_stamps (struct vfs_class *, vfsid,
|
||||
struct vfs_stamping *);
|
||||
void vfs_add_current_stamps (void);
|
||||
void vfs_timeout_handler (void);
|
||||
void vfs_expire (int);
|
||||
int vfs_timeouts (void);
|
||||
void vfs_release_path (const char *dir);
|
||||
vfsid vfs_ncs_getid (struct vfs_class *nvfs, const char *dir,
|
||||
struct vfs_stamping **par);
|
||||
void vfs_gc_done (void);
|
||||
|
||||
#endif /* __GC_H */
|
@ -22,6 +22,7 @@
|
||||
#include "utilvfs.h"
|
||||
|
||||
#include "vfs.h"
|
||||
#include "gc.h" /* vfs_add_noncurrent_stamps */
|
||||
#include "local.h"
|
||||
#include "../src/execute.h" /* EXECUTE_AS_SHELL */
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
#include "utilvfs.h"
|
||||
#include "gc.h" /* vfs_rmstamp */
|
||||
#include "xdirentry.h"
|
||||
|
||||
static struct vfs_class vfs_tarfs_ops;
|
||||
|
349
vfs/vfs.c
349
vfs/vfs.c
@ -28,10 +28,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifndef NO_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For atol() */
|
||||
#include <stdarg.h>
|
||||
@ -42,18 +38,13 @@
|
||||
#include <ctype.h> /* is_digit() */
|
||||
|
||||
#include "utilvfs.h"
|
||||
|
||||
#include "../src/panel.h" /* get_current_panel() */
|
||||
#include "../src/layout.h" /* get_current_type() */
|
||||
#include "../src/wtools.h" /* input_dialog() */
|
||||
#include "gc.h"
|
||||
|
||||
#include "vfs.h"
|
||||
#ifdef USE_NETCODE
|
||||
# include "tcputil.h"
|
||||
#endif
|
||||
|
||||
int vfs_timeout = 60; /* VFS timeout in seconds */
|
||||
|
||||
/* They keep track of the current directory */
|
||||
static struct vfs_class *current_vfs;
|
||||
static char *current_dir;
|
||||
@ -306,116 +297,6 @@ vfs_get_class (const char *path)
|
||||
return vfs;
|
||||
}
|
||||
|
||||
static struct vfs_stamping *stamps;
|
||||
|
||||
/*
|
||||
* Returns the number of seconds remaining to the vfs timeout
|
||||
*
|
||||
* FIXME: currently this is set to 10 seconds. We should compute this.
|
||||
*/
|
||||
int
|
||||
vfs_timeouts ()
|
||||
{
|
||||
return stamps ? 10 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
vfs_addstamp (struct vfs_class *v, vfsid id, struct vfs_stamping *parent)
|
||||
{
|
||||
if (!(v->flags & VFSF_LOCAL) && id != (vfsid)-1){
|
||||
struct vfs_stamping *stamp;
|
||||
struct vfs_stamping *last_stamp = NULL;
|
||||
|
||||
for (stamp = stamps; stamp != NULL; stamp = stamp->next) {
|
||||
if (stamp->v == v && stamp->id == id){
|
||||
gettimeofday(&(stamp->time), NULL);
|
||||
return;
|
||||
}
|
||||
last_stamp = stamp;
|
||||
}
|
||||
stamp = g_new (struct vfs_stamping, 1);
|
||||
stamp->v = v;
|
||||
stamp->id = id;
|
||||
if (parent){
|
||||
struct vfs_stamping *st = stamp;
|
||||
while (parent){
|
||||
st->parent = g_new (struct vfs_stamping, 1);
|
||||
*st->parent = *parent;
|
||||
parent = parent->parent;
|
||||
st = st->parent;
|
||||
}
|
||||
st->parent = 0;
|
||||
}
|
||||
else
|
||||
stamp->parent = 0;
|
||||
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
stamp->next = 0;
|
||||
|
||||
if (stamps) {
|
||||
/* Add to the end */
|
||||
last_stamp->next = stamp;
|
||||
} else {
|
||||
/* Add first element */
|
||||
stamps = stamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vfs_stamp (struct vfs_class *v, vfsid id)
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
|
||||
for (stamp = stamps; stamp != NULL; stamp = stamp->next)
|
||||
if (stamp->v == v && stamp->id == id){
|
||||
|
||||
gettimeofday (&(stamp->time), NULL);
|
||||
if (stamp->parent != NULL)
|
||||
vfs_stamp (stamp->parent->v, stamp->parent->id);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vfs_rm_parents (struct vfs_stamping *stamp)
|
||||
{
|
||||
struct vfs_stamping *parent;
|
||||
|
||||
while (stamp) {
|
||||
parent = stamp->parent;
|
||||
g_free (stamp);
|
||||
stamp = parent;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vfs_rmstamp (struct vfs_class *v, vfsid id, int removeparents)
|
||||
{
|
||||
struct vfs_stamping *stamp, *st1;
|
||||
|
||||
for (stamp = stamps, st1 = NULL; stamp != NULL;
|
||||
st1 = stamp, stamp = stamp->next)
|
||||
if (stamp->v == v && stamp->id == id) {
|
||||
if (stamp->parent != NULL) {
|
||||
if (removeparents)
|
||||
vfs_rmstamp (stamp->parent->v, stamp->parent->id, 1);
|
||||
vfs_rm_parents (stamp->parent);
|
||||
stamp->parent = NULL;
|
||||
continue; /* rescan the tree */
|
||||
}
|
||||
if (st1 == NULL) {
|
||||
stamps = stamp->next;
|
||||
} else {
|
||||
st1->next = stamp->next;
|
||||
}
|
||||
g_free (stamp);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ferrno (struct vfs_class *vfs)
|
||||
{
|
||||
@ -777,158 +658,6 @@ vfs_canon (const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
static vfsid
|
||||
vfs_ncs_getid (struct vfs_class *nvfs, const char *dir, struct vfs_stamping **par)
|
||||
{
|
||||
vfsid nvfsid;
|
||||
char *dir1;
|
||||
|
||||
dir1 = concat_dir_and_file (dir, "");
|
||||
nvfsid = (*nvfs->getid) (nvfs, dir1, par);
|
||||
g_free (dir1);
|
||||
return nvfsid;
|
||||
}
|
||||
|
||||
static int
|
||||
is_parent (struct vfs_class * nvfs, vfsid nvfsid, struct vfs_stamping *parent)
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
|
||||
for (stamp = parent; stamp; stamp = stamp->parent)
|
||||
if (stamp->v == nvfs && stamp->id == nvfsid)
|
||||
break;
|
||||
|
||||
return (stamp ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_vfs_add_noncurrent_stamps (struct vfs_class *oldvfs, vfsid oldvfsid,
|
||||
struct vfs_stamping *parent)
|
||||
{
|
||||
struct vfs_class *nvfs, *n2vfs, *n3vfs;
|
||||
vfsid nvfsid, n2vfsid, n3vfsid;
|
||||
struct vfs_stamping *par, *stamp;
|
||||
int f;
|
||||
|
||||
/* FIXME: As soon as we convert to multiple panels, this stuff
|
||||
has to change. It works like this: We do not time out the
|
||||
vfs's which are current in any panel and on the other
|
||||
side we add the old directory with all its parents which
|
||||
are not in any panel (if we find such one, we stop adding
|
||||
parents to the time-outing structure. */
|
||||
|
||||
/* There are three directories we have to take care of: current_dir,
|
||||
current_panel->cwd and other_panel->cwd. Athough most of the time either
|
||||
current_dir and current_panel->cwd or current_dir and other_panel->cwd are the
|
||||
same, it's possible that all three are different -- Norbert */
|
||||
|
||||
if (!current_panel)
|
||||
return;
|
||||
|
||||
nvfs = vfs_get_class (current_dir);
|
||||
nvfsid = vfs_ncs_getid (nvfs, current_dir, &par);
|
||||
vfs_rmstamp (nvfs, nvfsid, 1);
|
||||
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((nvfs == oldvfs && nvfsid == oldvfsid) || oldvfsid == (vfsid *) - 1
|
||||
|| f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_current_type () == view_listing) {
|
||||
n2vfs = vfs_get_class (current_panel->cwd);
|
||||
n2vfsid = vfs_ncs_getid (n2vfs, current_panel->cwd, &par);
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((n2vfs == oldvfs && n2vfsid == oldvfsid) || f)
|
||||
return;
|
||||
} else {
|
||||
n2vfs = (struct vfs_class *) -1;
|
||||
n2vfsid = (vfsid) - 1;
|
||||
}
|
||||
|
||||
if (get_other_type () == view_listing) {
|
||||
n3vfs = vfs_get_class (other_panel->cwd);
|
||||
n3vfsid = vfs_ncs_getid (n3vfs, other_panel->cwd, &par);
|
||||
f = is_parent (oldvfs, oldvfsid, par);
|
||||
vfs_rm_parents (par);
|
||||
if ((n3vfs == oldvfs && n3vfsid == oldvfsid) || f)
|
||||
return;
|
||||
} else {
|
||||
n3vfs = (struct vfs_class *) -1;
|
||||
n3vfsid = (vfsid) - 1;
|
||||
}
|
||||
|
||||
if ((*oldvfs->nothingisopen) (oldvfsid)) {
|
||||
#if 0 /* need setctl for this */
|
||||
if (oldvfs == &vfs_extfs_ops
|
||||
&& ((extfs_archive *) oldvfsid)->name == 0) {
|
||||
/* Free the resources immediatly when we leave a mtools fs
|
||||
('cd a:') instead of waiting for the vfs-timeout */
|
||||
(oldvfs->free) (oldvfsid);
|
||||
} else
|
||||
#endif
|
||||
vfs_addstamp (oldvfs, oldvfsid, parent);
|
||||
for (stamp = parent; stamp != NULL; stamp = stamp->parent) {
|
||||
if ((stamp->v == nvfs && stamp->id == nvfsid)
|
||||
|| (stamp->v == n2vfs && stamp->id == n2vfsid)
|
||||
|| (stamp->v == n3vfs && stamp->id == n3vfsid)
|
||||
|| stamp->id == (vfsid) - 1
|
||||
|| !(*stamp->v->nothingisopen) (stamp->id))
|
||||
break;
|
||||
#if 0
|
||||
if (stamp->v == &vfs_extfs_ops
|
||||
&& ((extfs_archive *) stamp->id)->name == 0) {
|
||||
(stamp->v->free) (stamp->id);
|
||||
vfs_rmstamp (stamp->v, stamp->id, 0);
|
||||
} else
|
||||
#endif
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vfs_add_noncurrent_stamps (struct vfs_class *oldvfs, vfsid oldvfsid,
|
||||
struct vfs_stamping *parent)
|
||||
{
|
||||
_vfs_add_noncurrent_stamps (oldvfs, oldvfsid, parent);
|
||||
vfs_rm_parents (parent);
|
||||
}
|
||||
|
||||
static void
|
||||
vfs_stamp_path (char *path)
|
||||
{
|
||||
struct vfs_class *vfs;
|
||||
vfsid id;
|
||||
struct vfs_stamping *par, *stamp;
|
||||
|
||||
vfs = vfs_get_class (path);
|
||||
id = vfs_ncs_getid (vfs, path, &par);
|
||||
vfs_addstamp (vfs, id, par);
|
||||
|
||||
for (stamp = par; stamp != NULL; stamp = stamp->parent)
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
vfs_rm_parents (par);
|
||||
}
|
||||
|
||||
void
|
||||
vfs_add_current_stamps (void)
|
||||
{
|
||||
vfs_stamp_path (current_dir);
|
||||
|
||||
if (current_panel) {
|
||||
if (get_current_type () == view_listing)
|
||||
vfs_stamp_path (current_panel->cwd);
|
||||
}
|
||||
|
||||
if (other_panel) {
|
||||
if (get_other_type () == view_listing)
|
||||
vfs_stamp_path (other_panel->cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* VFS chdir.
|
||||
* Return 0 on success, -1 on failure.
|
||||
@ -1175,52 +904,6 @@ mc_ungetlocalcopy (const char *pathname, char *local, int has_changed)
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hmm, as timeout is minute or so, do we need to care about usecs?
|
||||
*/
|
||||
static inline int
|
||||
timeoutcmp (struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return ((t1->tv_sec < t2->tv_sec)
|
||||
|| ((t1->tv_sec == t2->tv_sec) && (t1->tv_usec <= t2->tv_usec)));
|
||||
}
|
||||
|
||||
/* This is called from timeout handler with now = 0, or can be called
|
||||
with now = 1 to force freeing all filesystems that are not in use */
|
||||
|
||||
void
|
||||
vfs_expire (int now)
|
||||
{
|
||||
static int locked = 0;
|
||||
struct timeval time;
|
||||
struct vfs_stamping *stamp, *st;
|
||||
|
||||
/* Avoid recursive invocation, e.g. when one of the free functions
|
||||
calls message */
|
||||
if (locked)
|
||||
return;
|
||||
locked = 1;
|
||||
|
||||
gettimeofday (&time, NULL);
|
||||
time.tv_sec -= vfs_timeout;
|
||||
|
||||
for (stamp = stamps; stamp != NULL;){
|
||||
if (now || (timeoutcmp (&stamp->time, &time))){
|
||||
st = stamp->next;
|
||||
(*stamp->v->free) (stamp->id);
|
||||
vfs_rmstamp (stamp->v, stamp->id, 0);
|
||||
stamp = st;
|
||||
} else
|
||||
stamp = stamp->next;
|
||||
}
|
||||
locked = 0;
|
||||
}
|
||||
|
||||
void
|
||||
vfs_timeout_handler (void)
|
||||
{
|
||||
vfs_expire (0);
|
||||
}
|
||||
|
||||
void
|
||||
vfs_init (void)
|
||||
@ -1257,25 +940,16 @@ vfs_init (void)
|
||||
void
|
||||
vfs_shut (void)
|
||||
{
|
||||
struct vfs_stamping *stamp, *st;
|
||||
struct vfs_class *vfs;
|
||||
|
||||
for (stamp = stamps, stamps = 0; stamp != NULL;){
|
||||
(*stamp->v->free)(stamp->id);
|
||||
st = stamp->next;
|
||||
g_free (stamp);
|
||||
stamp = st;
|
||||
}
|
||||
vfs_gc_done ();
|
||||
|
||||
if (stamps)
|
||||
vfs_rmstamp (stamps->v, stamps->id, 1);
|
||||
|
||||
if (current_dir)
|
||||
g_free (current_dir);
|
||||
|
||||
for (vfs=vfs_list; vfs; vfs=vfs->next)
|
||||
if (vfs->done)
|
||||
(*vfs->done) (vfs);
|
||||
for (vfs = vfs_list; vfs; vfs = vfs->next)
|
||||
if (vfs->done)
|
||||
(*vfs->done) (vfs);
|
||||
|
||||
g_slist_free (vfs_openfiles);
|
||||
}
|
||||
@ -1308,16 +982,3 @@ vfs_translate_url (const char *url)
|
||||
else
|
||||
return g_strdup (url);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vfs_release_path (const char *dir)
|
||||
{
|
||||
struct vfs_class *oldvfs;
|
||||
vfsid oldvfsid;
|
||||
struct vfs_stamping *parent;
|
||||
|
||||
oldvfs = vfs_get_class (dir);
|
||||
oldvfsid = vfs_ncs_getid (oldvfs, dir, &parent);
|
||||
vfs_add_noncurrent_stamps (oldvfs, oldvfsid, parent);
|
||||
}
|
||||
|
20
vfs/vfs.h
20
vfs/vfs.h
@ -7,14 +7,7 @@
|
||||
|
||||
|
||||
typedef void *vfsid;
|
||||
|
||||
struct vfs_stamping {
|
||||
struct vfs_class *v;
|
||||
vfsid id;
|
||||
struct vfs_stamping *parent; /* At the moment applies to tarfs only */
|
||||
struct vfs_stamping *next;
|
||||
struct timeval time;
|
||||
};
|
||||
struct vfs_stamping;
|
||||
|
||||
/* Flags of VFS classes */
|
||||
#define VFSF_LOCAL 1 /* Class is local (not virtual) filesystem */
|
||||
@ -131,17 +124,6 @@ vfs_file_is_local (const char *filename)
|
||||
return vfs_file_class_flags (filename) & VFSF_LOCAL;
|
||||
}
|
||||
|
||||
extern int vfs_timeout;
|
||||
|
||||
void vfs_stamp (struct vfs_class *, vfsid);
|
||||
void vfs_rmstamp (struct vfs_class *, vfsid, int);
|
||||
void vfs_add_noncurrent_stamps (struct vfs_class *, vfsid, struct vfs_stamping *);
|
||||
void vfs_add_current_stamps (void);
|
||||
void vfs_timeout_handler (void);
|
||||
void vfs_expire (int);
|
||||
int vfs_timeouts (void);
|
||||
void vfs_release_path (const char *dir);
|
||||
|
||||
void vfs_fill_names (void (*)(char *));
|
||||
char *vfs_translate_url (const char *);
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user