Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus Torvalds committed Nov 20, 2005
2 parents d489227 + 1e6b39f commit 252ec9e
Show file tree
Hide file tree
Showing 15 changed files with 385 additions and 176 deletions.
2 changes: 2 additions & 0 deletions fs/cifs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Version 1.39
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
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
------------
Expand Down
13 changes: 7 additions & 6 deletions fs/cifs/cifs_unicode.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* 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)
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -31,7 +31,7 @@
*
*/
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 i;
Expand Down Expand Up @@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
*
*/
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)
{
int charlen;
int i;
wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */

for (i = 0; len && *from; i++, from += charlen, len -= charlen) {

/* 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) {
cERROR(1,
("cifs_strtoUCS: char2uni returned %d",
charlen));
/* A question mark */
to[i] = (wchar_t)cpu_to_le16(0x003f);
to[i] = cpu_to_le16(0x003f);
charlen = 1;
} else
to[i] = (wchar_t)cpu_to_le16(to[i]);
to[i] = cpu_to_le16(wchar_to[i]);

}

Expand Down
6 changes: 3 additions & 3 deletions fs/cifs/cifs_unicode.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Convert a unicode character to upper or lower case using
* 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
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[];
#endif /* UNIUPR_NOLOWER */

#ifdef __KERNEL__
int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *);
int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *);
int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
#endif

/*
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
char temp_hash[16];
struct HMACMD5Context ctx;
char * ucase_buf;
wchar_t * unicode_buf;
__le16 * unicode_buf;
unsigned int i,user_name_len,dom_name_len;

if(ses == NULL)
Expand Down
107 changes: 60 additions & 47 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type,
return sb;
}

static ssize_t
cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
loff_t * poffset)
static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos)
{
if(file->f_dentry == NULL)
return -EIO;
else if(file->f_dentry->d_inode == NULL)
return -EIO;

cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
struct inode *inode = file->f_dentry->d_inode;
ssize_t written;

if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
return generic_file_read(file,read_data,read_size,poffset);
} else {
/* BB do we need to lock inode from here until after invalidate? */
/* 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);
}
written = generic_file_writev(file, iov, nr_segs, ppos);
if (!CIFS_I(inode)->clientCanCacheAll)
filemap_fdatawrite(inode->i_mapping);
return written;
}

static ssize_t
cifs_write_wrapper(struct file * file, const char __user *write_data,
size_t write_size, loff_t * poffset)
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
size_t count, loff_t pos)
{
struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
ssize_t written;

if(file->f_dentry == NULL)
return -EIO;
else if(file->f_dentry->d_inode == NULL)
return -EIO;

cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));

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);
}
}
written = generic_file_aio_write(iocb, buf, count, pos);
if (!CIFS_I(inode)->clientCanCacheAll)
filemap_fdatawrite(inode->i_mapping);
return written;
}


static struct file_system_type cifs_fs_type = {
.owner = THIS_MODULE,
.name = "cifs",
Expand Down Expand Up @@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = {
};

struct file_operations cifs_file_ops = {
.read = cifs_read_wrapper,
.write = cifs_write_wrapper,
.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,
.lock = cifs_lock,
Expand All @@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = {
#endif /* CONFIG_CIFS_POSIX */

#ifdef CONFIG_CIFS_EXPERIMENTAL
.readv = generic_file_readv,
.writev = generic_file_writev,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
Expand All @@ -631,6 +604,46 @@ struct file_operations cifs_file_direct_ops = {
.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_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
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
Expand Down
2 changes: 2 additions & 0 deletions fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops;
/* Functions related to files and directories */
extern struct file_operations cifs_file_ops;
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_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file);
Expand Down
10 changes: 9 additions & 1 deletion fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
__u16 ByteCount;
} __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 smb_hdr hdr; /* wct = 0 */
__u16 ByteCount; /* bcc = 0 */
Expand Down Expand Up @@ -2025,6 +2027,12 @@ typedef struct {
} __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 {
unsigned char name_len;
char name[1];
Expand Down
43 changes: 23 additions & 20 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int bytes_returned, wct;
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)
wct = 14;
else
Expand Down Expand Up @@ -1553,7 +1555,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,

if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX
cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
Expand All @@ -1577,7 +1579,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
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 */
, nls_codepage);
name_len_target++; /* trailing null */
Expand Down Expand Up @@ -1803,7 +1805,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,

if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
Expand Down Expand Up @@ -1860,7 +1862,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
min_t(const int, buflen,count) / 2);
/* BB FIXME investigate remapping reserved chars here */
cifs_strfromUCS_le(symlinkinfo,
(wchar_t *) ((char *)&pSMBr->hdr.Protocol +
(__le16 *) ((char *)&pSMBr->hdr.Protocol +
data_offset),
name_len, nls_codepage);
} else {
Expand Down Expand Up @@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
reparse_buf->TargetNameOffset),
min(buflen/2, reparse_buf->TargetNameLen / 2));
cifs_strfromUCS_le(symlinkinfo,
(wchar_t *) (reparse_buf->LinkNamesBuf +
(__le16 *) (reparse_buf->LinkNamesBuf +
reparse_buf->TargetNameOffset),
name_len, nls_codepage);
} else { /* ASCII names */
Expand Down Expand Up @@ -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)
{
/* u8 cifs fields do not need le conversion */
ace->e_perm = (__u16)cifs_ace->cifs_e_perm;
ace->e_tag = (__u16)cifs_ace->cifs_e_tag;
ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid);
ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
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)); */

return;
Expand Down Expand Up @@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
} else if(size > buflen) {
return -ERANGE;
} 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++) {
cifs_convert_ace(&local_acl->a_entries[i],pACE);
pACE ++;
Expand All @@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
{
__u16 rc = 0; /* 0 = ACL converted ok */

cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm);
cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag);
cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
/* 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 */
cifs_ace->cifs_uid = cpu_to_le64(-1);
} 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));*/
return rc;
}
Expand All @@ -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);
cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
count,buflen,local_acl->a_version));
if(local_acl->a_version != 2) {
cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version));
count, buflen, le32_to_cpu(local_acl->a_version)));
if(le32_to_cpu(local_acl->a_version) != 2) {
cFYI(1,("unknown POSIX ACL version %d",
le32_to_cpu(local_acl->a_version)));
return 0;
}
cifs_acl->version = cpu_to_le16(1);
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)
cifs_acl->default_entry_count = count;
cifs_acl->default_entry_count = cpu_to_le16(count);
else {
cFYI(1,("unknown ACL type %d",acl_type));
return 0;
Expand Down Expand Up @@ -3203,7 +3206,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
cifs_strfromUCS_le(*targetUNCs,
(wchar_t *) temp, name_len, nls_codepage);
(__le16 *) temp, name_len, nls_codepage);
} else {
strncpy(*targetUNCs,temp,name_len);
}
Expand Down
Loading

0 comments on commit 252ec9e

Please sign in to comment.