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

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


File: fs/cifs/cifsfs.c
Instrumentation mode: function-decision-multicondition
TER: 16 % ( 50/312)

<
Start/ End/    
True False - Line Source

  1 /*
  2  *   fs/cifs/cifsfs.c
  3  *
  4  *   Copyright (C) International Business Machines  Corp., 2002,2004
  5  *   Author(s): Steve French (sfrench@us.ibm.com)
  6  *
  7  *   Common Internet FileSystem (CIFS) client
  8  *
  9  *   This library is free software; you can redistribute it and/or modify
  10  *   it under the terms of the GNU Lesser General Public License as published
  11  *   by the Free Software Foundation; either version 2.1 of the License, or
  12  *   (at your option) any later version.
  13  *
  14  *   This library is distributed in the hope that it will be useful,
  15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  17  *   the GNU Lesser General Public License for more details.
  18  *
  19  *   You should have received a copy of the GNU Lesser General Public License
  20  *   along with this library; if not, write to the Free Software
  21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22  */
  23 
  24 /* Note that BB means BUGBUG (ie something to fix eventually) */
  25 
  26 #include <linux/module.h>
  27 #include <linux/fs.h>
  28 #include <linux/mount.h>
  29 #include <linux/slab.h>
  30 #include <linux/init.h>
  31 #include <linux/list.h>
  32 #include <linux/seq_file.h>
  33 #include <linux/vfs.h>
  34 #include <linux/mempool.h>
  35 #include <linux/delay.h>
  36 #include "cifsfs.h"
  37 #include "cifspdu.h"
  38 #define DECLARE_GLOBALS_HERE
  39 #include "cifsglob.h"
  40 #include "cifsproto.h"
  41 #include "cifs_debug.h"
  42 #include "cifs_fs_sb.h"
  43 #include <linux/mm.h>
  44 #define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDUs */
  45 
  46 #ifdef CONFIG_CIFS_QUOTA
  47 static struct quotactl_ops cifs_quotactl_ops;
  48 #endif
  49 
  50 int cifsFYI = 0;
  51 int cifsERROR = 1;
  52 int traceSMB = 0;
  53 unsigned int oplockEnabled = 1;
  54 unsigned int experimEnabled = 0;
  55 unsigned int linuxExtEnabled = 1;
  56 unsigned int lookupCacheEnabled = 1;
  57 unsigned int multiuser_mount = 0;
  58 unsigned int extended_security = 0;
  59 unsigned int ntlmv2_support = 0;
  60 unsigned int sign_CIFS_PDUs = 1;
  61 extern struct task_struct * oplockThread; /* remove sparse warning */
  62 struct task_struct * oplockThread = NULL;
  63 extern struct task_struct * dnotifyThread; /* remove sparse warning */
  64 struct task_struct * dnotifyThread = NULL;
  65 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
 
- 66 module_param(CIFSMaxBufSize, int, 0);
 - 66 return ( & ( CIFSMaxBufSize ) )
  67 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
  68 unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
 
- 69 module_param(cifs_min_rcv, int, 0);
 - 69 return ( & ( cifs_min_rcv ) )
  70 MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
  71 unsigned int cifs_min_small = 30;
 
- 72 module_param(cifs_min_small, int, 0);
 - 72 return ( & ( cifs_min_small ) )
  73 MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256");
  74 unsigned int cifs_max_pending = CIFS_MAX_REQ;
 
- 75 module_param(cifs_max_pending, int, 0);
 - 75 return ( & ( cifs_max_pending ) )
  76 MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
  77 
  78 static DECLARE_COMPLETION(cifs_oplock_exited);
  79 static DECLARE_COMPLETION(cifs_dnotify_exited);
  80 
  81 extern mempool_t *cifs_sm_req_poolp;
  82 extern mempool_t *cifs_req_poolp;
  83 extern mempool_t *cifs_mid_poolp;
  84 
  85 extern kmem_cache_t *cifs_oplock_cachep;
  86 
  87 static int
 
- 88 cifs_read_super(struct super_block *sb, void *data,
  89       const char *devname, int silent)
  90 {
  91    struct inode *inode;
  92    struct cifs_sb_info *cifs_sb;
  93    int rc = 0;
  94 
  95    sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
  96    sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
  97    cifs_sb = CIFS_SB(sb);
- 98    if(cifs_sb == NULL)
 - 99       return -ENOMEM;
    100    else
  101       memset(cifs_sb,0,sizeof(struct cifs_sb_info));
  102    
  103 
  104    rc = cifs_mount(sb, cifs_sb, data, devname);
  105 
- 106    if (rc) {
- 107       if (!silent)
- 108          cERROR(1,
- 108       if (cifsERROR)
  109                 ("cifs_mount failed w/return code = %d", rc));
 - 110       goto out_mount_failed;
  111    }
  112 
  113    sb->s_magic = CIFS_MAGIC_NUMBER;
  114    sb->s_op = &cifs_super_ops;
  115 /*   if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
  116        sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
  117 #ifdef CONFIG_CIFS_QUOTA
  118    sb->s_qcop = &cifs_quotactl_ops;
  119 #endif
  120    sb->s_blocksize = CIFS_MAX_MSGSIZE;
  121    sb->s_blocksize_bits = 14;   /* default 2**14 = CIFS_MAX_MSGSIZE */
  122    inode = iget(sb, ROOT_I);
  123 
- 124    if (!inode) {
  125       rc = -ENOMEM;
 - 126       goto out_no_root;
  127    }
  128 
  129    sb->s_root = d_alloc_root(inode);
  130 
- 131    if (!sb->s_root) {
  132       rc = -ENOMEM;
 - 133       goto out_no_root;
  134    }
  135 
 - 136    return 0;
  137 
  138 out_no_root:
- 139    cERROR(1, ("cifs_read_super: get root inode failed"));
- 139   if (cifsERROR)
- 140    if (inode)
  141       iput(inode);
  142 
  143 out_mount_failed:
- 144    if(cifs_sb) {
- 145       if(cifs_sb->local_nls)
  146          unload_nls(cifs_sb->local_nls);   
  147       kfree(cifs_sb);
  148    }
 - 149    return rc;
  150 }
  151 
  152 static void
 
- 153 cifs_put_super(struct super_block *sb)
  154 {
  155    int rc = 0;
  156    struct cifs_sb_info *cifs_sb;
  157 
- 158    cFYI(1, ("In cifs_put_super"));
- 158   if (cifsFYI & 0x01)
  159    cifs_sb = CIFS_SB(sb);
- 160    if(cifs_sb == NULL) {
- 161       cFYI(1,("Empty cifs superblock info passed to unmount"));
- 161     if (cifsFYI & 0x01)
 - 162       return;
  163    }
  164    rc = cifs_umount(sb, cifs_sb); 
- 165    if (rc) {
- 166       cERROR(1, ("cifs_umount failed with return code %d", rc));
- 166     if (cifsERROR)
  167    }
  168    unload_nls(cifs_sb->local_nls);
  169    kfree(cifs_sb);
 - 170    return;
  171 }
  172 
  173 static int
 
- 174 cifs_statfs(struct super_block *sb, struct kstatfs *buf)
  175 {
  176    int xid; 
  177    int rc = -EOPNOTSUPP;
  178    struct cifs_sb_info *cifs_sb;
  179    struct cifsTconInfo *pTcon;
  180 
- 181    xid = GetXid();
- 181   if (cifsFYI & 0x01)
  182 
  183    cifs_sb = CIFS_SB(sb);
  184    pTcon = cifs_sb->tcon;
  185 
  186    buf->f_type = CIFS_MAGIC_NUMBER;
  187 
  188    /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
  189    buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would 
  190                   presumably be total path, but note
  191                   that some servers (includinng Samba 3)
  192                   have a shorter maximum path */
  193    buf->f_files = 0;   /* undefined */
  194    buf->f_ffree = 0;   /* unlimited */
  195 
  196 #ifdef CONFIG_CIFS_EXPERIMENTAL
  197 /* BB we could add a second check for a QFS Unix capability bit */
  198 /* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
  199     if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
  200          le64_to_cpu(pTcon->fsUnixInfo.Capability)))
  201        rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
  202 
  203     /* Only need to call the old QFSInfo if failed
  204     on newer one */
  205     if(rc)
  206 #endif /* CIFS_EXPERIMENTAL */
  207    rc = CIFSSMBQFSInfo(xid, pTcon, buf);
  208 
  209    /* Old Windows servers do not support level 103, retry with level 
  210       one if old server failed the previous call */ 
- 211    if(rc)
  212       rc = SMBOldQFSInfo(xid, pTcon, buf);
  213    /*     
  214       int f_type;
  215       __fsid_t f_fsid;
  216       int f_namelen;  */
  217    /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
- 218    FreeXid(xid);
- 218     if (cifsFYI & 0x01)
 - 219    return 0;      /* always return success? what if volume is no
  220                longer available? */
  221 }
  222 
 
- 223 static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
  224 {
  225    struct cifs_sb_info *cifs_sb;
  226 
  227    cifs_sb = CIFS_SB(inode->i_sb);
  228 
- 229    if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
 - 230       return 0;
    231    } else /* file mode might have been restricted at mount time 
  232       on the client (above and beyond ACL on servers) for  
  233       servers which do not support setting and viewing mode bits,
  234       so allowing client to check permissions is useful */ 
 - 235       return generic_permission(inode, mask, NULL);
  236 }
  237 
  238 static kmem_cache_t *cifs_inode_cachep;
  239 static kmem_cache_t *cifs_req_cachep;
  240 static kmem_cache_t *cifs_mid_cachep;
  241 kmem_cache_t *cifs_oplock_cachep;
  242 static kmem_cache_t *cifs_sm_req_cachep;
  243 mempool_t *cifs_sm_req_poolp;
  244 mempool_t *cifs_req_poolp;
  245 mempool_t *cifs_mid_poolp;
  246 
  247 static struct inode *
 
- 248 cifs_alloc_inode(struct super_block *sb)
  249 {
  250    struct cifsInodeInfo *cifs_inode;
  251    cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL);
- 252    if (!cifs_inode)
 - 253       return NULL;
  254    cifs_inode->cifsAttrs = 0x20;   /* default */
  255    atomic_set(&cifs_inode->inUse, 0);
  256    cifs_inode->time = 0;
  257    /* Until the file is open and we have gotten oplock
  258    info back from the server, can not assume caching of
  259    file data or metadata */
  260    cifs_inode->clientCanCacheRead = FALSE;
  261    cifs_inode->clientCanCacheAll = FALSE;
  262    cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
  263    cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
  264    cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
  265    INIT_LIST_HEAD(&cifs_inode->openFileList);
 - 266    return &cifs_inode->vfs_inode;
  267 }
  268 
  269 static void
 
- 270 cifs_destroy_inode(struct inode *inode)
  271 {
  272    kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
  273 }
  274 
  275 /*
  276  * cifs_show_options() is for displaying mount options in /proc/mounts.
  277  * Not all settable options are displayed but most of the important
  278  * ones are.
  279  */
  280 static int
 
- 281 cifs_show_options(struct seq_file *s, struct vfsmount *m)
  282 {
  283    struct cifs_sb_info *cifs_sb;
  284 
  285    cifs_sb = CIFS_SB(m->mnt_sb);
  286 
- 287    if (cifs_sb) {
- 288       if (cifs_sb->tcon) {
  289          seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
- 290          if (cifs_sb->tcon->ses) {
- 291             if (cifs_sb->tcon->ses->userName)
  292                seq_printf(s, ",username=%s",
  293                   cifs_sb->tcon->ses->userName);
- 294             if(cifs_sb->tcon->ses->domainName)
  295                seq_printf(s, ",domain=%s",
  296                   cifs_sb->tcon->ses->domainName);
  297          }
  298       }
  299       seq_printf(s, ",rsize=%d",cifs_sb->rsize);
  300       seq_printf(s, ",wsize=%d",cifs_sb->wsize);
  301    }
 - 302    return 0;
  303 }
  304 
  305 #ifdef CONFIG_CIFS_QUOTA
  306 int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
  307       struct fs_disk_quota * pdquota)
  308 {
  309    int xid;
  310    int rc = 0;
  311    struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
  312    struct cifsTconInfo *pTcon;
  313    
  314    if(cifs_sb)
  315       pTcon = cifs_sb->tcon;
  316    else
  317       return -EIO;
  318 
  319 
  320    xid = GetXid();
  321    if(pTcon) {
  322       cFYI(1,("set type: 0x%x id: %d",quota_type,qid));      
  323    } else {
  324       return -EIO;
  325    }
  326 
  327    FreeXid(xid);
  328    return rc;
  329 }
  330 
  331 int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
  332                 struct fs_disk_quota * pdquota)
  333 {
  334    int xid;
  335    int rc = 0;
  336    struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
  337    struct cifsTconInfo *pTcon;
  338 
  339    if(cifs_sb)
  340       pTcon = cifs_sb->tcon;
  341    else
  342       return -EIO;
  343 
  344    xid = GetXid();
  345    if(pTcon) {
  346                 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
  347    } else {
  348       rc = -EIO;
  349    }
  350 
  351    FreeXid(xid);
  352    return rc;
  353 }
  354 
  355 int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
  356 {
  357    int xid; 
  358    int rc = 0;
  359    struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
  360    struct cifsTconInfo *pTcon;
  361 
  362    if(cifs_sb)
  363       pTcon = cifs_sb->tcon;
  364    else
  365       return -EIO;
  366 
  367    xid = GetXid();
  368    if(pTcon) {
  369                 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
  370    } else {
  371       rc = -EIO;
  372    }
  373 
  374    FreeXid(xid);
  375    return rc;
  376 }
  377 
  378 int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
  379 {
  380    int xid;
  381    int rc = 0;
  382    struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
  383    struct cifsTconInfo *pTcon;
  384 
  385    if(cifs_sb) {
  386       pTcon = cifs_sb->tcon;
  387    } else {
  388       return -EIO;
  389    }
  390    xid = GetXid();
  391    if(pTcon) {
  392       cFYI(1,("pqstats %p",qstats));      
  393    } else {
  394       rc = -EIO;
  395    }
  396 
  397    FreeXid(xid);
  398    return rc;
  399 }
  400 
  401 static struct quotactl_ops cifs_quotactl_ops = {
  402    .set_xquota   = cifs_xquota_set,
  403    .get_xquota   = cifs_xquota_set,
  404    .set_xstate   = cifs_xstate_set,
  405    .get_xstate   = cifs_xstate_get,
  406 };
  407 #endif
  408 
  409 #ifdef CONFIG_CIFS_EXPERIMENTAL
  410 static void cifs_umount_begin(struct super_block * sblock)
  411 {
  412    struct cifs_sb_info *cifs_sb;
  413    struct cifsTconInfo * tcon;
  414 
  415    cifs_sb = CIFS_SB(sblock);
  416    if(cifs_sb == NULL)
  417       return;
  418 
  419    tcon = cifs_sb->tcon;
  420    if(tcon == NULL)
  421       return;
  422    down(&tcon->tconSem);
  423    if (atomic_read(&tcon->useCount) == 1)
  424       tcon->tidStatus = CifsExiting;
  425    up(&tcon->tconSem);
  426 
  427    /* cancel_brl_requests(tcon); */
  428    /* cancel_notify_requests(tcon); */
  429    if(tcon->ses && tcon->ses->server)
  430    {
  431       cFYI(1,("wake up tasks now - umount begin not complete"));
  432       wake_up_all(&tcon->ses->server->request_q);
  433       wake_up_all(&tcon->ses->server->response_q);
  434       msleep(1); /* yield */
  435       /* we have to kick the requests once more */
  436       wake_up_all(&tcon->ses->server->response_q);
  437       msleep(1);
  438    }
  439 /* BB FIXME - finish add checks for tidStatus BB */
  440 
  441    return;
  442 }
  443 #endif   
  444 
 
- 445 static int cifs_remount(struct super_block *sb, int *flags, char *data)
  446 {
  447    *flags |= MS_NODIRATIME;
 - 448    return 0;
  449 }
  450 
  451 struct super_operations cifs_super_ops = {
  452    .read_inode = cifs_read_inode,
  453    .put_super = cifs_put_super,
  454    .statfs = cifs_statfs,
  455    .alloc_inode = cifs_alloc_inode,
  456    .destroy_inode = cifs_destroy_inode,
  457 /*   .drop_inode       = generic_delete_inode, 
  458    .delete_inode   = cifs_delete_inode,  *//* Do not need the above two functions     
  459    unless later we add lazy close of inodes or unless the kernel forgets to call
  460    us with the same number of releases (closes) as opens */
  461    .show_options = cifs_show_options,
  462 #ifdef CONFIG_CIFS_EXPERIMENTAL
  463    .umount_begin   = cifs_umount_begin,
  464 #endif
  465    .remount_fs = cifs_remount,
  466 };
  467 
  468 static struct super_block *
 
- 469 cifs_get_sb(struct file_system_type *fs_type,
  470        int flags, const char *dev_name, void *data)
  471 {
  472    int rc;
  473    struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
  474 
- 475    cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
- 475   if (cifsFYI & 0x01)
  476 
- 477    if (IS_ERR(sb))
 - 478       return sb;
  479 
  480    sb->s_flags = flags;
  481 
    482    rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);
- 482 ternary-?: flags & 32768
- 483    if (rc) {
  484       up_write(&sb->s_umount);
  485       deactivate_super(sb);
 - 486       return ERR_PTR(rc);
  487    }
  488    sb->s_flags |= MS_ACTIVE;
 - 489    return sb;
  490 }
  491 
 
- 492 static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
  493             unsigned long nr_segs, loff_t *ppos)
  494 {
  495    struct inode *inode = file->f_dentry->d_inode;
  496    ssize_t written;
  497 
  498    written = generic_file_writev(file, iov, nr_segs, ppos);
- 499    if (!CIFS_I(inode)->clientCanCacheAll)
  500       filemap_fdatawrite(inode->i_mapping);
 - 501    return written;
  502 }
  503 
 
- 504 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
  505                size_t count, loff_t pos)
  506 {
  507    struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
  508    ssize_t written;
  509 
  510    written = generic_file_aio_write(iocb, buf, count, pos);
- 511    if (!CIFS_I(inode)->clientCanCacheAll)
  512       filemap_fdatawrite(inode->i_mapping);
 - 513    return written;
  514 }
  515 
 
- 516 static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
  517 {
  518    /* origin == SEEK_END => we must revalidate the cached file length */
- 519    if (origin == 2) {
  520       int retval = cifs_revalidate(file->f_dentry);
- 521       if (retval < 0)
 - 522          return (loff_t)retval;
  523    }
 - 524    return remote_llseek(file, offset, origin);
  525 }
  526 
  527 static struct file_system_type cifs_fs_type = {
  528    .owner = THIS_MODULE,
  529    .name = "cifs",
  530    .get_sb = cifs_get_sb,
  531    .kill_sb = kill_anon_super,
  532    /*  .fs_flags */
  533 };
  534 struct inode_operations cifs_dir_inode_ops = {
  535    .create = cifs_create,
  536    .lookup = cifs_lookup,
  537    .getattr = cifs_getattr,
  538    .unlink = cifs_unlink,
  539    .link = cifs_hardlink,
  540    .mkdir = cifs_mkdir,
  541    .rmdir = cifs_rmdir,
  542    .rename = cifs_rename,
  543    .permission = cifs_permission,
  544 /*   revalidate:cifs_revalidate,   */
  545    .setattr = cifs_setattr,
  546    .symlink = cifs_symlink,
  547    .mknod   = cifs_mknod,
  548 #ifdef CONFIG_CIFS_XATTR
  549    .setxattr = cifs_setxattr,
  550    .getxattr = cifs_getxattr,
  551    .listxattr = cifs_listxattr,
  552    .removexattr = cifs_removexattr,
  553 #endif
  554 };
  555 
  556 struct inode_operations cifs_file_inode_ops = {
  557 /*   revalidate:cifs_revalidate, */
  558    .setattr = cifs_setattr,
  559    .getattr = cifs_getattr, /* do we need this anymore? */
  560    .rename = cifs_rename,
  561    .permission = cifs_permission,
  562 #ifdef CONFIG_CIFS_XATTR
  563    .setxattr = cifs_setxattr,