Commit 252ec9e2 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6

parents d4892279 1e6b39fb
...@@ -3,6 +3,8 @@ Version 1.39 ...@@ -3,6 +3,8 @@ Version 1.39
Defer close of a file handle slightly if pending writes depend on that file handle Defer close of a file handle slightly if pending writes depend on that file handle
(this reduces the EBADF bad file handle errors that can be logged under heavy (this reduces the EBADF bad file handle errors that can be logged under heavy
stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
Unix Extensions. Fix setfacl/getfacl on bigendian.
Version 1.38 Version 1.38
------------ ------------
......
/* /*
* fs/cifs/cifs_unicode.c * fs/cifs/cifs_unicode.c
* *
* Copyright (c) International Business Machines Corp., 2000,2002 * Copyright (c) International Business Machines Corp., 2000,2005
* Modified by Steve French (sfrench@us.ibm.com) * Modified by Steve French (sfrench@us.ibm.com)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
*/ */
int int
cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ cifs_strfromUCS_le(char *to, const __le16 * from,
int len, const struct nls_table *codepage) int len, const struct nls_table *codepage)
{ {
int i; int i;
...@@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ ...@@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
* *
*/ */
int int
cifs_strtoUCS(wchar_t * to, const char *from, int len, cifs_strtoUCS(__le16 * to, const char *from, int len,
const struct nls_table *codepage) const struct nls_table *codepage)
{ {
int charlen; int charlen;
int i; int i;
wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */
for (i = 0; len && *from; i++, from += charlen, len -= charlen) { for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
/* works for 2.4.0 kernel or later */ /* works for 2.4.0 kernel or later */
charlen = codepage->char2uni(from, len, &to[i]); charlen = codepage->char2uni(from, len, &wchar_to[i]);
if (charlen < 1) { if (charlen < 1) {
cERROR(1, cERROR(1,
("cifs_strtoUCS: char2uni returned %d", ("cifs_strtoUCS: char2uni returned %d",
charlen)); charlen));
/* A question mark */ /* A question mark */
to[i] = (wchar_t)cpu_to_le16(0x003f); to[i] = cpu_to_le16(0x003f);
charlen = 1; charlen = 1;
} else } else
to[i] = (wchar_t)cpu_to_le16(to[i]); to[i] = cpu_to_le16(wchar_to[i]);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Convert a unicode character to upper or lower case using * Convert a unicode character to upper or lower case using
* compressed tables. * compressed tables.
* *
* Copyright (c) International Business Machines Corp., 2000,2002 * Copyright (c) International Business Machines Corp., 2000,2005555555555555555555555555555555555555555555555555555555
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[]; ...@@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[];
#endif /* UNIUPR_NOLOWER */ #endif /* UNIUPR_NOLOWER */
#ifdef __KERNEL__ #ifdef __KERNEL__
int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *); int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *); int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
#endif #endif
/* /*
......
...@@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_ ...@@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
char temp_hash[16]; char temp_hash[16];
struct HMACMD5Context ctx; struct HMACMD5Context ctx;
char * ucase_buf; char * ucase_buf;
wchar_t * unicode_buf; __le16 * unicode_buf;
unsigned int i,user_name_len,dom_name_len; unsigned int i,user_name_len,dom_name_len;
if(ses == NULL) if(ses == NULL)
......
...@@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type, ...@@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type,
return sb; return sb;
} }
static ssize_t static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, unsigned long nr_segs, loff_t *ppos)
loff_t * poffset)
{ {
if(file->f_dentry == NULL) struct inode *inode = file->f_dentry->d_inode;
return -EIO; ssize_t written;
else if(file->f_dentry->d_inode == NULL)
return -EIO;
cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) { written = generic_file_writev(file, iov, nr_segs, ppos);
return generic_file_read(file,read_data,read_size,poffset); if (!CIFS_I(inode)->clientCanCacheAll)
} else { filemap_fdatawrite(inode->i_mapping);
/* BB do we need to lock inode from here until after invalidate? */ return written;
/* if(file->f_dentry->d_inode->i_mapping) {
filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
}*/
/* cifs_revalidate(file->f_dentry);*/ /* BB fixme */
/* BB we should make timer configurable - perhaps
by simply calling cifs_revalidate here */
/* invalidate_remote_inode(file->f_dentry->d_inode);*/
return generic_file_read(file,read_data,read_size,poffset);
}
} }
static ssize_t static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
cifs_write_wrapper(struct file * file, const char __user *write_data, size_t count, loff_t pos)
size_t write_size, loff_t * poffset)
{ {
struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
ssize_t written; ssize_t written;
if(file->f_dentry == NULL) written = generic_file_aio_write(iocb, buf, count, pos);
return -EIO; if (!CIFS_I(inode)->clientCanCacheAll)
else if(file->f_dentry->d_inode == NULL) filemap_fdatawrite(inode->i_mapping);
return -EIO;
cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
written = generic_file_write(file,write_data,write_size,poffset);
if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll) {
if(file->f_dentry->d_inode->i_mapping) {
filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
}
}
return written; return written;
} }
static struct file_system_type cifs_fs_type = { static struct file_system_type cifs_fs_type = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "cifs", .name = "cifs",
...@@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = { ...@@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = {
}; };
struct file_operations cifs_file_ops = { struct file_operations cifs_file_ops = {
.read = cifs_read_wrapper, .read = do_sync_read,
.write = cifs_write_wrapper, .write = do_sync_write,
.readv = generic_file_readv,
.writev = cifs_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.lock = cifs_lock, .lock = cifs_lock,
...@@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = { ...@@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = {
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
.readv = generic_file_readv,
.writev = generic_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.dir_notify = cifs_dir_notify, .dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */ #endif /* CONFIG_CIFS_EXPERIMENTAL */
}; };
...@@ -631,6 +604,46 @@ struct file_operations cifs_file_direct_ops = { ...@@ -631,6 +604,46 @@ struct file_operations cifs_file_direct_ops = {
.ioctl = cifs_ioctl, .ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */ #endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
struct file_operations cifs_file_nobrl_ops = {
.read = do_sync_read,
.write = do_sync_write,
.readv = generic_file_readv,
.writev = cifs_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
.open = cifs_open,
.release = cifs_close,
.fsync = cifs_fsync,
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
struct file_operations cifs_file_direct_nobrl_ops = {
/* no mmap, no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
.read = cifs_user_read,
.write = cifs_user_write,
.open = cifs_open,
.release = cifs_close,
.fsync = cifs_fsync,
.flush = cifs_flush,
.sendfile = generic_file_sendfile, /* BB removeme BB */
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify, .dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */ #endif /* CONFIG_CIFS_EXPERIMENTAL */
......
...@@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops; ...@@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops;
/* Functions related to files and directories */ /* Functions related to files and directories */
extern struct file_operations cifs_file_ops; extern struct file_operations cifs_file_ops;
extern struct file_operations cifs_file_direct_ops; /* if directio mount */ extern struct file_operations cifs_file_direct_ops; /* if directio mount */
extern struct file_operations cifs_file_nobrl_ops;
extern struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */
extern int cifs_open(struct inode *inode, struct file *file); extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file); extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file); extern int cifs_closedir(struct inode *inode, struct file *file);
......
...@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp { ...@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
__u16 ByteCount; __u16 ByteCount;
} __attribute__((packed)) LOGOFF_ANDX_RSP; } __attribute__((packed)) LOGOFF_ANDX_RSP;
typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
tree_connect PDU to effect disconnect */
/* tdis is probably simplest SMB PDU */
struct { struct {
struct smb_hdr hdr; /* wct = 0 */ struct smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */ __u16 ByteCount; /* bcc = 0 */
...@@ -2025,6 +2027,12 @@ typedef struct { ...@@ -2025,6 +2027,12 @@ typedef struct {
} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
struct win_dev {
unsigned char type[8]; /* IntxCHR or IntxBLK */
__le64 major;
__le64 minor;
} __attribute__((packed));
struct gea { struct gea {
unsigned char name_len; unsigned char name_len;
char name[1]; char name[1];
......
...@@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, ...@@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int bytes_returned, wct; int bytes_returned, wct;
int smb_hdr_len; int smb_hdr_len;
cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ /* BB removeme BB */
cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
if(tcon->ses->capabilities & CAP_LARGE_FILES) if(tcon->ses->capabilities & CAP_LARGE_FILES)
wct = 14; wct = 14;
else else
...@@ -1553,7 +1555,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -1553,7 +1555,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
/* find define for this maxpathcomponent */ /* find define for this maxpathcomponent */
, nls_codepage); , nls_codepage);
name_len++; /* trailing null */ name_len++; /* trailing null */
...@@ -1577,7 +1579,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -1577,7 +1579,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
data_offset = (char *) (&pSMB->hdr.Protocol) + offset; data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len_target = name_len_target =
cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
/* find define for this maxpathcomponent */ /* find define for this maxpathcomponent */
, nls_codepage); , nls_codepage);
name_len_target++; /* trailing null */ name_len_target++; /* trailing null */
...@@ -1803,7 +1805,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -1803,7 +1805,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
/* find define for this maxpathcomponent */ /* find define for this maxpathcomponent */
, nls_codepage); , nls_codepage);
name_len++; /* trailing null */ name_len++; /* trailing null */
...@@ -1860,7 +1862,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -1860,7 +1862,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
min_t(const int, buflen,count) / 2); min_t(const int, buflen,count) / 2);
/* BB FIXME investigate remapping reserved chars here */ /* BB FIXME investigate remapping reserved chars here */
cifs_strfromUCS_le(symlinkinfo, cifs_strfromUCS_le(symlinkinfo,
(wchar_t *) ((char *)&pSMBr->hdr.Protocol + (__le16 *) ((char *)&pSMBr->hdr.Protocol +
data_offset), data_offset),
name_len, nls_codepage); name_len, nls_codepage);
} else { } else {
...@@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
reparse_buf->TargetNameOffset), reparse_buf->TargetNameOffset),
min(buflen/2, reparse_buf->TargetNameLen / 2)); min(buflen/2, reparse_buf->TargetNameLen / 2));
cifs_strfromUCS_le(symlinkinfo, cifs_strfromUCS_le(symlinkinfo,
(wchar_t *) (reparse_buf->LinkNamesBuf + (__le16 *) (reparse_buf->LinkNamesBuf +
reparse_buf->TargetNameOffset), reparse_buf->TargetNameOffset),
name_len, nls_codepage); name_len, nls_codepage);
} else { /* ASCII names */ } else { /* ASCII names */
...@@ -1983,9 +1985,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -1983,9 +1985,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace) static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace)
{ {
/* u8 cifs fields do not need le conversion */ /* u8 cifs fields do not need le conversion */
ace->e_perm = (__u16)cifs_ace->cifs_e_perm; ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
ace->e_tag = (__u16)cifs_ace->cifs_e_tag; ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid); ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
/* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */ /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
return; return;
...@@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen, ...@@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
} else if(size > buflen) { } else if(size > buflen) {
return -ERANGE; return -ERANGE;
} else /* buffer big enough */ { } else /* buffer big enough */ {
local_acl->a_version = POSIX_ACL_XATTR_VERSION; local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
for(i = 0;i < count ;i++) { for(i = 0;i < count ;i++) {
cifs_convert_ace(&local_acl->a_entries[i],pACE); cifs_convert_ace(&local_acl->a_entries[i],pACE);
pACE ++; pACE ++;
...@@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, ...@@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
{ {
__u16 rc = 0; /* 0 = ACL converted ok */ __u16 rc = 0; /* 0 = ACL converted ok */
cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm); cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag); cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
/* BB is there a better way to handle the large uid? */ /* BB is there a better way to handle the large uid? */
if(local_ace->e_id == -1) { if(local_ace->e_id == cpu_to_le32(-1)) {
/* Probably no need to le convert -1 on any arch but can not hurt */ /* Probably no need to le convert -1 on any arch but can not hurt */
cifs_ace->cifs_uid = cpu_to_le64(-1); cifs_ace->cifs_uid = cpu_to_le64(-1);
} else } else
cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id); cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
/*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/ /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
return rc; return rc;
} }
...@@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl ...@@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
count = posix_acl_xattr_count((size_t)buflen); count = posix_acl_xattr_count((size_t)buflen);
cFYI(1,("setting acl with %d entries from buf of length %d and version of %d", cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
count,buflen,local_acl->a_version)); count, buflen, le32_to_cpu(local_acl->a_version)));
if(local_acl->a_version != 2) { if(le32_to_cpu(local_acl->a_version) != 2) {
cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version)); cFYI(1,("unknown POSIX ACL version %d",
le32_to_cpu(local_acl->a_version)));
return 0; return 0;
} }
cifs_acl->version = cpu_to_le16(1); cifs_acl->version = cpu_to_le16(1);
if(acl_type == ACL_TYPE_ACCESS) if(acl_type == ACL_TYPE_ACCESS)
cifs_acl->access_entry_count = count; cifs_acl->access_entry_count = cpu_to_le16(count);
else if(acl_type == ACL_TYPE_DEFAULT) else if(acl_type == ACL_TYPE_DEFAULT)
cifs_acl->default_entry_count = count; cifs_acl->default_entry_count = cpu_to_le16(count);
else { else {
cFYI(1,("unknown ACL type %d",acl_type)); cFYI(1,("unknown ACL type %d",acl_type));
return 0; return 0;
...@@ -3203,7 +3206,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -3203,7 +3206,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset); temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
cifs_strfromUCS_le(*targetUNCs, cifs_strfromUCS_le(*targetUNCs,
(wchar_t *) temp, name_len, nls_codepage); (__le16 *) temp, name_len, nls_codepage);
} else { } else {
strncpy(*targetUNCs,temp,name_len); strncpy(*targetUNCs,temp,name_len);
} }
......
...@@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bytes_returned = 0; /* skill null user */ bytes_returned = 0; /* skill null user */
else else
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
nls_codepage); nls_codepage);
/* convert number of 16 bit words to bytes */ /* convert number of 16 bit words to bytes */
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* trailing null */ bcc_ptr += 2; /* trailing null */
if (domain == NULL) if (domain == NULL)
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, cifs_strtoUCS((__le16 *) bcc_ptr,
"CIFS_LINUX_DOM", 32, nls_codepage); "CIFS_LINUX_DOM", 32, nls_codepage);
else else
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
nls_codepage); nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
32, nls_codepage); 32, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
32, nls_codepage); 32, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
64, nls_codepage); 64, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
...@@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if(ses->serverOS == NULL) if(ses->serverOS == NULL)
goto sesssetup_nomem; goto sesssetup_nomem;
cifs_strfromUCS_le(ses->serverOS, cifs_strfromUCS_le(ses->serverOS,
(wchar_t *)bcc_ptr, len,nls_codepage); (__le16 *)bcc_ptr, len,nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
remaining_words -= len + 1; remaining_words -= len + 1;
ses->serverOS[2 * len] = 0; ses->serverOS[2 * len] = 0;
...@@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if(ses->serverNOS == NULL) if(ses->serverNOS == NULL)
goto sesssetup_nomem; goto sesssetup_nomem;
cifs_strfromUCS_le(ses->serverNOS, cifs_strfromUCS_le(ses->serverNOS,
(wchar_t *)bcc_ptr,len,nls_codepage); (__le16 *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
ses->serverNOS[2 * len] = 0; ses->serverNOS[2 * len] = 0;
ses->serverNOS[1 + (2 * len)] = 0; ses->serverNOS[1 + (2 * len)] = 0;
...@@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if(ses->serverDomain == NULL) if(ses->serverDomain == NULL)
goto sesssetup_nomem; goto sesssetup_nomem;
cifs_strfromUCS_le(ses->serverDomain, cifs_strfromUCS_le(ses->serverDomain,
(wchar_t *)bcc_ptr,len,nls_codepage); (__le16 *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
ses->serverDomain[2*len] = 0; ses->serverDomain[2*len] = 0;
ses->serverDomain[1+(2*len)] = 0; ses->serverDomain[1+(2*len)] = 0;
...@@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr++; bcc_ptr++;
} }
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage); cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */ bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
bcc_ptr += 2; /* trailing null */ bcc_ptr += 2; /* trailing null */
if (domain == NULL) if (domain == NULL)
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, cifs_strtoUCS((__le16 *) bcc_ptr,
"CIFS_LINUX_DOM", 32, nls_codepage); "CIFS_LINUX_DOM", 32, nls_codepage);
else else
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
nls_codepage); nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
32, nls_codepage); 32, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
nls_codepage); nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
64, nls_codepage); 64, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
...@@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses->serverOS = ses->serverOS =
kzalloc(2 * (len + 1), GFP_KERNEL); kzalloc(2 * (len + 1), GFP_KERNEL);
cifs_strfromUCS_le(ses->serverOS, cifs_strfromUCS_le(ses->serverOS,
(wchar_t *) (__le16 *)
bcc_ptr, len, bcc_ptr, len,
nls_codepage); nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
...@@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
kzalloc(2 * (len + 1), kzalloc(2 * (len + 1),
GFP_KERNEL); GFP_KERNEL);
cifs_strfromUCS_le(ses->serverNOS, cifs_strfromUCS_le(ses->serverNOS,
(wchar_t *)bcc_ptr, (__le16 *)bcc_ptr,
len, len,
nls_codepage); nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
...@@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
/* last string is not always null terminated (for e.g. for Windows XP & 2000) */ /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL); ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
cifs_strfromUCS_le(ses->serverDomain, cifs_strfromUCS_le(ses->serverDomain,
(wchar_t *)bcc_ptr, (__le16 *)bcc_ptr,
len, len, nls_codepage);
nls_codepage);
bcc_ptr += 2*(len+1); bcc_ptr += 2*(len+1);
ses->serverDomain[2*len] = 0; ses->serverDomain[2*len] = 0;
ses->serverDomain[1+(2*len)] = 0; ses->serverDomain[1+(2*len)] = 0;
...@@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
} }
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
32, nls_codepage); 32, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
nls_codepage); nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null terminate Linux version */ bcc_ptr += 2; /* null terminate Linux version */
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
64, nls_codepage); 64, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
*(bcc_ptr + 1) = 0; *(bcc_ptr + 1) = 0;
...@@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
ses->serverOS = ses->serverOS =
kzalloc(2 * (len + 1), GFP_KERNEL); kzalloc(2 * (len + 1), GFP_KERNEL);
cifs_strfromUCS_le(ses->serverOS, cifs_strfromUCS_le(ses->serverOS,
(wchar_t *) (__le16 *)
bcc_ptr, len, bcc_ptr, len,
nls_codepage); nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
...@@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
GFP_KERNEL); GFP_KERNEL);
cifs_strfromUCS_le(ses-> cifs_strfromUCS_le(ses->
serverNOS, serverNOS,
(wchar_t *) (__le16 *)
bcc_ptr, bcc_ptr,
len, len,
nls_codepage); nls_codepage);
...@@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
1), 1),
GFP_KERNEL); GFP_KERNEL);
cifs_strfromUCS_le cifs_strfromUCS_le
(ses-> (ses->serverDomain,
serverDomain, (__le16 *)bcc_ptr,
(wchar_t *) len, nls_codepage);
bcc_ptr, len,
nls_codepage);
bcc_ptr += bcc_ptr +=
2 * (len + 1); 2 * (len + 1);
ses-> ses->serverDomain[2*len]
serverDomain[2
* len]
= 0; = 0;
ses-> ses->serverDomain
serverDomain[1 [1 + (2 * len)]
+
(2
*
len)]
= 0; = 0;
} /* else no more room so create dummy domain string */ } /* else no more room so create dummy domain string */
else else
...@@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->DomainName.MaximumLength = 0; SecurityBlob->DomainName.MaximumLength = 0;
} else { } else {
__u16 len = __u16 len =
cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64, cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
nls_codepage); nls_codepage);
len *= 2; len *= 2;
SecurityBlob->DomainName.MaximumLength = SecurityBlob->DomainName.MaximumLength =
...@@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->UserName.MaximumLength = 0; SecurityBlob->UserName.MaximumLength = 0;
} else { } else {
__u16 len = __u16 len =
cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64, cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
nls_codepage); nls_codepage);
len *= 2; len *= 2;
SecurityBlob->UserName.MaximumLength = SecurityBlob->UserName.MaximumLength =
...@@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
cpu_to_le16(len); cpu_to_le16(len);
} }
/* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage); /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
SecurityBlob->WorkstationName.Length *= 2; SecurityBlob->WorkstationName.Length *= 2;
SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length); SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength); SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
...@@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr++; bcc_ptr++;
} }
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ", cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
32, nls_codepage); 32, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32, cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
nls_codepage); nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; /* null term version string */ bcc_ptr += 2; /* null term version string */
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS, cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
64, nls_codepage); 64, nls_codepage);
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
*(bcc_ptr + 1) = 0; *(bcc_ptr + 1) = 0;
...@@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses->serverOS = ses->serverOS =
kzalloc(2 * (len + 1), GFP_KERNEL); kzalloc(2 * (len + 1), GFP_KERNEL);
cifs_strfromUCS_le(ses->serverOS, cifs_strfromUCS_le(ses->serverOS,
(wchar_t *) (__le16 *)
bcc_ptr, len, bcc_ptr, len,
nls_codepage); nls_codepage);
bcc_ptr += 2 * (len + 1); bcc_ptr += 2 * (len + 1);
...@@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
GFP_KERNEL); GFP_KERNEL);
cifs_strfromUCS_le(ses-> cifs_strfromUCS_le(ses->
serverNOS, serverNOS,
(wchar_t *) (__le16 *)
bcc_ptr, bcc_ptr,
len, len,
nls_codepage); nls_codepage);
...@@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
cifs_strfromUCS_le cifs_strfromUCS_le
(ses-> (ses->
serverDomain, serverDomain,
(wchar_t *) (__le16 *)
bcc_ptr, len, bcc_ptr, len,
nls_codepage); nls_codepage);
bcc_ptr += bcc_ptr +=
...@@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if (ses->capabilities & CAP_UNICODE) { if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE; smb_buffer->Flags2 |= SMBFLG2_UNICODE;
length = length =
cifs_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage); cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
bcc_ptr += 2; /* skip trailing null */ bcc_ptr += 2; /* skip trailing null */
} else { /* ASCII */ } else { /* ASCII */
...@@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
tcon->nativeFileSystem = tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL); kzalloc(length + 2, GFP_KERNEL);
cifs_strfromUCS_le(tcon->nativeFileSystem, cifs_strfromUCS_le(tcon->nativeFileSystem,
(wchar_t *) bcc_ptr, (__le16 *) bcc_ptr,
length, nls_codepage); length, nls_codepage);
bcc_ptr += 2 * length; bcc_ptr += 2 * length;
bcc_ptr[0] = 0; /* null terminate the string */ bcc_ptr[0] = 0; /* null terminate the string */
......
...@@ -292,7 +292,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -292,7 +292,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
return rc; return rc;
} }
int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
dev_t device_number)
{ {
int rc = -EPERM; int rc = -EPERM;
int xid; int xid;
...@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev ...@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
if(!rc) { if(!rc) {
/* BB Do not bother to decode buf since no /* BB Do not bother to decode buf since no
local inode yet to put timestamps in */ local inode yet to put timestamps in,
but we can reuse it safely */
int bytes_written;
struct win_dev *pdev;
pdev = (struct win_dev *)buf;
if(S_ISCHR(mode)) {
memcpy(pdev->type, "IntxCHR", 8);
pdev->major =
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
} else if(S_ISBLK(mode)) {
memcpy(pdev->type, "IntxBLK", 8);
pdev->major =
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
} /* else if(S_ISFIFO */
CIFSSMBClose(xid, pTcon, fileHandle); CIFSSMBClose(xid, pTcon, fileHandle);
d_drop(direntry); d_drop(direntry);
} }
......
...@@ -489,8 +489,10 @@ int cifs_close(struct inode *inode, struct file *file) ...@@ -489,8 +489,10 @@ int cifs_close(struct inode *inode, struct file *file)
the struct would be in each open file, the struct would be in each open file,
but this should give enough time to but this should give enough time to
clear the socket */ clear the socket */
write_unlock(&file->f_owner.lock);
cERROR(1,("close with pending writes")); cERROR(1,("close with pending writes"));
msleep(timeout); msleep(timeout);
write_lock(&file->f_owner.lock);
timeout *= 4; timeout *= 4;
} }
write_unlock(&file->f_owner.lock); write_unlock(&file->f_owner.lock);
......
...@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
char *tmp_path; char *tmp_path;
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
cFYI(1, (" Getting info on %s ", search_path)); cFYI(1, ("Getting info on %s ", search_path));
/* could have done a find first instead but this returns more info */ /* could have done a find first instead but this returns more info */
rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
...@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode = *pinode; inode = *pinode;
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
cFYI(1, (" Old time %ld ", cifsInfo->time)); cFYI(1, ("Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, ("New time %ld ", cifsInfo->time));
/* this is ok to set on every inode revalidate */ /* this is ok to set on every inode revalidate */
atomic_set(&cifsInfo->inUse,1); atomic_set(&cifsInfo->inUse,1);
...@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_ctime = inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
inode->i_mode = le64_to_cpu(findData.Permissions); inode->i_mode = le64_to_cpu(findData.Permissions);
/* since we set the inode type below we need to mask off
to avoid strange results if bits set above */
inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) { if (type == UNIX_FILE) {
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
} else if (type == UNIX_SYMLINK) { } else if (type == UNIX_SYMLINK) {
...@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_mode |= S_IFIFO; inode->i_mode |= S_IFIFO;
} else if (type == UNIX_SOCKET) { } else if (type == UNIX_SOCKET) {
inode->i_mode |= S_IFSOCK; inode->i_mode |= S_IFSOCK;
} else {
/* safest to call it a file if we do not know */
inode->i_mode |= S_IFREG;
cFYI(1,("unknown type %d",type));
} }
inode->i_uid = le64_to_cpu(findData.Uid); inode->i_uid = le64_to_cpu(findData.Uid);
inode->i_gid = le64_to_cpu(findData.Gid); inode->i_gid = le64_to_cpu(findData.Gid);
...@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode,
} }
if (num_of_bytes < end_of_file) if (num_of_bytes < end_of_file)
cFYI(1, ("allocation size less than end of file ")); cFYI(1, ("allocation size less than end of file"));
cFYI(1, cFYI(1,
("Size %ld and blocks %ld", ("Size %ld and blocks %ld",
(unsigned long) inode->i_size, inode->i_blocks)); (unsigned long) inode->i_size, inode->i_blocks));
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode ")); cFYI(1, ("File inode"));
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
inode->i_fop = &cifs_file_direct_ops; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop =
&cifs_file_direct_nobrl_ops;
else else
inode->i_fop = &cifs_file_direct_ops;
} else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_nobrl_ops;
else /* not direct, send byte range locks */
inode->i_fop = &cifs_file_ops; inode->i_fop = &cifs_file_ops;
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop->lock = NULL;
inode->i_data.a_ops = &cifs_addr_ops; inode->i_data.a_ops = &cifs_addr_ops;
/* check if server can support readpages */ /* check if server can support readpages */
if(pTcon->ses->server->maxBuf < if(pTcon->ses->server->maxBuf <
4096 + MAX_CIFS_HDR_SIZE) 4096 + MAX_CIFS_HDR_SIZE)
inode->i_data.a_ops->readpages = NULL; inode->i_data.a_ops->readpages = NULL;
} else if (S_ISDIR(inode->i_mode)) { } else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode")); cFYI(1, ("Directory inode"));
inode->i_op = &cifs_dir_inode_ops; inode->i_op = &cifs_dir_inode_ops;
inode->i_fop = &cifs_dir_ops; inode->i_fop = &cifs_dir_ops;
} else if (S_ISLNK(inode->i_mode)) { } else if (S_ISLNK(inode->i_mode)) {
cFYI(1, (" Symbolic Link inode ")); cFYI(1, ("Symbolic Link inode"));
inode->i_op = &cifs_symlink_inode_ops; inode->i_op = &cifs_symlink_inode_ops;
/* tmp_inode->i_fop = */ /* do not need to set to anything */ /* tmp_inode->i_fop = */ /* do not need to set to anything */
} else { } else {
cFYI(1, (" Init special inode ")); cFYI(1, ("Init special inode"));
init_special_inode(inode, inode->i_mode, init_special_inode(inode, inode->i_mode,
inode->i_rdev); inode->i_rdev);
} }
...@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode,
return rc; return rc;
} }
static int decode_sfu_inode(struct inode * inode, __u64 size,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
{
int rc;
int oplock = FALSE;
__u16 netfid;
struct cifsTconInfo *pTcon = cifs_sb->tcon;
char buf[24];
unsigned int bytes_read;
char * pbuf;
pbuf = buf;
if(size == 0) {
inode->i_mode |= S_IFIFO;
return 0;
} else if (size < 8) {
return -EINVAL; /* EOPNOTSUPP? */
}
rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
CREATE_NOT_DIR, &netfid, &oplock, NULL,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc==0) {
/* Read header */
rc = CIFSSMBRead(xid, pTcon,
netfid,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf);
if((rc == 0) && (bytes_read >= 8)) {
if(memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1,("Block device"));
inode->i_mode |= S_IFBLK;
if(bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
inode->i_rdev = MKDEV(mjr, mnr);
}
} else if(memcmp("IntxCHR", pbuf, 8) == 0) {
cFYI(1,("Char device"));
inode->i_mode |= S_IFCHR;
if(bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
inode->i_rdev = MKDEV(mjr, mnr);
}
} else if(memcmp("IntxLNK", pbuf, 7) == 0) {
cFYI(1,("Symlink"));
inode->i_mode |= S_IFLNK;
} else {
inode->i_mode |= S_IFREG; /* file? */
rc = -EOPNOTSUPP;
}
} else {
inode->i_mode |= S_IFREG; /* then it is a file */
rc = -EOPNOTSUPP; /* or some unknown SFU type */
}
CIFSSMBClose(xid, pTcon, netfid);
}
return rc;
}
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
static int get_sfu_uid_mode(struct inode * inode,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
{
#ifdef CONFIG_CIFS_XATTR
ssize_t rc;
char ea_value[4];
__u32 mode;
rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
ea_value, 4 /* size of buf */, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if(rc < 0)
return (int)rc;
else if (rc > 3) {
mode = le32_to_cpu(*((__le32 *)ea_value));
inode->i_mode &= ~SFBITS_MASK;
cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
cFYI(1,("special mode bits 0%o", mode));
return 0;
} else {
return 0;
}
#else
return -EOPNOTSUPP;
#endif
}
int cifs_get_inode_info(struct inode **pinode, int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path, FILE_ALL_INFO *pfindData, const unsigned char *search_path, FILE_ALL_INFO *pfindData,
struct super_block *sb, int xid) struct super_block *sb, int xid)
...@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode,
char *buf = NULL; char *buf = NULL;
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
cFYI(1,("Getting info on %s ", search_path)); cFYI(1,("Getting info on %s", search_path));
if ((pfindData == NULL) && (*pinode != NULL)) { if ((pfindData == NULL) && (*pinode != NULL)) {
if (CIFS_I(*pinode)->clientCanCacheRead) { if (CIFS_I(*pinode)->clientCanCacheRead) {
...@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode,
inode = *pinode; inode = *pinode;
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
cifsInfo->cifsAttrs = attr; cifsInfo->cifsAttrs = attr;
cFYI(1, (" Old time %ld ", cifsInfo->time)); cFYI(1, ("Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, ("New time %ld ", cifsInfo->time));
/* blksize needs to be multiple of two. So safer to default to /* blksize needs to be multiple of two. So safer to default to
blksize and blkbits set in superblock so 2**blkbits and blksize blksize and blkbits set in superblock so 2**blkbits and blksize
...@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime = inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0, (" Attributes came in as 0x%x ", attr)); cFYI(0, ("Attributes came in as 0x%x ", attr));
/* set default mode. will override for dirs below */ /* set default mode. will override for dirs below */
if (atomic_read(&cifsInfo->inUse) == 0) if (atomic_read(&cifsInfo->inUse) == 0)
/* new inode, can safely set these fields */ /* new inode, can safely set these fields */
inode->i_mode = cifs_sb->mnt_file_mode; inode->i_mode = cifs_sb->mnt_file_mode;
else /* since we set the inode type below we need to mask off
to avoid strange results if type changes and both get orred in */
inode->i_mode &= ~S_IFMT;
/* if (attr & ATTR_REPARSE) */ /* if (attr & ATTR_REPARSE) */
/* We no longer handle these as symlinks because we could not /* We no longer handle these as symlinks because we could not
follow them due to the absolute path with drive letter */ follow them due to the absolute path with drive letter */
...@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode,
(pfindData->EndOfFile == 0)) { (pfindData->EndOfFile == 0)) {
inode->i_mode = cifs_sb->mnt_file_mode; inode->i_mode = cifs_sb->mnt_file_mode;
inode->i_mode |= S_IFIFO; inode->i_mode |= S_IFIFO;
/* BB Finish for SFU style symlinks and devies */ /* BB Finish for SFU style symlinks and devices */
/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
if (decode_sfu_inode(inode,
le64_to_cpu(pfindData->EndOfFile),
search_path,
cifs_sb, xid)) {
cFYI(1,("Unrecognized sfu inode type"));
}
cFYI(1,("sfu mode 0%o",inode->i_mode));
} else { } else {
inode->i_mode |= S_IFREG; inode->i_mode |= S_IFREG;
/* treat the dos attribute of read-only as read-only /* treat the dos attribute of read-only as read-only
...@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode,
/* BB fill in uid and gid here? with help from winbind? /* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */ or retrieve from NTFS stream extended attribute */
if (atomic_read(&cifsInfo->inUse) == 0) { if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
/* fill in uid, gid, mode from server ACL */
get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
} else if (atomic_read(&cifsInfo->inUse) == 0) {
inode->i_uid = cifs_sb->mnt_uid; inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid; inode->i_gid = cifs_sb->mnt_gid;
/* set so we do not keep refreshing these fields with /* set so we do not keep refreshing these fields with
...@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode,
} }
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode ")); cFYI(1, ("File inode"));
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
inode->i_fop = &cifs_file_direct_ops; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop =
&cifs_file_direct_nobrl_ops;
else else
inode->i_fop = &cifs_file_direct_ops;
} else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_nobrl_ops;
else /* not direct, send byte range locks */
inode->i_fop = &cifs_file_ops; inode->i_fop = &cifs_file_ops;
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop->lock = NULL;
inode->i_data.a_ops = &cifs_addr_ops; inode->i_data.a_ops = &cifs_addr_ops;
if(pTcon->ses->server->maxBuf < if(pTcon->ses->server->maxBuf <
4096 + MAX_CIFS_HDR_SIZE) 4096 + MAX_CIFS_HDR_SIZE)
inode->i_data.a_ops->readpages = NULL; inode->i_data.a_ops->readpages = NULL;
} else if (S_ISDIR(inode->i_mode)) { } else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode ")); cFYI(1, ("Directory inode"));
inode->i_op = &cifs_dir_inode_ops; inode->i_op = &cifs_dir_inode_ops;
inode->i_fop = &cifs_dir_ops; inode->i_fop = &cifs_dir_ops;
} else if (S_ISLNK(inode->i_mode)) { } else if (S_ISLNK(inode->i_mode)) {
cFYI(1, (" Symbolic Link inode ")); cFYI(1, ("Symbolic Link inode"));
inode->i_op = &cifs_symlink_inode_ops; inode->i_op = &cifs_symlink_inode_ops;
} else { } else {
init_special_inode(inode, inode->i_mode, init_special_inode(inode, inode->i_mode,
...@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
FILE_BASIC_INFO *pinfo_buf; FILE_BASIC_INFO *pinfo_buf;
cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) ...@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
char *full_path = NULL; char *full_path = NULL;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
xid = GetXid(); xid = GetXid();
cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
direntry->d_name.name, attrs->ia_valid)); direntry->d_name.name, attrs->ia_valid));
cifs_sb = CIFS_SB(direntry->d_inode->i_sb); cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
...@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
else if (attrs->ia_valid & ATTR_MODE) { else if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
if ((mode & S_IWUGO) == 0) /* not writeable */ { if ((mode & S_IWUGO) == 0) /* not writeable */ {
if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
time_buf.Attributes = time_buf.Attributes =
......
...@@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, ...@@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
__u16 temp; __u16 temp;
if(!mapChars) if(!mapChars)
return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); return cifs_strtoUCS(target, source, PATH_MAX, cp);
for(i = 0, j = 0; i < maxlen; j++) { for(i = 0, j = 0; i < maxlen; j++) {
src_char = source[i]; src_char = source[i];
......
...@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode, ...@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_gid = cifs_sb->mnt_gid; tmp_inode->i_gid = cifs_sb->mnt_gid;
/* set default mode. will override for dirs below */ /* set default mode. will override for dirs below */
tmp_inode->i_mode = cifs_sb->mnt_file_mode; tmp_inode->i_mode = cifs_sb->mnt_file_mode;
} else {
/* mask off the type bits since it gets set
below and we do not want to get two type
bits set */
tmp_inode->i_mode &= ~S_IFMT;
} }
if (attr & ATTR_DIRECTORY) { if (attr & ATTR_DIRECTORY) {
...@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode, ...@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
} }
tmp_inode->i_mode |= S_IFDIR; tmp_inode->i_mode |= S_IFDIR;
} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(attr & ATTR_SYSTEM) && (end_of_file == 0)) { (attr & ATTR_SYSTEM)) {
if (end_of_file == 0) {
*pobject_type = DT_FIFO; *pobject_type = DT_FIFO;
tmp_inode->i_mode |= S_IFIFO; tmp_inode->i_mode |= S_IFIFO;
/* BB Finish for SFU style symlinks and devies */ } else {
/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && /* rather than get the type here, we mark the
(attr & ATTR_SYSTEM) && ) { */ inode as needing revalidate and get the real type
(blk vs chr vs. symlink) later ie in lookup */
*pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG;
cifsInfo->time = 0;
}
/* we no longer mark these because we could not follow them */ /* we no longer mark these because we could not follow them */
/* } else if (attr & ATTR_REPARSE) { /* } else if (attr & ATTR_REPARSE) {
*pobject_type = DT_LNK; *pobject_type = DT_LNK;
...@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode, ...@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode,
if (S_ISREG(tmp_inode->i_mode)) { if (S_ISREG(tmp_inode->i_mode)) {
cFYI(1, ("File inode")); cFYI(1, ("File inode"));
tmp_inode->i_op = &cifs_file_inode_ops; tmp_inode->i_op = &cifs_file_inode_ops;
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 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; 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 else
tmp_inode->i_fop = &cifs_file_ops; tmp_inode->i_fop = &cifs_file_ops;
if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 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,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
/* since we set the inode type below we need to mask off type
to avoid strange results if bits above were corrupt */
tmp_inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) { if (type == UNIX_FILE) {
*pobject_type = DT_REG; *pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG; tmp_inode->i_mode |= S_IFREG;
...@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, ...@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
} else if (type == UNIX_SOCKET) { } else if (type == UNIX_SOCKET) {
*pobject_type = DT_SOCK; *pobject_type = DT_SOCK;
tmp_inode->i_mode |= S_IFSOCK; tmp_inode->i_mode |= S_IFSOCK;
} else {
/* safest to just call it a file */
*pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG;
cFYI(1,("unknown inode type %d",type));
} }
tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 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,7 +724,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
(__le16 *)filename, len/2, nlt); (__le16 *)filename, len/2, nlt);
else else
pqst->len = cifs_strfromUCS_le((char *)pqst->name, pqst->len = cifs_strfromUCS_le((char *)pqst->name,
(wchar_t *)filename,len/2,nlt); (__le16 *)filename,len/2,nlt);
} else { } else {
pqst->name = filename; pqst->name = filename;
pqst->len = len; pqst->len = len;
......
...@@ -522,7 +522,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -522,7 +522,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
sizeof (struct smb_hdr) - sizeof (struct smb_hdr) -
4 /* do not count RFC1001 header */ + 4 /* do not count RFC1001 header */ +
(2 * in_buf->WordCount) + 2 /* bcc */ ) (2 * in_buf->WordCount) + 2 /* bcc */ )
BCC(in_buf) = le16_to_cpu(BCC(in_buf)); BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
} else { } else {
rc = -EIO; rc = -EIO;
cFYI(1,("Bad MID state?")); cFYI(1,("Bad MID state?"));
...@@ -786,7 +786,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -786,7 +786,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
sizeof (struct smb_hdr) - sizeof (struct smb_hdr) -
4 /* do not count RFC1001 header */ + 4 /* do not count RFC1001 header */ +
(2 * out_buf->WordCount) + 2 /* bcc */ ) (2 * out_buf->WordCount) + 2 /* bcc */ )
BCC(out_buf) = le16_to_cpu(BCC(out_buf)); BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
} else { } else {
rc = -EIO; rc = -EIO;
cERROR(1,("Bad MID state? ")); cERROR(1,("Bad MID state? "));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment