CTC++ Coverage Report - Execution Profile    #839/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: fs/autofs4/inode.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/170)

Start/ End/    
True False - Line Source

  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/pagemap.h>
  17 #include <linux/parser.h>
  18 #include <linux/bitops.h>
  19 #include <linux/smp_lock.h>
  20 #include "autofs_i.h"
  21 #include <linux/module.h>
  22 
 
- 23 static void ino_lnkfree(struct autofs_info *ino)
  24 {
  25    kfree(ino->u.symlink);
  26    ino->u.symlink = NULL;
  27 }
  28 
 
- 29 struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
  30                  struct autofs_sb_info *sbi, mode_t mode)
  31 {
  32    int reinit = 1;
  33 
- 34    if (ino == NULL) {
  35       reinit = 0;
  36       ino = kmalloc(sizeof(*ino), GFP_KERNEL);
  37    }
  38 
- 39    if (ino == NULL)
 - 40       return NULL;
  41 
  42    ino->flags = 0;
  43    ino->mode = mode;
  44    ino->inode = NULL;
  45    ino->dentry = NULL;
  46    ino->size = 0;
  47 
  48    ino->last_used = jiffies;
  49 
  50    ino->sbi = sbi;
  51 
- 52    if (reinit && ino->free)
 - 52   T && T
 - 52   T && F
 - 52   F && _
  53       (ino->free)(ino);
  54 
  55    memset(&ino->u, 0, sizeof(ino->u));
  56 
  57    ino->free = NULL;
  58 
- 59    if (S_ISLNK(mode))
  60       ino->free = ino_lnkfree;
  61 
 - 62    return ino;
  63 }
  64 
 
- 65 void autofs4_free_ino(struct autofs_info *ino)
  66 {
- 67    if (ino->dentry) {
  68       ino->dentry->d_fsdata = NULL;
- 69       if (ino->dentry->d_inode)
  70          dput(ino->dentry);
  71       ino->dentry = NULL;
  72    }
- 73    if (ino->free)
  74       (ino->free)(ino);
  75    kfree(ino);
  76 }
  77 
  78 /*
  79  * Deal with the infamous "Busy inodes after umount ..." message.
  80  *
  81  * Clean up the dentry tree. This happens with autofs if the user
  82  * space program goes away due to a SIGKILL, SIGSEGV etc.
  83  */
 
- 84 static void autofs4_force_release(struct autofs_sb_info *sbi)
  85 {
  86    struct dentry *this_parent = sbi->root;
  87    struct list_head *next;
  88 
    89    spin_lock(&dcache_lock);
    89   do
- 89   do-while (0)
- 89 do-while (0)
  90 repeat:
  91    next = this_parent->d_subdirs.next;
  92 resume:
- 93    while (next != &this_parent->d_subdirs) {
  94       struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
  95 
  96       /* Negative dentry - don`t care */
- 97       if (!simple_positive(dentry)) {
  98          next = next->next;
 - 99          continue;
  100       }
  101 
- 102       if (!list_empty(&dentry->d_subdirs)) {
  103          this_parent = dentry;
 - 104          goto repeat;
  105       }
  106 
  107       next = next->next;
    108       spin_unlock(&dcache_lock);
    108     do
- 108     do-while (0)
- 108   do-while (0)
  109 
    110       DPRINTK("dentry %p %.*s",
- 110   do-while (0)
  111          dentry, (int)dentry->d_name.len, dentry->d_name.name);
  112 
  113       dput(dentry);
    114       spin_lock(&dcache_lock);
    114     do
- 114     do-while (0)
- 114   do-while (0)
  115    }
  116 
- 117    if (this_parent != sbi->root) {
  118       struct dentry *dentry = this_parent;
  119 
  120       next = this_parent->d_u.d_child.next;
  121       this_parent = this_parent->d_parent;
    122       spin_unlock(&dcache_lock);
    122     do
- 122     do-while (0)
- 122   do-while (0)
    123       DPRINTK("parent dentry %p %.*s",
- 123   do-while (0)
  124          dentry, (int)dentry->d_name.len, dentry->d_name.name);
  125       dput(dentry);
    126       spin_lock(&dcache_lock);
    126     do
- 126     do-while (0)
- 126   do-while (0)
 - 127       goto resume;
  128    }
    129    spin_unlock(&dcache_lock);
    129   do
- 129   do-while (0)
- 129 do-while (0)
  130 
  131    dput(sbi->root);
  132    sbi->root = NULL;
  133    shrink_dcache_sb(sbi->sb);
  134 
 - 135    return;
  136 }
  137 
 
- 138 static void autofs4_put_super(struct super_block *sb)
  139 {
  140    struct autofs_sb_info *sbi = autofs4_sbi(sb);
  141 
  142    sb->s_fs_info = NULL;
  143 
- 144    if ( !sbi->catatonic )
  145       autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
  146 
  147    /* Clean up and release dangling references */
- 148    if (sbi)
  149       autofs4_force_release(sbi);
  150 
  151    kfree(sbi);
  152 
    153    DPRINTK("shutting down");
- 153 do-while (0)
  154 }
  155 
  156 static struct super_operations autofs4_sops = {
  157    .put_super   = autofs4_put_super,
  158    .statfs      = simple_statfs,
  159 };
  160 
  161 enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
  162 
  163 static match_table_t tokens = {
  164    {Opt_fd, "fd=%u"},
  165    {Opt_uid, "uid=%u"},
  166    {Opt_gid, "gid=%u"},
  167    {Opt_pgrp, "pgrp=%u"},
  168    {Opt_minproto, "minproto=%u"},
  169    {Opt_maxproto, "maxproto=%u"},
  170    {Opt_err, NULL}
  171 };
  172 
 
- 173 static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
  174           pid_t *pgrp, int *minproto, int *maxproto)
  175 {
  176    char *p;
  177    substring_t args[MAX_OPT_ARGS];
  178    int option;
  179 
  180    *uid = current->uid;
  181    *gid = current->gid;
  182    *pgrp = process_group(current);
  183 
  184    *minproto = AUTOFS_MIN_PROTO_VERSION;
  185    *maxproto = AUTOFS_MAX_PROTO_VERSION;
  186 
  187    *pipefd = -1;
  188 
- 189    if (!options)
 - 190       return 1;
  191 
- 192    while ((p = strsep(&options, ",")) != NULL) {
  193       int token;
- 194       if (!*p)
 - 195          continue;
  196 
  197       token = match_token(p, tokens, args);
    198       switch (token) {
 - 199       case Opt_fd:
- 200          if (match_int(args, pipefd))
 - 201             return 1;
 - 202          break;
 - 203       case Opt_uid:
- 204          if (match_int(args, &option))
 - 205             return 1;
  206          *uid = option;
 - 207          break;
 - 208       case Opt_gid:
- 209          if (match_int(args, &option))
 - 210             return 1;
  211          *gid = option;
 - 212          break;
 - 213       case Opt_pgrp:
- 214          if (match_int(args, &option))
 - 215             return 1;
  216          *pgrp = option;
 - 217          break;
 - 218       case Opt_minproto:
- 219          if (match_int(args, &option))
 - 220             return 1;
  221          *minproto = option;
 - 222          break;
 - 223       case Opt_maxproto:
- 224          if (match_int(args, &option))
 - 225             return 1;
  226          *maxproto = option;
 - 227          break;
 - 228       default:
 - 229          return 1;
  230       }
  231    }
 - 232    return (*pipefd < 0);
  233 }
  234 
 
- 235 static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
  236 {
  237    struct autofs_info *ino;
  238 
  239    ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755);
- 240    if (!ino)
 - 241       return NULL;
  242 
 - 243    return ino;
  244 }
  245 
 
- 246 int autofs4_fill_super(struct super_block *s, void *data, int silent)
  247 {
  248    struct inode * root_inode;
  249    struct dentry * root;
  250    struct file * pipe;
  251    int pipefd;
  252    struct autofs_sb_info *sbi;
  253    struct autofs_info *ino;
  254    int minproto, maxproto;
  255 
  256    sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
- 257    if ( !sbi )
 - 258       goto fail_unlock;
    259    DPRINTK("starting up, sbi = %p",sbi);
- 259 do-while (0)
  260 
  261    memset(sbi, 0, sizeof(*sbi));
  262 
  263    s->s_fs_info = sbi;
  264    sbi->magic = AUTOFS_SBI_MAGIC;
  265    sbi->root = NULL;
  266    sbi->catatonic = 0;
  267    sbi->exp_timeout = 0;
  268    sbi->oz_pgrp = process_group(current);
  269    sbi->sb = s;
  270    sbi->version = 0;
  271    sbi->sub_version = 0;
  272    init_MUTEX(&sbi->wq_sem);
    273    spin_lock_init(&sbi->fs_lock);
- 273 do-while (0)
  274    sbi->queues = NULL;
  275    s->s_blocksize = 1024;
  276    s->s_blocksize_bits = 10;
  277    s->s_magic = AUTOFS_SUPER_MAGIC;
  278    s->s_op = &autofs4_sops;
  279    s->s_time_gran = 1;
  280 
  281    /*
  282     * Get the root inode and dentry, but defer checking for errors.
  283     */
  284    ino = autofs4_mkroot(sbi);
- 285    if (!ino)
 - 286       goto fail_free;
  287    root_inode = autofs4_get_inode(s, ino);
  288    kfree(ino);
- 289    if (!root_inode)
 - 290       goto fail_free;
  291 
  292    root_inode->i_op = &autofs4_root_inode_operations;
  293    root_inode->i_fop = &autofs4_root_operations;
  294    root = d_alloc_root(root_inode);
  295    pipe = NULL;
  296 
- 297    if (!root)
 - 298       goto fail_iput;
  299 
  300    /* Can this call block? */
  301    if (parse_options(data, &pipefd,
  302            &root_inode->i_uid, &root_inode->i_gid,
  303            &sbi->oz_pgrp,
- 304            &minproto, &maxproto)) {
  305       printk("autofs: called with bogus options\n");
 - 306       goto fail_dput;
  307    }
  308 
  309    /* Couldn't this be tested earlier? */
  310    if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
- 311        minproto > AUTOFS_MAX_PROTO_VERSION) {
 - 311   T || _
 - 311   F || T
 - 311   F || F
  312       printk("autofs: kernel does not match daemon version "
  313              "daemon (%d, %d) kernel (%d, %d)\n",
  314          minproto, maxproto,
  315          AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
 - 316       goto fail_dput;
  317    }
  318 
    319    sbi->version = maxproto > AUTOFS_MAX_PROTO_VERSION ? AUTOFS_MAX_PROTO_VERSION : maxproto;
- 319 ternary-?: maxproto > 4
  320    sbi->sub_version = AUTOFS_PROTO_SUBVERSION;
  321 
    322    DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp);
- 322 do-while (0)
  323    pipe = fget(pipefd);
  324    
- 325    if ( !pipe ) {
  326       printk("autofs: could not open pipe file descriptor\n");
 - 327       goto fail_dput;
  328    }
- 329    if ( !pipe->f_op || !pipe->f_op->write )
 - 329   T || _
 - 329   F || T
 - 329   F || F
 - 330       goto fail_fput;
  331    sbi->pipe = pipe;
  332 
  333    /*
  334     * Take a reference to the root dentry so we get a chance to
  335     * clean up the dentry tree on umount.
  336     * See autofs4_force_release.
  337     */
  338    sbi->root = dget(root);
  339 
  340    /*
  341     * Success! Install the root dentry now to indicate completion.
  342     */
  343    s->s_root = root;
 - 344    return 0;
  345    
  346    /*
  347     * Failure ... clean up.
  348     */
  349 fail_fput:
  350    printk("autofs: pipe file descriptor does not contain proper ops\n");
  351    fput(pipe);
  352    /* fall through */
  353 fail_dput:
  354    dput(root);
 - 355    goto fail_free;
  356 fail_iput:
  357    printk("autofs: get root dentry failed\n");
  358    iput(root_inode);
  359 fail_free:
  360    kfree(sbi);
  361 fail_unlock:
 - 362    return -EINVAL;
  363 }
  364 
 
- 365 struct inode *autofs4_get_inode(struct super_block *sb,
  366             struct autofs_info *inf)
  367 {
  368    struct inode *inode = new_inode(sb);
  369 
- 370    if (inode == NULL)
 - 371       return NULL;
  372 
  373    inf->inode = inode;
  374    inode->i_mode = inf->mode;
- 375    if (sb->s_root) {
  376       inode->i_uid = sb->s_root->d_inode->i_uid;
  377       inode->i_gid = sb->s_root->d_inode->i_gid;
    378    } else {
  379       inode->i_uid = 0;
  380       inode->i_gid = 0;
  381    }
  382    inode->i_blksize = PAGE_CACHE_SIZE;
  383    inode->i_blocks = 0;
  384    inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  385 
- 386    if (S_ISDIR(inf->mode)) {
  387       inode->i_nlink = 2;
  388       inode->i_op = &autofs4_dir_inode_operations;
  389       inode->i_fop = &autofs4_dir_operations;
- 390    } else if (S_ISLNK(inf->mode)) {
  391       inode->i_size = inf->size;
  392       inode->i_op = &autofs4_symlink_inode_operations;
  393    }
  394 
 - 395    return inode;
  396 }
***TER 0% (0/170) of SOURCE FILE inode.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top