vserver 2.0 rc7
[linux-2.6.git] / fs / cifs / cifsfs.c
index b0884aa..8cc23e7 100644 (file)
@@ -57,29 +57,28 @@ unsigned int multiuser_mount = 0;
 unsigned int extended_security = 0;
 unsigned int ntlmv2_support = 0;
 unsigned int sign_CIFS_PDUs = 1;
+extern struct task_struct * oplockThread; /* remove sparse warning */
 struct task_struct * oplockThread = NULL;
 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
-module_param(CIFSMaxBufSize, int, CIFS_MAX_MSGSIZE);
+module_param(CIFSMaxBufSize, int, 0);
 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
 unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
-module_param(cifs_min_rcv, int, CIFS_MIN_RCV_POOL);
+module_param(cifs_min_rcv, int, 0);
 MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
 unsigned int cifs_min_small = 30;
-module_param(cifs_min_small, int, 30);
-MODULE_PARM_DESC(cifs_small_rcv,"Small network buffers in pool. Default: 30 Range: 2 to 256");
+module_param(cifs_min_small, int, 0);
+MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256");
 unsigned int cifs_max_pending = CIFS_MAX_REQ;
-module_param(cifs_max_pending, int, CIFS_MAX_REQ);
+module_param(cifs_max_pending, int, 0);
 MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
 
-
-extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
-                       const char *);
-extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
-void cifs_proc_init(void);
-void cifs_proc_clean(void);
-
 static DECLARE_COMPLETION(cifs_oplock_exited);
 
+extern mempool_t *cifs_sm_req_poolp;
+extern mempool_t *cifs_req_poolp;
+extern mempool_t *cifs_mid_poolp;
+
+extern kmem_cache_t *cifs_oplock_cachep;
 
 static int
 cifs_read_super(struct super_block *sb, void *data,
@@ -170,7 +169,8 @@ cifs_put_super(struct super_block *sb)
 static int
 cifs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
-       int xid, rc;
+       int xid; 
+       int rc = -EOPNOTSUPP;
        struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
 
@@ -182,22 +182,34 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
        buf->f_type = CIFS_MAGIC_NUMBER;
 
        /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
-       buf->f_namelen = PATH_MAX;      /* PATH_MAX may be too long - it would presumably
-                                          be length of total path, note that some servers may be 
-                                          able to support more than this, but best to be safe
-                                          since Win2k and others can not handle very long filenames */
+       buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would 
+                                     presumably be total path, but note
+                                     that some servers (includinng Samba 3)
+                                     have a shorter maximum path */
        buf->f_files = 0;       /* undefined */
        buf->f_ffree = 0;       /* unlimited */
 
-       rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls);
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+/* BB we could add a second check for a QFS Unix capability bit */
+/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
+    if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
+                       le64_to_cpu(pTcon->fsUnixInfo.Capability)))
+           rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
+
+    /* Only need to call the old QFSInfo if failed
+    on newer one */
+    if(rc)
+#endif /* CIFS_EXPERIMENTAL */
+       rc = CIFSSMBQFSInfo(xid, pTcon, buf);
 
        /*     
           int f_type;
           __fsid_t f_fsid;
           int f_namelen;  */
-       /* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */
+       /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
        FreeXid(xid);
-       return 0;               /* always return success? what if volume is no longer available? */
+       return 0;               /* always return success? what if volume is no
+                                  longer available? */
 }
 
 static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
@@ -228,9 +240,7 @@ static struct inode *
 cifs_alloc_inode(struct super_block *sb)
 {
        struct cifsInodeInfo *cifs_inode;
-       cifs_inode =
-           (struct cifsInodeInfo *) kmem_cache_alloc(cifs_inode_cachep,
-                                                     SLAB_KERNEL);
+       cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL);
        if (!cifs_inode)
                return NULL;
        cifs_inode->cifsAttrs = 0x20;   /* default */
@@ -437,28 +447,13 @@ static ssize_t
 cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
           loff_t * poffset)
 {
-       if(file == NULL)
-               return -EIO;
-       else if(file->f_dentry == NULL)
+       if(file->f_dentry == NULL)
                return -EIO;
        else if(file->f_dentry->d_inode == NULL)
                return -EIO;
 
        cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-       /* check whether we can cache writes locally */
-       if(file->f_dentry->d_sb) {
-               struct cifs_sb_info *cifs_sb;
-               cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-               if(cifs_sb != NULL) {
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-                               return cifs_user_read(file,read_data,
-                                                       read_size,poffset);
-               }
-       }
-#endif /* CIFS_EXPERIMENTAL */
-
        if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
                return generic_file_read(file,read_data,read_size,poffset);
        } else {
@@ -482,28 +477,13 @@ cifs_write_wrapper(struct file * file, const char __user *write_data,
 {
        ssize_t written;
 
-       if(file == NULL)
-               return -EIO;
-       else if(file->f_dentry == NULL)
+       if(file->f_dentry == NULL)
                return -EIO;
        else if(file->f_dentry->d_inode == NULL)
                return -EIO;
 
        cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL    /* BB fixme - fix user char * to kernel char * mapping here BB */
-       /* check whether we can cache writes locally */
-       if(file->f_dentry->d_sb) {
-               struct cifs_sb_info *cifs_sb;
-               cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-               if(cifs_sb != NULL) {
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
-                               return cifs_user_write(file,write_data,
-                                                       write_size,poffset);
-                       }
-               }
-       }
-#endif /* CIFS_EXPERIMENTAL */
        written = generic_file_write(file,write_data,write_size,poffset);
        if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll)  {
                if(file->f_dentry->d_inode->i_mapping) {
@@ -583,6 +563,34 @@ struct file_operations cifs_file_ops = {
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
+#ifdef CONFIG_CIFS_POSIX
+       .ioctl  = cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       .readv = generic_file_readv,
+       .writev = generic_file_writev,
+       .aio_read = generic_file_aio_read,
+       .aio_write = generic_file_aio_write,
+       .dir_notify = cifs_dir_notify,
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
+};
+
+struct file_operations cifs_file_direct_ops = {
+       /* no mmap, no aio, no readv - 
+          BB reevaluate whether they can be done with directio, no cache */
+       .read = cifs_user_read,
+       .write = cifs_user_write,
+       .open = cifs_open,
+       .release = cifs_close,
+       .lock = cifs_lock,
+       .fsync = cifs_fsync,
+       .flush = cifs_flush,
+       .sendfile = generic_file_sendfile, /* BB removeme BB */
+#ifdef CONFIG_CIFS_POSIX
+       .ioctl  = cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@ -595,12 +603,13 @@ struct file_operations cifs_dir_ops = {
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
+        .ioctl  = cifs_ioctl,
 };
 
 static void
 cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags)
 {
-       struct cifsInodeInfo *cifsi = (struct cifsInodeInfo *) inode;
+       struct cifsInodeInfo *cifsi = inode;
 
        if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
            SLAB_CTOR_CONSTRUCTOR) {
@@ -653,7 +662,7 @@ cifs_init_request_bufs(void)
                cifs_min_rcv = 1;
        else if (cifs_min_rcv > 64) {
                cifs_min_rcv = 64;
-               cFYI(1,("cifs_min_rcv set to maximum (64)"));
+               cERROR(1,("cifs_min_rcv set to maximum (64)"));
        }
 
        cifs_req_poolp = mempool_create(cifs_min_rcv,
@@ -826,6 +835,7 @@ static int cifs_oplock_thread(void * dummyarg)
                }
        } while(!signal_pending(current));
        complete_and_exit (&cifs_oplock_exited, 0);
+       oplockThread = NULL;
 }
 
 static int __init