lkml.org 
[lkml]   [2004]   [Oct]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH 5/28] VFS: Make expiry timeout configurable
Date
From
This patch modifies the expiry logic to make timeouts configurable.  We do
this by using an atomic counter that ticks downwards every second of
non-usage. We also store a per vfsmount value of what this timer gets reset
to on every mntput.

Signed-off-by: Mike Waychison <michael.waychison@sun.com>
---
fs/namespace.c | 33 +++++++++++++++++++++++----------
include/linux/mount.h | 6 ++++--
2 files changed, 27 insertions(+), 12 deletions(-)
Index: linux-2.6.9-quilt/include/linux/mount.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/mount.h 2004-10-22 17:17:34.147272968 -0400
+++ linux-2.6.9-quilt/include/linux/mount.h 2004-10-22 17:17:35.377086008 -0400
@@ -29,7 +29,9 @@ struct vfsmount
struct list_head mnt_child; /* and going through their mnt_child */
atomic_t mnt_count;
int mnt_flags;
- int mnt_expiry_mark; /* true if marked for expiry */
+ int mnt_active; /* flag set on mntput() */
+ int mnt_expiry_countdown; /* countdown of ticks until expiry */
+ int mnt_expiry_ticks; /* total ticks before expiry */
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
@@ -56,7 +58,7 @@ static inline void _mntput(struct vfsmou
static inline void mntput(struct vfsmount *mnt)
{
if (mnt) {
- mnt->mnt_expiry_mark = 0;
+ xchg(&mnt->mnt_active, 1);
_mntput(mnt);
}
}
Index: linux-2.6.9-quilt/fs/namespace.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/namespace.c 2004-10-22 17:17:34.148272816 -0400
+++ linux-2.6.9-quilt/fs/namespace.c 2004-10-22 17:17:35.378085856 -0400
@@ -68,6 +68,8 @@ struct vfsmount *alloc_vfsmnt(const char
INIT_LIST_HEAD(&mnt->mnt_mounts);
INIT_LIST_HEAD(&mnt->mnt_list);
INIT_LIST_HEAD(&mnt->mnt_expire);
+ mnt->mnt_expiry_ticks = mnt->mnt_expiry_countdown = 0;
+ mnt->mnt_active = 1;
if (name) {
int size = strlen(name)+1;
char *newname = kmalloc(size, GFP_KERNEL);
@@ -365,9 +367,9 @@ static void umount_tree(struct vfsmount
struct nameidata old_nd;
detach_mnt(mnt, &old_nd);
spin_unlock(&vfsmount_lock);
- path_release(&old_nd);
+ path_release_on_umount(&old_nd);
}
- mntput(mnt);
+ _mntput(mnt);
spin_lock(&vfsmount_lock);
}
}
@@ -395,7 +397,7 @@ static int do_umount(struct vfsmount *mn
if (atomic_read(&mnt->mnt_count) != 2)
return -EBUSY;

- if (!xchg(&mnt->mnt_expiry_mark, 1))
+ if (--mnt->mnt_expiry_countdown != 0)
return -EAGAIN;
}

@@ -840,6 +842,8 @@ void mnt_expire(struct vfsmount *mnt, un
goto out;

list_del_init(&mnt->mnt_expire);
+ mnt->mnt_expiry_ticks = mnt->mnt_expiry_countdown = expire;
+ mnt->mnt_active = 1;
if (expire > 0)
list_add_tail(&mnt->mnt_expire, &expiry_list);
out:
@@ -847,7 +851,7 @@ out:
up(&expiry_sem);
}
EXPORT_SYMBOL_GPL(mnt_expire);
-
+
/*
* process a list of expirable mountpoints with the intent of discarding any
* mountpoints that aren't in use and haven't been touched since last we came
@@ -872,12 +876,21 @@ static void do_expiry_run(void *nothing)
* cleared by mntput())
*/
list_for_each_entry_safe(mnt, next, &expiry_list, mnt_expire) {
- if (!xchg(&mnt->mnt_expiry_mark, 1) ||
- atomic_read(&mnt->mnt_count) != 1)
+ /*
+ * Something might still hold a reference to this mount. If
+ * mnt_active is set, we can just move on. If it gets set
+ * after we xchg() here, we'll catch it on the graveyard list.
+ */
+ if (xchg(&mnt->mnt_active, 0)) {
+ mnt->mnt_expiry_countdown = mnt->mnt_expiry_ticks;
continue;
-
- mntget(mnt);
- list_move(&mnt->mnt_expire, &graveyard);
+ }
+ if (mnt->mnt_expiry_countdown >= 1)
+ mnt->mnt_expiry_countdown--;
+ if (atomic_read(&mnt->mnt_count) == 2 && mnt->mnt_expiry_countdown == 0) {
+ mntget(mnt);
+ list_move(&mnt->mnt_expire, &graveyard);
+ }
}

/*
@@ -903,7 +916,7 @@ static void do_expiry_run(void *nothing)

/* check that it is still dead: the count should now be 2 - as
* contributed by the vfsmount parent and the mntget above */
- if (atomic_read(&mnt->mnt_count) == 2) {
+ if (atomic_read(&mnt->mnt_count) == 2 && !mnt->mnt_active) {
struct vfsmount *xdmnt;
struct dentry *xdentry;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:07    [from the cache]
©2003-2011 Jasper Spaans