The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/autofs4/inode.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* -*- c -*- --------------------------------------------------------------- *
    2  *
    3  * linux/fs/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/slab.h>
   15 #include <linux/file.h>
   16 #include <linux/locks.h>
   17 #include <asm/bitops.h>
   18 #include "autofs_i.h"
   19 #define __NO_VERSION__
   20 #include <linux/module.h>
   21 
   22 static void ino_lnkfree(struct autofs_info *ino)
   23 {
   24         if (ino->u.symlink) {
   25                 kfree(ino->u.symlink);
   26                 ino->u.symlink = NULL;
   27         }
   28 }
   29 
   30 struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
   31                                      struct autofs_sb_info *sbi, mode_t mode)
   32 {
   33         int reinit = 1;
   34 
   35         if (ino == NULL) {
   36                 reinit = 0;
   37                 ino = kmalloc(sizeof(*ino), GFP_KERNEL);
   38         }
   39 
   40         if (ino == NULL)
   41                 return NULL;
   42 
   43         ino->flags = 0;
   44         ino->mode = mode;
   45         ino->inode = NULL;
   46         ino->dentry = NULL;
   47         ino->size = 0;
   48 
   49         ino->last_used = jiffies;
   50 
   51         ino->sbi = sbi;
   52 
   53         if (reinit && ino->free)
   54                 (ino->free)(ino);
   55 
   56         memset(&ino->u, 0, sizeof(ino->u));
   57 
   58         ino->free = NULL;
   59 
   60         if (S_ISLNK(mode))
   61                 ino->free = ino_lnkfree;
   62 
   63         return ino;
   64 }
   65 
   66 void autofs4_free_ino(struct autofs_info *ino)
   67 {
   68         if (ino->dentry) {
   69                 ino->dentry->d_fsdata = NULL;
   70                 if (ino->dentry->d_inode)
   71                         dput(ino->dentry);
   72                 ino->dentry = NULL;
   73         }
   74         if (ino->free)
   75                 (ino->free)(ino);
   76         kfree(ino);
   77 }
   78 
   79 static void autofs4_put_super(struct super_block *sb)
   80 {
   81         struct autofs_sb_info *sbi = autofs4_sbi(sb);
   82 
   83         sb->u.generic_sbp = NULL;
   84 
   85         if ( !sbi->catatonic )
   86                 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
   87 
   88         kfree(sbi);
   89 
   90         DPRINTK(("autofs: shutting down\n"));
   91 }
   92 
   93 static int autofs4_statfs(struct super_block *sb, struct statfs *buf);
   94 
   95 static struct super_operations autofs4_sops = {
   96         put_super:      autofs4_put_super,
   97         statfs:         autofs4_statfs,
   98 };
   99 
  100 static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
  101                          pid_t *pgrp, int *minproto, int *maxproto)
  102 {
  103         char *this_char, *value;
  104         
  105         *uid = current->uid;
  106         *gid = current->gid;
  107         *pgrp = current->pgrp;
  108 
  109         *minproto = AUTOFS_MIN_PROTO_VERSION;
  110         *maxproto = AUTOFS_MAX_PROTO_VERSION;
  111 
  112         *pipefd = -1;
  113 
  114         if ( !options ) return 1;
  115         for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
  116                 if ((value = strchr(this_char,'=')) != NULL)
  117                         *value++ = 0;
  118                 if (!strcmp(this_char,"fd")) {
  119                         if (!value || !*value)
  120                                 return 1;
  121                         *pipefd = simple_strtoul(value,&value,0);
  122                         if (*value)
  123                                 return 1;
  124                 }
  125                 else if (!strcmp(this_char,"uid")) {
  126                         if (!value || !*value)
  127                                 return 1;
  128                         *uid = simple_strtoul(value,&value,0);
  129                         if (*value)
  130                                 return 1;
  131                 }
  132                 else if (!strcmp(this_char,"gid")) {
  133                         if (!value || !*value)
  134                                 return 1;
  135                         *gid = simple_strtoul(value,&value,0);
  136                         if (*value)
  137                                 return 1;
  138                 }
  139                 else if (!strcmp(this_char,"pgrp")) {
  140                         if (!value || !*value)
  141                                 return 1;
  142                         *pgrp = simple_strtoul(value,&value,0);
  143                         if (*value)
  144                                 return 1;
  145                 }
  146                 else if (!strcmp(this_char,"minproto")) {
  147                         if (!value || !*value)
  148                                 return 1;
  149                         *minproto = simple_strtoul(value,&value,0);
  150                         if (*value)
  151                                 return 1;
  152                 }
  153                 else if (!strcmp(this_char,"maxproto")) {
  154                         if (!value || !*value)
  155                                 return 1;
  156                         *maxproto = simple_strtoul(value,&value,0);
  157                         if (*value)
  158                                 return 1;
  159                 }
  160                 else break;
  161         }
  162         return (*pipefd < 0);
  163 }
  164 
  165 static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
  166 {
  167         struct autofs_info *ino;
  168 
  169         ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755);
  170         if (!ino)
  171                 return NULL;
  172 
  173         return ino;
  174 }
  175 
  176 struct super_block *autofs4_read_super(struct super_block *s, void *data,
  177                                       int silent)
  178 {
  179         struct inode * root_inode;
  180         struct dentry * root;
  181         struct file * pipe;
  182         int pipefd;
  183         struct autofs_sb_info *sbi;
  184         int minproto, maxproto;
  185 
  186         sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
  187         if ( !sbi )
  188                 goto fail_unlock;
  189         DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
  190 
  191         memset(sbi, 0, sizeof(*sbi));
  192 
  193         s->u.generic_sbp = sbi;
  194         sbi->magic = AUTOFS_SBI_MAGIC;
  195         sbi->catatonic = 0;
  196         sbi->exp_timeout = 0;
  197         sbi->oz_pgrp = current->pgrp;
  198         sbi->sb = s;
  199         sbi->version = 0;
  200         sbi->queues = NULL;
  201         s->s_blocksize = 1024;
  202         s->s_blocksize_bits = 10;
  203         s->s_magic = AUTOFS_SUPER_MAGIC;
  204         s->s_op = &autofs4_sops;
  205 
  206         /*
  207          * Get the root inode and dentry, but defer checking for errors.
  208          */
  209         root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi));
  210         root_inode->i_op = &autofs4_root_inode_operations;
  211         root_inode->i_fop = &autofs4_root_operations;
  212         root = d_alloc_root(root_inode);
  213         pipe = NULL;
  214 
  215         if (!root)
  216                 goto fail_iput;
  217 
  218         /* Can this call block? */
  219         if (parse_options(data, &pipefd,
  220                           &root_inode->i_uid, &root_inode->i_gid,
  221                           &sbi->oz_pgrp,
  222                           &minproto, &maxproto)) {
  223                 printk("autofs: called with bogus options\n");
  224                 goto fail_dput;
  225         }
  226 
  227         /* Couldn't this be tested earlier? */
  228         if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
  229             minproto > AUTOFS_MAX_PROTO_VERSION) {
  230                 printk("autofs: kernel does not match daemon version "
  231                        "daemon (%d, %d) kernel (%d, %d)\n",
  232                         minproto, maxproto,
  233                         AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
  234                 goto fail_dput;
  235         }
  236 
  237         sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto;
  238 
  239         DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
  240         pipe = fget(pipefd);
  241         
  242         if ( !pipe ) {
  243                 printk("autofs: could not open pipe file descriptor\n");
  244                 goto fail_dput;
  245         }
  246         if ( !pipe->f_op || !pipe->f_op->write )
  247                 goto fail_fput;
  248         sbi->pipe = pipe;
  249 
  250         /*
  251          * Success! Install the root dentry now to indicate completion.
  252          */
  253         s->s_root = root;
  254         return s;
  255         
  256         /*
  257          * Failure ... clean up.
  258          */
  259 fail_fput:
  260         printk("autofs: pipe file descriptor does not contain proper ops\n");
  261         /*
  262          * fput() can block, so we clear the super block first.
  263          */
  264         fput(pipe);
  265         /* fall through */
  266 fail_dput:
  267         /*
  268          * dput() can block, so we clear the super block first.
  269          */
  270         dput(root);
  271         goto fail_free;
  272 fail_iput:
  273         printk("autofs: get root dentry failed\n");
  274         /*
  275          * iput() can block, so we clear the super block first.
  276          */
  277         iput(root_inode);
  278 fail_free:
  279         kfree(sbi);
  280 fail_unlock:
  281         return NULL;
  282 }
  283 
  284 static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
  285 {
  286         buf->f_type = AUTOFS_SUPER_MAGIC;
  287         buf->f_bsize = 1024;
  288         buf->f_namelen = NAME_MAX;
  289         return 0;
  290 }
  291 
  292 struct inode *autofs4_get_inode(struct super_block *sb,
  293                                 struct autofs_info *inf)
  294 {
  295         struct inode *inode = new_inode(sb);
  296 
  297         if (inode == NULL)
  298                 return NULL;
  299 
  300         inf->inode = inode;
  301         inode->i_mode = inf->mode;
  302         if (sb->s_root) {
  303                 inode->i_uid = sb->s_root->d_inode->i_uid;
  304                 inode->i_gid = sb->s_root->d_inode->i_gid;
  305         } else {
  306                 inode->i_uid = 0;
  307                 inode->i_gid = 0;
  308         }
  309         inode->i_blksize = PAGE_CACHE_SIZE;
  310         inode->i_blocks = 0;
  311         inode->i_rdev = 0;
  312         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  313 
  314         if (S_ISDIR(inf->mode)) {
  315                 inode->i_nlink = 2;
  316                 inode->i_op = &autofs4_dir_inode_operations;
  317                 inode->i_fop = &dcache_dir_ops;
  318         } else if (S_ISLNK(inf->mode)) {
  319                 inode->i_size = inf->size;
  320                 inode->i_op = &autofs4_symlink_inode_operations;
  321         }
  322 
  323         return inode;
  324 }

Cache object: 776e87532c93ac29cb28cfc8797816b8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.