summaryrefslogtreecommitdiffstats
path: root/fs/autofs4
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
commitb9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch)
tree42d07b0c7246ae2536a702e7c5de9e2732341116 /fs/autofs4
parent7406b0a326f2d70ade2671c37d1beef62249db97 (diff)
Merge with 2.3.99-pre6.
Diffstat (limited to 'fs/autofs4')
-rw-r--r--fs/autofs4/Makefile2
-rw-r--r--fs/autofs4/autofs_i.h21
-rw-r--r--fs/autofs4/expire.c15
-rw-r--r--fs/autofs4/init.c2
-rw-r--r--fs/autofs4/inode.c133
-rw-r--r--fs/autofs4/inohash.c68
-rw-r--r--fs/autofs4/root.c59
-rw-r--r--fs/autofs4/symlink.c2
-rw-r--r--fs/autofs4/waitq.c3
9 files changed, 55 insertions, 250 deletions
diff --git a/fs/autofs4/Makefile b/fs/autofs4/Makefile
index 0095b8aed..3e3f2cc22 100644
--- a/fs/autofs4/Makefile
+++ b/fs/autofs4/Makefile
@@ -5,7 +5,7 @@
#
O_TARGET := autofs4.o
-O_OBJS := inohash.o init.o inode.o root.o symlink.o waitq.o expire.o
+O_OBJS := init.o inode.o root.o symlink.o waitq.o expire.o
M_OBJS := $(O_TARGET)
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index b55afd6c4..bc23ed145 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
+/* -*- c -*- ------------------------------------------------------------- *
*
* linux/fs/autofs/autofs_i.h
*
@@ -57,10 +57,8 @@ struct autofs_info {
int flags;
struct autofs_sb_info *sbi;
- struct list_head ino_hash;
unsigned long last_used;
- ino_t ino;
mode_t mode;
size_t size;
@@ -72,10 +70,6 @@ struct autofs_info {
#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
-struct autofs_inohash {
- struct list_head head;
-};
-
struct autofs_wait_queue {
wait_queue_head_t queue;
struct autofs_wait_queue *next;
@@ -89,9 +83,6 @@ struct autofs_wait_queue {
int wait_ctr;
};
-#define AUTOFS_ROOT_INO 1
-#define AUTOFS_FIRST_INO 2
-
#define AUTOFS_SBI_MAGIC 0x6d4a556d
struct autofs_sb_info {
@@ -101,10 +92,8 @@ struct autofs_sb_info {
int catatonic;
int version;
unsigned long exp_timeout;
- ino_t next_ino;
struct super_block *sb;
struct autofs_wait_queue *queues; /* Wait queue pointer */
- struct autofs_inohash ihash;
};
static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb)
@@ -134,13 +123,7 @@ static inline int autofs4_ispending(struct dentry *dentry)
(inf != NULL && inf->flags & AUTOFS_INF_EXPIRING);
}
-/* Inode hash operations */
-void autofs4_init_ihash(struct autofs_inohash *);
-void autofs4_ihash_insert(struct autofs_inohash *ih, struct autofs_info *ino);
-void autofs4_ihash_delete(struct autofs_info *ino);
-void autofs4_ihash_nuke(struct autofs_inohash *ih);
-struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih, ino_t ino);
-
+struct inode *autofs4_get_inode(struct super_block *, struct autofs_info *);
struct autofs_info *autofs4_init_inf(struct autofs_sb_info *, mode_t mode);
void autofs4_free_ino(struct autofs_info *);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index dd3695648..e93557db8 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/expire.c
*
@@ -46,8 +46,9 @@ static int is_tree_busy(struct dentry *root)
count--;
}
- /* Mountpoints don't count */
- if (d_mountpoint(root)) {
+ /* Mountpoints don't count (either mountee or mounter) */
+ if (d_mountpoint(root) ||
+ root != root->d_covers) {
DPRINTK(("is_tree_busy: mountpoint\n"));
count--;
}
@@ -75,9 +76,11 @@ resume:
/* Decrement count for unused children */
count += (dentry->d_count - 1);
- /* Mountpoints don't count */
- if (d_mountpoint(dentry)) {
- DPRINTK(("is_tree_busy: mountpoint\n"));
+ /* Mountpoints don't count (either mountee or mounter) */
+ if (d_mountpoint(dentry) ||
+ dentry != dentry->d_covers) {
+ DPRINTK(("is_tree_busy: mountpoint dentry=%p covers=%p mounts=%p\n",
+ dentry, dentry->d_covers, dentry->d_mounts));
adj++;
}
diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c
index baf12d913..dc63926ad 100644
--- a/fs/autofs4/init.c
+++ b/fs/autofs4/init.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/init.c
*
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index b4ea73fdb..077df4c2b 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/inode.c
*
@@ -41,7 +41,6 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
return NULL;
ino->flags = 0;
- ino->ino = sbi->next_ino++;
ino->mode = mode;
ino->inode = NULL;
ino->dentry = NULL;
@@ -50,7 +49,6 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
ino->last_used = jiffies;
ino->sbi = sbi;
- INIT_LIST_HEAD(&ino->ino_hash);
if (reinit && ino->free)
(ino->free)(ino);
@@ -67,7 +65,6 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
void autofs4_free_ino(struct autofs_info *ino)
{
- autofs4_ihash_delete(ino);
if (ino->dentry) {
ino->dentry->d_fsdata = NULL;
if (ino->dentry->d_inode)
@@ -79,18 +76,6 @@ void autofs4_free_ino(struct autofs_info *ino)
kfree(ino);
}
-/*
- * Dummy functions - do we ever actually want to do
- * something here?
- */
-static void autofs4_put_inode(struct inode *inode)
-{
-}
-
-static void autofs4_clear_inode(struct inode *inode)
-{
-}
-
static void autofs4_put_super(struct super_block *sb)
{
struct autofs_sb_info *sbi = autofs4_sbi(sb);
@@ -105,26 +90,11 @@ static void autofs4_put_super(struct super_block *sb)
DPRINTK(("autofs: shutting down\n"));
}
-static void autofs4_umount_begin(struct super_block *sb)
-{
- struct autofs_sb_info *sbi = autofs4_sbi(sb);
-
- if (!sbi->catatonic)
- autofs4_catatonic_mode(sbi);
-}
-
static int autofs4_statfs(struct super_block *sb, struct statfs *buf);
-static void autofs4_read_inode(struct inode *inode);
-static void autofs4_write_inode(struct inode *inode);
static struct super_operations autofs4_sops = {
- read_inode: autofs4_read_inode,
- write_inode: autofs4_write_inode,
- put_inode: autofs4_put_inode,
- clear_inode: autofs4_clear_inode,
put_super: autofs4_put_super,
statfs: autofs4_statfs,
- umount_begin: autofs4_umount_begin,
};
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
@@ -200,8 +170,6 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
if (!ino)
return NULL;
- ino->ino = AUTOFS_ROOT_INO;
-
return ino;
}
@@ -215,10 +183,6 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data,
struct autofs_sb_info *sbi;
int minproto, maxproto;
- /* Super block already completed? */
- if (s->s_root)
- goto out_unlock;
-
sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
if ( !sbi )
goto fail_unlock;
@@ -233,30 +197,21 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data,
sbi->oz_pgrp = current->pgrp;
sbi->sb = s;
sbi->version = 0;
- autofs4_init_ihash(&sbi->ihash);
sbi->queues = NULL;
- sbi->next_ino = AUTOFS_FIRST_INO;
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
s->s_magic = AUTOFS_SUPER_MAGIC;
s->s_op = &autofs4_sops;
- s->s_root = NULL;
/*
* Get the root inode and dentry, but defer checking for errors.
*/
- autofs4_ihash_insert(&sbi->ihash, autofs4_mkroot(sbi));
-
- root_inode = iget(s, AUTOFS_ROOT_INO);
+ root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi));
+ root_inode->i_op = &autofs4_root_inode_operations;
+ root_inode->i_fop = &autofs4_root_operations;
root = d_alloc_root(root_inode);
pipe = NULL;
- /*
- * Check whether somebody else completed the super block.
- */
- if (s->s_root)
- goto out_dput;
-
if (!root)
goto fail_iput;
@@ -283,11 +238,6 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data,
DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
pipe = fget(pipefd);
- /*
- * Check whether somebody else completed the super block.
- */
- if (s->s_root)
- goto out_fput;
if ( !pipe ) {
printk("autofs: could not open pipe file descriptor\n");
@@ -302,25 +252,9 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data,
*/
s->s_root = root;
return s;
-
- /*
- * Success ... somebody else completed the super block for us.
- */
-out_unlock:
- goto out_dec;
-out_fput:
- if (pipe)
- fput(pipe);
-out_dput:
- if (root)
- dput(root);
- else
- iput(root_inode);
-out_dec:
- return s;
/*
- * Failure ... clear the s_dev slot and clean up.
+ * Failure ... clean up.
*/
fail_fput:
printk("autofs: pipe file descriptor does not contain proper ops\n");
@@ -351,55 +285,44 @@ static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
{
buf->f_type = AUTOFS_SUPER_MAGIC;
buf->f_bsize = 1024;
- buf->f_bfree = 0;
- buf->f_bavail = 0;
- buf->f_ffree = 0;
buf->f_namelen = NAME_MAX;
return 0;
}
-static void autofs4_read_inode(struct inode *inode)
+struct inode *autofs4_get_inode(struct super_block *sb,
+ struct autofs_info *inf)
{
- struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
- struct autofs_info *inf;
+ struct inode *inode = get_empty_inode();
- inf = autofs4_ihash_find(&sbi->ihash, inode->i_ino);
-
- if (inf == NULL || inf->inode != NULL)
- return;
+ if (inode == NULL)
+ return NULL;
+ inf->inode = inode;
+ inode->i_sb = sb;
+ inode->i_dev = sb->s_dev;
inode->i_mode = inf->mode;
- inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
- inode->i_size = inf->size;
-
- inode->i_blocks = 0;
- inode->i_blksize = 0;
- inode->i_nlink = 1;
-
- if (inode->i_sb->s_root) {
- inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
- inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
+ if (sb->s_root) {
+ inode->i_uid = sb->s_root->d_inode->i_uid;
+ inode->i_gid = sb->s_root->d_inode->i_gid;
} else {
inode->i_uid = 0;
inode->i_gid = 0;
}
-
- inf->inode = inode;
+ inode->i_size = 0;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = 0;
+ inode->i_rdev = 0;
+ inode->i_nlink = 1;
+ inode->i_op = NULL;
+ inode->i_fop = NULL;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
if (S_ISDIR(inf->mode)) {
inode->i_nlink = 2;
- if (inode->i_ino == AUTOFS_ROOT_INO) {
- inode->i_op = &autofs4_root_inode_operations;
- inode->i_fop = &autofs4_root_operations;
- } else {
- inode->i_op = &autofs4_dir_inode_operations;
- inode->i_fop = &autofs4_dir_operations;
- }
- } else if (S_ISLNK(inf->mode)) {
+ inode->i_op = &autofs4_dir_inode_operations;
+ inode->i_fop = &autofs4_dir_operations;
+ } else if (S_ISLNK(inf->mode))
inode->i_op = &autofs4_symlink_inode_operations;
- }
-}
-static void autofs4_write_inode(struct inode *inode)
-{
+ return inode;
}
diff --git a/fs/autofs4/inohash.c b/fs/autofs4/inohash.c
deleted file mode 100644
index 6190a55d3..000000000
--- a/fs/autofs4/inohash.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * "inohash" is a misnomer. Inodes are just stored in a single list,
- * since this code is only ever asked for the most recently inserted
- * inode.
- *
- * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org>
- */
-
-#include "autofs_i.h"
-
-void autofs4_init_ihash(struct autofs_inohash *ih)
-{
- INIT_LIST_HEAD(&ih->head);
-}
-
-void autofs4_ihash_insert(struct autofs_inohash *ih,
- struct autofs_info *ino)
-{
- DPRINTK(("autofs_ihash_insert: adding ino %ld\n", ino->ino));
-
- list_add(&ino->ino_hash, &ih->head);
-}
-
-void autofs4_ihash_delete(struct autofs_info *inf)
-{
- DPRINTK(("autofs_ihash_delete: deleting ino %ld\n", inf->ino));
-
- if (!list_empty(&inf->ino_hash))
- list_del(&inf->ino_hash);
-}
-
-struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih,
- ino_t inum)
-{
- struct list_head *tmp;
-
- for(tmp = ih->head.next;
- tmp != &ih->head;
- tmp = tmp->next) {
- struct autofs_info *ino = list_entry(tmp, struct autofs_info, ino_hash);
- if (ino->ino == inum) {
- DPRINTK(("autofs_ihash_find: found %ld -> %p\n",
- inum, ino));
- return ino;
- }
- }
- DPRINTK(("autofs_ihash_find: didn't find %ld\n", inum));
- return NULL;
-}
-
-void autofs4_ihash_nuke(struct autofs_inohash *ih)
-{
- struct list_head *tmp = ih->head.next;
- struct list_head *next;
-
- for(; tmp != &ih->head; tmp = next) {
- struct autofs_info *ino;
-
- next = tmp->next;
-
- ino = list_entry(tmp, struct autofs_info, ino_hash);
-
- DPRINTK(("autofs_ihash_nuke: nuking %ld\n", ino->ino));
- autofs4_free_ino(ino);
- }
- INIT_LIST_HEAD(&ih->head);
-}
-
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 41dc98984..ab05ed7d5 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/root.c
*
@@ -87,7 +87,7 @@ static int autofs4_dir_readdir(struct file *filp, void *dirent,
filp->f_pos = ++nr;
/* fall through */
case 1:
- if (filldir(dirent, "..", 2, nr, dentry->d_covers->d_parent->d_inode->i_ino) < 0)
+ if (filldir(dirent, "..", 2, nr, dentry->d_parent->d_inode->i_ino) < 0)
return 0;
filp->f_pos = ++nr;
/* fall through */
@@ -175,7 +175,7 @@ static int try_to_fill_dentry(struct dentry *dentry,
/* Return a negative dentry, but leave it "pending" */
return 1;
}
- status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT);
+ /* status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT); */
}
/* If this is an unused directory that isn't a mount point,
@@ -230,7 +230,7 @@ static int autofs4_root_revalidate(struct dentry * dentry, int flags)
list_empty(&dentry->d_subdirs)) {
DPRINTK(("autofs_root_revalidate: dentry=%p %.*s, emptydir\n",
dentry, dentry->d_name.len, dentry->d_name.name));
- if (autofs4_oz_mode(sbi))
+ if (oz_mode)
return 1;
else
return try_to_fill_dentry(dentry, dir->i_sb, sbi);
@@ -305,7 +305,7 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
dentry->d_name.len, dentry->d_name.name));
if (dentry->d_name.len > NAME_MAX)
- return ERR_PTR(-ENOENT);/* File name too long to exist */
+ return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */
sbi = autofs4_sbi(dir->i_sb);
@@ -323,12 +323,10 @@ static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dent
*
* We need to do this before we release the directory semaphore.
*/
- if (dir->i_ino == AUTOFS_ROOT_INO)
- dentry->d_op = &autofs4_root_dentry_operations;
- else
- dentry->d_op = &autofs4_dentry_operations;
+ dentry->d_op = &autofs4_root_dentry_operations;
- dentry->d_flags |= DCACHE_AUTOFS_PENDING;
+ if (!oz_mode)
+ dentry->d_flags |= DCACHE_AUTOFS_PENDING;
dentry->d_fsdata = NULL;
d_add(dentry, NULL);
@@ -371,18 +369,9 @@ static int autofs4_dir_symlink(struct inode *dir,
DPRINTK(("autofs_dir_symlink: %s <- %.*s\n", symname,
dentry->d_name.len, dentry->d_name.name));
- if (!S_ISDIR(dir->i_mode))
- return -ENOTDIR;
-
if (!autofs4_oz_mode(sbi))
return -EACCES;
- if (dentry->d_name.len > NAME_MAX)
- return -ENAMETOOLONG;
-
- if (dentry->d_inode != NULL)
- return -EEXIST;
-
ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555);
if (ino == NULL)
return -ENOSPC;
@@ -397,11 +386,10 @@ static int autofs4_dir_symlink(struct inode *dir,
strcpy(cp, symname);
- autofs4_ihash_insert(&sbi->ihash, ino);
- inode = iget(dir->i_sb,ino->ino);
+ inode = autofs4_get_inode(dir->i_sb, ino);
d_instantiate(dentry, inode);
- if (dir->i_ino == AUTOFS_ROOT_INO)
+ if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
else
dentry->d_op = &autofs4_dentry_operations;
@@ -434,12 +422,6 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
{
struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
-
- if (!S_ISDIR(dir->i_mode))
- return -ENOTDIR;
-
- if (dentry->d_inode == NULL)
- return -ENOENT;
/* This allows root to remove symlinks */
if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
@@ -464,12 +446,6 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
{
struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
-
- if (!S_ISDIR(dir->i_mode))
- return -ENOTDIR;
-
- if (dentry->d_inode == NULL)
- return -ENOENT;
if (!autofs4_oz_mode(sbi))
return -EACCES;
@@ -501,18 +477,9 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct autofs_info *ino = autofs4_dentry_ino(dentry);
struct inode *inode;
- if (!S_ISDIR(dir->i_mode))
- return -ENOTDIR;
-
if ( !autofs4_oz_mode(sbi) )
return -EACCES;
- if ( dentry->d_inode != NULL )
- return -EEXIST;
-
- if ( dentry->d_name.len > NAME_MAX )
- return -ENAMETOOLONG;
-
DPRINTK(("autofs_dir_mkdir: dentry %p, creating %.*s\n",
dentry, dentry->d_name.len, dentry->d_name.name));
@@ -520,12 +487,10 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (ino == NULL)
return -ENOSPC;
- autofs4_ihash_insert(&sbi->ihash, ino);
-
- inode = iget(dir->i_sb, ino->ino);
+ inode = autofs4_get_inode(dir->i_sb, ino);
d_instantiate(dentry, inode);
- if (dir->i_ino == AUTOFS_ROOT_INO)
+ if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
else
dentry->d_op = &autofs4_dentry_operations;
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
index 0bcb312e0..40f3e80b7 100644
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/symlink.c
*
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index b3b45fc0b..f49f213e0 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -1,4 +1,4 @@
-/* -*- linux-c -*- --------------------------------------------------------- *
+/* -*- c -*- --------------------------------------------------------------- *
*
* linux/fs/autofs/waitq.c
*
@@ -45,7 +45,6 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
sbi->pipe = NULL;
}
- autofs4_ihash_nuke(&sbi->ihash);
shrink_dcache_sb(sbi->sb);
}