From 9ccf3216238ca70c0df2ff06494fcf616b62e7dc Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 18 Oct 2014 17:01:15 -0500 Subject: [PATCH 01/10] Add support for original fallocate In many cases the simple fallocate call is a no op (since the file is already not sparse) or can simply be converted from a sparse to a non-sparse file if we are fallocating the whole file and keeping the size. Signed-off-by: Steven French --- fs/cifs/smb2ops.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index c5f521bcdee2..568f323665c8 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1102,6 +1102,64 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, return rc; } +static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, + loff_t off, loff_t len, bool keep_size) +{ + struct inode *inode; + struct cifsInodeInfo *cifsi; + struct cifsFileInfo *cfile = file->private_data; + long rc = -EOPNOTSUPP; + unsigned int xid; + + xid = get_xid(); + + inode = cfile->dentry->d_inode; + cifsi = CIFS_I(inode); + + /* if file not oplocked can't be sure whether asking to extend size */ + if (!CIFS_CACHE_READ(cifsi)) + if (keep_size == false) + return -EOPNOTSUPP; + + /* + * Files are non-sparse by default so falloc may be a no-op + * Must check if file sparse. If not sparse, and not extending + * then no need to do anything since file already allocated + */ + if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) { + if (keep_size == true) + return 0; + /* check if extending file */ + else if (i_size_read(inode) >= off + len) + /* not extending file and already not sparse */ + return 0; + /* BB: in future add else clause to extend file */ + else + return -EOPNOTSUPP; + } + + if ((keep_size == true) || (i_size_read(inode) >= off + len)) { + /* + * Check if falloc starts within first few pages of file + * and ends within a few pages of the end of file to + * ensure that most of file is being forced to be + * fallocated now. If so then setting whole file sparse + * ie potentially making a few extra pages at the beginning + * or end of the file non-sparse via set_sparse is harmless. + */ + if ((off > 8192) || (off + len + 8192 < i_size_read(inode))) + return -EOPNOTSUPP; + + rc = smb2_set_sparse(xid, tcon, cfile, inode, false); + } + /* BB: else ... in future add code to extend file and set sparse */ + + + free_xid(xid); + return rc; +} + + static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, loff_t off, loff_t len) { @@ -1112,7 +1170,10 @@ static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, if (mode & FALLOC_FL_KEEP_SIZE) return smb3_zero_range(file, tcon, off, len, true); return smb3_zero_range(file, tcon, off, len, false); - } + } else if (mode == FALLOC_FL_KEEP_SIZE) + return smb3_simple_falloc(file, tcon, off, len, true); + else if (mode == 0) + return smb3_simple_falloc(file, tcon, off, len, false); return -EOPNOTSUPP; } From 911a8dfa47a45ff52d771a5b4162ce3b1e55b33d Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 19 Oct 2014 19:18:05 -0500 Subject: [PATCH 02/10] Add missing defines for ACL query support Add missing defines needed for ACL query support. For definitions of these security info type additionalinfo flags and also the EA Flags see MS-SMB2 (2.2.37) or MS-DTYP Signed-of-by: Steven French Reviewed-by: Shirish Pargaonkar --- fs/cifs/smb2pdu.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index e3188abdafd0..d84f46c5b2c5 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -836,6 +836,25 @@ struct smb2_query_directory_rsp { #define SMB2_O_INFO_SECURITY 0x03 #define SMB2_O_INFO_QUOTA 0x04 +/* Security info type additionalinfo flags. See MS-SMB2 (2.2.37) or MS-DTYP */ +#define OWNER_SECINFO 0x00000001 +#define GROUP_SECINFO 0x00000002 +#define DACL_SECINFO 0x00000004 +#define SACL_SECINFO 0x00000008 +#define LABEL_SECINFO 0x00000010 +#define ATTRIBUTE_SECINFO 0x00000020 +#define SCOPE_SECINFO 0x00000040 +#define BACKUP_SECINFO 0x00010000 +#define UNPROTECTED_SACL_SECINFO 0x10000000 +#define UNPROTECTED_DACL_SECINFO 0x20000000 +#define PROTECTED_SACL_SECINFO 0x40000000 +#define PROTECTED_DACL_SECINFO 0x80000000 + +/* Flags used for FileFullEAinfo */ +#define SL_RESTART_SCAN 0x00000001 +#define SL_RETURN_SINGLE_ENTRY 0x00000002 +#define SL_INDEX_SPECIFIED 0x00000004 + struct smb2_query_info_req { struct smb2_hdr hdr; __le16 StructureSize; /* Must be 41 */ From ebdd207e29164d5de70d2b027b8a3a14c603d42c Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 20 Oct 2014 12:48:23 -0500 Subject: [PATCH 03/10] decode_negTokenInit had wrong calling sequence For krb5 enablement of SMB3, decoding negprot, caller now passes server struct not the old sec_type --- fs/cifs/smb2pdu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 8f1672bb82d5..0ca7f6364754 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -431,8 +431,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) if (rc) goto neg_exit; if (blob_length) - rc = decode_neg_token_init(security_blob, blob_length, - &server->sec_type); + rc = decode_negTokenInit(security_blob, blob_length, server); if (rc == 1) rc = 0; else if (rc == 0) { From f8098b82aa11d966eb6790d6703552e7e4918326 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 20 Oct 2014 12:50:27 -0500 Subject: [PATCH 04/10] Update modinfo cifs version for cifs.ko update cifs version to 2.06 Signed-off-by: Steve French --- fs/cifs/cifsfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 002e0c173939..252f5c15806b 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -136,5 +136,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "2.05" +#define CIFS_VERSION "2.06" #endif /* _CIFSFS_H */ From bb1d5ddaf962921a5c3ad4166e3c1b7b70ba5778 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Mon, 10 Nov 2014 13:09:24 -0800 Subject: [PATCH 05/10] Update MAINTAINERS entry Update link to point to Steve's current tree on git.samba.org. Remove link to the old patchwork instance which shows no new patches since 2010. Signed-off-by: Kevin Cernekee Signed-off-by: Steve French --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c721042e7e45..f1e593297ddf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2504,8 +2504,7 @@ M: Steve French L: linux-cifs@vger.kernel.org L: samba-technical@lists.samba.org (moderated for non-subscribers) W: http://linux-cifs.samba.org/ -Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git +T: git git://git.samba.org/sfrench/cifs-2.6.git S: Supported F: Documentation/filesystems/cifs/ F: fs/cifs/ From 28e2aed244b1b81e45b105d90ffb82384665dfb7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 27 Aug 2014 16:49:42 +0300 Subject: [PATCH 06/10] cifs: call strtobool instead of custom implementation Meanwhile it cleans up the code, the behaviour is slightly changed. In case of providing non-boolean value it will fails with corresponding error. In the original code the attempt of an update was just ignored in such case. Signed-off-by: Andy Shevchenko Acked-by: Jeff Layton Reviewed-by: Alexander Bokovoy Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 51 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 44ec72684df5..7c50bfa9c438 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -274,6 +274,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { char c; + bool bv; int rc; struct list_head *tmp1, *tmp2, *tmp3; struct TCP_Server_Info *server; @@ -284,7 +285,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, if (rc) return rc; - if (c == '1' || c == 'y' || c == 'Y' || c == '0') { + if (strtobool(&c, &bv) == 0) { #ifdef CONFIG_CIFS_STATS2 atomic_set(&totBufAllocCount, 0); atomic_set(&totSmBufAllocCount, 0); @@ -451,15 +452,14 @@ static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { char c; + bool bv; int rc; rc = get_user(c, buffer); if (rc) return rc; - if (c == '0' || c == 'n' || c == 'N') - cifsFYI = 0; - else if (c == '1' || c == 'y' || c == 'Y') - cifsFYI = 1; + if (strtobool(&c, &bv) == 0) + cifsFYI = bv; else if ((c > '1') && (c <= '9')) cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ @@ -490,15 +490,18 @@ static ssize_t cifs_linux_ext_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { char c; + bool bv; int rc; rc = get_user(c, buffer); if (rc) return rc; - if (c == '0' || c == 'n' || c == 'N') - linuxExtEnabled = 0; - else if (c == '1' || c == 'y' || c == 'Y') - linuxExtEnabled = 1; + + rc = strtobool(&c, &bv); + if (rc) + return rc; + + linuxExtEnabled = bv; return count; } @@ -527,15 +530,18 @@ static ssize_t cifs_lookup_cache_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { char c; + bool bv; int rc; rc = get_user(c, buffer); if (rc) return rc; - if (c == '0' || c == 'n' || c == 'N') - lookupCacheEnabled = 0; - else if (c == '1' || c == 'y' || c == 'Y') - lookupCacheEnabled = 1; + + rc = strtobool(&c, &bv); + if (rc) + return rc; + + lookupCacheEnabled = bv; return count; } @@ -564,15 +570,18 @@ static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { char c; + bool bv; int rc; rc = get_user(c, buffer); if (rc) return rc; - if (c == '0' || c == 'n' || c == 'N') - traceSMB = 0; - else if (c == '1' || c == 'y' || c == 'Y') - traceSMB = 1; + + rc = strtobool(&c, &bv); + if (rc) + return rc; + + traceSMB = bv; return count; } @@ -630,6 +639,7 @@ static ssize_t cifs_security_flags_proc_write(struct file *file, unsigned int flags; char flags_string[12]; char c; + bool bv; if ((count < 1) || (count > 11)) return -EINVAL; @@ -642,11 +652,8 @@ static ssize_t cifs_security_flags_proc_write(struct file *file, if (count < 3) { /* single char or single char followed by null */ c = flags_string[0]; - if (c == '0' || c == 'n' || c == 'N') { - global_secflags = CIFSSEC_DEF; /* default */ - return count; - } else if (c == '1' || c == 'y' || c == 'Y') { - global_secflags = CIFSSEC_MAX; + if (strtobool(&c, &bv) == 0) { + global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF; return count; } else if (!isdigit(c)) { cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", From 55d83e0dbb3ed91e05b11ef32afb30acfbf8ba45 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 27 Aug 2014 16:49:43 +0300 Subject: [PATCH 07/10] cifs: convert to print_hex_dump() instead of custom implementation This patch converts custom dumper to use native print_hex_dump() instead. The cifs_dump_mem() will have an offsets per each line which differs it from the original code. In the dump_smb() we may use native print_hex_dump() as well. It will show slightly different output in ASCII part when character is unprintable, otherwise it keeps same structure. Signed-off-by: Andy Shevchenko Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 21 ++------------------- fs/cifs/misc.c | 32 ++------------------------------ 2 files changed, 4 insertions(+), 49 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 7c50bfa9c438..14e082ff1944 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -34,27 +34,10 @@ void cifs_dump_mem(char *label, void *data, int length) { - int i, j; - int *intptr = data; - char *charptr = data; - char buf[10], line[80]; - printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", label, length, data); - for (i = 0; i < length; i += 16) { - line[0] = 0; - for (j = 0; (j < 4) && (i + j * 4 < length); j++) { - sprintf(buf, " %08x", intptr[i / 4 + j]); - strcat(line, buf); - } - buf[0] = ' '; - buf[2] = 0; - for (j = 0; (j < 16) && (i + j < length); j++) { - buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.'; - strcat(line, buf); - } - printk(KERN_DEBUG "%s\n", line); - } + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, + data, length, true); } #ifdef CONFIG_CIFS_DEBUG diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index b7415d596dbd..337946355b29 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -513,39 +513,11 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) void dump_smb(void *buf, int smb_buf_length) { - int i, j; - char debug_line[17]; - unsigned char *buffer = buf; - if (traceSMB == 0) return; - for (i = 0, j = 0; i < smb_buf_length; i++, j++) { - if (i % 8 == 0) { - /* have reached the beginning of line */ - printk(KERN_DEBUG "| "); - j = 0; - } - printk("%0#4x ", buffer[i]); - debug_line[2 * j] = ' '; - if (isprint(buffer[i])) - debug_line[1 + (2 * j)] = buffer[i]; - else - debug_line[1 + (2 * j)] = '_'; - - if (i % 8 == 7) { - /* reached end of line, time to print ascii */ - debug_line[16] = 0; - printk(" | %s\n", debug_line); - } - } - for (; j < 8; j++) { - printk(" "); - debug_line[2 * j] = ' '; - debug_line[1 + (2 * j)] = ' '; - } - printk(" | %s\n", debug_line); - return; + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, 8, 2, buf, + smb_buf_length, true); } void From 0b456f04bcdf5b1151136adaada158bfc26f1be7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 27 Aug 2014 16:49:44 +0300 Subject: [PATCH 08/10] cifs: convert printk(LEVEL...) to pr_ The useful macros embed message level in the name. Thus, it cleans up the code a bit. In cases when it was plain printk() the conversion was done to info level. Signed-off-by: Andy Shevchenko Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 5 ++--- fs/cifs/cifs_debug.h | 7 +++--- fs/cifs/connect.c | 51 ++++++++++++++++---------------------------- fs/cifs/transport.c | 4 ++-- 4 files changed, 25 insertions(+), 42 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 14e082ff1944..9c56ef776407 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -34,8 +34,7 @@ void cifs_dump_mem(char *label, void *data, int length) { - printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", - label, length, data); + pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, data, length, true); } @@ -51,7 +50,7 @@ void cifs_vfs_err(const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - printk(KERN_ERR "CIFS VFS: %pV", &vaf); + pr_err("CIFS VFS: %pV", &vaf); va_end(args); } diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h index c99b40fb609b..f40fbaca1b2a 100644 --- a/fs/cifs/cifs_debug.h +++ b/fs/cifs/cifs_debug.h @@ -53,13 +53,12 @@ __printf(1, 2) void cifs_vfs_err(const char *fmt, ...); do { \ if (type == FYI) { \ if (cifsFYI & CIFS_INFO) { \ - printk(KERN_DEBUG "%s: " fmt, \ - __FILE__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__); \ } \ } else if (type == VFS) { \ cifs_vfs_err(fmt, ##__VA_ARGS__); \ } else if (type == NOISY && type != 0) { \ - printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ + pr_debug(fmt, ##__VA_ARGS__); \ } \ } while (0) @@ -71,7 +70,7 @@ do { \ #define cifs_dbg(type, fmt, ...) \ do { \ if (0) \ - printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ + pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #endif diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 24fa08d261fb..2a772da16b83 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1466,9 +1466,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->seal = 1; break; case Opt_noac: - printk(KERN_WARNING "CIFS: Mount option noac not " - "supported. Instead set " - "/proc/fs/cifs/LookupCacheEnabled to 0\n"); + pr_warn("CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); break; case Opt_fsc: #ifndef CONFIG_CIFS_FSCACHE @@ -1598,7 +1596,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (strnlen(string, CIFS_MAX_USERNAME_LEN) > CIFS_MAX_USERNAME_LEN) { - printk(KERN_WARNING "CIFS: username too long\n"); + pr_warn("CIFS: username too long\n"); goto cifs_parse_mount_err; } vol->username = kstrdup(string, GFP_KERNEL); @@ -1662,8 +1660,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, temp_len = strlen(value); vol->password = kzalloc(temp_len+1, GFP_KERNEL); if (vol->password == NULL) { - printk(KERN_WARNING "CIFS: no memory " - "for password\n"); + pr_warn("CIFS: no memory for password\n"); goto cifs_parse_mount_err; } @@ -1687,8 +1684,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (!cifs_convert_address(dstaddr, string, strlen(string))) { - printk(KERN_ERR "CIFS: bad ip= option (%s).\n", - string); + pr_err("CIFS: bad ip= option (%s).\n", string); goto cifs_parse_mount_err; } got_ip = true; @@ -1700,15 +1696,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN) == CIFS_MAX_DOMAINNAME_LEN) { - printk(KERN_WARNING "CIFS: domain name too" - " long\n"); + pr_warn("CIFS: domain name too long\n"); goto cifs_parse_mount_err; } vol->domainname = kstrdup(string, GFP_KERNEL); if (!vol->domainname) { - printk(KERN_WARNING "CIFS: no memory " - "for domainname\n"); + pr_warn("CIFS: no memory for domainname\n"); goto cifs_parse_mount_err; } cifs_dbg(FYI, "Domain name set\n"); @@ -1721,8 +1715,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (!cifs_convert_address( (struct sockaddr *)&vol->srcaddr, string, strlen(string))) { - printk(KERN_WARNING "CIFS: Could not parse" - " srcaddr: %s\n", string); + pr_warn("CIFS: Could not parse srcaddr: %s\n", + string); goto cifs_parse_mount_err; } break; @@ -1732,8 +1726,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto out_nomem; if (strnlen(string, 1024) >= 65) { - printk(KERN_WARNING "CIFS: iocharset name " - "too long.\n"); + pr_warn("CIFS: iocharset name too long.\n"); goto cifs_parse_mount_err; } @@ -1741,8 +1734,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->iocharset = kstrdup(string, GFP_KERNEL); if (!vol->iocharset) { - printk(KERN_WARNING "CIFS: no memory" - "for charset\n"); + pr_warn("CIFS: no memory for charset\n"); goto cifs_parse_mount_err; } } @@ -1773,9 +1765,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, * set at top of the function */ if (i == RFC1001_NAME_LEN && string[i] != 0) - printk(KERN_WARNING "CIFS: netbiosname" - " longer than 15 truncated.\n"); - + pr_warn("CIFS: netbiosname longer than 15 truncated.\n"); break; case Opt_servern: /* servernetbiosname specified override *SMBSERVER */ @@ -1801,8 +1791,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* The string has 16th byte zero still from set at top of the function */ if (i == RFC1001_NAME_LEN && string[i] != 0) - printk(KERN_WARNING "CIFS: server net" - "biosname longer than 15 truncated.\n"); + pr_warn("CIFS: server netbiosname longer than 15 truncated.\n"); break; case Opt_ver: string = match_strdup(args); @@ -1814,8 +1803,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, break; } /* For all other value, error */ - printk(KERN_WARNING "CIFS: Invalid version" - " specified\n"); + pr_warn("CIFS: Invalid version specified\n"); goto cifs_parse_mount_err; case Opt_vers: string = match_strdup(args); @@ -1856,7 +1844,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } if (!sloppy && invalid) { - printk(KERN_ERR "CIFS: Unknown mount option \"%s\"\n", invalid); + pr_err("CIFS: Unknown mount option \"%s\"\n", invalid); goto cifs_parse_mount_err; } @@ -1882,8 +1870,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* No ip= option specified? Try to get it from UNC */ if (!cifs_convert_address(dstaddr, &vol->UNC[2], strlen(&vol->UNC[2]))) { - printk(KERN_ERR "Unable to determine destination " - "address.\n"); + pr_err("Unable to determine destination address.\n"); goto cifs_parse_mount_err; } } @@ -1894,20 +1881,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (uid_specified) vol->override_uid = override_uid; else if (override_uid == 1) - printk(KERN_NOTICE "CIFS: ignoring forceuid mount option " - "specified with no uid= option.\n"); + pr_notice("CIFS: ignoring forceuid mount option specified with no uid= option.\n"); if (gid_specified) vol->override_gid = override_gid; else if (override_gid == 1) - printk(KERN_NOTICE "CIFS: ignoring forcegid mount option " - "specified with no gid= option.\n"); + pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n"); kfree(mountdata_copy); return 0; out_nomem: - printk(KERN_WARNING "Could not allocate temporary buffer\n"); + pr_warn("Could not allocate temporary buffer\n"); cifs_parse_mount_err: kfree(string); kfree(mountdata_copy); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 9d087f4e7d4e..126f46b887cc 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -99,9 +99,9 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) something is wrong, unless it is quite a slow link or server */ if ((now - midEntry->when_alloc) > HZ) { if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) { - printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu", + pr_debug(" CIFS slow rsp: cmd %d mid %llu", midEntry->command, midEntry->mid); - printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n", + pr_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n", now - midEntry->when_alloc, now - midEntry->when_sent, now - midEntry->when_received); From ee9bbf465d8bb82ff2081834cb53a0ea7574c423 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Wed, 3 Dec 2014 12:26:36 +0000 Subject: [PATCH 09/10] Set UID in sess_auth_rawntlmssp_authenticate too A user complained that they were unable to login to their cifs share after a kernel update. From the wiretrace we can see that the server returns different UIDs as response to NTLMSSP_NEGOTIATE and NTLMSSP_AUTH phases. With changes in the authentication code, we no longer set the cifs_sess->Suid returned in response to the NTLM_AUTH phase and continue to use the UID sent in response to the NTLMSSP_NEGOTIATE phase. This results in the server denying access to the user when the user attempts to do a tcon connect. See https://bugzilla.redhat.com/show_bug.cgi?id=1163927 A test kernel containing patch was tested successfully by the user. Signed-off-by: Sachin Prabhu Signed-off-by: Steve French --- fs/cifs/sess.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 57db63ff88da..446cb7fb3f58 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -1303,6 +1303,11 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */ + if (ses->Suid != smb_buf->Uid) { + ses->Suid = smb_buf->Uid; + cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid); + } + bytes_remaining = get_bcc(smb_buf); bcc_ptr = pByteArea(smb_buf); blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); From 15d987063348c93adb3e7c7378226abea03608e2 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 25 Nov 2014 16:52:48 +0900 Subject: [PATCH 10/10] cifs: remove unneeded condition check file->private_data can never be null after calling initiate_cifs_search. So private null check condition is not needed. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Signed-off-by: Steve French --- fs/cifs/readdir.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 8fd2a95860ba..803030c9ab68 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -794,10 +794,6 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) if it before then restart search if after then keep searching till find it */ - if (file->private_data == NULL) { - rc = -EINVAL; - goto rddir2_exit; - } cifsFile = file->private_data; if (cifsFile->srch_inf.endOfSearch) { if (cifsFile->srch_inf.emptyDir) {