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

From: Alexander Viro (viro@math.psu.edu)
Date: Sat Apr 29 2000 - 18:35:45 EST


Got it. Patch below seems to fix the problems with procfs - we used to
lose a reference to vfsmnt of /proc upon every follow_link() on
/proc/<pid>/fd/<n>, where n was an descriptor of pipe or socket. Fixed.
Linus, if you need incremental to previous patch - tell and I'll send it.
Patch below is against -pre7-1.
                                                        Cheers,
                                                                Al
diff -urN linux-2.3.99-pre7-1/drivers/block/loop.c linux-bird.vfs/drivers/block/loop.c
--- linux-2.3.99-pre7-1/drivers/block/loop.c Fri Mar 24 03:22:11 2000
+++ linux-bird.vfs/drivers/block/loop.c Sat Apr 29 18:41:56 2000
@@ -443,6 +443,7 @@
                         lo->lo_backing_file->f_flags = file->f_flags;
                         lo->lo_backing_file->f_owner = file->f_owner;
                         lo->lo_backing_file->f_dentry = file->f_dentry;
+ lo->lo_backing_file->f_vfsmnt = file->f_vfsmnt;
                         lo->lo_backing_file->f_op = file->f_op;
                         lo->lo_backing_file->private_data = file->private_data;
                         file_moveto(lo->lo_backing_file, file);
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:28:42 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/pipe.c linux-bird.vfs/fs/pipe.c
--- linux-2.3.99-pre7-1/fs/pipe.c Wed Apr 26 21:01:02 2000
+++ linux-bird.vfs/fs/pipe.c Sat Apr 29 18:40:10 2000
@@ -528,6 +528,8 @@
 
         error = -ENOMEM;
         f1->f_dentry = f2->f_dentry = dget(d_alloc_root(inode));
+ /* MOUNT_REWRITE: set to pipefs internal vfsmnt */
+ f1->f_vfsmnt = f2->f_vfsmnt = NULL;
         if (!f1->f_dentry)
                 goto close_f12_inode_i_j;
 
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 19:21:31 2000
@@ -40,12 +40,18 @@
 int proc_pid_cpu(struct task_struct*,char*);
 
 /* MOUNT_REWRITE: make all files have non-NULL ->f_vfsmnt (pipefs, sockfs) */
+/* Until then... */
+#define NULL_VFSMNT /* remove as soon as pipefs and sockfs will be there */
+
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
         if (inode->u.proc_i.file) {
- if (inode->u.proc_i.file->f_vfsmnt) {
- *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
- }
+#ifdef NULL_VFSMNT
+ if (!inode->u.proc_i.file->f_vfsmnt)
+ mntget(*mnt);
+ else
+#endif
+ *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
                 *dentry = dget(inode->u.proc_i.file->f_dentry);
                 return 0;
         }
@@ -174,7 +180,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 +192,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))
@@ -368,6 +371,9 @@
 {
         struct inode *inode = dentry->d_inode;
         int error;
+#ifdef NULL_VFSMNT
+ struct vfsmount *dummy = mntget(nd->mnt);
+#endif
 
         /* We don't need a base pointer in the /proc filesystem */
         dput(nd->dentry);
@@ -379,6 +385,9 @@
 
         error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
 out:
+#ifdef NULL_VFSMNT
+ mntput(dummy);
+#endif
         return error;
 }
 
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:22:32 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)
 {
diff -urN linux-2.3.99-pre7-1/net/socket.c linux-bird.vfs/net/socket.c
--- linux-2.3.99-pre7-1/net/socket.c Wed Apr 26 21:01:08 2000
+++ linux-bird.vfs/net/socket.c Sat Apr 29 18:41:28 2000
@@ -269,6 +269,8 @@
                 }
 
                 file->f_dentry = d_alloc_root(sock->inode);
+ /* MOUNT_REWRITE: set to sockfs internal vfsmnt */
+ file->f_vfsmnt = NULL;
                 if (!file->f_dentry) {
                         put_filp(file);
                         put_unused_fd(fd);

-
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