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

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


File: fs/fat/inode.c
Instrumentation mode: function-decision-multicondition
TER: 36 % (224/629)

Start/ End/    
True False - Line Source

  1 /*
  2  *  linux/fs/fat/inode.c
  3  *
  4  *  Written 1992,1993 by Werner Almesberger
  5  *  VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
  6  *  Rewritten for the constant inumbers support by Al Viro
  7  *
  8  *  Fixes:
  9  *
  10  *   Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
  11  */
  12 
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 #include <linux/time.h>
  16 #include <linux/slab.h>
  17 #include <linux/smp_lock.h>
  18 #include <linux/seq_file.h>
  19 #include <linux/msdos_fs.h>
  20 #include <linux/pagemap.h>
  21 #include <linux/mpage.h>
  22 #include <linux/buffer_head.h>
  23 #include <linux/mount.h>
  24 #include <linux/vfs.h>
  25 #include <linux/parser.h>
  26 #include <linux/uio.h>
  27 #include <asm/unaligned.h>
  28 
  29 #ifndef CONFIG_FAT_DEFAULT_IOCHARSET
  30 /* if user don't select VFAT, this is undefined. */
  31 #define CONFIG_FAT_DEFAULT_IOCHARSET   ""
  32 #endif
  33 
  34 static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
  35 static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
  36 
  37 
 
392   38 static int fat_add_cluster(struct inode *inode)
  39 {
  40    int err, cluster;
  41 
  42    err = fat_alloc_clusters(inode, &cluster, 1);
392 - 43    if (err)
 - 44       return err;
  45    /* FIXME: this cluster should be added after data of this
  46     * cluster is writed */
  47    err = fat_chain_add(inode, cluster, 1);
392 - 48    if (err)
  49       fat_free_clusters(inode, cluster);
392    50    return err;
  51 }
  52 
 
265019   53 static int __fat_get_blocks(struct inode *inode, sector_t iblock,
  54              unsigned long *max_blocks,
  55              struct buffer_head *bh_result, int create)
  56 {
  57    struct super_block *sb = inode->i_sb;
  58    struct msdos_sb_info *sbi = MSDOS_SB(sb);
  59    sector_t phys;
  60    unsigned long mapped_blocks;
  61    int err, offset;
  62 
  63    err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
265019 - 64    if (err)
 - 65       return err;
239978 25041   66    if (phys) {
  67       map_bh(bh_result, sb, phys);
  68       *max_blocks = min(mapped_blocks, *max_blocks);
239978    69       return 0;
  70    }
25041 - 71    if (!create)
 - 72       return 0;
  73 
25041 - 74    if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
  75       fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
  76               MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
 - 77       return -EIO;
  78    }
  79 
  80    offset = (unsigned long)iblock & (sbi->sec_per_clus - 1);
392 24649   81    if (!offset) {
  82       /* TODO: multiple cluster allocation would be desirable. */
  83       err = fat_add_cluster(inode);
392 - 84       if (err)
 - 85          return err;
  86    }
  87    /* available blocks on this cluster */
  88    mapped_blocks = sbi->sec_per_clus - offset;
  89 
  90    *max_blocks = min(mapped_blocks, *max_blocks);
  91    MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;
  92 
  93    err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
25041 - 94    if (err)
 - 95       return err;
    96    BUG_ON(!phys);
25041 - 96   if (__builtin_expect ( ! ! ( ( ! phys ) != 0..
25041 - 96 do-while (0)
    97    BUG_ON(*max_blocks != mapped_blocks);
25041 - 97   if (__builtin_expect ( ! ! ( ( * max_blocks ..
25041 - 97 do-while (0)
  98    set_buffer_new(bh_result);
  99    map_bh(bh_result, sb, phys);
25041    100    return 0;
  101 }
  102 
 
- 103 static int fat_get_blocks(struct inode *inode, sector_t iblock,
  104            unsigned long max_blocks,
  105            struct buffer_head *bh_result, int create)
  106 {
  107    struct super_block *sb = inode->i_sb;
  108    int err;
  109 
  110    err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
- 111    if (err)
 - 112       return err;
  113    bh_result->b_size = max_blocks << sb->s_blocksize_bits;
 - 114    return 0;
  115 }
  116 
 
265019   117 static int fat_get_block(struct inode *inode, sector_t iblock,
  118           struct buffer_head *bh_result, int create)
  119 {
  120    unsigned long max_blocks = 1;
265019    121    return __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
  122 }
  123 
 
- 124 static int fat_writepage(struct page *page, struct writeback_control *wbc)
  125 {
 - 126    return block_write_full_page(page, fat_get_block, wbc);
  127 }
  128 
 
209   129 static int fat_writepages(struct address_space *mapping,
  130            struct writeback_control *wbc)
  131 {
209    132    return mpage_writepages(mapping, wbc, fat_get_block);
  133 }
  134 
 
- 135 static int fat_readpage(struct file *file, struct page *page)
  136 {
 - 137    return mpage_readpage(page, fat_get_block);
  138 }
  139 
 
1120   140 static int fat_readpages(struct file *file, struct address_space *mapping,
  141           struct list_head *pages, unsigned nr_pages)
  142 {
1120    143    return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
  144 }
  145 
 
3131   146 static int fat_prepare_write(struct file *file, struct page *page,
  147               unsigned from, unsigned to)
  148 {
  149    return cont_prepare_write(page, from, to, fat_get_block,
3131    150               &MSDOS_I(page->mapping->host)->mmu_private);
  151 }
  152 
 
3131   153 static int fat_commit_write(struct file *file, struct page *page,
  154              unsigned from, unsigned to)
  155 {
  156    struct inode *inode = page->mapping->host;
  157    int err = generic_commit_write(file, page, from, to);
3131 - 158    if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
 - 158   T && !(F)
 3131   158   T && !(T)
 - 158   F && !(_)
  159       inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
  160       MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
  161       mark_inode_dirty(inode);
  162    }
3131    163    return err;
  164 }
  165 
 
- 166 static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
  167               const struct iovec *iov,
  168               loff_t offset, unsigned long nr_segs)
  169 {
  170    struct file *file = iocb->ki_filp;
  171    struct inode *inode = file->f_mapping->host;
  172 
- 173    if (rw == WRITE) {
  174       /*
  175        * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(),
  176        * so we need to update the ->mmu_private to block boundary.
  177        *
  178        * But we must fill the remaining area or hole by nul for
  179        * updating ->mmu_private.
  180        */
  181       loff_t size = offset + iov_length(iov, nr_segs);
- 182       if (MSDOS_I(inode)->mmu_private < size)
 - 183          return -EINVAL;
  184    }
  185 
  186    /*
  187     * FAT need to use the DIO_LOCKING for avoiding the race
  188     * condition of fat_get_block() and ->truncate().
  189     */
  190    return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
 - 191               offset, nr_segs, fat_get_blocks, NULL);
  192 }
  193 
 
- 194 static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
  195 {
 - 196    return generic_block_bmap(mapping, block, fat_get_block);
  197 }
  198 
  199 static struct address_space_operations fat_aops = {
  200    .readpage   = fat_readpage,
  201    .readpages   = fat_readpages,
  202    .writepage   = fat_writepage,
  203    .writepages   = fat_writepages,
  204    .sync_page   = block_sync_page,
  205    .prepare_write   = fat_prepare_write,
  206    .commit_write   = fat_commit_write,
  207    .direct_IO   = fat_direct_IO,
  208    .bmap      = _fat_bmap
  209 };
  210 
  211 /*
  212  * New FAT inode stuff. We do the following:
  213  *   a) i_ino is constant and has nothing with on-disk location.
  214  *   b) FAT manages its own cache of directory entries.
  215  *   c) *This* cache is indexed by on-disk location.
  216  *   d) inode has an associated directory entry, all right, but
  217  *      it may be unhashed.
  218  *   e) currently entries are stored within struct inode. That should
  219  *      change.
  220  *   f) we deal with races in the following way:
  221  *      1. readdir() and lookup() do FAT-dir-cache lookup.
  222  *      2. rename() unhashes the F-d-c entry and rehashes it in
  223  *         a new place.
  224  *      3. unlink() and rmdir() unhash F-d-c entry.
  225  *      4. fat_write_inode() checks whether the thing is unhashed.
  226  *         If it is we silently return. If it isn't we do bread(),
  227  *         check if the location is still valid and retry if it
  228  *         isn't. Otherwise we do changes.
  229  *      5. Spinlock is used to protect hash/unhash/location check/lookup
  230  *      6. fat_clear_inode() unhashes the F-d-c entry.
  231  *      7. lookup() and readdir() do igrab() if they find a F-d-c entry
  232  *         and consider negative result as cache miss.
  233  */
  234 
 
13 13   235 static void fat_hash_init(struct super_block *sb)
  236 {
  237    struct msdos_sb_info *sbi = MSDOS_SB(sb);
  238    int i;
  239 
    240    spin_lock_init(&sbi->inode_hash_lock);
13 - 240 do-while (0)
3328 13   241    for (i = 0; i < FAT_HASH_SIZE; i++)
  242       INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);
  243 }
  244 
 
646128   245 static inline unsigned long fat_hash(struct super_block *sb, loff_t i_pos)
  246 {
  247    unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
  248    tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2);
646128    249    return tmp & FAT_HASH_MASK;
  250 }
  251 
 
215153 215153   252 void fat_attach(struct inode *inode, loff_t i_pos)
  253 {
  254    struct super_block *sb = inode->i_sb;
  255    struct msdos_sb_info *sbi = MSDOS_SB(sb);
  256 
    257    spin_lock(&sbi->inode_hash_lock);
    257   do
215153 - 257   do-while (0)
215153 - 257 do-while (0)
  258    MSDOS_I(inode)->i_pos = i_pos;
  259    hlist_add_head(&MSDOS_I(inode)->i_fat_hash,
  260          sbi->inode_hashtable + fat_hash(sb, i_pos));
    261    spin_unlock(&sbi->inode_hash_lock);
    261   do
215153 - 261   do-while (0)
215153 - 261 do-while (0)
  262 }
  263 
  264 EXPORT_SYMBOL_GPL(fat_attach);
  265 
 
- 266 void fat_detach(struct inode *inode)
  267 {
  268    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
    269    spin_lock(&sbi->inode_hash_lock);
    269   do
- 269   do-while (0)
- 269 do-while (0)
  270    MSDOS_I(inode)->i_pos = 0;
  271    hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
    272    spin_unlock(&sbi->inode_hash_lock);
    272   do
- 272   do-while (0)
- 272 do-while (0)
  273 }
  274 
  275 EXPORT_SYMBOL_GPL(fat_detach);
  276 
 
430975   277 struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
  278 {
  279    struct msdos_sb_info *sbi = MSDOS_SB(sb);
  280    struct hlist_head *head = sbi->inode_hashtable + fat_hash(sb, i_pos);
  281    struct hlist_node *_p;
  282    struct msdos_inode_info *i;
  283    struct inode *inode = NULL;
  284 
    285    spin_lock(&sbi->inode_hash_lock);
    285   do
430975 - 285   do-while (0)
430975 - 285 do-while (0)
6019E4 430477   286    hlist_for_each_entry(i, _p, head, i_fat_hash) {
6019E4    286   T && (T) && (T)
 - 286   T && (T) && (F)
 - 286   T && (F) && (_)
 430477   286   F && (_) && (_)
    287       BUG_ON(i->vfs_inode.i_sb != sb);
6019E4 - 287     if (__builtin_expect ( ! ! ( ( i -> vfs_in..
6019E4 - 287   do-while (0)
6019E4 498   288       if (i->i_pos != i_pos)
6019E4    289          continue;
  290       inode = igrab(&i->vfs_inode);
498 - 291       if (inode)
498    292          break;
  293    }
    294    spin_unlock(&sbi->inode_hash_lock);
    294   do
430975 - 294   do-while (0)
430975 - 294 do-while (0)
430975    295    return inode;
  296 }
  297 
 
- 298 static int is_exec(unsigned char *extension)
  299 {
  300    unsigned char *exe_extensions = "EXECOMBAT", *walk;
  301 
- 302    for (walk = exe_extensions; *walk; walk += 3)
- 303       if (!strncmp(extension, walk, 3))
 - 304          return 1;
 - 305    return 0;
  306 }
  307 
 
20601   308 static int fat_calc_dir_size(struct inode *inode)
  309 {
  310    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
  311    int ret, fclus, dclus;
  312 
  313    inode->i_size = 0;
20601 - 314    if (MSDOS_I(inode)->i_start == 0)
 - 315       return 0;
  316 
  317    ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
20601 - 318    if (ret < 0)
 - 319       return ret;
  320    inode->i_size = (fclus + 1) << sbi->cluster_bits;
  321 
20601    322    return 0;
  323 }
  324 
  325 /* doesn't deal with root inode */
 
215153   326 static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
  327 {
  328    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
  329    int error;
  330 
  331    MSDOS_I(inode)->i_pos = 0;
  332    inode->i_uid = sbi->options.fs_uid;
  333    inode->i_gid = sbi->options.fs_gid;
  334    inode->i_version++;
  335    inode->i_generation = get_seconds();
  336 
20589 194564   337    if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
20589    337   (T) && !(F || F)
 - 337   (T) && !(T || _)
 - 337   (T) && !(F || T)
 194564   337   (F) && !(_ || _)
  338       inode->i_generation &= ~1;
    339       inode->i_mode = MSDOS_MKMODE(de->attr,
289 20300   339   ternary-?: de -> attr & 1
  340          S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
  341       inode->i_op = sbi->dir_ops;
  342       inode->i_fop = &fat_dir_operations;
  343 
  344       MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
20586   345       if (sbi->fat_bits == 32)
  346          MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
  347 
  348       MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
  349       error = fat_calc_dir_size(inode);
20589 - 350       if (error < 0)
 - 351          return error;
  352       MSDOS_I(inode)->mmu_private = inode->i_size;
  353 
  354       inode->i_nlink = fat_subdirs(inode);
    355    } else { /* not a directory */
  356       inode->i_generation |= 1;
    357       inode->i_mode = MSDOS_MKMODE(de->attr,
194564 - 357   ternary-?: ( sbi -> options . showexec && ! ..
4546 190018   357   ternary-?: de -> attr & 1
  358           ((sbi->options.showexec &&
  359          !is_exec(de->ext))
  360          ? S_IRUGO|S_IWUGO : S_IRWXUGO)
  361           & ~sbi->options.fs_fmask) | S_IFREG;
  362       MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
194468 96   363       if (sbi->fat_bits == 32)
  364          MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
  365 
  366       MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
  367       inode->i_size = le32_to_cpu(de->size);
  368       inode->i_op = &fat_file_inode_operations;
  369       inode->i_fop = &fat_file_operations;
  370       inode->i_mapping->a_ops = &fat_aops;
  371       MSDOS_I(inode)->mmu_private = inode->i_size;
  372    }
1050 214103   373    if (de->attr & ATTR_SYS) {
1050 - 374       if (sbi->options.sys_immutable)
  375          inode->i_flags |= S_IMMUTABLE;
  376    }
  377    MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
  378    /* this is as close to the truth as we can get ... */
  379    inode->i_blksize = sbi->cluster_size;
  380    inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
  381             & ~((loff_t)sbi->cluster_size - 1)) >> 9;
  382    inode->i_mtime.tv_sec =
  383       date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
  384    inode->i_mtime.tv_nsec = 0;
215153 - 385    if (sbi->options.isvfat) {
  386       int secs = de->ctime_cs / 100;
  387       int csecs = de->ctime_cs % 100;
  388       inode->i_ctime.tv_sec  =
  389          date_dos2unix(le16_to_cpu(de->ctime),
  390                   le16_to_cpu(de->cdate)) + secs;
  391       inode->i_ctime.tv_nsec = csecs * 10000000;
  392       inode->i_atime.tv_sec =
  393          date_dos2unix(le16_to_cpu(0), le16_to_cpu(de->adate));
  394       inode->i_atime.tv_nsec = 0;
    395    } else
  396       inode->i_ctime = inode->i_atime = inode->i_mtime;
  397 
215153    398    return 0;
  399 }
  400 
 
215219   401 struct inode *fat_build_inode(struct super_block *sb,
  402          struct msdos_dir_entry *de, loff_t i_pos)
  403 {
  404    struct inode *inode;
  405    int err;
  406 
  407    inode = fat_iget(sb, i_pos);
66 215153   408    if (inode)
66    409       goto out;
  410    inode = new_inode(sb);
215153 - 411    if (!inode) {
  412       inode = ERR_PTR(-ENOMEM);
 - 413       goto out;
  414    }
  415    inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
  416    inode->i_version = 1;
  417    err = fat_fill_inode(inode, de);
215153 - 418    if (err) {
  419       iput(inode);
  420       inode = ERR_PTR(err);
 - 421       goto out;
  422    }
  423    fat_attach(inode, i_pos);
  424    insert_inode_hash(inode);
  425 out:
215219    426    return inode;
  427 }
  428 
  429 EXPORT_SYMBOL_GPL(fat_build_inode);
  430 
 
- 431 static void fat_delete_inode(struct inode *inode)
  432 {
  433    truncate_inode_pages(&inode->i_data, 0);
  434 
- 435    if (!is_bad_inode(inode)) {
  436       inode->i_size = 0;
  437       fat_truncate(inode);
  438    }
  439    clear_inode(inode);
  440 }
  441 
 
211509 211509   442 static void fat_clear_inode(struct inode *inode)
  443 {
  444    struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
  445 
211509 - 446    if (is_bad_inode(inode))
 - 447       return;
    448    lock_kernel();
211509 - 448 do-while (0)
    449    spin_lock(&sbi->inode_hash_lock);
    449   do
211509 - 449   do-while (0)
211509 - 449 do-while (0)
  450    fat_cache_inval_inode(inode);
  451    hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
    452    spin_unlock(&sbi->inode_hash_lock);
    452   do
211509 - 452   do-while (0)
211509 - 452 do-while (0)
    453    unlock_kernel();
211509 - 453 do-while (0)
  454 }
  455 
 
  456 static void fat_write_super(struct super_block *sb)
  457 {
  458    sb->s_dirt = 0;
  459 
- 460    if (!(sb->s_flags & MS_RDONLY))
  461       fat_clusters_flush(sb);
  462 }
  463 
 
  464 static void fat_put_super(struct super_block *sb)
  465 {
  466    struct msdos_sb_info *sbi = MSDOS_SB(sb);
  467 
- 468    if (sbi->nls_disk) {
  469       unload_nls(sbi->nls_disk);
  470       sbi->nls_disk = NULL;
  471       sbi->options.codepage = fat_default_codepage;
  472    }
- 473    if (sbi->nls_io) {
  474       unload_nls(sbi->nls_io);
  475       sbi->nls_io = NULL;
  476    }
- 477&n