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

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


File: fs/nfs/dir.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/824)

Start/ End/    
True False - Line Source

  1 /*
  2  *  linux/fs/nfs/dir.c
  3  *
  4  *  Copyright (C) 1992  Rick Sladkey
  5  *
  6  *  nfs directory handling functions
  7  *
  8  * 10 Apr 1996   Added silly rename for unlink   --okir
  9  * 28 Sep 1996   Improved directory cache --okir
  10  * 23 Aug 1997  Claus Heine claus@momo.math.rwth-aachen.de 
  11  *              Re-implemented silly rename for unlink, newly implemented
  12  *              silly rename for nfs_rename() following the suggestions
  13  *              of Olaf Kirch (okir) found in this file.
  14  *              Following Linus comments on my original hack, this version
  15  *              depends only on the dcache stuff and doesn't touch the inode
  16  *              layer (iput() and friends).
  17  *  6 Jun 1999   Cache readdir lookups in the page cache. -DaveM
  18  */
  19 
  20 #include <linux/time.h>
  21 #include <linux/errno.h>
  22 #include <linux/stat.h>
  23 #include <linux/fcntl.h>
  24 #include <linux/string.h>
  25 #include <linux/kernel.h>
  26 #include <linux/slab.h>
  27 #include <linux/mm.h>
  28 #include <linux/sunrpc/clnt.h>
  29 #include <linux/nfs_fs.h>
  30 #include <linux/nfs_mount.h>
  31 #include <linux/pagemap.h>
  32 #include <linux/smp_lock.h>
  33 #include <linux/namei.h>
  34 
  35 #include "nfs4_fs.h"
  36 #include "delegation.h"
  37 
  38 #define NFS_PARANOIA 1
  39 /* #define NFS_DEBUG_VERBOSE 1 */
  40 
  41 static int nfs_opendir(struct inode *, struct file *);
  42 static int nfs_readdir(struct file *, void *, filldir_t);
  43 static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
  44 static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
  45 static int nfs_mkdir(struct inode *, struct dentry *, int);
  46 static int nfs_rmdir(struct inode *, struct dentry *);
  47 static int nfs_unlink(struct inode *, struct dentry *);
  48 static int nfs_symlink(struct inode *, struct dentry *, const char *);
  49 static int nfs_link(struct dentry *, struct inode *, struct dentry *);
  50 static int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
  51 static int nfs_rename(struct inode *, struct dentry *,
  52             struct inode *, struct dentry *);
  53 static int nfs_fsync_dir(struct file *, struct dentry *, int);
  54 static loff_t nfs_llseek_dir(struct file *, loff_t, int);
  55 
  56 struct file_operations nfs_dir_operations = {
  57    .llseek      = nfs_llseek_dir,
  58    .read      = generic_read_dir,
  59    .readdir   = nfs_readdir,
  60    .open      = nfs_opendir,
  61    .release   = nfs_release,
  62    .fsync      = nfs_fsync_dir,
  63 };
  64 
  65 struct inode_operations nfs_dir_inode_operations = {
  66    .create      = nfs_create,
  67    .lookup      = nfs_lookup,
  68    .link      = nfs_link,
  69    .unlink      = nfs_unlink,
  70    .symlink   = nfs_symlink,
  71    .mkdir      = nfs_mkdir,
  72    .rmdir      = nfs_rmdir,
  73    .mknod      = nfs_mknod,
  74    .rename      = nfs_rename,
  75    .permission   = nfs_permission,
  76    .getattr   = nfs_getattr,
  77    .setattr   = nfs_setattr,
  78 };
  79 
  80 #ifdef CONFIG_NFS_V3
  81 struct inode_operations nfs3_dir_inode_operations = {
  82    .create      = nfs_create,
  83    .lookup      = nfs_lookup,
  84    .link      = nfs_link,
  85    .unlink      = nfs_unlink,
  86    .symlink   = nfs_symlink,
  87    .mkdir      = nfs_mkdir,
  88    .rmdir      = nfs_rmdir,
  89    .mknod      = nfs_mknod,
  90    .rename      = nfs_rename,
  91    .permission   = nfs_permission,
  92    .getattr   = nfs_getattr,
  93    .setattr   = nfs_setattr,
  94    .listxattr   = nfs3_listxattr,
  95    .getxattr   = nfs3_getxattr,
  96    .setxattr   = nfs3_setxattr,
  97    .removexattr   = nfs3_removexattr,
  98 };
  99 #endif  /* CONFIG_NFS_V3 */
  100 
  101 #ifdef CONFIG_NFS_V4
  102 
  103 static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
  104 struct inode_operations nfs4_dir_inode_operations = {
  105    .create      = nfs_create,
  106    .lookup      = nfs_atomic_lookup,
  107    .link      = nfs_link,
  108    .unlink      = nfs_unlink,
  109    .symlink   = nfs_symlink,
  110    .mkdir      = nfs_mkdir,
  111    .rmdir      = nfs_rmdir,
  112    .mknod      = nfs_mknod,
  113    .rename      = nfs_rename,
  114    .permission   = nfs_permission,
  115    .getattr   = nfs_getattr,
  116    .setattr   = nfs_setattr,
  117    .getxattr       = nfs4_getxattr,
  118    .setxattr       = nfs4_setxattr,
  119    .listxattr      = nfs4_listxattr,
  120 };
  121 
  122 #endif /* CONFIG_NFS_V4 */
  123 
  124 /*
  125  * Open file
  126  */
  127 static int
 
- 128 nfs_opendir(struct inode *inode, struct file *filp)
  129 {
  130    int res = 0;
  131 
    132    lock_kernel();
- 132 do-while (0)
  133    /* Call generic open code in order to cache credentials */
- 134    if (!res)
  135       res = nfs_open(inode, filp);
    136    unlock_kernel();
- 136 do-while (0)
 - 137    return res;
  138 }
  139 
  140 typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int);
  141 typedef struct {
  142    struct file   *file;
  143    struct page   *page;
  144    unsigned long   page_index;
  145    u32      *ptr;
  146    u64      *dir_cookie;
  147    loff_t      current_index;
  148    struct nfs_entry *entry;
  149    decode_dirent_t   decode;
  150    int      plus;
  151    int      error;
  152 } nfs_readdir_descriptor_t;
  153 
  154 /* Now we cache directories properly, by stuffing the dirent
  155  * data directly in the page cache.
  156  *
  157  * Inode invalidation due to refresh etc. takes care of
  158  * _everything_, no sloppy entry flushing logic, no extraneous
  159  * copying, network direct to page cache, the way it was meant
  160  * to be.
  161  *
  162  * NOTE: Dirent information verification is done always by the
  163  *    page-in of the RPC reply, nowhere else, this simplies
  164  *    things substantially.
  165  */
  166 static
 
- 167 int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
  168 {
  169    struct file   *file = desc->file;
  170    struct inode   *inode = file->f_dentry->d_inode;
  171    struct rpc_cred   *cred = nfs_file_cred(file);
  172    unsigned long   timestamp;
  173    int      error;
  174 
    175    dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %lu.\n", (long long)desc->entry->cookie, page->index);
- 175   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 175 do-while (0)
  176 
  177  again:
  178    timestamp = jiffies;
  179    error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page,
  180                  NFS_SERVER(inode)->dtsize, desc->plus);
- 181    if (error < 0) {
  182       /* We requested READDIRPLUS, but the server doesn't grok it */
- 183       if (error == -ENOTSUPP && desc->plus) {
 - 183     T && T
 - 183     T && F
 - 183     F && _
  184          NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
  185          clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
  186          desc->plus = 0;
 - 187          goto again;
  188       }
 - 189       goto error;
  190    }
  191    SetPageUptodate(page);
    192    spin_lock(&inode->i_lock);
    192   do
- 192   do-while (0)
- 192 do-while (0)
  193    NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
    194    spin_unlock(&inode->i_lock);
    194   do
- 194   do-while (0)
- 194 do-while (0)
  195    /* Ensure consistent page alignment of the data.
  196     * Note: assumes we have exclusive access to this mapping either
  197     *    through inode->i_mutex or some other mechanism.
  198     */
- 199    if (page->index == 0)
  200       invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);
  201    unlock_page(page);
 - 202    return 0;
  203  error:
  204    SetPageError(page);
  205    unlock_page(page);
  206    nfs_zap_caches(inode);
  207    desc->error = error;
 - 208    return -EIO;
  209 }
  210 
  211 static inline
 
- 212 int dir_decode(nfs_readdir_descriptor_t *desc)
  213 {
  214    u32   *p = desc->ptr;
  215    p = desc->decode(p, desc->entry, desc->plus);
- 216    if (IS_ERR(p))
 - 217       return PTR_ERR(p);
  218    desc->ptr = p;
 - 219    return 0;
  220 }
  221 
  222 static inline
 
- 223 void dir_page_release(nfs_readdir_descriptor_t *desc)
  224 {
    225    kunmap(desc->page);
- 225 do-while (0)
  226    page_cache_release(desc->page);
  227    desc->page = NULL;
  228    desc->ptr = NULL;
  229 }
  230 
  231 /*
  232  * Given a pointer to a buffer that has already been filled by a call
  233  * to readdir, find the next entry with cookie '*desc->dir_cookie'.
  234  *
  235  * If the end of the buffer has been reached, return -EAGAIN, if not,
  236  * return the offset within the buffer of the next entry to be
  237  * read.
  238  */
  239 static inline
 
- 240 int find_dirent(nfs_readdir_descriptor_t *desc)
  241 {
  242    struct nfs_entry *entry = desc->entry;
  243    int      loop_count = 0,
  244          status;
  245 
- 246    while((status = dir_decode(desc)) == 0) {
    247       dfprintk(VFS, "NFS: found cookie %Lu\n", (unsigned long long)entry->cookie);
- 247     if (__builtin_expect ( ! ! ( nfs_debug & 0..
- 247   do-while (0)
- 248       if (entry->prev_cookie == *desc->dir_cookie)
 - 249          break;
- 250       if (loop_count++ > 200) {
  251          loop_count = 0;
  252          schedule();
  253       }
  254    }
    255    dfprintk(VFS, "NFS: find_dirent() returns %d\n", status);
- 255   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 255 do-while (0)
 - 256    return status;
  257 }
  258 
  259 /*
  260  * Given a pointer to a buffer that has already been filled by a call
  261  * to readdir, find the entry at offset 'desc->file->f_pos'.
  262  *
  263  * If the end of the buffer has been reached, return -EAGAIN, if not,
  264  * return the offset within the buffer of the next entry to be
  265  * read.
  266  */
  267 static inline
 
- 268 int find_dirent_index(nfs_readdir_descriptor_t *desc)
  269 {
  270    struct nfs_entry *entry = desc->entry;
  271    int      loop_count = 0,
  272          status;
  273 
- 274    for(;;) {
  275       status = dir_decode(desc);
- 276       if (status)
 - 277          break;
  278 
    279       dfprintk(VFS, "NFS: found cookie %Lu at index %Ld\n", (unsigned long long)entry->cookie, desc->current_index);
- 279     if (__builtin_expect ( ! ! ( nfs_debug & 0..
- 279   do-while (0)
  280 
- 281       if (desc->file->f_pos == desc->current_index) {
  282          *desc->dir_cookie = entry->cookie;
 - 283          break;
  284       }
  285       desc->current_index++;
- 286       if (loop_count++ > 200) {
  287          loop_count = 0;
  288          schedule();
  289       }
  290    }
    291    dfprintk(VFS, "NFS: find_dirent_index() returns %d\n", status);
- 291   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 291 do-while (0)
 - 292    return status;
  293 }
  294 
  295 /*
  296  * Find the given page, and call find_dirent() or find_dirent_index in
  297  * order to try to return the next entry.
  298  */
  299 static inline
 
- 300 int find_dirent_page(nfs_readdir_descriptor_t *desc)
  301 {
  302    struct inode   *inode = desc->file->f_dentry->d_inode;
  303    struct page   *page;
  304    int      status;
  305 
    306    dfprintk(VFS, "NFS: find_dirent_page() searching directory page %ld\n", desc->page_index);
- 306   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 306 do-while (0)
  307 
  308    page = read_cache_page(inode->i_mapping, desc->page_index,
  309                 (filler_t *)nfs_readdir_filler, desc);
- 310    if (IS_ERR(page)) {
  311       status = PTR_ERR(page);
 - 312       goto out;
  313    }
- 314    if (!PageUptodate(page))
- 314 ternary-?: __builtin_constant_p ( 3 )
 - 315       goto read_error;
  316 
  317    /* NOTE: Someone else may have changed the READDIRPLUS flag */
  318    desc->page = page;
  319    desc->ptr = kmap(page);      /* matching kunmap in nfs_do_filldir */
- 320    if (*desc->dir_cookie != 0)
  321       status = find_dirent(desc);
    322    else
  323       status = find_dirent_index(desc);
- 324    if (status < 0)
  325       dir_page_release(desc);
  326  out:
    327    dfprintk(VFS, "NFS: find_dirent_page() returns %d\n", status);
- 327   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 327 do-while (0)
 - 328    return status;
  329  read_error:
  330    page_cache_release(page);
 - 331    return -EIO;
  332 }
  333 
  334 /*
  335  * Recurse through the page cache pages, and return a
  336  * filled nfs_entry structure of the next directory entry if possible.
  337  *
  338  * The target for the search is '*desc->dir_cookie' if non-0,
  339  * 'desc->file->f_pos' otherwise
  340  */
  341 static inline
 
- 342 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
  343 {
  344    int      loop_count = 0;
  345    int      res;
  346 
  347    /* Always search-by-index from the beginning of the cache */
- 348    if (*desc->dir_cookie == 0) {
    349       dfprintk(VFS, "NFS: readdir_search_pagecache() searching for offset %Ld\n", (long long)desc->file->f_pos);
- 349     if (__builtin_expect ( ! ! ( nfs_debug & 0..
- 349   do-while (0)
  350       desc->page_index = 0;
  351       desc->entry->cookie = desc->entry->prev_cookie = 0;
  352       desc->entry->eof = 0;
  353       desc->current_index = 0;
    354    } else
    355       dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
- 355     if (__builtin_expect ( ! ! ( nfs_debug & 0..
- 355   do-while (0)
  356 
- 357    for (;;) {
  358       res = find_dirent_page(desc);
- 359       if (res != -EAGAIN)
 - 360          break;
  361       /* Align to beginning of next page */
  362       desc->page_index ++;
- 363       if (loop_count++ > 200) {
  364          loop_count = 0;
  365          schedule();
  366       }
  367    }
    368    dfprintk(VFS, "NFS: readdir_search_pagecache() returned %d\n", res);
- 368   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 368 do-while (0)
 - 369    return res;
  370 }
  371 
 
- 372 static inline unsigned int dt_type(struct inode *inode)
  373 {
 - 374    return (inode->i_mode >> 12) & 15;
  375 }
  376 
  377 static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc);
  378 
  379 /*
  380  * Once we've found the start of the dirent within a page: fill 'er up...
  381  */
  382 static 
 
- 383 int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
  384          filldir_t filldir)
  385 {
  386    struct file   *file = desc->file;
  387    struct nfs_entry *entry = desc->entry;
  388    struct dentry   *dentry = NULL;
  389    unsigned long   fileid;
  390    int      loop_count = 0,
  391          res;
  392 
    393    dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)entry->cookie);
- 393   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 393 do-while (0)
  394 
- 395    for(;;) {
  396       unsigned d_type = DT_UNKNOWN;
  397       /* Note: entry->prev_cookie contains the cookie for
  398        *    retrieving the current dirent on the server */
  399       fileid = nfs_fileid_to_ino_t(entry->ino);
  400 
  401       /* Get a dentry if we have one */
- 402       if (dentry != NULL)
  403          dput(dentry);
  404       dentry = nfs_readdir_lookup(desc);
  405 
  406       /* Use readdirplus info */
- 407       if (dentry != NULL && dentry->d_inode != NULL) {
 - 407     T && T
 - 407     T && F
 - 407     F && _
  408          d_type = dt_type(dentry->d_inode);
  409          fileid = dentry->d_inode->i_ino;
  410       }
  411 
  412       res = filldir(dirent, entry->name, entry->len, 
  413                file->f_pos, fileid, d_type);
- 414       if (res < 0)
 - 415          break;
  416       file->f_pos++;
  417       *desc->dir_cookie = entry->cookie;
- 418       if (dir_decode(desc) != 0) {
  419          desc->page_index ++;
 - 420          break;
  421       }
- 422       if (loop_count++ > 200) {
  423          loop_count = 0;
  424          schedule();
  425       }
  426    }
  427    dir_page_release(desc);
- 428    if (dentry != NULL)
  429       dput(dentry);
    430    dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (unsigned long long)*desc->dir_cookie, res);
- 430   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 430 do-while (0)
 - 431    return res;
  432 }
  433 
  434 /*
  435  * If we cannot find a cookie in our cache, we suspect that this is
  436  * because it points to a deleted file, so we ask the server to return
  437  * whatever it thinks is the next entry. We then feed this to filldir.
  438  * If all goes well, we should then be able to find our way round the
  439  * cache on the next call to readdir_search_pagecache();
  440  *
  441  * NOTE: we cannot add the anonymous page to the pagecache because
  442  *    the data it contains might not be page aligned. Besides,
  443  *    we should already have a complete representation of the
  444  *    directory in the page cache by the time we get here.
  445  */
  446 static inline
 
- 447 int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
  448            filldir_t filldir)
  449 {
  450    struct file   *file = desc->file;
  451    struct inode   *inode = file->f_dentry->d_inode;
  452    struct rpc_cred   *cred = nfs_file_cred(file);
  453    struct page   *page = NULL;
  454    int      status;
  455 
    456    dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
- 456   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 456 do-while (0)
  457 
  458    page = alloc_page(GFP_HIGHUSER);
- 459    if (!page) {
  460       status = -ENOMEM;
 - 461       goto out;
  462    }
  463    desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, *desc->dir_cookie,
  464                   page,
  465                   NFS_SERVER(inode)->dtsize,
  466                   desc->plus);
    467    spin_lock(&inode->i_lock);
    467   do
- 467   do-while (0)
- 467 do-while (0)
  468    NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
    469    spin_unlock(&inode->i_lock);
    469   do
- 469   do-while (0)
- 469 do-while (0)
  470    desc->page = page;
  471    desc->ptr = kmap(page);      /* matching kunmap in nfs_do_filldir */
- 472    if (desc->error >= 0) {
- 473       if ((status = dir_decode(desc)) == 0)
  474          desc->entry->prev_cookie = *desc->dir_cookie;
    475    } else
  476       status = -EIO;
- 477    if (status < 0)
 - 478<