Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
authorSteve French <sfrench@us.ibm.com>
Thu, 12 Jan 2006 22:47:08 +0000 (14:47 -0800)
committerSteve French <sfrench@us.ibm.com>
Thu, 12 Jan 2006 22:47:08 +0000 (14:47 -0800)
Signed-off-by: Steve French <sfrench@us.ibm.com>
19 files changed:
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifs_debug.c
fs/cifs/cifsacl.h [new file with mode: 0644]
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/readdir.c
fs/cifs/rfc1002pdu.h
fs/cifs/transport.c

index 943ef9b82244ef9b71a3211e24bb1a1899f51409..1d2137561c557afeb5ab03e7085a4767d29d69a7 100644 (file)
@@ -1,3 +1,8 @@
+Version 1.40
+------------
+Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
+of readpages by eliminating one extra memcpy.
+
 Version 1.39
 ------------
 Defer close of a file handle slightly if pending writes depend on that handle
@@ -7,6 +12,8 @@ Fix SFU style symlinks and mknod needed for servers which do not support the
 CIFS Unix Extensions.  Fix setfacl/getfacl on bigendian. Timeout negative
 dentries so files that the client sees as deleted but that later get created
 on the server will be recognized.  Add client side permission check on setattr.
+Timeout stuck requests better (where server has never responded or sent corrupt
+responses)
 
 Version 1.38
 ------------
index e5d09a2fc7a5eccf7a7b8f15b56de07173a5d535..b0070d1b149d6d240e2457bd59455b945faa7005 100644 (file)
@@ -436,7 +436,17 @@ A partial list of the supported mount options follows:
                SFU does).  In the future the bottom 9 bits of the mode
                mode also will be emulated using queries of the security
                descriptor (ACL).
-               
+sec            Security mode.  Allowed values are:
+                       none    attempt to connection as a null user (no name)
+                       krb5    Use Kerberos version 5 authentication
+                       krb5i   Use Kerberos authentication and packet signing
+                       ntlm    Use NTLM password hashing (default)
+                       ntlmi   Use NTLM password hashing with signing (if
+                               /proc/fs/cifs/PacketSigningEnabled on or if
+                               server requires signing also can be the default) 
+                       ntlmv2  Use NTLMv2 password hashing      
+                       ntlmv2i Use NTLMv2 password hashing with packet signing
+
 The mount.cifs mount helper also accepts a few mount options before -o
 including:
 
index 22a444a3fe4c2fb9325a0fdaa2e4eb09d3707670..f4124a32bef8974edd3f02111f8e382a63f02199 100644 (file)
@@ -219,6 +219,10 @@ cifs_stats_write(struct file *file, const char __user *buffer,
 
         if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
                read_lock(&GlobalSMBSeslock);
+#ifdef CONFIG_CIFS_STATS2
+               atomic_set(&totBufAllocCount, 0);
+               atomic_set(&totSmBufAllocCount, 0);
+#endif /* CONFIG_CIFS_STATS2 */
                list_for_each(tmp, &GlobalTreeConnectionList) {
                        tcon = list_entry(tmp, struct cifsTconInfo,
                                        cifsConnectionList);
@@ -276,6 +280,14 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
                        smBufAllocCount.counter,cifs_min_small);
        length += item_length;
        buf += item_length;
+#ifdef CONFIG_CIFS_STATS2
+        item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
+                               atomic_read(&totBufAllocCount),
+                               atomic_read(&totSmBufAllocCount));
+       length += item_length;
+       buf += item_length;
+#endif /* CONFIG_CIFS_STATS2 */
+
        item_length = 
                sprintf(buf,"Operations (MIDs): %d\n",
                        midCount.counter);
@@ -389,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
 static write_proc_t ntlmv2_enabled_write;
 static read_proc_t packet_signing_enabled_read;
 static write_proc_t packet_signing_enabled_write;
-static read_proc_t quotaEnabled_read;
-static write_proc_t quotaEnabled_write;
+static read_proc_t experimEnabled_read;
+static write_proc_t experimEnabled_write;
 static read_proc_t linuxExtensionsEnabled_read;
 static write_proc_t linuxExtensionsEnabled_write;
 
@@ -430,9 +442,9 @@ cifs_proc_init(void)
                pde->write_proc = oplockEnabled_write;
 
        pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
-                               quotaEnabled_read, NULL);
+                               experimEnabled_read, NULL);
        if (pde)
-               pde->write_proc = quotaEnabled_write;
+               pde->write_proc = experimEnabled_write;
 
        pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
                                linuxExtensionsEnabled_read, NULL);
@@ -574,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
 }
 
 static int
-quotaEnabled_read(char *page, char **start, off_t off,
+experimEnabled_read(char *page, char **start, off_t off,
                    int count, int *eof, void *data)
 {
         int len;
 
         len = sprintf(page, "%d\n", experimEnabled);
-/* could also check if quotas are enabled in kernel
-       as a whole first */
+
         len -= off;
         *start = page + off;
 
@@ -596,21 +607,23 @@ quotaEnabled_read(char *page, char **start, off_t off,
         return len;
 }
 static int
-quotaEnabled_write(struct file *file, const char __user *buffer,
+experimEnabled_write(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
 {
-        char c;
-        int rc;
+       char c;
+       int rc;
 
-        rc = get_user(c, buffer);
-        if (rc)
-                return rc;
-        if (c == '0' || c == 'n' || c == 'N')
-                experimEnabled = 0;
-        else if (c == '1' || c == 'y' || c == 'Y')
-                experimEnabled = 1;
+       rc = get_user(c, buffer);
+       if (rc)
+               return rc;
+       if (c == '0' || c == 'n' || c == 'N')
+               experimEnabled = 0;
+       else if (c == '1' || c == 'y' || c == 'Y')
+               experimEnabled = 1;
+       else if (c == '2')
+               experimEnabled = 2;
 
-        return count;
+       return count;
 }
 
 static int
@@ -620,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
         int len;
 
         len = sprintf(page, "%d\n", linuxExtEnabled);
-/* could also check if quotas are enabled in kernel
-       as a whole first */
         len -= off;
         *start = page + off;
 
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
new file mode 100644 (file)
index 0000000..d152ff5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *   fs/cifs/cifsacl.h
+ *
+ *   Copyright (c) International Business Machines  Corp., 2005
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CIFSACL_H
+#define _CIFSACL_H
+
+struct cifs_sid {
+       __u8 revision; /* revision level */
+       __u8 num_subauths;
+       __u8 authority[6];
+       __u8 sub_auth[4];
+       /* next sub_auth if any ... */
+} __attribute__((packed));
+
+/* everyone */
+const cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
+/* group users */
+const cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
+
+#endif /* _CIFSACL_H */
index fe2bb7c4c9121c4bcc2cfeeb5ca9ec9669bcc944..a2c24858d40f94f449de0e958c7971b31c3fff61 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsencrypt.c
  *
- *   Copyright (C) International Business Machines  Corp., 2003
+ *   Copyright (C) International Business Machines  Corp., 2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
        return rc;
 }
 
+static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
+                               const char * key, char * signature)
+{
+        struct  MD5Context context;
+
+        if((iov == NULL) || (signature == NULL))
+                return -EINVAL;
+
+        MD5Init(&context);
+        MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
+
+/*        MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */
+
+        MD5Final(signature,&context);
+
+       return -EOPNOTSUPP;
+/*        return 0; */
+}
+
+
+int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server,
+                  __u32 * pexpected_response_sequence_number)
+{
+       int rc = 0;
+       char smb_signature[20];
+       struct smb_hdr * cifs_pdu = iov[0].iov_base;
+
+       if((cifs_pdu == NULL) || (server == NULL))
+               return -EINVAL;
+
+       if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
+               return rc;
+
+        spin_lock(&GlobalMid_Lock);
+        cifs_pdu->Signature.Sequence.SequenceNumber = 
+                               cpu_to_le32(server->sequence_number);
+        cifs_pdu->Signature.Sequence.Reserved = 0;
+
+        *pexpected_response_sequence_number = server->sequence_number++;
+        server->sequence_number++;
+        spin_unlock(&GlobalMid_Lock);
+
+        rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key,
+                                     smb_signature);
+        if(rc)
+                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
+        else
+                memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
+
+        return rc;
+
+}
+
 int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
        __u32 expected_sequence_number)
 {
index e10213b7541e4ec6685daa2c91ffe6a8aaf2c1c4..79eeccd0437f08c2a3ac56a51af2de0cadc36f19 100644 (file)
@@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
        return written;
 }
 
+static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
+{
+       /* origin == SEEK_END => we must revalidate the cached file length */
+       if (origin == 2) {
+               int retval = cifs_revalidate(file->f_dentry);
+               if (retval < 0)
+                       return (loff_t)retval;
+       }
+       return remote_llseek(file, offset, origin);
+}
+
 static struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
        .name = "cifs",
@@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = {
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
+       .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
@@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
+       .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_ops = {
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
+       .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
@@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_nobrl_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
+       .llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@ -733,7 +746,7 @@ cifs_init_request_bufs(void)
                kmem_cache_destroy(cifs_req_cachep);
                return -ENOMEM;
        }
-       /* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
+       /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
        almost all handle based requests (but not write response, nor is it
        sufficient for path based requests).  A smaller size would have
        been more efficient (compacting multiple slab items on one 4k page) 
@@ -742,7 +755,8 @@ cifs_init_request_bufs(void)
        efficient to alloc 1 per page off the slab compared to 17K (5page) 
        alloc of large cifs buffers even when page debugging is on */
        cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
-                       MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+                       MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 
+                       NULL, NULL);
        if (cifs_sm_req_cachep == NULL) {
                mempool_destroy(cifs_req_poolp);
                kmem_cache_destroy(cifs_req_cachep);
@@ -954,6 +968,12 @@ init_cifs(void)
        atomic_set(&tconInfoReconnectCount, 0);
 
        atomic_set(&bufAllocCount, 0);
+       atomic_set(&smBufAllocCount, 0);
+#ifdef CONFIG_CIFS_STATS2
+       atomic_set(&totBufAllocCount, 0);
+       atomic_set(&totSmBufAllocCount, 0);
+#endif /* CONFIG_CIFS_STATS2 */
+
        atomic_set(&midCount, 0);
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
index 9ec40e0e54fc4eed289eb9070aeb0c8120f610cd..821a8eb2255965a77e031c37a6b2f4c674f97e48 100644 (file)
@@ -99,5 +99,5 @@ extern ssize_t        cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
                       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.39"
+#define CIFS_VERSION   "1.40"
 #endif                         /* _CIFSFS_H */
index 1ba08f8c5bc4aafac85cf3f83929391d6c633e17..862e403ff211ad28608fe1a6421bdb1534e2e793 100644 (file)
@@ -285,6 +285,7 @@ struct cifs_search_info {
        unsigned endOfSearch:1;
        unsigned emptyDir:1;
        unsigned unicode:1;
+       unsigned smallBuf:1; /* so we know which buf_release function to call */
 };
 
 struct cifsFileInfo {
@@ -420,7 +421,12 @@ struct dir_notify_req {
 #define   MID_RESPONSE_RECEIVED 4
 #define   MID_RETRY_NEEDED      8 /* session closed while this request out */
 #define   MID_NO_RESP_NEEDED 0x10
-#define   MID_SMALL_BUFFER   0x20 /* 112 byte response buffer instead of 4K */
+
+/* Types of response buffer returned from SendReceive2 */
+#define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
+#define   CIFS_SMALL_BUFFER     1
+#define   CIFS_LARGE_BUFFER     2
+#define   CIFS_IOVEC            4    /* array of response buffers */
 
 /*
  *****************************************************************
@@ -505,8 +511,12 @@ GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
 GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
 
 /* Various Debug counters to remove someday (BB) */
-GLOBAL_EXTERN atomic_t bufAllocCount;
-GLOBAL_EXTERN atomic_t smBufAllocCount;      
+GLOBAL_EXTERN atomic_t bufAllocCount;    /* current number allocated  */
+#ifdef CONFIG_CIFS_STATS2
+GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
+GLOBAL_EXTERN atomic_t totSmBufAllocCount;
+#endif
+GLOBAL_EXTERN atomic_t smBufAllocCount;
 GLOBAL_EXTERN atomic_t midCount;
 
 /* Misc globals */
index 33e1859fd2f67ced969247e6a6bc365a941a8895..3c09fb9cc56974efe12d8613246735eb5578da3c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifspdu.h
  *
- *   Copyright (c) International Business Machines  Corp., 2002
+ *   Copyright (c) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
 #define NT_TRANSACT_GET_USER_QUOTA    0x07
 #define NT_TRANSACT_SET_USER_QUOTA    0x08
 
-#define MAX_CIFS_HDR_SIZE 256  /* is future chained NTCreateXReadX bigger? */
+#define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
+/* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
+/* among the requests (NTCreateX response is bigger with wct of 34) */
+#define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
+#define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */
 
 /* internal cifs vfs structures */
 /*****************************************************************
index 1b73f4f4c5ce6d1cb88e95e53fa8420fe1382957..8ef0ce47f5b6d7f5c97245ffdd5454affa5718eb 100644 (file)
@@ -48,8 +48,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
                        struct smb_hdr * /* out */ ,
                        int * /* bytes returned */ , const int long_op);
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
-                       struct kvec *, int /* nvec */,
-                       int * /* bytes returned */ , const int long_op);
+                       struct kvec *, int /* nvec to send */, 
+                       int * /* type of buf returned */ , const int long_op);
 extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb);
@@ -93,11 +93,12 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        const struct nls_table *);
 
 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
-            const char *searchName, const struct nls_table *nls_codepage,
-            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
+               const char *searchName, const struct nls_table *nls_codepage,
+               __u16 *searchHandle, struct cifs_search_info * psrch_inf, 
+               int map, const char dirsep);
 
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-            __u16 searchHandle, struct cifs_search_info * psrch_inf);
+               __u16 searchHandle, struct cifs_search_info * psrch_inf);
 
 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
                        const __u16 search_handle);
@@ -230,19 +231,18 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
                        const int smb_file_id);
 
 extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-                       const int netfid, unsigned int count,
-                       const __u64 lseek, unsigned int *nbytes, char **buf);
+                        const int netfid, unsigned int count,
+                        const __u64 lseek, unsigned int *nbytes, char **buf,
+                       int * return_buf_type);
 extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
                        const int netfid, const unsigned int count,
                        const __u64 lseek, unsigned int *nbytes,
                        const char *buf, const char __user *ubuf, 
                        const int long_op);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                        const int netfid, const unsigned int count,
                        const __u64 offset, unsigned int *nbytes, 
                        struct kvec *iov, const int nvec, const int long_op);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName, __u64 * inode_number,
                        const struct nls_table *nls_codepage, 
@@ -269,6 +269,8 @@ extern void tconInfoFree(struct cifsTconInfo *);
 extern int cifs_reconnect(struct TCP_Server_Info *server);
 
 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
+extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
+                         __u32 *);
 extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
        __u32 expected_sequence_number);
 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
index 6867e556d37e51485a4e9d35fb7ea332fc971b6d..1620991cd4d280593301d99ab00e49d210a27798 100644 (file)
@@ -958,21 +958,19 @@ openRetry:
        return rc;
 }
 
-/* If no buffer passed in, then caller wants to do the copy
-       as in the case of readpages so the SMB buffer must be
-       freed by the caller */
-
 int
 CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-           const int netfid, const unsigned int count,
-           const __u64 lseek, unsigned int *nbytes, char **buf)
+            const int netfid, const unsigned int count,
+            const __u64 lseek, unsigned int *nbytes, char **buf,
+           int * pbuf_type)
 {
        int rc = -EACCES;
        READ_REQ *pSMB = NULL;
        READ_RSP *pSMBr = NULL;
        char *pReadData = NULL;
-       int bytes_returned;
        int wct;
+       int resp_buf_type = 0;
+       struct kvec iov[1];
 
        cFYI(1,("Reading %d bytes on fid %d",count,netfid));
        if(tcon->ses->capabilities & CAP_LARGE_FILES)
@@ -981,8 +979,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
                wct = 10; /* old style read */
 
        *nbytes = 0;
-       rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
-                     (void **) &pSMBr);
+       rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
        if (rc)
                return rc;
 
@@ -990,13 +987,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
        if (tcon->ses->server == NULL)
                return -ECONNABORTED;
 
-       pSMB->AndXCommand = 0xFF;       /* none */
+       pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
        pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
        if(wct == 12)
                pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
-        else if((lseek >> 32) > 0) /* can not handle this big offset for old */
-                return -EIO;
+       else if((lseek >> 32) > 0) /* can not handle this big offset for old */
+               return -EIO;
 
        pSMB->Remaining = 0;
        pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
@@ -1005,14 +1002,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
                pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
        else {
                /* old style read */
-               struct smb_com_readx_req * pSMBW = 
+               struct smb_com_readx_req * pSMBW =
                        (struct smb_com_readx_req *)pSMB;
-               pSMBW->ByteCount = 0;   
+               pSMBW->ByteCount = 0;
        }
-       
-       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+
+       iov[0].iov_base = (char *)pSMB;
+       iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+       rc = SendReceive2(xid, tcon->ses, iov, 
+                         1 /* num iovecs */,
+                         &resp_buf_type, 0); 
        cifs_stats_inc(&tcon->num_reads);
+       pSMBr = (READ_RSP *)iov[0].iov_base;
        if (rc) {
                cERROR(1, ("Send error in read = %d", rc));
        } else {
@@ -1022,33 +1023,43 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
                *nbytes = data_length;
 
                /*check that DataLength would not go beyond end of SMB */
-               if ((data_length > CIFSMaxBufSize) 
+               if ((data_length > CIFSMaxBufSize)
                                || (data_length > count)) {
                        cFYI(1,("bad length %d for count %d",data_length,count));
                        rc = -EIO;
                        *nbytes = 0;
                } else {
-                       pReadData =
-                           (char *) (&pSMBr->hdr.Protocol) +
+                       pReadData = (char *) (&pSMBr->hdr.Protocol) +
                            le16_to_cpu(pSMBr->DataOffset);
-/*                     if(rc = copy_to_user(buf, pReadData, data_length)) {
-                               cERROR(1,("Faulting on read rc = %d",rc));
-                               rc = -EFAULT;
-                       }*/ /* can not use copy_to_user when using page cache*/
+/*                      if(rc = copy_to_user(buf, pReadData, data_length)) {
+                                cERROR(1,("Faulting on read rc = %d",rc));
+                                rc = -EFAULT;
+                        }*/ /* can not use copy_to_user when using page cache*/
                        if(*buf)
-                           memcpy(*buf,pReadData,data_length);
+                               memcpy(*buf,pReadData,data_length);
                }
        }
-       if(*buf)
-               cifs_buf_release(pSMB);
-       else
-               *buf = (char *)pSMB;
 
-       /* Note: On -EAGAIN error only caller can retry on handle based calls 
+       cifs_small_buf_release(pSMB);
+       if(*buf) {
+               if(resp_buf_type == CIFS_SMALL_BUFFER)
+                       cifs_small_buf_release(iov[0].iov_base);
+               else if(resp_buf_type == CIFS_LARGE_BUFFER)
+                       cifs_buf_release(iov[0].iov_base);
+       } else /* return buffer to caller to free */ /* BB FIXME how do we tell caller if it is not a large buffer */ {
+               *buf = iov[0].iov_base;
+               if(resp_buf_type == CIFS_SMALL_BUFFER)
+                       *pbuf_type = CIFS_SMALL_BUFFER;
+               else if(resp_buf_type == CIFS_LARGE_BUFFER)
+                       *pbuf_type = CIFS_LARGE_BUFFER;
+       }
+
+       /* Note: On -EAGAIN error only caller can retry on handle based calls
                since file handle passed in no longer valid */
        return rc;
 }
 
+
 int
 CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
             const int netfid, const unsigned int count,
@@ -1155,7 +1166,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 int
 CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
             const int netfid, const unsigned int count,
@@ -1164,10 +1174,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 {
        int rc = -EACCES;
        WRITE_REQ *pSMB = NULL;
-       int bytes_returned, wct;
+       int wct;
        int smb_hdr_len;
+       int resp_buf_type = 0;
 
-       /* BB removeme BB */
        cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
 
        if(tcon->ses->capabilities & CAP_LARGE_FILES)
@@ -1210,22 +1220,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                pSMBW->ByteCount = cpu_to_le16(count + 5);
        }
        iov[0].iov_base = pSMB;
-       iov[0].iov_len = smb_hdr_len + 4;
+       if(wct == 14)
+               iov[0].iov_len = smb_hdr_len + 4;
+       else /* wct == 12 pad bigger by four bytes */
+               iov[0].iov_len = smb_hdr_len + 8;
+       
 
-       rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
+       rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
                          long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
                cFYI(1, ("Send error Write2 = %d", rc));
                *nbytes = 0;
+       } else if(resp_buf_type == 0) {
+               /* presumably this can not happen, but best to be safe */
+               rc = -EIO;
+               *nbytes = 0;
        } else {
-               WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
+               WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base;
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
                *nbytes += le16_to_cpu(pSMBr->Count);
-       }
+       } 
 
        cifs_small_buf_release(pSMB);
+       if(resp_buf_type == CIFS_SMALL_BUFFER)
+               cifs_small_buf_release(iov[0].iov_base);
+       else if(resp_buf_type == CIFS_LARGE_BUFFER)
+               cifs_buf_release(iov[0].iov_base);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls 
                since file handle passed in no longer valid */
@@ -1234,8 +1256,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 }
 
 
-#endif /* CIFS_EXPERIMENTAL */
-
 int
 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
            const __u16 smb_file_id, const __u64 len,
index c467de8576105bdd3bdb4d1983b591be53609b2e..45c9d726c0021b71abd5c16ab48e45d785d54042 100644 (file)
@@ -82,6 +82,12 @@ struct smb_vol {
        unsigned remap:1;   /* set to remap seven reserved chars in filenames */
        unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
        unsigned sfu_emul:1;
+       unsigned krb5:1;
+       unsigned ntlm:1;
+       unsigned ntlmv2:1;
+       unsigned nullauth:1; /* attempt to authenticate with null user */
+       unsigned sign:1;
+       unsigned seal:1;     /* encrypt */
        unsigned nocase;     /* request case insensitive filenames */
        unsigned nobrl;      /* disable sending byte range locks to srv */
        unsigned int rsize;
@@ -508,7 +514,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                /* else length ok */
                reconnect = 0;
 
-               if(pdu_length > MAX_CIFS_HDR_SIZE - 4) {
+               if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
                        isLargeBuf = TRUE;
                        memcpy(bigbuf, smallbuf, 4);
                        smb_buffer = bigbuf;
@@ -777,7 +783,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
 
        /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
        vol->rw = TRUE;
-
+       vol->ntlm = TRUE;
        /* default is always to request posix paths. */
        vol->posix_paths = 1;
 
@@ -903,6 +909,39 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                                printk(KERN_WARNING "CIFS: ip address too long\n");
                                return 1;
                        }
+                } else if (strnicmp(data, "sec", 3) == 0) { 
+                        if (!value || !*value) {
+                               cERROR(1,("no security value specified"));
+                                continue;
+                        } else if (strnicmp(value, "krb5i", 5) == 0) {
+                               vol->sign = 1;
+                               vol->krb5 = 1;
+                       } else if (strnicmp(value, "krb5p", 5) == 0) {
+                               /* vol->seal = 1; 
+                                  vol->krb5 = 1; */
+                               cERROR(1,("Krb5 cifs privacy not supported"));
+                               return 1;
+                       } else if (strnicmp(value, "krb5", 4) == 0) {
+                               vol->krb5 = 1;
+                       } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
+                               vol->ntlmv2 = 1;
+                               vol->sign = 1;
+                       } else if (strnicmp(value, "ntlmv2", 6) == 0) {
+                               vol->ntlmv2 = 1;
+                       } else if (strnicmp(value, "ntlmi", 5) == 0) {
+                               vol->ntlm = 1;
+                               vol->sign = 1;
+                       } else if (strnicmp(value, "ntlm", 4) == 0) {
+                               /* ntlm is default so can be turned off too */
+                               vol->ntlm = 1;
+                       } else if (strnicmp(value, "nontlm", 6) == 0) {
+                               vol->ntlm = 0;
+                       } else if (strnicmp(value, "none", 4) == 0) {
+                               vol->nullauth = 1; 
+                        } else {
+                                cERROR(1,("bad security option: %s", value));
+                                return 1;
+                        }
                } else if ((strnicmp(data, "unc", 3) == 0)
                           || (strnicmp(data, "target", 6) == 0)
                           || (strnicmp(data, "path", 4) == 0)) {
@@ -1546,7 +1585,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                cFYI(1, ("Username: %s ", volume_info.username));
 
        } else {
-               cifserror("No username specified ");
+               cifserror("No username specified");
         /* In userspace mount helper we can get user name from alternate
            locations such as env variables and files on disk */
                kfree(volume_info.UNC);
@@ -1587,7 +1626,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                return -EINVAL;
        } else /* which servers DFS root would we conect to */ {
                cERROR(1,
-                      ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));
+                      ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
                kfree(volume_info.UNC);
                kfree(volume_info.password);
                FreeXid(xid);
@@ -1626,7 +1665,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
 
        if (srvTcp) {
-               cFYI(1, ("Existing tcp session with server found "));                
+               cFYI(1, ("Existing tcp session with server found"));                
        } else {        /* create socket */
                if(volume_info.port)
                        sin_server.sin_port = htons(volume_info.port);
@@ -1689,11 +1728,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
        if (existingCifsSes) {
                pSesInfo = existingCifsSes;
-               cFYI(1, ("Existing smb sess found "));
+               cFYI(1, ("Existing smb sess found"));
                kfree(volume_info.password);
                /* volume_info.UNC freed at end of function */
        } else if (!rc) {
-               cFYI(1, ("Existing smb sess not found "));
+               cFYI(1, ("Existing smb sess not found"));
                pSesInfo = sesInfoAlloc();
                if (pSesInfo == NULL)
                        rc = -ENOMEM;
@@ -1777,7 +1816,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                    find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
                             volume_info.username);
                if (tcon) {
-                       cFYI(1, ("Found match on UNC path "));
+                       cFYI(1, ("Found match on UNC path"));
                        /* we can have only one retry value for a connection
                           to a share so for resources mounted more than once
                           to the same server share the last value passed in 
index 32cc96cafa3eb050d19871f85cf4e089c68b7562..fed55e3c53dfab365c72886001ed4f240ddd6cee 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with dentries
  * 
- *   Copyright (C) International Business Machines  Corp., 2002,2003
+ *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -200,8 +200,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        (oplock & CIFS_CREATE_ACTION))
                        if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
-                                       (__u64)current->euid,
-                                       (__u64)current->egid,
+                                       (__u64)current->fsuid,
+                                       (__u64)current->fsgid,
                                        0 /* dev */,
                                        cifs_sb->local_nls, 
                                        cifs_sb->mnt_cifs_flags & 
@@ -325,7 +325,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
        else if (pTcon->ses->capabilities & CAP_UNIX) {
                if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                        rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
-                               mode,(__u64)current->euid,(__u64)current->egid,
+                               mode,(__u64)current->fsuid,(__u64)current->fsgid,
                                device_number, cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags & 
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
index 5ade53d7bca89624cd6b9381d4e6ba91543517be..378095a442d0a5ba325ee7ac118b50d4f9fdebf6 100644 (file)
@@ -553,13 +553,13 @@ int cifs_closedir(struct inode *inode, struct file *file)
                }
                ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
                if (ptmp) {
-   /* BB removeme BB */        cFYI(1, ("freeing smb buf in srch struct in closedir"));
+                       cFYI(1, ("closedir free smb buf in srch struct"));
                        pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
                        cifs_buf_release(ptmp);
                }
                ptmp = pCFileStruct->search_resume_name;
                if (ptmp) {
-   /* BB removeme BB */        cFYI(1, ("freeing resume name in closedir"));
+                       cFYI(1, ("closedir free resume name"));
                        pCFileStruct->search_resume_name = NULL;
                        kfree(ptmp);
                }
@@ -868,10 +868,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                if (rc != 0)
                                        break;
                        }
-#ifdef CONFIG_CIFS_EXPERIMENTAL
                        /* BB FIXME We can not sign across two buffers yet */
-                       if((experimEnabled) && ((pTcon->ses->server->secMode & 
-                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
+                       if((pTcon->ses->server->secMode & 
+                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
                                struct kvec iov[2];
                                unsigned int len;
 
@@ -887,7 +886,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                                iov, 1, long_op);
                        } else
                        /* BB FIXME fixup indentation of line below */
-#endif                 
                        rc = CIFSSMBWrite(xid, pTcon,
                                 open_file->netfid,
                                 min_t(const int, cifs_sb->wsize, 
@@ -1024,7 +1022,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
        return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int cifs_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
 {
@@ -1227,7 +1224,6 @@ retry:
 
        return rc;
 }
-#endif
 
 static int cifs_writepage(struct page* page, struct writeback_control *wbc)
 {
@@ -1426,6 +1422,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
                rc = -EAGAIN;
                smb_read_data = NULL;
                while (rc == -EAGAIN) {
+                       int buf_type = CIFS_NO_BUFFER;
                        if ((open_file->invalidHandle) && 
                            (!open_file->closePend)) {
                                rc = cifs_reopen_file(file->f_dentry->d_inode,
@@ -1434,20 +1431,22 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
                                        break;
                        }
                        rc = CIFSSMBRead(xid, pTcon,
-                                       open_file->netfid,
-                                       current_read_size, *poffset,
-                                       &bytes_read, &smb_read_data);
+                                        open_file->netfid,
+                                        current_read_size, *poffset,
+                                        &bytes_read, &smb_read_data,
+                                        &buf_type);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
                        if (copy_to_user(current_offset, 
                                         smb_read_data + 4 /* RFC1001 hdr */
                                         + le16_to_cpu(pSMBr->DataOffset), 
                                         bytes_read)) {
                                rc = -EFAULT;
-                               FreeXid(xid);
-                               return rc;
-            }
+                       }
                        if (smb_read_data) {
-                               cifs_buf_release(smb_read_data);
+                               if(buf_type == CIFS_SMALL_BUFFER)
+                                       cifs_small_buf_release(smb_read_data);
+                               else if(buf_type == CIFS_LARGE_BUFFER)
+                                       cifs_buf_release(smb_read_data);
                                smb_read_data = NULL;
                        }
                }
@@ -1480,6 +1479,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
        int xid;
        char *current_offset;
        struct cifsFileInfo *open_file;
+       int buf_type = CIFS_NO_BUFFER;
 
        xid = GetXid();
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
@@ -1516,9 +1516,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
                                        break;
                        }
                        rc = CIFSSMBRead(xid, pTcon,
-                                       open_file->netfid,
-                                       current_read_size, *poffset,
-                                       &bytes_read, &current_offset);
+                                        open_file->netfid,
+                                        current_read_size, *poffset,
+                                        &bytes_read, &current_offset,
+                                        &buf_type);
                }
                if (rc || (bytes_read == 0)) {
                        if (total_read) {
@@ -1616,6 +1617,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        struct smb_com_read_rsp *pSMBr;
        struct pagevec lru_pvec;
        struct cifsFileInfo *open_file;
+       int buf_type = CIFS_NO_BUFFER;
 
        xid = GetXid();
        if (file->private_data == NULL) {
@@ -1672,14 +1674,17 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        }
 
                        rc = CIFSSMBRead(xid, pTcon,
-                                       open_file->netfid,
-                                       read_size, offset,
-                                       &bytes_read, &smb_read_data);
-
+                                        open_file->netfid,
+                                        read_size, offset,
+                                        &bytes_read, &smb_read_data,
+                                        &buf_type);
                        /* BB more RC checks ? */
                        if (rc== -EAGAIN) {
                                if (smb_read_data) {
-                                       cifs_buf_release(smb_read_data);
+                                       if(buf_type == CIFS_SMALL_BUFFER)
+                                               cifs_small_buf_release(smb_read_data);
+                                       else if(buf_type == CIFS_LARGE_BUFFER)
+                                               cifs_buf_release(smb_read_data);
                                        smb_read_data = NULL;
                                }
                        }
@@ -1736,7 +1741,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        break;
                }
                if (smb_read_data) {
-                       cifs_buf_release(smb_read_data);
+                       if(buf_type == CIFS_SMALL_BUFFER)
+                               cifs_small_buf_release(smb_read_data);
+                       else if(buf_type == CIFS_LARGE_BUFFER)
+                               cifs_buf_release(smb_read_data);
                        smb_read_data = NULL;
                }
                bytes_read = 0;
@@ -1825,10 +1833,20 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
                open_file =  find_writable_file(cifsInode);
  
        if(open_file) {
+               struct cifs_sb_info *cifs_sb;
+
                /* there is not actually a write pending so let
                this handle go free and allow it to
                be closable if needed */
                atomic_dec(&open_file->wrtPending);
+
+               cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
+               if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
+                       /* since no page cache to corrupt on directio 
+                       we can change size safely */
+                       return 1;
+               }
+
                return 0;
        } else
                return 1;
@@ -1873,9 +1891,7 @@ struct address_space_operations cifs_addr_ops = {
        .readpage = cifs_readpage,
        .readpages = cifs_readpages,
        .writepage = cifs_writepage,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .writepages = cifs_writepages,
-#endif
        .prepare_write = cifs_prepare_write,
        .commit_write = cifs_commit_write,
        .set_page_dirty = __set_page_dirty_nobuffers,
index 3ebce9430f4a9f6af94085f998d4682027d01edc..59359911f4810c601923261c94cd49ffeebf5542 100644 (file)
@@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
                         cifs_sb->mnt_cifs_flags &
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc==0) {
+               int buf_type = CIFS_NO_BUFFER;
                        /* Read header */
                rc = CIFSSMBRead(xid, pTcon,
                                 netfid,
                                 24 /* length */, 0 /* offset */,
-                                &bytes_read, &pbuf);
+                                &bytes_read, &pbuf, &buf_type);
                if((rc == 0) && (bytes_read >= 8)) {
                        if(memcmp("IntxBLK", pbuf, 8) == 0) {
                                cFYI(1,("Block device"));
@@ -267,7 +268,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
                } else {
                        inode->i_mode |= S_IFREG; /* then it is a file */
                        rc = -EOPNOTSUPP; /* or some unknown SFU type */        
-               }
+               }               
                CIFSSMBClose(xid, pTcon, netfid);
        }
        return rc;
@@ -750,8 +751,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
                                CIFSSMBUnixSetPerms(xid, pTcon, full_path,
                                                    mode,
-                                                   (__u64)current->euid,
-                                                   (__u64)current->egid,
+                                                   (__u64)current->fsuid,
+                                                   (__u64)current->fsgid,
                                                    0 /* dev_t */,
                                                    cifs_sb->local_nls,
                                                    cifs_sb->mnt_cifs_flags &
index 94baf6c8ecbda85946984cd2e4d524034cc94644..812c6bb0fe38adff74cc25c8dc7848cbae3315bd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/misc.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2004
+ *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -161,6 +161,9 @@ cifs_buf_get(void)
        if (ret_buf) {
                memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
                atomic_inc(&bufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+               atomic_inc(&totBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
        }
 
        return ret_buf;
@@ -195,6 +198,10 @@ cifs_small_buf_get(void)
        /* No need to clear memory here, cleared in header assemble */
        /*      memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
                atomic_inc(&smBufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+               atomic_inc(&totSmBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
+
        }
        return ret_buf;
 }
@@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
        struct cifsSesInfo * ses;
        char *temp = (char *) buffer;
 
-       memset(temp,0,MAX_CIFS_HDR_SIZE);
+       memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */
 
        buffer->smb_buf_length =
            (2 * word_count) + sizeof (struct smb_hdr) -
@@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
                /*  BB Add support for establishing new tCon and SMB Session  */
                /*      with userid/password pairs found on the smb session   */ 
                /*      for other target tcp/ip addresses               BB    */
-                               if(current->uid != treeCon->ses->linux_uid) {
-                                       cFYI(1,("Multiuser mode and UID did not match tcon uid "));
+                               if(current->fsuid != treeCon->ses->linux_uid) {
+                                       cFYI(1,("Multiuser mode and UID did not match tcon uid"));
                                        read_lock(&GlobalSMBSeslock);
                                        list_for_each(temp_item, &GlobalSMBSessionList) {
                                                ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
-                                               if(ses->linux_uid == current->uid) {
+                                               if(ses->linux_uid == current->fsuid) {
                                                        if(ses->server == treeCon->ses->server) {
                                                                cFYI(1,("found matching uid substitute right smb_uid"));  
                                                                buffer->Uid = ses->Suid;
index 9bdaaecae36f683ef52196b4d54cee256b006029..288cc048d37f1e5b2373c8dd04157bcc90383bcc 100644 (file)
@@ -214,8 +214,7 @@ static void fill_in_inode(struct inode *tmp_inode,
                        tmp_inode->i_fop = &cifs_file_nobrl_ops;
                else
                        tmp_inode->i_fop = &cifs_file_ops;
-               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-                       tmp_inode->i_fop->lock = NULL;
+
                tmp_inode->i_data.a_ops = &cifs_addr_ops;
                if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
                   (cifs_sb->tcon->ses->server->maxBuf <
@@ -327,12 +326,18 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
        if (S_ISREG(tmp_inode->i_mode)) {
                cFYI(1, ("File inode"));
                tmp_inode->i_op = &cifs_file_inode_ops;
-               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-                       tmp_inode->i_fop = &cifs_file_direct_ops;
+
+               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                               tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
+                       else
+                               tmp_inode->i_fop = &cifs_file_direct_ops;
+               
+               } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                       tmp_inode->i_fop = &cifs_file_nobrl_ops;
                else
                        tmp_inode->i_fop = &cifs_file_ops;
-               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-                       tmp_inode->i_fop->lock = NULL;
+
                tmp_inode->i_data.a_ops = &cifs_addr_ops;
                if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
                   (cifs_sb->tcon->ses->server->maxBuf < 
index 9222033cad8ec34a5623b21402ca3998c394344a..aede606132aaa091028aa515b60f5addc6911a69 100644 (file)
 /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
 
        /* RFC 1002 session packet types */
-#define RFC1002_SESSION_MESASAGE 0x00
+#define RFC1002_SESSION_MESSAGE 0x00
 #define RFC1002_SESSION_REQUEST  0x81
 #define RFC1002_POSITIVE_SESSION_RESPONSE 0x82
 #define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83
-#define RFC1002_RETARGET_SESSION_RESPONSE 0x83
+#define RFC1002_RETARGET_SESSION_RESPONSE 0x84
 #define RFC1002_SESSION_KEEP_ALIVE 0x85
 
        /* RFC 1002 flags (only one defined */
index f8871196098c9abe371a64a1df5d269cb407f503..c96a148c39b22fd34a5314da9218ccd2b57f403e 100644 (file)
@@ -206,7 +206,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
        return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int
 smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
          struct sockaddr *sin)
@@ -299,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
 
 int
 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
-            struct kvec *iov, int n_vec, int *pbytes_returned,
+            struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
             const int long_op)
 {
        int rc = 0;
@@ -307,6 +306,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        unsigned long timeout;
        struct mid_q_entry *midQ;
        struct smb_hdr *in_buf = iov[0].iov_base;
+       
+       *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
 
        if (ses == NULL) {
                cERROR(1,("Null smb session"));
@@ -392,8 +393,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                return -ENOMEM;
        }
 
-/* BB FIXME */
-/*     rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
+       rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
 
        midQ->midState = MID_REQUEST_SUBMITTED;
 #ifdef CONFIG_CIFS_STATS2
@@ -492,18 +492,21 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
 
                if (midQ->resp_buf && 
                        (midQ->midState == MID_RESPONSE_RECEIVED)) {
-                       in_buf->smb_buf_length = receive_len;
-                       /* BB verify that length would not overrun small buf */
-                       memcpy((char *)in_buf + 4,
-                              (char *)midQ->resp_buf + 4,
-                              receive_len);
 
-                       dump_smb(in_buf, 80);
+                       iov[0].iov_base = (char *)midQ->resp_buf;
+                       if(midQ->largeBuf)
+                               *pRespBufType = CIFS_LARGE_BUFFER;
+                       else
+                               *pRespBufType = CIFS_SMALL_BUFFER;
+                       iov[0].iov_len = receive_len + 4;
+                       iov[1].iov_len = 0;
+
+                       dump_smb(midQ->resp_buf, 80);
                        /* convert the length into a more usable form */
                        if((receive_len > 24) &&
                           (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                        SECMODE_SIGN_ENABLED))) {
-                               rc = cifs_verify_signature(in_buf,
+                               rc = cifs_verify_signature(midQ->resp_buf,
                                                ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                                if(rc) {
@@ -512,18 +515,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                                }
                        }
 
-                       *pbytes_returned = in_buf->smb_buf_length;
-
                        /* BB special case reconnect tid and uid here? */
                        /* BB special case Errbadpassword and pwdexpired here */
-                       rc = map_smb_to_linux_error(in_buf);
+                       rc = map_smb_to_linux_error(midQ->resp_buf);
 
                        /* convert ByteCount if necessary */
                        if (receive_len >=
                            sizeof (struct smb_hdr) -
                            4 /* do not count RFC1001 header */  +
-                           (2 * in_buf->WordCount) + 2 /* bcc */ )
-                               BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
+                           (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
+                               BCC(midQ->resp_buf) = 
+                                       le16_to_cpu(BCC_LE(midQ->resp_buf));
+                       midQ->resp_buf = NULL;  /* mark it so will not be freed
+                                               by DeleteMidQEntry */
                } else {
                        rc = -EIO;
                        cFYI(1,("Bad MID state?"));
@@ -549,7 +553,6 @@ out_unlock2:
 
        return rc;
 }
-#endif /* CIFS_EXPERIMENTAL */
 
 int
 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
@@ -790,7 +793,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                                BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
                } else {
                        rc = -EIO;
-                       cERROR(1,("Bad MID state? "));
+                       cERROR(1,("Bad MID state?"));
                }
        }
 cifs_no_response_exit: