public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/3] autofs4 - expiring filesystem from under process
@ 2005-04-10 12:50 raven
  2005-04-10 23:15 ` Andrew Morton
  2005-04-11  7:01 ` Andrew Morton
  0 siblings, 2 replies; 5+ messages in thread
From: raven @ 2005-04-10 12:50 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Michael Blandford, linux-fsdevel, Jeff Moyer, autofs mailing list


autofs4-2.6.12-rc1-mm4-tree-race.patch

For tree mount maps, a call to chdir or chroot, to a directory above the
moint point directories at a certain time during the expire results in
the expire incorrectly thinking the tree is not busy. This patch adds a
check to see if the filesystem above the tree mount points is busy and
also locks the filesystem during the tree mount expire to prevent the
race.

Signed-off-by: Ian Kent <raven@themaw.net>

--- linux-2.6.12-rc1-mm4/fs/autofs4/autofs_i.h.tree-race	2005-04-03 12:34:00.000000000 +0800
+++ linux-2.6.12-rc1-mm4/fs/autofs4/autofs_i.h	2005-04-03 12:38:09.000000000 +0800
@@ -102,6 +102,7 @@ struct autofs_sb_info {
  	int needs_reghost;
  	struct super_block *sb;
  	struct semaphore wq_sem;
+	spinlock_t fs_lock;
  	struct autofs_wait_queue *queues; /* Wait queue pointer */
  };

@@ -127,9 +128,18 @@ static inline int autofs4_oz_mode(struct
  static inline int autofs4_ispending(struct dentry *dentry)
  {
  	struct autofs_info *inf = autofs4_dentry_ino(dentry);
+	int pending;

-	return (dentry->d_flags & DCACHE_AUTOFS_PENDING) ||
-		(inf != NULL && inf->flags & AUTOFS_INF_EXPIRING);
+	if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
+		return 1;
+
+	if (inf) {
+		spin_lock(&inf->sbi->fs_lock);
+		pending = inf->flags & AUTOFS_INF_EXPIRING;
+		spin_unlock(&inf->sbi->fs_lock);
+	}
+
+	return pending;
  }

  static inline void autofs4_copy_atime(struct file *src, struct file *dst)
--- linux-2.6.12-rc1-mm4/fs/autofs4/inode.c.tree-race	2005-04-03 12:34:10.000000000 +0800
+++ linux-2.6.12-rc1-mm4/fs/autofs4/inode.c	2005-04-03 12:34:54.000000000 +0800
@@ -206,6 +206,7 @@ int autofs4_fill_super(struct super_bloc
  	sbi->version = 0;
  	sbi->sub_version = 0;
  	init_MUTEX(&sbi->wq_sem);
+	spin_lock_init(&sbi->fs_lock);
  	sbi->queues = NULL;
  	s->s_blocksize = 1024;
  	s->s_blocksize_bits = 10;
--- linux-2.6.12-rc1-mm4/fs/autofs4/expire.c.tree-race	2005-04-03 12:34:22.000000000 +0800
+++ linux-2.6.12-rc1-mm4/fs/autofs4/expire.c	2005-04-03 12:42:41.000000000 +0800
@@ -99,6 +99,10 @@ static int autofs4_check_tree(struct vfs
  	if (!autofs4_can_expire(top, timeout, do_now))
  		return 0;

+	/* Is someone visiting anywhere in the tree ? */
+	if (autofs4_may_umount(mnt))
+		return 0;
+
  	spin_lock(&dcache_lock);
  repeat:
  	next = this_parent->d_subdirs.next;
@@ -270,10 +274,18 @@ static struct dentry *autofs4_expire(str

  		/* Case 2: tree mount, expire iff entire tree is not busy */
  		if (!exp_leaves) {
+			/* Lock the tree as we must expire as a whole */
+			spin_lock(&sbi->fs_lock);
  			if (autofs4_check_tree(mnt, dentry, timeout, do_now)) {
-			expired = dentry;
-			break;
+				struct autofs_info *inf = autofs4_dentry_ino(dentry);
+
+				/* Set this flag early to catch sys_chdir and the like */
+				inf->flags |= AUTOFS_INF_EXPIRING;
+				spin_unlock(&sbi->fs_lock);
+				expired = dentry;
+				break;
  			}
+			spin_unlock(&sbi->fs_lock);
  		/* Case 3: direct mount, expire individual leaves */
  		} else {
  			expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-11  8:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-10 12:50 [PATCH 2/3] autofs4 - expiring filesystem from under process raven
2005-04-10 23:15 ` Andrew Morton
2005-04-11  2:44   ` raven
2005-04-11  7:01 ` Andrew Morton
2005-04-11  8:52   ` Ian Kent

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox