linux/drivers/staging/autofs/inode.c
<<
>>
Prefs
   1/* -*- linux-c -*- --------------------------------------------------------- *
   2 *
   3 * drivers/staging/autofs/inode.c
   4 *
   5 *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
   6 *
   7 * This file is part of the Linux kernel and is made available under
   8 * the terms of the GNU General Public License, version 2, or at your
   9 * option, any later version, incorporated herein by reference.
  10 *
  11 * ------------------------------------------------------------------------- */
  12
  13#include <linux/kernel.h>
  14#include <linux/mm.h>
  15#include <linux/slab.h>
  16#include <linux/file.h>
  17#include <linux/parser.h>
  18#include <linux/bitops.h>
  19#include <linux/magic.h>
  20#include "autofs_i.h"
  21#include <linux/module.h>
  22
  23void autofs_kill_sb(struct super_block *sb)
  24{
  25        struct autofs_sb_info *sbi = autofs_sbi(sb);
  26        unsigned int n;
  27
  28        /*
  29         * In the event of a failure in get_sb_nodev the superblock
  30         * info is not present so nothing else has been setup, so
  31         * just call kill_anon_super when we are called from
  32         * deactivate_super.
  33         */
  34        if (!sbi)
  35                goto out_kill_sb;
  36
  37        if (!sbi->catatonic)
  38                autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
  39
  40        put_pid(sbi->oz_pgrp);
  41
  42        autofs_hash_nuke(sbi);
  43        for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) {
  44                if (test_bit(n, sbi->symlink_bitmap))
  45                        kfree(sbi->symlink[n].data);
  46        }
  47
  48        kfree(sb->s_fs_info);
  49
  50out_kill_sb:
  51        DPRINTK(("autofs: shutting down\n"));
  52        kill_anon_super(sb);
  53}
  54
  55static const struct super_operations autofs_sops = {
  56        .statfs         = simple_statfs,
  57        .show_options   = generic_show_options,
  58};
  59
  60enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
  61
  62static const match_table_t autofs_tokens = {
  63        {Opt_fd, "fd=%u"},
  64        {Opt_uid, "uid=%u"},
  65        {Opt_gid, "gid=%u"},
  66        {Opt_pgrp, "pgrp=%u"},
  67        {Opt_minproto, "minproto=%u"},
  68        {Opt_maxproto, "maxproto=%u"},
  69        {Opt_err, NULL}
  70};
  71
  72static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
  73                pid_t *pgrp, int *minproto, int *maxproto)
  74{
  75        char *p;
  76        substring_t args[MAX_OPT_ARGS];
  77        int option;
  78
  79        *uid = current_uid();
  80        *gid = current_gid();
  81        *pgrp = task_pgrp_nr(current);
  82
  83        *minproto = *maxproto = AUTOFS_PROTO_VERSION;
  84
  85        *pipefd = -1;
  86
  87        if (!options)
  88                return 1;
  89
  90        while ((p = strsep(&options, ",")) != NULL) {
  91                int token;
  92                if (!*p)
  93                        continue;
  94
  95                token = match_token(p, autofs_tokens, args);
  96                switch (token) {
  97                case Opt_fd:
  98                        if (match_int(&args[0], &option))
  99                                return 1;
 100                        *pipefd = option;
 101                        break;
 102                case Opt_uid:
 103                        if (match_int(&args[0], &option))
 104                                return 1;
 105                        *uid = option;
 106                        break;
 107                case Opt_gid:
 108                        if (match_int(&args[0], &option))
 109                                return 1;
 110                        *gid = option;
 111                        break;
 112                case Opt_pgrp:
 113                        if (match_int(&args[0], &option))
 114                                return 1;
 115                        *pgrp = option;
 116                        break;
 117                case Opt_minproto:
 118                        if (match_int(&args[0], &option))
 119                                return 1;
 120                        *minproto = option;
 121                        break;
 122                case Opt_maxproto:
 123                        if (match_int(&args[0], &option))
 124                                return 1;
 125                        *maxproto = option;
 126                        break;
 127                default:
 128                        return 1;
 129                }
 130        }
 131        return (*pipefd < 0);
 132}
 133
 134int autofs_fill_super(struct super_block *s, void *data, int silent)
 135{
 136        struct inode * root_inode;
 137        struct dentry * root;
 138        struct file * pipe;
 139        int pipefd;
 140        struct autofs_sb_info *sbi;
 141        int minproto, maxproto;
 142        pid_t pgid;
 143
 144        save_mount_options(s, data);
 145
 146        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
 147        if (!sbi)
 148                goto fail_unlock;
 149        DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
 150
 151        s->s_fs_info = sbi;
 152        sbi->magic = AUTOFS_SBI_MAGIC;
 153        sbi->pipe = NULL;
 154        sbi->catatonic = 1;
 155        sbi->exp_timeout = 0;
 156        autofs_initialize_hash(&sbi->dirhash);
 157        sbi->queues = NULL;
 158        memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
 159        sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
 160        s->s_blocksize = 1024;
 161        s->s_blocksize_bits = 10;
 162        s->s_magic = AUTOFS_SUPER_MAGIC;
 163        s->s_op = &autofs_sops;
 164        s->s_time_gran = 1;
 165        sbi->sb = s;
 166
 167        root_inode = autofs_iget(s, AUTOFS_ROOT_INO);
 168        if (IS_ERR(root_inode))
 169                goto fail_free;
 170        root = d_alloc_root(root_inode);
 171        pipe = NULL;
 172
 173        if (!root)
 174                goto fail_iput;
 175
 176        /* Can this call block?  - WTF cares? s is locked. */
 177        if (parse_options(data, &pipefd, &root_inode->i_uid,
 178                                &root_inode->i_gid, &pgid, &minproto,
 179                                &maxproto)) {
 180                printk("autofs: called with bogus options\n");
 181                goto fail_dput;
 182        }
 183
 184        /* Couldn't this be tested earlier? */
 185        if (minproto > AUTOFS_PROTO_VERSION ||
 186             maxproto < AUTOFS_PROTO_VERSION) {
 187                printk("autofs: kernel does not match daemon version\n");
 188                goto fail_dput;
 189        }
 190
 191        DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid));
 192        sbi->oz_pgrp = find_get_pid(pgid);
 193
 194        if (!sbi->oz_pgrp) {
 195                printk("autofs: could not find process group %d\n", pgid);
 196                goto fail_dput;
 197        }
 198
 199        pipe = fget(pipefd);
 200        
 201        if (!pipe) {
 202                printk("autofs: could not open pipe file descriptor\n");
 203                goto fail_put_pid;
 204        }
 205
 206        if (!pipe->f_op || !pipe->f_op->write)
 207                goto fail_fput;
 208        sbi->pipe = pipe;
 209        sbi->catatonic = 0;
 210
 211        /*
 212         * Success! Install the root dentry now to indicate completion.
 213         */
 214        s->s_root = root;
 215        return 0;
 216
 217fail_fput:
 218        printk("autofs: pipe file descriptor does not contain proper ops\n");
 219        fput(pipe);
 220fail_put_pid:
 221        put_pid(sbi->oz_pgrp);
 222fail_dput:
 223        dput(root);
 224        goto fail_free;
 225fail_iput:
 226        printk("autofs: get root dentry failed\n");
 227        iput(root_inode);
 228fail_free:
 229        kfree(sbi);
 230        s->s_fs_info = NULL;
 231fail_unlock:
 232        return -EINVAL;
 233}
 234
 235struct inode *autofs_iget(struct super_block *sb, unsigned long ino)
 236{
 237        unsigned int n;
 238        struct autofs_sb_info *sbi = autofs_sbi(sb);
 239        struct inode *inode;
 240
 241        inode = iget_locked(sb, ino);
 242        if (!inode)
 243                return ERR_PTR(-ENOMEM);
 244        if (!(inode->i_state & I_NEW))
 245                return inode;
 246
 247        /* Initialize to the default case (stub directory) */
 248
 249        inode->i_op = &simple_dir_inode_operations;
 250        inode->i_fop = &simple_dir_operations;
 251        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 252        inode->i_nlink = 2;
 253        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 254
 255        if (ino == AUTOFS_ROOT_INO) {
 256                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
 257                inode->i_op = &autofs_root_inode_operations;
 258                inode->i_fop = &autofs_root_operations;
 259                goto done;
 260        } 
 261        
 262        inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
 263        inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
 264        
 265        if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) {
 266                /* Symlink inode - should be in symlink list */
 267                struct autofs_symlink *sl;
 268
 269                n = ino - AUTOFS_FIRST_SYMLINK;
 270                if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
 271                        printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino);
 272                        goto done;
 273                }
 274                
 275                inode->i_op = &autofs_symlink_inode_operations;
 276                sl = &sbi->symlink[n];
 277                inode->i_private = sl;
 278                inode->i_mode = S_IFLNK | S_IRWXUGO;
 279                inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = sl->mtime;
 280                inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
 281                inode->i_size = sl->len;
 282                inode->i_nlink = 1;
 283        }
 284
 285done:
 286        unlock_new_inode(inode);
 287        return inode;
 288}
 289