[PATCH][mount-7-1-A] fixes to pre7-1 and more mount cleanups

From: Alexander Viro (viro@math.psu.edu)
Date: Sat Apr 29 2000 - 16:47:39 EST


        Apologies for knfsd braino, folks - that's definitely my fault.
Hopefully, patch below will be enough to fix it.
        Another group of problems (fuser ones) is much more interesting -
sounds like an extra mntput() somewhere. If somebody has oopsen with the
thing - please, send them to me.
        Patch also contains autofs cleanup (doesn't affect autofs4,
doesn't change behaviour) and proc_permission() one.
                                                        Cheers,
                                                                Al
diff -urN linux-2.3.99-pre7-1/fs/autofs/autofs_i.h linux-bird.vfs/fs/autofs/autofs_i.h
--- linux-2.3.99-pre7-1/fs/autofs/autofs_i.h Wed Apr 26 21:01:00 2000
+++ linux-bird.vfs/fs/autofs/autofs_i.h Sat Apr 29 17:13:08 2000
@@ -132,7 +132,7 @@
 /* Expiration-handling functions */
 
 void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *);
-struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *);
+struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *, struct vfsmount *mnt);
 
 /* Operations structures */
 
diff -urN linux-2.3.99-pre7-1/fs/autofs/dirhash.c linux-bird.vfs/fs/autofs/dirhash.c
--- linux-2.3.99-pre7-1/fs/autofs/dirhash.c Sat Apr 29 17:11:00 2000
+++ linux-bird.vfs/fs/autofs/dirhash.c Sat Apr 29 17:13:08 2000
@@ -34,7 +34,8 @@
 }
 
 struct autofs_dir_ent *autofs_expire(struct super_block *sb,
- struct autofs_sb_info *sbi)
+ struct autofs_sb_info *sbi,
+ struct vfsmount *mnt)
 {
         struct autofs_dirhash *dh = &sbi->dirhash;
         struct autofs_dir_ent *ent;
@@ -79,12 +80,25 @@
                         DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
                         continue;
                 }
+ mntget(mnt);
+ dget(dentry);
+ if (!follow_down(&mnt, &dentry)) {
+ dput(dentry);
+ mntput(mnt);
+ DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
+ continue;
+ }
+ while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
+ ;
+ dput(dentry);
 
- if ( may_umount(dentry->d_mounts->d_sb) == 0 ) {
+ if ( may_umount(mnt) == 0 ) {
+ mntput(mnt);
                         DPRINTK(("autofs: signaling expire on %s\n", ent->name));
                         return ent; /* Expirable! */
                 }
                 DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
+ mntput(mnt);
         }
         return NULL; /* No expirable entries */
 }
diff -urN linux-2.3.99-pre7-1/fs/autofs/root.c linux-bird.vfs/fs/autofs/root.c
--- linux-2.3.99-pre7-1/fs/autofs/root.c Wed Apr 26 21:01:00 2000
+++ linux-bird.vfs/fs/autofs/root.c Sat Apr 29 17:13:08 2000
@@ -432,6 +432,7 @@
 /* Perform an expiry operation */
 static inline int autofs_expire_run(struct super_block *sb,
                                     struct autofs_sb_info *sbi,
+ struct vfsmount *mnt,
                                     struct autofs_packet_expire *pkt_p)
 {
         struct autofs_dir_ent *ent;
@@ -443,7 +444,7 @@
         pkt.hdr.type = autofs_ptype_expire;
 
         if ( !sbi->exp_timeout ||
- !(ent = autofs_expire(sb,sbi)) )
+ !(ent = autofs_expire(sb,sbi,mnt)) )
                 return -EAGAIN;
 
         pkt.len = ent->len;
@@ -487,7 +488,7 @@
         case AUTOFS_IOC_SETTIMEOUT:
                 return autofs_get_set_timeout(sbi,(unsigned long *)arg);
         case AUTOFS_IOC_EXPIRE:
- return autofs_expire_run(inode->i_sb,sbi,
+ return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt,
                                          (struct autofs_packet_expire *)arg);
         default:
                 return -ENOSYS;
diff -urN linux-2.3.99-pre7-1/fs/nfsd/vfs.c linux-bird.vfs/fs/nfsd/vfs.c
--- linux-2.3.99-pre7-1/fs/nfsd/vfs.c Sat Apr 29 17:11:00 2000
+++ linux-bird.vfs/fs/nfsd/vfs.c Sat Apr 29 17:14:56 2000
@@ -141,7 +141,7 @@
         } else {
                 dentry = lookup_one(name, dparent);
                 err = PTR_ERR(dentry);
- if (err)
+ if (IS_ERR(dentry))
                         goto out_nfserr;
                 /*
                  * check if we have crossed a mount point ...
diff -urN linux-2.3.99-pre7-1/fs/proc/base.c linux-bird.vfs/fs/proc/base.c
--- linux-2.3.99-pre7-1/fs/proc/base.c Wed Apr 26 21:01:02 2000
+++ linux-bird.vfs/fs/proc/base.c Sat Apr 29 17:13:08 2000
@@ -174,7 +174,6 @@
 static int proc_permission(struct inode *inode, int mask)
 {
         struct dentry *de, *base, *root;
- struct super_block *our_sb, *sb, *below;
         struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
 
         if (standard_permission(inode, mask) != 0)
@@ -187,14 +186,12 @@
 
         de = root;
         mnt = vfsmnt;
- our_sb = base->d_inode->i_sb;
- sb = de->d_inode->i_sb;
- while (sb != our_sb) {
- de = sb->s_root->d_covers;
- below = de->d_inode->i_sb;
- if (sb == below)
+
+ while (vfsmnt != our_vfsmnt) {
+ if (vfsmnt == vfsmnt->mnt_parent)
                         goto out;
- sb = below;
+ de = vfsmnt->mnt_mountpoint;
+ vfsmnt = vfsmnt->mnt_parent;
         }
 
         if (!is_subdir(de, base))
diff -urN linux-2.3.99-pre7-1/fs/super.c linux-bird.vfs/fs/super.c
--- linux-2.3.99-pre7-1/fs/super.c Sat Apr 29 17:11:00 2000
+++ linux-bird.vfs/fs/super.c Sat Apr 29 17:13:08 2000
@@ -872,16 +872,30 @@
  * give false negatives. The main reason why it's here is that we need
  * a non-destructive way to look for easily umountable filesystems.
  */
- /* MOUNT_REWRITE: it should take vfsmount, not superblock */
-int may_umount(struct super_block *sb)
+int may_umount(struct vfsmount *mnt)
 {
+ struct super_block * sb = mnt->mnt_sb;
         struct dentry * root;
         int count;
 
+ if (atomic_read(&mnt->mnt_count) > 2)
+ return -EBUSY;
+
+ if (mnt->mnt_instances.next != mnt->mnt_instances.prev)
+ return 0;
+
+ /*
+ * OK, at that point we have only one instance. We should have
+ * one active reference from ->s_root, one active reference
+ * from ->mnt_root (which may be different) and possibly one
+ * active reference from ->mnt_mountpoint (if mnt->mnt_parent == mnt).
+ * Anything above that means that tree is busy.
+ */
+
         root = sb->s_root;
 
         count = d_active_refs(root);
- if (root->d_covers == root)
+ if (mnt->mnt_parent == mnt)
                 count--;
         if (count != 2)
                 return -EBUSY;
diff -urN linux-2.3.99-pre7-1/include/linux/fs.h linux-bird.vfs/include/linux/fs.h
--- linux-2.3.99-pre7-1/include/linux/fs.h Sat Apr 29 17:11:00 2000
+++ linux-bird.vfs/include/linux/fs.h Sat Apr 29 17:13:08 2000
@@ -786,7 +786,7 @@
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
-extern int may_umount(struct super_block *);
+extern int may_umount(struct vfsmount *);
 
 static inline int vfs_statfs(struct super_block *sb, struct statfs *buf)
 {

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



This archive was generated by hypermail 2b29 : Sun Apr 30 2000 - 21:00:17 EST