diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-08 00:53:00 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-08 00:53:00 +0000 |
commit | b8553086288629b4efb77e97f5582e08bc50ad65 (patch) | |
tree | 0a19bd1c21e148f35c7a0f76baa4f7a056b966b0 /fs/autofs4 | |
parent | 75b6d92f2dd5112b02f4e78cf9f35f9825946ef0 (diff) |
Merge with 2.4.0-test3-pre4.
Diffstat (limited to 'fs/autofs4')
-rw-r--r-- | fs/autofs4/expire.c | 12 | ||||
-rw-r--r-- | fs/autofs4/root.c | 25 |
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; } |