aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/cifs_unicode.c13
-rw-r--r--fs/cifs/cifs_unicode.h6
-rw-r--r--fs/cifs/cifsencrypt.c2
-rw-r--r--fs/cifs/cifsfs.c107
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifspdu.h10
-rw-r--r--fs/cifs/cifssmb.c43
-rw-r--r--fs/cifs/connect.c91
-rw-r--r--fs/cifs/dir.c32
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/cifs/inode.c202
-rw-r--r--fs/cifs/misc.c2
-rw-r--r--fs/cifs/readdir.c43
-rw-r--r--fs/cifs/transport.c4
15 files changed, 385 insertions, 176 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index eab3750cf304..6bded10c0d50 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -3,6 +3,8 @@ Version 1.39
3Defer close of a file handle slightly if pending writes depend on that file handle 3Defer close of a file handle slightly if pending writes depend on that file handle
4(this reduces the EBADF bad file handle errors that can be logged under heavy 4(this reduces the EBADF bad file handle errors that can be logged under heavy
5stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 5stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
6Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
7Unix Extensions. Fix setfacl/getfacl on bigendian.
6 8
7Version 1.38 9Version 1.38
8------------ 10------------
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 4e12053f0806..d2b128255944 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifs_unicode.c 2 * fs/cifs/cifs_unicode.c
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2000,2002 4 * Copyright (c) International Business Machines Corp., 2000,2005
5 * Modified by Steve French (sfrench@us.ibm.com) 5 * Modified by Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
31 * 31 *
32 */ 32 */
33int 33int
34cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ 34cifs_strfromUCS_le(char *to, const __le16 * from,
35 int len, const struct nls_table *codepage) 35 int len, const struct nls_table *codepage)
36{ 36{
37 int i; 37 int i;
@@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
60 * 60 *
61 */ 61 */
62int 62int
63cifs_strtoUCS(wchar_t * to, const char *from, int len, 63cifs_strtoUCS(__le16 * to, const char *from, int len,
64 const struct nls_table *codepage) 64 const struct nls_table *codepage)
65{ 65{
66 int charlen; 66 int charlen;
67 int i; 67 int i;
68 wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */
68 69
69 for (i = 0; len && *from; i++, from += charlen, len -= charlen) { 70 for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
70 71
71 /* works for 2.4.0 kernel or later */ 72 /* works for 2.4.0 kernel or later */
72 charlen = codepage->char2uni(from, len, &to[i]); 73 charlen = codepage->char2uni(from, len, &wchar_to[i]);
73 if (charlen < 1) { 74 if (charlen < 1) {
74 cERROR(1, 75 cERROR(1,
75 ("cifs_strtoUCS: char2uni returned %d", 76 ("cifs_strtoUCS: char2uni returned %d",
76 charlen)); 77 charlen));
77 /* A question mark */ 78 /* A question mark */
78 to[i] = (wchar_t)cpu_to_le16(0x003f); 79 to[i] = cpu_to_le16(0x003f);
79 charlen = 1; 80 charlen = 1;
80 } else 81 } else
81 to[i] = (wchar_t)cpu_to_le16(to[i]); 82 to[i] = cpu_to_le16(wchar_to[i]);
82 83
83 } 84 }
84 85
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index da8dde965275..39e5b970325f 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -5,7 +5,7 @@
5 * Convert a unicode character to upper or lower case using 5 * Convert a unicode character to upper or lower case using
6 * compressed tables. 6 * compressed tables.
7 * 7 *
8 * Copyright (c) International Business Machines Corp., 2000,2002 8 * Copyright (c) International Business Machines Corp., 2000,2005555555555555555555555555555555555555555555555555555555
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[];
59#endif /* UNIUPR_NOLOWER */ 59#endif /* UNIUPR_NOLOWER */
60 60
61#ifdef __KERNEL__ 61#ifdef __KERNEL__
62int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *); 62int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
63int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *); 63int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
64#endif 64#endif
65 65
66/* 66/*
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 1959c7c4b185..fe2bb7c4c912 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
149 char temp_hash[16]; 149 char temp_hash[16];
150 struct HMACMD5Context ctx; 150 struct HMACMD5Context ctx;
151 char * ucase_buf; 151 char * ucase_buf;
152 wchar_t * unicode_buf; 152 __le16 * unicode_buf;
153 unsigned int i,user_name_len,dom_name_len; 153 unsigned int i,user_name_len,dom_name_len;
154 154
155 if(ses == NULL) 155 if(ses == NULL)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 682b0235ad9a..51548ed2e9cc 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type,
483 return sb; 483 return sb;
484} 484}
485 485
486static ssize_t 486static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
487cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, 487 unsigned long nr_segs, loff_t *ppos)
488 loff_t * poffset)
489{ 488{
490 if(file->f_dentry == NULL) 489 struct inode *inode = file->f_dentry->d_inode;
491 return -EIO; 490 ssize_t written;
492 else if(file->f_dentry->d_inode == NULL)
493 return -EIO;
494
495 cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
496 491
497 if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) { 492 written = generic_file_writev(file, iov, nr_segs, ppos);
498 return generic_file_read(file,read_data,read_size,poffset); 493 if (!CIFS_I(inode)->clientCanCacheAll)
499 } else { 494 filemap_fdatawrite(inode->i_mapping);
500 /* BB do we need to lock inode from here until after invalidate? */ 495 return written;
501/* if(file->f_dentry->d_inode->i_mapping) {
502 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
503 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
504 }*/
505/* cifs_revalidate(file->f_dentry);*/ /* BB fixme */
506
507 /* BB we should make timer configurable - perhaps
508 by simply calling cifs_revalidate here */
509 /* invalidate_remote_inode(file->f_dentry->d_inode);*/
510 return generic_file_read(file,read_data,read_size,poffset);
511 }
512} 496}
513 497
514static ssize_t 498static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
515cifs_write_wrapper(struct file * file, const char __user *write_data, 499 size_t count, loff_t pos)
516 size_t write_size, loff_t * poffset)
517{ 500{
501 struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
518 ssize_t written; 502 ssize_t written;
519 503
520 if(file->f_dentry == NULL) 504 written = generic_file_aio_write(iocb, buf, count, pos);
521 return -EIO; 505 if (!CIFS_I(inode)->clientCanCacheAll)
522 else if(file->f_dentry->d_inode == NULL) 506 filemap_fdatawrite(inode->i_mapping);
523 return -EIO;
524
525 cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
526
527 written = generic_file_write(file,write_data,write_size,poffset);
528 if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll) {
529 if(file->f_dentry->d_inode->i_mapping) {
530 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
531 }
532 }
533 return written; 507 return written;
534} 508}
535 509
536
537static struct file_system_type cifs_fs_type = { 510static struct file_system_type cifs_fs_type = {
538 .owner = THIS_MODULE, 511 .owner = THIS_MODULE,
539 .name = "cifs", 512 .name = "cifs",
@@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = {
594}; 567};
595 568
596struct file_operations cifs_file_ops = { 569struct file_operations cifs_file_ops = {
597 .read = cifs_read_wrapper, 570 .read = do_sync_read,
598 .write = cifs_write_wrapper, 571 .write = do_sync_write,
572 .readv = generic_file_readv,
573 .writev = cifs_file_writev,
574 .aio_read = generic_file_aio_read,
575 .aio_write = cifs_file_aio_write,
599 .open = cifs_open, 576 .open = cifs_open,
600 .release = cifs_close, 577 .release = cifs_close,
601 .lock = cifs_lock, 578 .lock = cifs_lock,
@@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = {
608#endif /* CONFIG_CIFS_POSIX */ 585#endif /* CONFIG_CIFS_POSIX */
609 586
610#ifdef CONFIG_CIFS_EXPERIMENTAL 587#ifdef CONFIG_CIFS_EXPERIMENTAL
611 .readv = generic_file_readv,
612 .writev = generic_file_writev,
613 .aio_read = generic_file_aio_read,
614 .aio_write = generic_file_aio_write,
615 .dir_notify = cifs_dir_notify, 588 .dir_notify = cifs_dir_notify,
616#endif /* CONFIG_CIFS_EXPERIMENTAL */ 589#endif /* CONFIG_CIFS_EXPERIMENTAL */
617}; 590};
@@ -635,6 +608,46 @@ struct file_operations cifs_file_direct_ops = {
635 .dir_notify = cifs_dir_notify, 608 .dir_notify = cifs_dir_notify,
636#endif /* CONFIG_CIFS_EXPERIMENTAL */ 609#endif /* CONFIG_CIFS_EXPERIMENTAL */
637}; 610};
611struct file_operations cifs_file_nobrl_ops = {
612 .read = do_sync_read,
613 .write = do_sync_write,
614 .readv = generic_file_readv,
615 .writev = cifs_file_writev,
616 .aio_read = generic_file_aio_read,
617 .aio_write = cifs_file_aio_write,
618 .open = cifs_open,
619 .release = cifs_close,
620 .fsync = cifs_fsync,
621 .flush = cifs_flush,
622 .mmap = cifs_file_mmap,
623 .sendfile = generic_file_sendfile,
624#ifdef CONFIG_CIFS_POSIX
625 .ioctl = cifs_ioctl,
626#endif /* CONFIG_CIFS_POSIX */
627
628#ifdef CONFIG_CIFS_EXPERIMENTAL
629 .dir_notify = cifs_dir_notify,
630#endif /* CONFIG_CIFS_EXPERIMENTAL */
631};
632
633struct file_operations cifs_file_direct_nobrl_ops = {
634 /* no mmap, no aio, no readv -
635 BB reevaluate whether they can be done with directio, no cache */
636 .read = cifs_user_read,
637 .write = cifs_user_write,
638 .open = cifs_open,
639 .release = cifs_close,
640 .fsync = cifs_fsync,
641 .flush = cifs_flush,
642 .sendfile = generic_file_sendfile, /* BB removeme BB */
643#ifdef CONFIG_CIFS_POSIX
644 .ioctl = cifs_ioctl,
645#endif /* CONFIG_CIFS_POSIX */
646
647#ifdef CONFIG_CIFS_EXPERIMENTAL
648 .dir_notify = cifs_dir_notify,
649#endif /* CONFIG_CIFS_EXPERIMENTAL */
650};
638 651
639struct file_operations cifs_dir_ops = { 652struct file_operations cifs_dir_ops = {
640 .readdir = cifs_readdir, 653 .readdir = cifs_readdir,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 1223fa81dbd2..9ec40e0e54fc 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops;
63/* Functions related to files and directories */ 63/* Functions related to files and directories */
64extern struct file_operations cifs_file_ops; 64extern struct file_operations cifs_file_ops;
65extern struct file_operations cifs_file_direct_ops; /* if directio mount */ 65extern struct file_operations cifs_file_direct_ops; /* if directio mount */
66extern struct file_operations cifs_file_nobrl_ops;
67extern struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */
66extern int cifs_open(struct inode *inode, struct file *file); 68extern int cifs_open(struct inode *inode, struct file *file);
67extern int cifs_close(struct inode *inode, struct file *file); 69extern int cifs_close(struct inode *inode, struct file *file);
68extern int cifs_closedir(struct inode *inode, struct file *file); 70extern int cifs_closedir(struct inode *inode, struct file *file);
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 48a05b9df7eb..33e1859fd2f6 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
603 __u16 ByteCount; 603 __u16 ByteCount;
604} __attribute__((packed)) LOGOFF_ANDX_RSP; 604} __attribute__((packed)) LOGOFF_ANDX_RSP;
605 605
606typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ 606typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
607 tree_connect PDU to effect disconnect */
608 /* tdis is probably simplest SMB PDU */
607 struct { 609 struct {
608 struct smb_hdr hdr; /* wct = 0 */ 610 struct smb_hdr hdr; /* wct = 0 */
609 __u16 ByteCount; /* bcc = 0 */ 611 __u16 ByteCount; /* bcc = 0 */
@@ -2025,6 +2027,12 @@ typedef struct {
2025} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ 2027} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
2026 2028
2027 2029
2030struct win_dev {
2031 unsigned char type[8]; /* IntxCHR or IntxBLK */
2032 __le64 major;
2033 __le64 minor;
2034} __attribute__((packed));
2035
2028struct gea { 2036struct gea {
2029 unsigned char name_len; 2037 unsigned char name_len;
2030 char name[1]; 2038 char name[1];
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a53c596e1082..d179b0c3eee4 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1142 int bytes_returned, wct; 1142 int bytes_returned, wct;
1143 int smb_hdr_len; 1143 int smb_hdr_len;
1144 1144
1145 cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ 1145 /* BB removeme BB */
1146 cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
1147
1146 if(tcon->ses->capabilities & CAP_LARGE_FILES) 1148 if(tcon->ses->capabilities & CAP_LARGE_FILES)
1147 wct = 14; 1149 wct = 14;
1148 else 1150 else
@@ -1553,7 +1555,7 @@ createSymLinkRetry:
1553 1555
1554 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1556 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1555 name_len = 1557 name_len =
1556 cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX 1558 cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
1557 /* find define for this maxpathcomponent */ 1559 /* find define for this maxpathcomponent */
1558 , nls_codepage); 1560 , nls_codepage);
1559 name_len++; /* trailing null */ 1561 name_len++; /* trailing null */
@@ -1577,7 +1579,7 @@ createSymLinkRetry:
1577 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 1579 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1578 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1580 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1579 name_len_target = 1581 name_len_target =
1580 cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX 1582 cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
1581 /* find define for this maxpathcomponent */ 1583 /* find define for this maxpathcomponent */
1582 , nls_codepage); 1584 , nls_codepage);
1583 name_len_target++; /* trailing null */ 1585 name_len_target++; /* trailing null */
@@ -1803,7 +1805,7 @@ querySymLinkRetry:
1803 1805
1804 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1806 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1805 name_len = 1807 name_len =
1806 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX 1808 cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
1807 /* find define for this maxpathcomponent */ 1809 /* find define for this maxpathcomponent */
1808 , nls_codepage); 1810 , nls_codepage);
1809 name_len++; /* trailing null */ 1811 name_len++; /* trailing null */
@@ -1860,7 +1862,7 @@ querySymLinkRetry:
1860 min_t(const int, buflen,count) / 2); 1862 min_t(const int, buflen,count) / 2);
1861 /* BB FIXME investigate remapping reserved chars here */ 1863 /* BB FIXME investigate remapping reserved chars here */
1862 cifs_strfromUCS_le(symlinkinfo, 1864 cifs_strfromUCS_le(symlinkinfo,
1863 (wchar_t *) ((char *)&pSMBr->hdr.Protocol + 1865 (__le16 *) ((char *)&pSMBr->hdr.Protocol +
1864 data_offset), 1866 data_offset),
1865 name_len, nls_codepage); 1867 name_len, nls_codepage);
1866 } else { 1868 } else {
@@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1951 reparse_buf->TargetNameOffset), 1953 reparse_buf->TargetNameOffset),
1952 min(buflen/2, reparse_buf->TargetNameLen / 2)); 1954 min(buflen/2, reparse_buf->TargetNameLen / 2));
1953 cifs_strfromUCS_le(symlinkinfo, 1955 cifs_strfromUCS_le(symlinkinfo,
1954 (wchar_t *) (reparse_buf->LinkNamesBuf + 1956 (__le16 *) (reparse_buf->LinkNamesBuf +
1955 reparse_buf->TargetNameOffset), 1957 reparse_buf->TargetNameOffset),
1956 name_len, nls_codepage); 1958 name_len, nls_codepage);
1957 } else { /* ASCII names */ 1959 } else { /* ASCII names */
@@ -1983,9 +1985,9 @@ qreparse_out:
1983static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) 1985static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace)
1984{ 1986{
1985 /* u8 cifs fields do not need le conversion */ 1987 /* u8 cifs fields do not need le conversion */
1986 ace->e_perm = (__u16)cifs_ace->cifs_e_perm; 1988 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
1987 ace->e_tag = (__u16)cifs_ace->cifs_e_tag; 1989 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
1988 ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid); 1990 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
1989 /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */ 1991 /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
1990 1992
1991 return; 1993 return;
@@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
2037 } else if(size > buflen) { 2039 } else if(size > buflen) {
2038 return -ERANGE; 2040 return -ERANGE;
2039 } else /* buffer big enough */ { 2041 } else /* buffer big enough */ {
2040 local_acl->a_version = POSIX_ACL_XATTR_VERSION; 2042 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
2041 for(i = 0;i < count ;i++) { 2043 for(i = 0;i < count ;i++) {
2042 cifs_convert_ace(&local_acl->a_entries[i],pACE); 2044 cifs_convert_ace(&local_acl->a_entries[i],pACE);
2043 pACE ++; 2045 pACE ++;
@@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
2051{ 2053{
2052 __u16 rc = 0; /* 0 = ACL converted ok */ 2054 __u16 rc = 0; /* 0 = ACL converted ok */
2053 2055
2054 cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm); 2056 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
2055 cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag); 2057 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
2056 /* BB is there a better way to handle the large uid? */ 2058 /* BB is there a better way to handle the large uid? */
2057 if(local_ace->e_id == -1) { 2059 if(local_ace->e_id == cpu_to_le32(-1)) {
2058 /* Probably no need to le convert -1 on any arch but can not hurt */ 2060 /* Probably no need to le convert -1 on any arch but can not hurt */
2059 cifs_ace->cifs_uid = cpu_to_le64(-1); 2061 cifs_ace->cifs_uid = cpu_to_le64(-1);
2060 } else 2062 } else
2061 cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id); 2063 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
2062 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ 2064 /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
2063 return rc; 2065 return rc;
2064} 2066}
@@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
2078 2080
2079 count = posix_acl_xattr_count((size_t)buflen); 2081 count = posix_acl_xattr_count((size_t)buflen);
2080 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", 2082 cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
2081 count,buflen,local_acl->a_version)); 2083 count, buflen, le32_to_cpu(local_acl->a_version)));
2082 if(local_acl->a_version != 2) { 2084 if(le32_to_cpu(local_acl->a_version) != 2) {
2083 cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version)); 2085 cFYI(1,("unknown POSIX ACL version %d",
2086 le32_to_cpu(local_acl->a_version)));
2084 return 0; 2087 return 0;
2085 } 2088 }
2086 cifs_acl->version = cpu_to_le16(1); 2089 cifs_acl->version = cpu_to_le16(1);
2087 if(acl_type == ACL_TYPE_ACCESS) 2090 if(acl_type == ACL_TYPE_ACCESS)
2088 cifs_acl->access_entry_count = count; 2091 cifs_acl->access_entry_count = cpu_to_le16(count);
2089 else if(acl_type == ACL_TYPE_DEFAULT) 2092 else if(acl_type == ACL_TYPE_DEFAULT)
2090 cifs_acl->default_entry_count = count; 2093 cifs_acl->default_entry_count = cpu_to_le16(count);
2091 else { 2094 else {
2092 cFYI(1,("unknown ACL type %d",acl_type)); 2095 cFYI(1,("unknown ACL type %d",acl_type));
2093 return 0; 2096 return 0;
@@ -3203,7 +3206,7 @@ getDFSRetry:
3203 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); 3206 temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
3204 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 3207 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
3205 cifs_strfromUCS_le(*targetUNCs, 3208 cifs_strfromUCS_le(*targetUNCs,
3206 (wchar_t *) temp, name_len, nls_codepage); 3209 (__le16 *) temp, name_len, nls_codepage);
3207 } else { 3210 } else {
3208 strncpy(*targetUNCs,temp,name_len); 3211 strncpy(*targetUNCs,temp,name_len);
3209 } 3212 }
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2cb620716bc1..c467de857610 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1986 bytes_returned = 0; /* skill null user */ 1986 bytes_returned = 0; /* skill null user */
1987 else 1987 else
1988 bytes_returned = 1988 bytes_returned =
1989 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, 1989 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
1990 nls_codepage); 1990 nls_codepage);
1991 /* convert number of 16 bit words to bytes */ 1991 /* convert number of 16 bit words to bytes */
1992 bcc_ptr += 2 * bytes_returned; 1992 bcc_ptr += 2 * bytes_returned;
1993 bcc_ptr += 2; /* trailing null */ 1993 bcc_ptr += 2; /* trailing null */
1994 if (domain == NULL) 1994 if (domain == NULL)
1995 bytes_returned = 1995 bytes_returned =
1996 cifs_strtoUCS((wchar_t *) bcc_ptr, 1996 cifs_strtoUCS((__le16 *) bcc_ptr,
1997 "CIFS_LINUX_DOM", 32, nls_codepage); 1997 "CIFS_LINUX_DOM", 32, nls_codepage);
1998 else 1998 else
1999 bytes_returned = 1999 bytes_returned =
2000 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, 2000 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2001 nls_codepage); 2001 nls_codepage);
2002 bcc_ptr += 2 * bytes_returned; 2002 bcc_ptr += 2 * bytes_returned;
2003 bcc_ptr += 2; 2003 bcc_ptr += 2;
2004 bytes_returned = 2004 bytes_returned =
2005 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", 2005 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2006 32, nls_codepage); 2006 32, nls_codepage);
2007 bcc_ptr += 2 * bytes_returned; 2007 bcc_ptr += 2 * bytes_returned;
2008 bytes_returned = 2008 bytes_returned =
2009 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 2009 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
2010 32, nls_codepage); 2010 32, nls_codepage);
2011 bcc_ptr += 2 * bytes_returned; 2011 bcc_ptr += 2 * bytes_returned;
2012 bcc_ptr += 2; 2012 bcc_ptr += 2;
2013 bytes_returned = 2013 bytes_returned =
2014 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, 2014 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2015 64, nls_codepage); 2015 64, nls_codepage);
2016 bcc_ptr += 2 * bytes_returned; 2016 bcc_ptr += 2 * bytes_returned;
2017 bcc_ptr += 2; 2017 bcc_ptr += 2;
@@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2081 if(ses->serverOS == NULL) 2081 if(ses->serverOS == NULL)
2082 goto sesssetup_nomem; 2082 goto sesssetup_nomem;
2083 cifs_strfromUCS_le(ses->serverOS, 2083 cifs_strfromUCS_le(ses->serverOS,
2084 (wchar_t *)bcc_ptr, len,nls_codepage); 2084 (__le16 *)bcc_ptr, len,nls_codepage);
2085 bcc_ptr += 2 * (len + 1); 2085 bcc_ptr += 2 * (len + 1);
2086 remaining_words -= len + 1; 2086 remaining_words -= len + 1;
2087 ses->serverOS[2 * len] = 0; 2087 ses->serverOS[2 * len] = 0;
@@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2093 if(ses->serverNOS == NULL) 2093 if(ses->serverNOS == NULL)
2094 goto sesssetup_nomem; 2094 goto sesssetup_nomem;
2095 cifs_strfromUCS_le(ses->serverNOS, 2095 cifs_strfromUCS_le(ses->serverNOS,
2096 (wchar_t *)bcc_ptr,len,nls_codepage); 2096 (__le16 *)bcc_ptr,len,nls_codepage);
2097 bcc_ptr += 2 * (len + 1); 2097 bcc_ptr += 2 * (len + 1);
2098 ses->serverNOS[2 * len] = 0; 2098 ses->serverNOS[2 * len] = 0;
2099 ses->serverNOS[1 + (2 * len)] = 0; 2099 ses->serverNOS[1 + (2 * len)] = 0;
@@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2111 if(ses->serverDomain == NULL) 2111 if(ses->serverDomain == NULL)
2112 goto sesssetup_nomem; 2112 goto sesssetup_nomem;
2113 cifs_strfromUCS_le(ses->serverDomain, 2113 cifs_strfromUCS_le(ses->serverDomain,
2114 (wchar_t *)bcc_ptr,len,nls_codepage); 2114 (__le16 *)bcc_ptr,len,nls_codepage);
2115 bcc_ptr += 2 * (len + 1); 2115 bcc_ptr += 2 * (len + 1);
2116 ses->serverDomain[2*len] = 0; 2116 ses->serverDomain[2*len] = 0;
2117 ses->serverDomain[1+(2*len)] = 0; 2117 ses->serverDomain[1+(2*len)] = 0;
@@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2255 bcc_ptr++; 2255 bcc_ptr++;
2256 } 2256 }
2257 bytes_returned = 2257 bytes_returned =
2258 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage); 2258 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
2259 bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */ 2259 bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
2260 bcc_ptr += 2; /* trailing null */ 2260 bcc_ptr += 2; /* trailing null */
2261 if (domain == NULL) 2261 if (domain == NULL)
2262 bytes_returned = 2262 bytes_returned =
2263 cifs_strtoUCS((wchar_t *) bcc_ptr, 2263 cifs_strtoUCS((__le16 *) bcc_ptr,
2264 "CIFS_LINUX_DOM", 32, nls_codepage); 2264 "CIFS_LINUX_DOM", 32, nls_codepage);
2265 else 2265 else
2266 bytes_returned = 2266 bytes_returned =
2267 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, 2267 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2268 nls_codepage); 2268 nls_codepage);
2269 bcc_ptr += 2 * bytes_returned; 2269 bcc_ptr += 2 * bytes_returned;
2270 bcc_ptr += 2; 2270 bcc_ptr += 2;
2271 bytes_returned = 2271 bytes_returned =
2272 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", 2272 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2273 32, nls_codepage); 2273 32, nls_codepage);
2274 bcc_ptr += 2 * bytes_returned; 2274 bcc_ptr += 2 * bytes_returned;
2275 bytes_returned = 2275 bytes_returned =
2276 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, 2276 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2277 nls_codepage); 2277 nls_codepage);
2278 bcc_ptr += 2 * bytes_returned; 2278 bcc_ptr += 2 * bytes_returned;
2279 bcc_ptr += 2; 2279 bcc_ptr += 2;
2280 bytes_returned = 2280 bytes_returned =
2281 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, 2281 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2282 64, nls_codepage); 2282 64, nls_codepage);
2283 bcc_ptr += 2 * bytes_returned; 2283 bcc_ptr += 2 * bytes_returned;
2284 bcc_ptr += 2; 2284 bcc_ptr += 2;
@@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2357 ses->serverOS = 2357 ses->serverOS =
2358 kzalloc(2 * (len + 1), GFP_KERNEL); 2358 kzalloc(2 * (len + 1), GFP_KERNEL);
2359 cifs_strfromUCS_le(ses->serverOS, 2359 cifs_strfromUCS_le(ses->serverOS,
2360 (wchar_t *) 2360 (__le16 *)
2361 bcc_ptr, len, 2361 bcc_ptr, len,
2362 nls_codepage); 2362 nls_codepage);
2363 bcc_ptr += 2 * (len + 1); 2363 bcc_ptr += 2 * (len + 1);
@@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2372 kzalloc(2 * (len + 1), 2372 kzalloc(2 * (len + 1),
2373 GFP_KERNEL); 2373 GFP_KERNEL);
2374 cifs_strfromUCS_le(ses->serverNOS, 2374 cifs_strfromUCS_le(ses->serverNOS,
2375 (wchar_t *)bcc_ptr, 2375 (__le16 *)bcc_ptr,
2376 len, 2376 len,
2377 nls_codepage); 2377 nls_codepage);
2378 bcc_ptr += 2 * (len + 1); 2378 bcc_ptr += 2 * (len + 1);
@@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2384 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */ 2384 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2385 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); 2385 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
2386 cifs_strfromUCS_le(ses->serverDomain, 2386 cifs_strfromUCS_le(ses->serverDomain,
2387 (wchar_t *)bcc_ptr, 2387 (__le16 *)bcc_ptr,
2388 len, 2388 len, nls_codepage);
2389 nls_codepage);
2390 bcc_ptr += 2*(len+1); 2389 bcc_ptr += 2*(len+1);
2391 ses->serverDomain[2*len] = 0; 2390 ses->serverDomain[2*len] = 0;
2392 ses->serverDomain[1+(2*len)] = 0; 2391 ses->serverDomain[1+(2*len)] = 0;
@@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2560 } 2559 }
2561 2560
2562 bytes_returned = 2561 bytes_returned =
2563 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", 2562 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2564 32, nls_codepage); 2563 32, nls_codepage);
2565 bcc_ptr += 2 * bytes_returned; 2564 bcc_ptr += 2 * bytes_returned;
2566 bytes_returned = 2565 bytes_returned =
2567 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, 2566 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2568 nls_codepage); 2567 nls_codepage);
2569 bcc_ptr += 2 * bytes_returned; 2568 bcc_ptr += 2 * bytes_returned;
2570 bcc_ptr += 2; /* null terminate Linux version */ 2569 bcc_ptr += 2; /* null terminate Linux version */
2571 bytes_returned = 2570 bytes_returned =
2572 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, 2571 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2573 64, nls_codepage); 2572 64, nls_codepage);
2574 bcc_ptr += 2 * bytes_returned; 2573 bcc_ptr += 2 * bytes_returned;
2575 *(bcc_ptr + 1) = 0; 2574 *(bcc_ptr + 1) = 0;
@@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2673 ses->serverOS = 2672 ses->serverOS =
2674 kzalloc(2 * (len + 1), GFP_KERNEL); 2673 kzalloc(2 * (len + 1), GFP_KERNEL);
2675 cifs_strfromUCS_le(ses->serverOS, 2674 cifs_strfromUCS_le(ses->serverOS,
2676 (wchar_t *) 2675 (__le16 *)
2677 bcc_ptr, len, 2676 bcc_ptr, len,
2678 nls_codepage); 2677 nls_codepage);
2679 bcc_ptr += 2 * (len + 1); 2678 bcc_ptr += 2 * (len + 1);
@@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2690 GFP_KERNEL); 2689 GFP_KERNEL);
2691 cifs_strfromUCS_le(ses-> 2690 cifs_strfromUCS_le(ses->
2692 serverNOS, 2691 serverNOS,
2693 (wchar_t *) 2692 (__le16 *)
2694 bcc_ptr, 2693 bcc_ptr,
2695 len, 2694 len,
2696 nls_codepage); 2695 nls_codepage);
@@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2708 1), 2707 1),
2709 GFP_KERNEL); 2708 GFP_KERNEL);
2710 cifs_strfromUCS_le 2709 cifs_strfromUCS_le
2711 (ses-> 2710 (ses->serverDomain,
2712 serverDomain, 2711 (__le16 *)bcc_ptr,
2713 (wchar_t *) 2712 len, nls_codepage);
2714 bcc_ptr, len,
2715 nls_codepage);
2716 bcc_ptr += 2713 bcc_ptr +=
2717 2 * (len + 1); 2714 2 * (len + 1);
2718 ses-> 2715 ses->serverDomain[2*len]
2719 serverDomain[2
2720 * len]
2721 = 0; 2716 = 0;
2722 ses-> 2717 ses->serverDomain
2723 serverDomain[1 2718 [1 + (2 * len)]
2724 +
2725 (2
2726 *
2727 len)]
2728 = 0; 2719 = 0;
2729 } /* else no more room so create dummy domain string */ 2720 } /* else no more room so create dummy domain string */
2730 else 2721 else
@@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2903 SecurityBlob->DomainName.MaximumLength = 0; 2894 SecurityBlob->DomainName.MaximumLength = 0;
2904 } else { 2895 } else {
2905 __u16 len = 2896 __u16 len =
2906 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, 2897 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2907 nls_codepage); 2898 nls_codepage);
2908 len *= 2; 2899 len *= 2;
2909 SecurityBlob->DomainName.MaximumLength = 2900 SecurityBlob->DomainName.MaximumLength =
@@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2921 SecurityBlob->UserName.MaximumLength = 0; 2912 SecurityBlob->UserName.MaximumLength = 0;
2922 } else { 2913 } else {
2923 __u16 len = 2914 __u16 len =
2924 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64, 2915 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2925 nls_codepage); 2916 nls_codepage);
2926 len *= 2; 2917 len *= 2;
2927 SecurityBlob->UserName.MaximumLength = 2918 SecurityBlob->UserName.MaximumLength =
@@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2934 cpu_to_le16(len); 2925 cpu_to_le16(len);
2935 } 2926 }
2936 2927
2937 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage); 2928 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2938 SecurityBlob->WorkstationName.Length *= 2; 2929 SecurityBlob->WorkstationName.Length *= 2;
2939 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length); 2930 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2940 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength); 2931 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
@@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2947 bcc_ptr++; 2938 bcc_ptr++;
2948 } 2939 }
2949 bytes_returned = 2940 bytes_returned =
2950 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", 2941 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2951 32, nls_codepage); 2942 32, nls_codepage);
2952 bcc_ptr += 2 * bytes_returned; 2943 bcc_ptr += 2 * bytes_returned;
2953 bytes_returned = 2944 bytes_returned =
2954 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, 2945 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2955 nls_codepage); 2946 nls_codepage);
2956 bcc_ptr += 2 * bytes_returned; 2947 bcc_ptr += 2 * bytes_returned;
2957 bcc_ptr += 2; /* null term version string */ 2948 bcc_ptr += 2; /* null term version string */
2958 bytes_returned = 2949 bytes_returned =
2959 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, 2950 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2960 64, nls_codepage); 2951 64, nls_codepage);
2961 bcc_ptr += 2 * bytes_returned; 2952 bcc_ptr += 2 * bytes_returned;
2962 *(bcc_ptr + 1) = 0; 2953 *(bcc_ptr + 1) = 0;
@@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3069 ses->serverOS = 3060 ses->serverOS =
3070 kzalloc(2 * (len + 1), GFP_KERNEL); 3061 kzalloc(2 * (len + 1), GFP_KERNEL);
3071 cifs_strfromUCS_le(ses->serverOS, 3062 cifs_strfromUCS_le(ses->serverOS,
3072 (wchar_t *) 3063 (__le16 *)
3073 bcc_ptr, len, 3064 bcc_ptr, len,
3074 nls_codepage); 3065 nls_codepage);
3075 bcc_ptr += 2 * (len + 1); 3066 bcc_ptr += 2 * (len + 1);
@@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3086 GFP_KERNEL); 3077 GFP_KERNEL);
3087 cifs_strfromUCS_le(ses-> 3078 cifs_strfromUCS_le(ses->
3088 serverNOS, 3079 serverNOS,
3089 (wchar_t *) 3080 (__le16 *)
3090 bcc_ptr, 3081 bcc_ptr,
3091 len, 3082 len,
3092 nls_codepage); 3083 nls_codepage);
@@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3105 cifs_strfromUCS_le 3096 cifs_strfromUCS_le
3106 (ses-> 3097 (ses->
3107 serverDomain, 3098 serverDomain,
3108 (wchar_t *) 3099 (__le16 *)
3109 bcc_ptr, len, 3100 bcc_ptr, len,
3110 nls_codepage); 3101 nls_codepage);
3111 bcc_ptr += 3102 bcc_ptr +=
@@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3227 if (ses->capabilities & CAP_UNICODE) { 3218 if (ses->capabilities & CAP_UNICODE) {
3228 smb_buffer->Flags2 |= SMBFLG2_UNICODE; 3219 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3229 length = 3220 length =
3230 cifs_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage); 3221 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
3231 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ 3222 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
3232 bcc_ptr += 2; /* skip trailing null */ 3223 bcc_ptr += 2; /* skip trailing null */
3233 } else { /* ASCII */ 3224 } else { /* ASCII */
@@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3263 tcon->nativeFileSystem = 3254 tcon->nativeFileSystem =
3264 kzalloc(length + 2, GFP_KERNEL); 3255 kzalloc(length + 2, GFP_KERNEL);
3265 cifs_strfromUCS_le(tcon->nativeFileSystem, 3256 cifs_strfromUCS_le(tcon->nativeFileSystem,
3266 (wchar_t *) bcc_ptr, 3257 (__le16 *) bcc_ptr,
3267 length, nls_codepage); 3258 length, nls_codepage);
3268 bcc_ptr += 2 * length; 3259 bcc_ptr += 2 * length;
3269 bcc_ptr[0] = 0; /* null terminate the string */ 3260 bcc_ptr[0] = 0; /* null terminate the string */
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 8dfe717a332a..16b21522e8fe 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -292,7 +292,8 @@ cifs_create_out:
292 return rc; 292 return rc;
293} 293}
294 294
295int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) 295int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
296 dev_t device_number)
296{ 297{
297 int rc = -EPERM; 298 int rc = -EPERM;
298 int xid; 299 int xid;
@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
368 369
369 if(!rc) { 370 if(!rc) {
370 /* BB Do not bother to decode buf since no 371 /* BB Do not bother to decode buf since no
371 local inode yet to put timestamps in */ 372 local inode yet to put timestamps in,
373 but we can reuse it safely */
374 int bytes_written;
375 struct win_dev *pdev;
376 pdev = (struct win_dev *)buf;
377 if(S_ISCHR(mode)) {
378 memcpy(pdev->type, "IntxCHR", 8);
379 pdev->major =
380 cpu_to_le64(MAJOR(device_number));
381 pdev->minor =
382 cpu_to_le64(MINOR(device_number));
383 rc = CIFSSMBWrite(xid, pTcon,
384 fileHandle,
385 sizeof(struct win_dev),
386 0, &bytes_written, (char *)pdev,
387 NULL, 0);
388 } else if(S_ISBLK(mode)) {
389 memcpy(pdev->type, "IntxBLK", 8);
390 pdev->major =
391 cpu_to_le64(MAJOR(device_number));
392 pdev->minor =
393 cpu_to_le64(MINOR(device_number));
394 rc = CIFSSMBWrite(xid, pTcon,
395 fileHandle,
396 sizeof(struct win_dev),
397 0, &bytes_written, (char *)pdev,
398 NULL, 0);
399 } /* else if(S_ISFIFO */
372 CIFSSMBClose(xid, pTcon, fileHandle); 400 CIFSSMBClose(xid, pTcon, fileHandle);
373 d_drop(direntry); 401 d_drop(direntry);
374 } 402 }
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index da4f5e10b3cc..14a1c72ced92 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -489,8 +489,10 @@ int cifs_close(struct inode *inode, struct file *file)
489 the struct would be in each open file, 489 the struct would be in each open file,
490 but this should give enough time to 490 but this should give enough time to
491 clear the socket */ 491 clear the socket */
492 write_unlock(&file->f_owner.lock);
492 cERROR(1,("close with pending writes")); 493 cERROR(1,("close with pending writes"));
493 msleep(timeout); 494 msleep(timeout);
495 write_lock(&file->f_owner.lock);
494 timeout *= 4; 496 timeout *= 4;
495 } 497 }
496 write_unlock(&file->f_owner.lock); 498 write_unlock(&file->f_owner.lock);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 923d071163b2..05b525812adb 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
41 char *tmp_path; 41 char *tmp_path;
42 42
43 pTcon = cifs_sb->tcon; 43 pTcon = cifs_sb->tcon;
44 cFYI(1, (" Getting info on %s ", search_path)); 44 cFYI(1, ("Getting info on %s ", search_path));
45 /* could have done a find first instead but this returns more info */ 45 /* could have done a find first instead but this returns more info */
46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
97 inode = *pinode; 97 inode = *pinode;
98 cifsInfo = CIFS_I(inode); 98 cifsInfo = CIFS_I(inode);
99 99
100 cFYI(1, (" Old time %ld ", cifsInfo->time)); 100 cFYI(1, ("Old time %ld ", cifsInfo->time));
101 cifsInfo->time = jiffies; 101 cifsInfo->time = jiffies;
102 cFYI(1, (" New time %ld ", cifsInfo->time)); 102 cFYI(1, ("New time %ld ", cifsInfo->time));
103 /* this is ok to set on every inode revalidate */ 103 /* this is ok to set on every inode revalidate */
104 atomic_set(&cifsInfo->inUse,1); 104 atomic_set(&cifsInfo->inUse,1);
105 105
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
111 inode->i_ctime = 111 inode->i_ctime =
112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); 112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
113 inode->i_mode = le64_to_cpu(findData.Permissions); 113 inode->i_mode = le64_to_cpu(findData.Permissions);
114 /* since we set the inode type below we need to mask off
115 to avoid strange results if bits set above */
116 inode->i_mode &= ~S_IFMT;
114 if (type == UNIX_FILE) { 117 if (type == UNIX_FILE) {
115 inode->i_mode |= S_IFREG; 118 inode->i_mode |= S_IFREG;
116 } else if (type == UNIX_SYMLINK) { 119 } else if (type == UNIX_SYMLINK) {
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
129 inode->i_mode |= S_IFIFO; 132 inode->i_mode |= S_IFIFO;
130 } else if (type == UNIX_SOCKET) { 133 } else if (type == UNIX_SOCKET) {
131 inode->i_mode |= S_IFSOCK; 134 inode->i_mode |= S_IFSOCK;
135 } else {
136 /* safest to call it a file if we do not know */
137 inode->i_mode |= S_IFREG;
138 cFYI(1,("unknown type %d",type));
132 } 139 }
133 inode->i_uid = le64_to_cpu(findData.Uid); 140 inode->i_uid = le64_to_cpu(findData.Uid);
134 inode->i_gid = le64_to_cpu(findData.Gid); 141 inode->i_gid = le64_to_cpu(findData.Gid);
@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode,
155 } 162 }
156 163
157 if (num_of_bytes < end_of_file) 164 if (num_of_bytes < end_of_file)
158 cFYI(1, ("allocation size less than end of file ")); 165 cFYI(1, ("allocation size less than end of file"));
159 cFYI(1, 166 cFYI(1,
160 ("Size %ld and blocks %ld", 167 ("Size %ld and blocks %ld",
161 (unsigned long) inode->i_size, inode->i_blocks)); 168 (unsigned long) inode->i_size, inode->i_blocks));
162 if (S_ISREG(inode->i_mode)) { 169 if (S_ISREG(inode->i_mode)) {
163 cFYI(1, (" File inode ")); 170 cFYI(1, ("File inode"));
164 inode->i_op = &cifs_file_inode_ops; 171 inode->i_op = &cifs_file_inode_ops;
165 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 172 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
166 inode->i_fop = &cifs_file_direct_ops; 173 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
167 else 174 inode->i_fop =
175 &cifs_file_direct_nobrl_ops;
176 else
177 inode->i_fop = &cifs_file_direct_ops;
178 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
179 inode->i_fop = &cifs_file_nobrl_ops;
180 else /* not direct, send byte range locks */
168 inode->i_fop = &cifs_file_ops; 181 inode->i_fop = &cifs_file_ops;
169 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 182
170 inode->i_fop->lock = NULL;
171 inode->i_data.a_ops = &cifs_addr_ops; 183 inode->i_data.a_ops = &cifs_addr_ops;
172 /* check if server can support readpages */ 184 /* check if server can support readpages */
173 if(pTcon->ses->server->maxBuf < 185 if(pTcon->ses->server->maxBuf <
174 4096 + MAX_CIFS_HDR_SIZE) 186 4096 + MAX_CIFS_HDR_SIZE)
175 inode->i_data.a_ops->readpages = NULL; 187 inode->i_data.a_ops->readpages = NULL;
176 } else if (S_ISDIR(inode->i_mode)) { 188 } else if (S_ISDIR(inode->i_mode)) {
177 cFYI(1, (" Directory inode")); 189 cFYI(1, ("Directory inode"));
178 inode->i_op = &cifs_dir_inode_ops; 190 inode->i_op = &cifs_dir_inode_ops;
179 inode->i_fop = &cifs_dir_ops; 191 inode->i_fop = &cifs_dir_ops;
180 } else if (S_ISLNK(inode->i_mode)) { 192 } else if (S_ISLNK(inode->i_mode)) {
181 cFYI(1, (" Symbolic Link inode ")); 193 cFYI(1, ("Symbolic Link inode"));
182 inode->i_op = &cifs_symlink_inode_ops; 194 inode->i_op = &cifs_symlink_inode_ops;
183 /* tmp_inode->i_fop = */ /* do not need to set to anything */ 195 /* tmp_inode->i_fop = */ /* do not need to set to anything */
184 } else { 196 } else {
185 cFYI(1, (" Init special inode ")); 197 cFYI(1, ("Init special inode"));
186 init_special_inode(inode, inode->i_mode, 198 init_special_inode(inode, inode->i_mode,
187 inode->i_rdev); 199 inode->i_rdev);
188 } 200 }
@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode,
190 return rc; 202 return rc;
191} 203}
192 204
205static int decode_sfu_inode(struct inode * inode, __u64 size,
206 const unsigned char *path,
207 struct cifs_sb_info *cifs_sb, int xid)
208{
209 int rc;
210 int oplock = FALSE;
211 __u16 netfid;
212 struct cifsTconInfo *pTcon = cifs_sb->tcon;
213 char buf[24];
214 unsigned int bytes_read;
215 char * pbuf;
216
217 pbuf = buf;
218
219 if(size == 0) {
220 inode->i_mode |= S_IFIFO;
221 return 0;
222 } else if (size < 8) {
223 return -EINVAL; /* EOPNOTSUPP? */
224 }
225
226 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
227 CREATE_NOT_DIR, &netfid, &oplock, NULL,
228 cifs_sb->local_nls,
229 cifs_sb->mnt_cifs_flags &
230 CIFS_MOUNT_MAP_SPECIAL_CHR);
231 if (rc==0) {
232 /* Read header */
233 rc = CIFSSMBRead(xid, pTcon,
234 netfid,
235 24 /* length */, 0 /* offset */,
236 &bytes_read, &pbuf);
237 if((rc == 0) && (bytes_read >= 8)) {
238 if(memcmp("IntxBLK", pbuf, 8) == 0) {
239 cFYI(1,("Block device"));
240 inode->i_mode |= S_IFBLK;
241 if(bytes_read == 24) {
242 /* we have enough to decode dev num */
243 __u64 mjr; /* major */
244 __u64 mnr; /* minor */
245 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
246 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
247 inode->i_rdev = MKDEV(mjr, mnr);
248 }
249 } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
250 cFYI(1,("Char device"));
251 inode->i_mode |= S_IFCHR;
252 if(bytes_read == 24) {
253 /* we have enough to decode dev num */
254 __u64 mjr; /* major */
255 __u64 mnr; /* minor */
256 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
257 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
258 inode->i_rdev = MKDEV(mjr, mnr);
259 }
260 } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
261 cFYI(1,("Symlink"));
262 inode->i_mode |= S_IFLNK;
263 } else {
264 inode->i_mode |= S_IFREG; /* file? */
265 rc = -EOPNOTSUPP;
266 }
267 } else {
268 inode->i_mode |= S_IFREG; /* then it is a file */
269 rc = -EOPNOTSUPP; /* or some unknown SFU type */
270 }
271 CIFSSMBClose(xid, pTcon, netfid);
272 }
273 return rc;
274
275}
276
277#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
278
279static int get_sfu_uid_mode(struct inode * inode,
280 const unsigned char *path,
281 struct cifs_sb_info *cifs_sb, int xid)
282{
283#ifdef CONFIG_CIFS_XATTR
284 ssize_t rc;
285 char ea_value[4];
286 __u32 mode;
287
288 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
289 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
290 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
291 if(rc < 0)
292 return (int)rc;
293 else if (rc > 3) {
294 mode = le32_to_cpu(*((__le32 *)ea_value));
295 inode->i_mode &= ~SFBITS_MASK;
296 cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
297 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
298 cFYI(1,("special mode bits 0%o", mode));
299 return 0;
300 } else {
301 return 0;
302 }
303#else
304 return -EOPNOTSUPP;
305#endif
306
307
308}
309
193int cifs_get_inode_info(struct inode **pinode, 310int cifs_get_inode_info(struct inode **pinode,
194 const unsigned char *search_path, FILE_ALL_INFO *pfindData, 311 const unsigned char *search_path, FILE_ALL_INFO *pfindData,
195 struct super_block *sb, int xid) 312 struct super_block *sb, int xid)
@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode,
202 char *buf = NULL; 319 char *buf = NULL;
203 320
204 pTcon = cifs_sb->tcon; 321 pTcon = cifs_sb->tcon;
205 cFYI(1,("Getting info on %s ", search_path)); 322 cFYI(1,("Getting info on %s", search_path));
206 323
207 if ((pfindData == NULL) && (*pinode != NULL)) { 324 if ((pfindData == NULL) && (*pinode != NULL)) {
208 if (CIFS_I(*pinode)->clientCanCacheRead) { 325 if (CIFS_I(*pinode)->clientCanCacheRead) {
@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode,
303 inode = *pinode; 420 inode = *pinode;
304 cifsInfo = CIFS_I(inode); 421 cifsInfo = CIFS_I(inode);
305 cifsInfo->cifsAttrs = attr; 422 cifsInfo->cifsAttrs = attr;
306 cFYI(1, (" Old time %ld ", cifsInfo->time)); 423 cFYI(1, ("Old time %ld ", cifsInfo->time));
307 cifsInfo->time = jiffies; 424 cifsInfo->time = jiffies;
308 cFYI(1, (" New time %ld ", cifsInfo->time)); 425 cFYI(1, ("New time %ld ", cifsInfo->time));
309 426
310 /* blksize needs to be multiple of two. So safer to default to 427 /* blksize needs to be multiple of two. So safer to default to
311 blksize and blkbits set in superblock so 2**blkbits and blksize 428 blksize and blkbits set in superblock so 2**blkbits and blksize
@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode,
319 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 436 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
320 inode->i_ctime = 437 inode->i_ctime =
321 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 438 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
322 cFYI(0, (" Attributes came in as 0x%x ", attr)); 439 cFYI(0, ("Attributes came in as 0x%x ", attr));
323 440
324 /* set default mode. will override for dirs below */ 441 /* set default mode. will override for dirs below */
325 if (atomic_read(&cifsInfo->inUse) == 0) 442 if (atomic_read(&cifsInfo->inUse) == 0)
326 /* new inode, can safely set these fields */ 443 /* new inode, can safely set these fields */
327 inode->i_mode = cifs_sb->mnt_file_mode; 444 inode->i_mode = cifs_sb->mnt_file_mode;
328 445 else /* since we set the inode type below we need to mask off
446 to avoid strange results if type changes and both get orred in */
447 inode->i_mode &= ~S_IFMT;
329/* if (attr & ATTR_REPARSE) */ 448/* if (attr & ATTR_REPARSE) */
330 /* We no longer handle these as symlinks because we could not 449 /* We no longer handle these as symlinks because we could not
331 follow them due to the absolute path with drive letter */ 450 follow them due to the absolute path with drive letter */
@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode,
340 (pfindData->EndOfFile == 0)) { 459 (pfindData->EndOfFile == 0)) {
341 inode->i_mode = cifs_sb->mnt_file_mode; 460 inode->i_mode = cifs_sb->mnt_file_mode;
342 inode->i_mode |= S_IFIFO; 461 inode->i_mode |= S_IFIFO;
343/* BB Finish for SFU style symlinks and devies */ 462/* BB Finish for SFU style symlinks and devices */
344/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 463 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
345 (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ 464 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
346 465 if (decode_sfu_inode(inode,
466 le64_to_cpu(pfindData->EndOfFile),
467 search_path,
468 cifs_sb, xid)) {
469 cFYI(1,("Unrecognized sfu inode type"));
470 }
471 cFYI(1,("sfu mode 0%o",inode->i_mode));
347 } else { 472 } else {
348 inode->i_mode |= S_IFREG; 473 inode->i_mode |= S_IFREG;
349 /* treat the dos attribute of read-only as read-only 474 /* treat the dos attribute of read-only as read-only
@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode,
368 493
369 /* BB fill in uid and gid here? with help from winbind? 494 /* BB fill in uid and gid here? with help from winbind?
370 or retrieve from NTFS stream extended attribute */ 495 or retrieve from NTFS stream extended attribute */
371 if (atomic_read(&cifsInfo->inUse) == 0) { 496 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
497 /* fill in uid, gid, mode from server ACL */
498 get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
499 } else if (atomic_read(&cifsInfo->inUse) == 0) {
372 inode->i_uid = cifs_sb->mnt_uid; 500 inode->i_uid = cifs_sb->mnt_uid;
373 inode->i_gid = cifs_sb->mnt_gid; 501 inode->i_gid = cifs_sb->mnt_gid;
374 /* set so we do not keep refreshing these fields with 502 /* set so we do not keep refreshing these fields with
@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode,
377 } 505 }
378 506
379 if (S_ISREG(inode->i_mode)) { 507 if (S_ISREG(inode->i_mode)) {
380 cFYI(1, (" File inode ")); 508 cFYI(1, ("File inode"));
381 inode->i_op = &cifs_file_inode_ops; 509 inode->i_op = &cifs_file_inode_ops;
382 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 510 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
383 inode->i_fop = &cifs_file_direct_ops; 511 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
384 else 512 inode->i_fop =
513 &cifs_file_direct_nobrl_ops;
514 else
515 inode->i_fop = &cifs_file_direct_ops;
516 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
517 inode->i_fop = &cifs_file_nobrl_ops;
518 else /* not direct, send byte range locks */
385 inode->i_fop = &cifs_file_ops; 519 inode->i_fop = &cifs_file_ops;
386 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 520
387 inode->i_fop->lock = NULL;
388 inode->i_data.a_ops = &cifs_addr_ops; 521 inode->i_data.a_ops = &cifs_addr_ops;
389 if(pTcon->ses->server->maxBuf < 522 if(pTcon->ses->server->maxBuf <
390 4096 + MAX_CIFS_HDR_SIZE) 523 4096 + MAX_CIFS_HDR_SIZE)
391 inode->i_data.a_ops->readpages = NULL; 524 inode->i_data.a_ops->readpages = NULL;
392 } else if (S_ISDIR(inode->i_mode)) { 525 } else if (S_ISDIR(inode->i_mode)) {
393 cFYI(1, (" Directory inode ")); 526 cFYI(1, ("Directory inode"));
394 inode->i_op = &cifs_dir_inode_ops; 527 inode->i_op = &cifs_dir_inode_ops;
395 inode->i_fop = &cifs_dir_ops; 528 inode->i_fop = &cifs_dir_ops;
396 } else if (S_ISLNK(inode->i_mode)) { 529 } else if (S_ISLNK(inode->i_mode)) {
397 cFYI(1, (" Symbolic Link inode ")); 530 cFYI(1, ("Symbolic Link inode"));
398 inode->i_op = &cifs_symlink_inode_ops; 531 inode->i_op = &cifs_symlink_inode_ops;
399 } else { 532 } else {
400 init_special_inode(inode, inode->i_mode, 533 init_special_inode(inode, inode->i_mode,
@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
431 struct cifsInodeInfo *cifsInode; 564 struct cifsInodeInfo *cifsInode;
432 FILE_BASIC_INFO *pinfo_buf; 565 FILE_BASIC_INFO *pinfo_buf;
433 566
434 cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); 567 cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
435 568
436 xid = GetXid(); 569 xid = GetXid();
437 570
@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
651 char *full_path = NULL; 784 char *full_path = NULL;
652 struct cifsInodeInfo *cifsInode; 785 struct cifsInodeInfo *cifsInode;
653 786
654 cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); 787 cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
655 788
656 xid = GetXid(); 789 xid = GetXid();
657 790
@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
970 1103
971 xid = GetXid(); 1104 xid = GetXid();
972 1105
973 cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1106 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
974 direntry->d_name.name, attrs->ia_valid)); 1107 direntry->d_name.name, attrs->ia_valid));
975 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); 1108 cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
976 pTcon = cifs_sb->tcon; 1109 pTcon = cifs_sb->tcon;
@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1086 cifs_sb->mnt_cifs_flags & 1219 cifs_sb->mnt_cifs_flags &
1087 CIFS_MOUNT_MAP_SPECIAL_CHR); 1220 CIFS_MOUNT_MAP_SPECIAL_CHR);
1088 else if (attrs->ia_valid & ATTR_MODE) { 1221 else if (attrs->ia_valid & ATTR_MODE) {
1222 rc = 0;
1089 if ((mode & S_IWUGO) == 0) /* not writeable */ { 1223 if ((mode & S_IWUGO) == 0) /* not writeable */ {
1090 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) 1224 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
1091 time_buf.Attributes = 1225 time_buf.Attributes =
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 34a06692e4fa..ca27a82c54cd 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
678 __u16 temp; 678 __u16 temp;
679 679
680 if(!mapChars) 680 if(!mapChars)
681 return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); 681 return cifs_strtoUCS(target, source, PATH_MAX, cp);
682 682
683 for(i = 0, j = 0; i < maxlen; j++) { 683 for(i = 0, j = 0; i < maxlen; j++) {
684 src_char = source[i]; 684 src_char = source[i];
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index a86bd1c07602..9bdaaecae36f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
142 tmp_inode->i_gid = cifs_sb->mnt_gid; 142 tmp_inode->i_gid = cifs_sb->mnt_gid;
143 /* set default mode. will override for dirs below */ 143 /* set default mode. will override for dirs below */
144 tmp_inode->i_mode = cifs_sb->mnt_file_mode; 144 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
145 } else {
146 /* mask off the type bits since it gets set
147 below and we do not want to get two type
148 bits set */
149 tmp_inode->i_mode &= ~S_IFMT;
145 } 150 }
146 151
147 if (attr & ATTR_DIRECTORY) { 152 if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
152 } 157 }
153 tmp_inode->i_mode |= S_IFDIR; 158 tmp_inode->i_mode |= S_IFDIR;
154 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 159 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
155 (attr & ATTR_SYSTEM) && (end_of_file == 0)) { 160 (attr & ATTR_SYSTEM)) {
156 *pobject_type = DT_FIFO; 161 if (end_of_file == 0) {
157 tmp_inode->i_mode |= S_IFIFO; 162 *pobject_type = DT_FIFO;
158/* BB Finish for SFU style symlinks and devies */ 163 tmp_inode->i_mode |= S_IFIFO;
159/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 164 } else {
160 (attr & ATTR_SYSTEM) && ) { */ 165 /* rather than get the type here, we mark the
166 inode as needing revalidate and get the real type
167 (blk vs chr vs. symlink) later ie in lookup */
168 *pobject_type = DT_REG;
169 tmp_inode->i_mode |= S_IFREG;
170 cifsInfo->time = 0;
171 }
161/* we no longer mark these because we could not follow them */ 172/* we no longer mark these because we could not follow them */
162/* } else if (attr & ATTR_REPARSE) { 173/* } else if (attr & ATTR_REPARSE) {
163 *pobject_type = DT_LNK; 174 *pobject_type = DT_LNK;
@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode,
193 if (S_ISREG(tmp_inode->i_mode)) { 204 if (S_ISREG(tmp_inode->i_mode)) {
194 cFYI(1, ("File inode")); 205 cFYI(1, ("File inode"));
195 tmp_inode->i_op = &cifs_file_inode_ops; 206 tmp_inode->i_op = &cifs_file_inode_ops;
196 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 207 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
197 tmp_inode->i_fop = &cifs_file_direct_ops; 208 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
209 tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
210 else
211 tmp_inode->i_fop = &cifs_file_direct_ops;
212
213 } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
214 tmp_inode->i_fop = &cifs_file_nobrl_ops;
198 else 215 else
199 tmp_inode->i_fop = &cifs_file_ops; 216 tmp_inode->i_fop = &cifs_file_ops;
200 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 217 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
@@ -258,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
258 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); 275 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
259 276
260 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 277 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
278 /* since we set the inode type below we need to mask off type
279 to avoid strange results if bits above were corrupt */
280 tmp_inode->i_mode &= ~S_IFMT;
261 if (type == UNIX_FILE) { 281 if (type == UNIX_FILE) {
262 *pobject_type = DT_REG; 282 *pobject_type = DT_REG;
263 tmp_inode->i_mode |= S_IFREG; 283 tmp_inode->i_mode |= S_IFREG;
@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
283 } else if (type == UNIX_SOCKET) { 303 } else if (type == UNIX_SOCKET) {
284 *pobject_type = DT_SOCK; 304 *pobject_type = DT_SOCK;
285 tmp_inode->i_mode |= S_IFSOCK; 305 tmp_inode->i_mode |= S_IFSOCK;
306 } else {
307 /* safest to just call it a file */
308 *pobject_type = DT_REG;
309 tmp_inode->i_mode |= S_IFREG;
310 cFYI(1,("unknown inode type %d",type));
286 } 311 }
287 312
288 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 313 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
@@ -699,7 +724,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
699 (__le16 *)filename, len/2, nlt); 724 (__le16 *)filename, len/2, nlt);
700 else 725 else
701 pqst->len = cifs_strfromUCS_le((char *)pqst->name, 726 pqst->len = cifs_strfromUCS_le((char *)pqst->name,
702 (wchar_t *)filename,len/2,nlt); 727 (__le16 *)filename,len/2,nlt);
703 } else { 728 } else {
704 pqst->name = filename; 729 pqst->name = filename;
705 pqst->len = len; 730 pqst->len = len;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 981ea0d8b9cd..41a9659c16bc 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -522,7 +522,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
522 sizeof (struct smb_hdr) - 522 sizeof (struct smb_hdr) -
523 4 /* do not count RFC1001 header */ + 523 4 /* do not count RFC1001 header */ +
524 (2 * in_buf->WordCount) + 2 /* bcc */ ) 524 (2 * in_buf->WordCount) + 2 /* bcc */ )
525 BCC(in_buf) = le16_to_cpu(BCC(in_buf)); 525 BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
526 } else { 526 } else {
527 rc = -EIO; 527 rc = -EIO;
528 cFYI(1,("Bad MID state?")); 528 cFYI(1,("Bad MID state?"));
@@ -786,7 +786,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
786 sizeof (struct smb_hdr) - 786 sizeof (struct smb_hdr) -
787 4 /* do not count RFC1001 header */ + 787 4 /* do not count RFC1001 header */ +
788 (2 * out_buf->WordCount) + 2 /* bcc */ ) 788 (2 * out_buf->WordCount) + 2 /* bcc */ )
789 BCC(out_buf) = le16_to_cpu(BCC(out_buf)); 789 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
790 } else { 790 } else {
791 rc = -EIO; 791 rc = -EIO;
792 cERROR(1,("Bad MID state? ")); 792 cERROR(1,("Bad MID state? "));