summaryrefslogtreecommitdiffstats
path: root/fs/autofs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs/inode.c')
-rw-r--r--fs/autofs/inode.c251
1 files changed, 129 insertions, 122 deletions
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index 20ca0907a..870ff120d 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -19,11 +19,17 @@
#define __NO_VERSION__
#include <linux/module.h>
+/*
+ * Dummy functions - do we ever actually want to do
+ * something here?
+ */
static void autofs_put_inode(struct inode *inode)
{
- if (inode->i_nlink)
- return;
- inode->i_size = 0;
+}
+
+static void autofs_delete_inode(struct inode *inode)
+{
+ inode->i_size = 0;
}
static void autofs_put_super(struct super_block *sb)
@@ -35,16 +41,16 @@ static void autofs_put_super(struct super_block *sb)
if ( !sbi->catatonic )
autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
- lock_super(sb);
+ lock_super(sb);
autofs_hash_nuke(&sbi->dirhash);
for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
if ( test_bit(n, sbi->symlink_bitmap) )
kfree(sbi->symlink[n].data);
}
- sb->s_dev = 0;
+ sb->s_dev = 0;
kfree(sb->u.generic_sbp);
- unlock_super(sb);
+ unlock_super(sb);
DPRINTK(("autofs: shutting down\n"));
@@ -53,95 +59,96 @@ static void autofs_put_super(struct super_block *sb)
#endif
}
-static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
static void autofs_read_inode(struct inode *inode);
static void autofs_write_inode(struct inode *inode);
static struct super_operations autofs_sops = {
- autofs_read_inode,
- NULL,
- autofs_write_inode,
- autofs_put_inode,
- autofs_put_super,
- NULL,
- autofs_statfs,
- NULL
+ autofs_read_inode,
+ autofs_write_inode,
+ autofs_put_inode,
+ autofs_delete_inode,
+ NULL, /* notify_change */
+ autofs_put_super,
+ NULL, /* write_super */
+ autofs_statfs,
+ NULL
};
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
{
- char *this_char, *value;
-
- *uid = current->uid;
- *gid = current->gid;
+ char *this_char, *value;
+
+ *uid = current->uid;
+ *gid = current->gid;
*pgrp = current->pgrp;
*minproto = *maxproto = AUTOFS_PROTO_VERSION;
- *pipefd = -1;
+ *pipefd = -1;
- if ( !options ) return 1;
- for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
- if (!strcmp(this_char,"fd")) {
- if (!value || !*value)
- return 1;
- *pipefd = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"uid")) {
- if (!value || !*value)
- return 1;
- *uid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"gid")) {
- if (!value || !*value)
- return 1;
- *gid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"pgrp")) {
- if (!value || !*value)
- return 1;
- *pgrp = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"minproto")) {
- if (!value || !*value)
- return 1;
- *minproto = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"maxproto")) {
- if (!value || !*value)
- return 1;
- *maxproto = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else break;
- }
- return (*pipefd < 0);
+ if ( !options ) return 1;
+ for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
+ if ((value = strchr(this_char,'=')) != NULL)
+ *value++ = 0;
+ if (!strcmp(this_char,"fd")) {
+ if (!value || !*value)
+ return 1;
+ *pipefd = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"uid")) {
+ if (!value || !*value)
+ return 1;
+ *uid = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"gid")) {
+ if (!value || !*value)
+ return 1;
+ *gid = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"pgrp")) {
+ if (!value || !*value)
+ return 1;
+ *pgrp = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"minproto")) {
+ if (!value || !*value)
+ return 1;
+ *minproto = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"maxproto")) {
+ if (!value || !*value)
+ return 1;
+ *maxproto = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else break;
+ }
+ return (*pipefd < 0);
}
struct super_block *autofs_read_super(struct super_block *s, void *data,
- int silent)
+ int silent)
{
- int pipefd;
+ int pipefd;
struct autofs_sb_info *sbi;
int minproto, maxproto;
MOD_INC_USE_COUNT;
- lock_super(s);
- sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
+ lock_super(s);
+ sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL);
if ( !sbi ) {
s->s_dev = 0;
MOD_DEC_USE_COUNT;
@@ -158,30 +165,31 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
sbi->queues = NULL;
memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN);
sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
- s->s_blocksize = 1024;
- s->s_blocksize_bits = 10;
- s->s_magic = AUTOFS_SUPER_MAGIC;
- s->s_op = &autofs_sops;
- unlock_super(s);
- if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) {
- s->s_dev = 0;
+ s->s_blocksize = 1024;
+ s->s_blocksize_bits = 10;
+ s->s_magic = AUTOFS_SUPER_MAGIC;
+ s->s_op = &autofs_sops;
+ unlock_super(s);
+ s->s_root = d_alloc_root(iget(s, AUTOFS_ROOT_INO), NULL);
+ if (!s->s_root) {
+ s->s_dev = 0;
kfree(sbi);
- printk("autofs: get root inode failed\n");
+ printk("autofs: get root inode failed\n");
MOD_DEC_USE_COUNT;
- return NULL;
- }
+ return NULL;
+ }
- if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
- iput(s->s_mounted);
- s->s_dev = 0;
+ if ( parse_options(data,&pipefd,&s->s_root->d_inode->i_uid,&s->s_root->d_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
+ dput(s->s_root);
+ s->s_dev = 0;
kfree(sbi);
- printk("autofs: called with bogus options\n");
+ printk("autofs: called with bogus options\n");
MOD_DEC_USE_COUNT;
- return NULL;
- }
+ return NULL;
+ }
if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) {
- iput(s->s_mounted);
+ dput(s->s_root);
s->s_dev = 0;
kfree(sbi);
printk("autofs: kernel does not match daemon version\n");
@@ -193,60 +201,60 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
sbi->pipe = fget(pipefd);
if ( !sbi->pipe || !sbi->pipe->f_op || !sbi->pipe->f_op->write ) {
if ( sbi->pipe ) {
- fput(sbi->pipe, sbi->pipe->f_inode);
+ fput(sbi->pipe);
printk("autofs: pipe file descriptor does not contain proper ops\n");
} else {
printk("autofs: could not open pipe file descriptor\n");
}
- iput(s->s_mounted);
+ dput(s->s_root);
s->s_dev = 0;
kfree(sbi);
MOD_DEC_USE_COUNT;
return NULL;
}
- return s;
+ return s;
}
-static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
{
- struct statfs tmp;
+ struct statfs tmp;
- tmp.f_type = AUTOFS_SUPER_MAGIC;
- tmp.f_bsize = 1024;
- tmp.f_blocks = 0;
- tmp.f_bfree = 0;
- tmp.f_bavail = 0;
- tmp.f_files = 0;
- tmp.f_ffree = 0;
- tmp.f_namelen = NAME_MAX;
- copy_to_user(buf, &tmp, bufsiz);
+ tmp.f_type = AUTOFS_SUPER_MAGIC;
+ tmp.f_bsize = 1024;
+ tmp.f_blocks = 0;
+ tmp.f_bfree = 0;
+ tmp.f_bavail = 0;
+ tmp.f_files = 0;
+ tmp.f_ffree = 0;
+ tmp.f_namelen = NAME_MAX;
+ return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
}
static void autofs_read_inode(struct inode *inode)
{
- ino_t ino = inode->i_ino;
+ ino_t ino = inode->i_ino;
unsigned int n;
- struct autofs_sb_info *sbi =
+ struct autofs_sb_info *sbi =
(struct autofs_sb_info *) inode->i_sb->u.generic_sbp;
- inode->i_op = NULL;
- inode->i_mode = 0;
- inode->i_nlink = 2;
- inode->i_size = 0;
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_blocks = 0;
- inode->i_blksize = 1024;
+ inode->i_op = NULL;
+ inode->i_mode = 0;
+ inode->i_nlink = 2;
+ inode->i_size = 0;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode->i_blocks = 0;
+ inode->i_blksize = 1024;
- if ( ino == AUTOFS_ROOT_INO ) {
- inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
- inode->i_op = &autofs_root_inode_operations;
+ if ( ino == AUTOFS_ROOT_INO ) {
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
+ inode->i_op = &autofs_root_inode_operations;
inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
- return;
- }
+ return;
+ }
+
+ inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
+ inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
- inode->i_uid = inode->i_sb->s_mounted->i_uid;
- inode->i_gid = inode->i_sb->s_mounted->i_gid;
-
if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
/* Symlink inode - should be in symlink list */
struct autofs_symlink *sl;
@@ -273,5 +281,4 @@ static void autofs_read_inode(struct inode *inode)
static void autofs_write_inode(struct inode *inode)
{
- inode->i_dirt = 0;
}