summaryrefslogtreecommitdiffstats
path: root/fs/autofs4
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-08 00:53:00 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-08 00:53:00 +0000
commitb8553086288629b4efb77e97f5582e08bc50ad65 (patch)
tree0a19bd1c21e148f35c7a0f76baa4f7a056b966b0 /fs/autofs4
parent75b6d92f2dd5112b02f4e78cf9f35f9825946ef0 (diff)
Merge with 2.4.0-test3-pre4.
Diffstat (limited to 'fs/autofs4')
-rw-r--r--fs/autofs4/expire.c12
-rw-r--r--fs/autofs4/root.c25
2 files changed, 27 insertions, 10 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 98a7a0e6c..aca401b73 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -22,6 +22,7 @@ static int is_tree_busy(struct vfsmount *mnt)
struct list_head *next;
int count;
+ spin_lock(&dcache_lock);
count = atomic_read(&mnt->mnt_count);
repeat:
next = this_parent->mnt_mounts.next;
@@ -38,8 +39,10 @@ resume:
goto repeat;
}
/* root is busy if any leaf is busy */
- if (atomic_read(&p->mnt_count) > 1)
+ if (atomic_read(&p->mnt_count) > 1) {
+ spin_unlock(&dcache_lock);
return 1;
+ }
}
/*
* All done at this level ... ascend and resume the search.
@@ -49,6 +52,7 @@ resume:
this_parent = this_parent->mnt_parent;
goto resume;
}
+ spin_unlock(&dcache_lock);
DPRINTK(("is_tree_busy: count=%d\n", count));
return count != 0; /* remaining users? */
@@ -77,6 +81,7 @@ static struct dentry *autofs4_expire(struct super_block *sb,
timeout = sbi->exp_timeout;
+ spin_lock(&dcache_lock);
for(tmp = root->d_subdirs.next;
tmp != &root->d_subdirs;
tmp = tmp->next) {
@@ -110,6 +115,7 @@ static struct dentry *autofs4_expire(struct super_block *sb,
}
p = mntget(mnt);
d = dget(dentry);
+ spin_unlock(&dcache_lock);
while(d_mountpoint(d) && follow_down(&p, &d))
;
@@ -119,13 +125,17 @@ static struct dentry *autofs4_expire(struct super_block *sb,
DPRINTK(("autofs_expire: returning %p %.*s\n",
dentry, dentry->d_name.len, dentry->d_name.name));
/* Start from here next time */
+ spin_lock(&dcache_lock);
list_del(&root->d_subdirs);
list_add(&root->d_subdirs, &dentry->d_child);
+ spin_unlock(&dcache_lock);
return dentry;
}
dput(d);
mntput(p);
+ spin_lock(&dcache_lock);
}
+ spin_unlock(&dcache_lock);
return NULL;
}
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 00951bf8e..f3c3e9e12 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -14,6 +14,8 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/param.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "autofs_i.h"
static struct dentry *autofs4_dir_lookup(struct inode *,struct dentry *);
@@ -118,12 +120,15 @@ static int try_to_fill_dentry(struct dentry *dentry,
/* If this is an unused directory that isn't a mount point,
bitch at the daemon and fix it in user space */
+ spin_lock(&dcache_lock);
if (S_ISDIR(dentry->d_inode->i_mode) &&
!d_mountpoint(dentry) &&
list_empty(&dentry->d_subdirs)) {
DPRINTK(("try_to_fill_entry: mounting existing dir\n"));
+ spin_unlock(&dcache_lock);
return autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT) == 0;
}
+ spin_unlock(&dcache_lock);
/* We don't update the usages for the autofs daemon itself, this
is necessary for recursive autofs mounts */
@@ -163,16 +168,19 @@ static int autofs4_root_revalidate(struct dentry * dentry, int flags)
ino = autofs4_dentry_ino(dentry);
/* Check for a non-mountpoint directory with no contents */
+ spin_lock(&dcache_lock);
if (S_ISDIR(dentry->d_inode->i_mode) &&
!d_mountpoint(dentry) &&
list_empty(&dentry->d_subdirs)) {
DPRINTK(("autofs_root_revalidate: dentry=%p %.*s, emptydir\n",
dentry, dentry->d_name.len, dentry->d_name.name));
+ spin_unlock(&dcache_lock);
if (oz_mode)
return 1;
else
return try_to_fill_dentry(dentry, dir->i_sb, sbi);
}
+ spin_unlock(&dcache_lock);
/* Update the usage list */
if (!oz_mode)
@@ -197,6 +205,7 @@ static void autofs4_dentry_release(struct dentry *de)
DPRINTK(("autofs4_dentry_release: releasing %p\n", de));
+ lock_kernel();
de->d_fsdata = NULL;
if (inf) {
inf->dentry = NULL;
@@ -204,6 +213,7 @@ static void autofs4_dentry_release(struct dentry *de)
autofs4_free_ino(inf);
}
+ unlock_kernel();
}
/* For dentries of directories in the root dir */
@@ -372,9 +382,6 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
dir->i_mtime = CURRENT_TIME;
- DPRINTK(("autofs_dir_unlink: unlinking %p %.*s, count=%d\n",
- dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count));
-
d_drop(dentry);
return 0;
@@ -388,8 +395,13 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
if (!autofs4_oz_mode(sbi))
return -EACCES;
- if (!list_empty(&dentry->d_subdirs))
+ spin_lock(&dcache_lock);
+ if (!list_empty(&dentry->d_subdirs)) {
+ spin_unlock(&dcache_lock);
return -ENOTEMPTY;
+ }
+ list_del(&dentry->d_hash);
+ spin_unlock(&dcache_lock);
dput(ino->dentry);
@@ -399,11 +411,6 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
if (dir->i_nlink)
dir->i_nlink--;
- DPRINTK(("autofs_dir_rmdir: rmdir %p %.*s, count=%d\n",
- dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count));
-
- d_drop(dentry);
-
return 0;
}