Commit 78d9affb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '5.2-smb3' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "CIFS/SMB3 changes:

   - three fixes for stable

   - add fiemap support

   - improve zero-range support

   - various RDMA (smb direct fixes)

  I have an additional set of fixes (for improved handling of sparse
  files, mode bits, POSIX extensions) that are still being tested that
  are not included in this pull request but I expect to send in the next
  week"

* tag '5.2-smb3' of git://git.samba.org/sfrench/cifs-2.6: (29 commits)
  cifs: update module internal version number
  SMB3: Clean up query symlink when reparse point
  cifs: fix strcat buffer overflow and reduce raciness in smb21_set_oplock_level()
  Negotiate and save preferred compression algorithms
  cifs: rename and clarify CIFS_ASYNC_OP and CIFS_NO_RESP
  cifs: fix credits leak for SMB1 oplock breaks
  smb3: Add protocol structs for change notify support
  cifs: fix smb3_zero_range for Azure
  cifs: zero-range does not require the file is sparse
  Add new flag on SMB3.1.1 read
  cifs: add fiemap support
  SMB3: Add defines for new negotiate contexts
  cifs: fix bi-directional fsctl passthrough calls
  cifs: smbd: take an array of reqeusts when sending upper layer data
  SMB3: Add handling for different FSCTL access flags
  cifs: Add support for FSCTL passthrough that write data to the server
  cifs: remove superfluous inode_lock in cifs_{strict_}fsync
  cifs: Call MID callback before destroying transport
  cifs: smbd: Retry on memory registration failure
  cifs: smbd: Indicate to retry on transport sending failure
  ...
parents 8c79f4cd cb4f7bf6
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -312,12 +312,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			atomic_read(&server->smbd_conn->send_credits),
			atomic_read(&server->smbd_conn->receive_credits),
			server->smbd_conn->receive_credit_target);
		seq_printf(m, "\nPending send_pending: %x send_payload_pending:"
			" %x smbd_send_pending: %x smbd_recv_pending: %x",
		seq_printf(m, "\nPending send_pending: %x "
			"send_payload_pending: %x",
			atomic_read(&server->smbd_conn->send_pending),
			atomic_read(&server->smbd_conn->send_payload_pending),
			server->smbd_conn->smbd_send_pending,
			server->smbd_conn->smbd_recv_pending);
			atomic_read(&server->smbd_conn->send_payload_pending));
		seq_printf(m, "\nReceive buffers count_receive_queue: %x "
			"count_empty_packet_queue: %x",
			server->smbd_conn->count_receive_queue,
@@ -334,6 +332,12 @@ skip_rdma:
#endif
		seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
			server->credits,  server->dialect);
		if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
			seq_printf(m, " COMPRESS_LZNT1");
		else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
			seq_printf(m, " COMPRESS_LZ77");
		else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF)
			seq_printf(m, " COMPRESS_LZ77_HUFF");
		if (server->sign)
			seq_printf(m, " signed");
		if (server->posix_ext_supported)
@@ -462,8 +466,13 @@ static ssize_t cifs_stats_proc_write(struct file *file,
			server = list_entry(tmp1, struct TCP_Server_Info,
					    tcp_ses_list);
#ifdef CONFIG_CIFS_STATS2
			for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++)
			for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
				atomic_set(&server->num_cmds[i], 0);
				atomic_set(&server->smb2slowcmd[i], 0);
				server->time_per_cmd[i] = 0;
				server->slowest_cmd[i] = 0;
				server->fastest_cmd[0] = 0;
			}
#endif /* CONFIG_CIFS_STATS2 */
			list_for_each(tmp2, &server->smb_ses_list) {
				ses = list_entry(tmp2, struct cifs_ses,
@@ -531,6 +540,16 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
		server = list_entry(tmp1, struct TCP_Server_Info,
				    tcp_ses_list);
#ifdef CONFIG_CIFS_STATS2
		seq_puts(m, "\nTotal time spent processing by command. Time ");
		seq_printf(m, "units are jiffies (%d per second)\n", HZ);
		seq_puts(m, "  SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n");
		seq_puts(m, "  --------\t------\t----------\t-------\t-------\n");
		for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
			seq_printf(m, "  %d\t\t%d\t%llu\t\t%u\t%u\n", j,
				atomic_read(&server->num_cmds[j]),
				server->time_per_cmd[j],
				server->fastest_cmd[j],
				server->slowest_cmd[j]);
		for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
			if (atomic_read(&server->smb2slowcmd[j]))
				seq_printf(m, "  %d slow responses from %s for command %d\n",
+3 −0
Original line number Diff line number Diff line
@@ -483,6 +483,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
		seq_puts(s, ",seal");
	if (tcon->nocase)
		seq_puts(s, ",nocase");
	if (tcon->local_lease)
		seq_puts(s, ",locallease");
	if (tcon->retry)
		seq_puts(s, ",hard");
	else
@@ -984,6 +986,7 @@ const struct inode_operations cifs_file_inode_ops = {
	.getattr = cifs_getattr,
	.permission = cifs_permission,
	.listxattr = cifs_listxattr,
	.fiemap = cifs_fiemap,
};

const struct inode_operations cifs_symlink_inode_ops = {
+3 −1
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ extern int cifs_revalidate_mapping(struct inode *inode);
extern int cifs_zap_mapping(struct inode *inode);
extern int cifs_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int cifs_setattr(struct dentry *, struct iattr *);
extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start,
		       u64 len);

extern const struct inode_operations cifs_file_inode_ops;
extern const struct inode_operations cifs_symlink_inode_ops;
@@ -150,5 +152,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.19"
#define CIFS_VERSION   "2.20"
#endif				/* _CIFSFS_H */
+23 −4
Original line number Diff line number Diff line
@@ -355,7 +355,8 @@ struct smb_version_operations {
			       struct cifs_sb_info *);
	/* query symlink target */
	int (*query_symlink)(const unsigned int, struct cifs_tcon *,
			     const char *, char **, struct cifs_sb_info *);
			     struct cifs_sb_info *, const char *,
			     char **, bool);
	/* open a file for non-posix mounts */
	int (*open)(const unsigned int, struct cifs_open_parms *,
		    __u32 *, FILE_ALL_INFO *);
@@ -493,6 +494,9 @@ struct smb_version_operations {
			 char *full_path,
			 umode_t mode,
			 dev_t device_number);
	/* version specific fiemap implementation */
	int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *,
		      struct fiemap_extent_info *, u64, u64);
};

struct smb_version_values {
@@ -596,6 +600,10 @@ struct smb_vol {
	unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */
};

/**
 * CIFS superblock mount flags (mnt_cifs_flags) to consider when
 * trying to reuse existing superblock for a new mount
 */
#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
			 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
			 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
@@ -606,8 +614,13 @@ struct smb_vol {
			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
			 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID)
			 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
			 CIFS_MOUNT_NO_DFS)

/**
 * Generic VFS superblock mount flags (s_flags) to consider when
 * trying to reuse existing superblock for a new mount
 */
#define CIFS_MS_MASK (SB_RDONLY | SB_MANDLOCK | SB_NOEXEC | SB_NOSUID | \
		      SB_NODEV | SB_SYNCHRONOUS)

@@ -714,10 +727,15 @@ struct TCP_Server_Info {
#ifdef CONFIG_CIFS_STATS2
	atomic_t in_send; /* requests trying to send */
	atomic_t num_waiters;   /* blocked waiting to get in sendrecv */
	atomic_t num_cmds[NUMBER_OF_SMB2_COMMANDS]; /* total requests by cmd */
	atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */
	__u64 time_per_cmd[NUMBER_OF_SMB2_COMMANDS]; /* total time per cmd */
	__u32 slowest_cmd[NUMBER_OF_SMB2_COMMANDS];
	__u32 fastest_cmd[NUMBER_OF_SMB2_COMMANDS];
#endif /* STATS2 */
	unsigned int	max_read;
	unsigned int	max_write;
	__le16	compress_algorithm;
	__le16	cipher_type;
	 /* save initital negprot hash */
	__u8	preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
@@ -1673,11 +1691,11 @@ static inline bool is_retryable_error(int error)

/* Type of Request to SendReceive2 */
#define   CIFS_BLOCKING_OP      1    /* operation can block */
#define   CIFS_ASYNC_OP         2    /* do not wait for response */
#define   CIFS_NON_BLOCKING     2    /* do not block waiting for credits */
#define   CIFS_TIMEOUT_MASK 0x003    /* only one of above set in req */
#define   CIFS_LOG_ERROR    0x010    /* log NT STATUS if non-zero */
#define   CIFS_LARGE_BUF_OP 0x020    /* large request buffer */
#define   CIFS_NO_RESP      0x040    /* no response buffer required */
#define   CIFS_NO_RSP_BUF   0x040    /* no response buffer required */

/* Type of request operation */
#define   CIFS_ECHO_OP      0x080    /* echo request */
@@ -1687,6 +1705,7 @@ static inline bool is_retryable_error(int error)

#define   CIFS_HAS_CREDITS 0x0400    /* already has credits */
#define   CIFS_TRANSFORM_REQ 0x0800    /* transform request before sending */
#define   CIFS_NO_SRV_RSP    0x1000    /* there is no server response */

/* Security Flags: indicate type of session setup needed */
#define   CIFSSEC_MAY_SIGN	0x00001
+9 −0
Original line number Diff line number Diff line
@@ -526,12 +526,21 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
			const struct nls_table *codepage);
extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
			unsigned char *p24);

extern int
cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
		       const char *devname, bool is_smb3);
extern void
cifs_cleanup_volume_info_contents(struct smb_vol *volume_info);

extern struct TCP_Server_Info *
cifs_find_tcp_session(struct smb_vol *vol);

extern void cifs_put_smb_ses(struct cifs_ses *ses);

extern struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info);

void cifs_readdata_release(struct kref *refcount);
int cifs_async_readv(struct cifs_readdata *rdata);
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
Loading