> >> Nope, you need it to have a working: extract cd, change cd,
> >>make it working.
> >>
>
> borzenkov> Nope, it is just an accidental side effect. Put_inode (as
> borzenkov> it was) is buggy and not needed.
>
> Are you sure? We are using put_inode() to _never_ cache inodes of
> supermounted media after use. Supermount relies on that behaviour.
To clarify - inode caching is not a problem because supermount never
reuse inodes. On first lookup new dentry/inode pair is allocated,
after media change inode is stale, on next lookup d_revalidate returns
false and we allocate new dentry/inode pair. (directories is
special case but it does not change general rule). We never lookup
or reuse old inode. using force_delete just purges them from cache
faster.
> borzenkov> - fix the last case of improper ESTALE
>
> I thought this one should been fixed, will look at it.
No, the attached patch really fixes it. It disconnects busy dentries
from fs tree. they go away when process that holds them open goes away.
It is as much as I expect to go into update for 9.0 (assuming no
serious bugs is found). For 9.1 if time permit see later.
> borzenkov> - some more vague ideas
>
> Humm, that is really vague.
No more.
- keep list of struct files; close subfs files on media change to
allow clean umount; mark supermount files as dead; provide mount
option on_media_change={TERM,KILL,EIO,ESTALE} to respectively TERM or
KILL owners or just return EIO/ESTALE on subsequent read/write and
let them handle it.
- add strict_media_change option to always check; intended for slow
writable media like floppy to catch media change as soon as possible
to avoid overwriting of newly inserted floppy.
- add user interface to umount subfs; it is pretty trivial to
implement as remount option but I am not sure about permissions.
Intentional use is approximately
mount -o remount,release /mnt/floppy
format /dev/fd
mkfs /dev/fd
cp /vmlinuz /mnt/floppy
Not sure how really useful it is but it is quite trivial to implement.
- document the whole stuff
-andrey
diff -ru -x '*.o' -x '*~' /home/bor/src/supermount/super.c
linux-2.4.21-0.pre3.1mdk/fs/supermount/super.c
--- /home/bor/src/supermount/super.c 2003-01-28 00:29:42.000000000 +0300
+++ linux-2.4.21-0.pre3.1mdk/fs/supermount/super.c 2003-01-28 23:39:55.000000000
++0300
@@ -71,6 +71,30 @@
}
}
+/*
+ * Cut off busy dentries unless mounted over. They go away when
+ * their owners die
+ * We run under mutex or sb lock so nobody can change directory structure
+ * d_drop holds dcache lock for us
+ * FIXME: it probably should unmount submounts
+ */
+static void
+supermount_drop_dentries(struct super_block *sb)
+{
+ struct dentry *d;
+ struct list_head *ptr;
+
+ if (!sb->s_root)
+ return;
+
+ list_for_each(ptr, &sb->s_root->d_subdirs) {
+ d = list_entry(ptr, struct dentry, d_child);
+
+ if (!have_submounts(d))
+ d_drop(d);
+ }
+}
+
void
subfs_umount(struct super_block *sb)
{
@@ -87,6 +111,7 @@
}
shrink_dcache_sb(sb);
supermount_clean_inodes(sb);
+ supermount_drop_dentries(sb);
if (!mnt)
supermount_panic(sb, "subfs_umount",
"Can't find mount point\n");
diff -ru -x '*.o' -x '*~' /home/bor/src/supermount/super_operations.c
linux-2.4.21-0.pre3.1mdk/fs/supermount/super_operations.c
--- /home/bor/src/supermount/super_operations.c 2003-01-28 00:25:51.000000000 +0300
+++ linux-2.4.21-0.pre3.1mdk/fs/supermount/super_operations.c 2003-01-28
+23:31:43.000000000 +0300
@@ -125,10 +125,9 @@
{
struct supermount_sb_info *sbi = supermount_sbi(sb);
- dput(sb->s_root);
-
if (subfs_is_mounted(sbi))
subfs_umount(sb);
+
sb->u.generic_sbp = 0;
free_sbi(sbi);
sb->s_dev = 0;