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 Jan 19, 2006
2 parents 648bf4f + 47c886b commit 0f36b01
Show file tree
Hide file tree
Showing 21 changed files with 729 additions and 183 deletions.
10 changes: 10 additions & 0 deletions fs/cifs/CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Version 1.40
------------
Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
of readpages by eliminating one extra memcpy. Allow update of file size
from remote server even if file is open for write as long as mount is
directio. Recognize share mode security and send NTLM encrypted password
on tree connect if share mode negotiated.

Version 1.39
------------
Defer close of a file handle slightly if pending writes depend on that handle
Expand All @@ -7,6 +15,8 @@ Fix SFU style symlinks and mknod needed for servers which do not support the
CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative
dentries so files that the client sees as deleted but that later get created
on the server will be recognized. Add client side permission check on setattr.
Timeout stuck requests better (where server has never responded or sent corrupt
responses)

Version 1.38
------------
Expand Down
12 changes: 11 additions & 1 deletion fs/cifs/README
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,17 @@ A partial list of the supported mount options follows:
SFU does). In the future the bottom 9 bits of the mode
mode also will be emulated using queries of the security
descriptor (ACL).

sec Security mode. Allowed values are:
none attempt to connection as a null user (no name)
krb5 Use Kerberos version 5 authentication
krb5i Use Kerberos authentication and packet signing
ntlm Use NTLM password hashing (default)
ntlmi Use NTLM password hashing with signing (if
/proc/fs/cifs/PacketSigningEnabled on or if
server requires signing also can be the default)
ntlmv2 Use NTLMv2 password hashing
ntlmv2i Use NTLMv2 password hashing with packet signing

The mount.cifs mount helper also accepts a few mount options before -o
including:

Expand Down
51 changes: 31 additions & 20 deletions fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ cifs_stats_write(struct file *file, const char __user *buffer,

if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
read_lock(&GlobalSMBSeslock);
#ifdef CONFIG_CIFS_STATS2
atomic_set(&totBufAllocCount, 0);
atomic_set(&totSmBufAllocCount, 0);
#endif /* CONFIG_CIFS_STATS2 */
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo,
cifsConnectionList);
Expand Down Expand Up @@ -276,6 +280,14 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
smBufAllocCount.counter,cifs_min_small);
length += item_length;
buf += item_length;
#ifdef CONFIG_CIFS_STATS2
item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
atomic_read(&totBufAllocCount),
atomic_read(&totSmBufAllocCount));
length += item_length;
buf += item_length;
#endif /* CONFIG_CIFS_STATS2 */

item_length =
sprintf(buf,"Operations (MIDs): %d\n",
midCount.counter);
Expand Down Expand Up @@ -389,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
static write_proc_t ntlmv2_enabled_write;
static read_proc_t packet_signing_enabled_read;
static write_proc_t packet_signing_enabled_write;
static read_proc_t quotaEnabled_read;
static write_proc_t quotaEnabled_write;
static read_proc_t experimEnabled_read;
static write_proc_t experimEnabled_write;
static read_proc_t linuxExtensionsEnabled_read;
static write_proc_t linuxExtensionsEnabled_write;

Expand Down Expand Up @@ -430,9 +442,9 @@ cifs_proc_init(void)
pde->write_proc = oplockEnabled_write;

pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
quotaEnabled_read, NULL);
experimEnabled_read, NULL);
if (pde)
pde->write_proc = quotaEnabled_write;
pde->write_proc = experimEnabled_write;

pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
linuxExtensionsEnabled_read, NULL);
Expand Down Expand Up @@ -574,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer,
}

static int
quotaEnabled_read(char *page, char **start, off_t off,
experimEnabled_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;

len = sprintf(page, "%d\n", experimEnabled);
/* could also check if quotas are enabled in kernel
as a whole first */

len -= off;
*start = page + off;

Expand All @@ -596,21 +607,23 @@ quotaEnabled_read(char *page, char **start, off_t off,
return len;
}
static int
quotaEnabled_write(struct file *file, const char __user *buffer,
experimEnabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
int rc;
char c;
int rc;

rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '0' || c == 'n' || c == 'N')
experimEnabled = 0;
else if (c == '1' || c == 'y' || c == 'Y')
experimEnabled = 1;
rc = get_user(c, buffer);
if (rc)
return rc;
if (c == '0' || c == 'n' || c == 'N')
experimEnabled = 0;
else if (c == '1' || c == 'y' || c == 'Y')
experimEnabled = 1;
else if (c == '2')
experimEnabled = 2;

return count;
return count;
}

static int
Expand All @@ -620,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off,
int len;

len = sprintf(page, "%d\n", linuxExtEnabled);
/* could also check if quotas are enabled in kernel
as a whole first */
len -= off;
*start = page + off;

Expand Down
5 changes: 3 additions & 2 deletions fs/cifs/cifs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */

struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
Expand Down
38 changes: 38 additions & 0 deletions fs/cifs/cifsacl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* fs/cifs/cifsacl.h
*
* Copyright (c) International Business Machines Corp., 2005
* Author(s): Steve French ([email protected])
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef _CIFSACL_H
#define _CIFSACL_H

struct cifs_sid {
__u8 revision; /* revision level */
__u8 num_subauths;
__u8 authority[6];
__u32 sub_auth[4];
/* next sub_auth if any ... */
} __attribute__((packed));

/* everyone */
extern const struct cifs_sid sid_everyone;
/* group users */
extern const struct cifs_sid sid_user;

#endif /* _CIFSACL_H */
55 changes: 54 additions & 1 deletion fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsencrypt.c
*
* Copyright (C) International Business Machines Corp., 2003
* Copyright (C) International Business Machines Corp., 2005
* Author(s): Steve French ([email protected])
*
* This library is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
return rc;
}

static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
const char * key, char * signature)
{
struct MD5Context context;

if((iov == NULL) || (signature == NULL))
return -EINVAL;

MD5Init(&context);
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);

/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */

MD5Final(signature,&context);

return -EOPNOTSUPP;
/* return 0; */
}


int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server,
__u32 * pexpected_response_sequence_number)
{
int rc = 0;
char smb_signature[20];
struct smb_hdr * cifs_pdu = iov[0].iov_base;

if((cifs_pdu == NULL) || (server == NULL))
return -EINVAL;

if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
return rc;

spin_lock(&GlobalMid_Lock);
cifs_pdu->Signature.Sequence.SequenceNumber =
cpu_to_le32(server->sequence_number);
cifs_pdu->Signature.Sequence.Reserved = 0;

*pexpected_response_sequence_number = server->sequence_number++;
server->sequence_number++;
spin_unlock(&GlobalMid_Lock);

rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key,
smb_signature);
if(rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
else
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);

return rc;

}

int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
__u32 expected_sequence_number)
{
Expand Down
28 changes: 24 additions & 4 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
return written;
}

static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
{
/* origin == SEEK_END => we must revalidate the cached file length */
if (origin == 2) {
int retval = cifs_revalidate(file->f_dentry);
if (retval < 0)
return (loff_t)retval;
}
return remote_llseek(file, offset, origin);
}

static struct file_system_type cifs_fs_type = {
.owner = THIS_MODULE,
.name = "cifs",
Expand Down Expand Up @@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = {
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
Expand All @@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_ops = {
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */

.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
Expand All @@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_ops = {
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
Expand All @@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_nobrl_ops = {
#ifdef CONFIG_CIFS_POSIX
.ioctl = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */

.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
Expand Down Expand Up @@ -733,7 +746,7 @@ cifs_init_request_bufs(void)
kmem_cache_destroy(cifs_req_cachep);
return -ENOMEM;
}
/* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
/* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
almost all handle based requests (but not write response, nor is it
sufficient for path based requests). A smaller size would have
been more efficient (compacting multiple slab items on one 4k page)
Expand All @@ -742,7 +755,8 @@ cifs_init_request_bufs(void)
efficient to alloc 1 per page off the slab compared to 17K (5page)
alloc of large cifs buffers even when page debugging is on */
cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
NULL, NULL);
if (cifs_sm_req_cachep == NULL) {
mempool_destroy(cifs_req_poolp);
kmem_cache_destroy(cifs_req_cachep);
Expand Down Expand Up @@ -954,6 +968,12 @@ init_cifs(void)
atomic_set(&tconInfoReconnectCount, 0);

atomic_set(&bufAllocCount, 0);
atomic_set(&smBufAllocCount, 0);
#ifdef CONFIG_CIFS_STATS2
atomic_set(&totBufAllocCount, 0);
atomic_set(&totSmBufAllocCount, 0);
#endif /* CONFIG_CIFS_STATS2 */

atomic_set(&midCount, 0);
GlobalCurrentXid = 0;
GlobalTotalActiveXid = 0;
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern int cifs_ioctl (struct inode * inode, struct file * filep,
unsigned int command, unsigned long arg);
#define CIFS_VERSION "1.39"
#define CIFS_VERSION "1.40"
#endif /* _CIFSFS_H */
Loading

0 comments on commit 0f36b01

Please sign in to comment.