Commit 1b907d05 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.7-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

 - ctime caching fix (for setxattr)

 - encryption fix

 - DNS resolver mount fix

 - debugging improvements

 - multichannel fixes including cases where server stops or starts
   supporting multichannel after mount

 - reconnect fix

 - minor cleanups

* tag '6.7-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: update internal module version number for cifs.ko
  cifs: handle when server stops supporting multichannel
  cifs: handle when server starts supporting multichannel
  Missing field not being returned in ioctl CIFS_IOC_GET_MNT_INFO
  smb3: allow dumping session and tcon id to improve stats analysis and debugging
  smb: client: fix mount when dns_resolver key is not available
  smb3: fix caching of ctime on setxattr
  smb3: minor cleanup of session handling code
  cifs: reconnect work should have reference on server struct
  cifs: do not pass cifs_sb when trying to add channels
  cifs: account for primary channel in the interface list
  cifs: distribute channels across interfaces based on speed
  cifs: handle cases where a channel is closed
  smb3: more minor cleanups for session handling routines
  smb3: minor RDMA cleanup
  cifs: Fix encryption of cleared, but unset rq_iter data buffers
parents 3ca112b7 fd2bd7c0
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -136,6 +136,11 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
{
	struct TCP_Server_Info *server = chan->server;

	if (!server) {
		seq_printf(m, "\n\n\t\tChannel: %d DISABLED", i+1);
		return;
	}

	seq_printf(m, "\n\n\t\tChannel: %d ConnectionId: 0x%llx"
		   "\n\t\tNumber of credits: %d,%d,%d Dialect 0x%x"
		   "\n\t\tTCP status: %d Instance: %d"
@@ -279,6 +284,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
	struct cifs_server_iface *iface;
	size_t iface_weight = 0, iface_min_speed = 0;
	struct cifs_server_iface *last_iface = NULL;
	int c, i, j;

	seq_puts(m,
@@ -544,11 +551,25 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
					   "\tLast updated: %lu seconds ago",
					   ses->iface_count,
					   (jiffies - ses->iface_last_update) / HZ);

			last_iface = list_last_entry(&ses->iface_list,
						     struct cifs_server_iface,
						     iface_head);
			iface_min_speed = last_iface->speed;

			j = 0;
			list_for_each_entry(iface, &ses->iface_list,
						 iface_head) {
				seq_printf(m, "\n\t%d)", ++j);
				cifs_dump_iface(m, iface);

				iface_weight = iface->speed / iface_min_speed;
				seq_printf(m, "\t\tWeight (cur,total): (%zu,%zu)"
					   "\n\t\tAllocated channels: %u\n",
					   iface->weight_fulfilled,
					   iface_weight,
					   iface->num_channels);

				if (is_ses_using_iface(ses, iface))
					seq_puts(m, "\t\t[CONNECTED]\n");
			}
+6 −0
Original line number Diff line number Diff line
@@ -26,6 +26,11 @@ struct smb_mnt_fs_info {
	__u64   cifs_posix_caps;
} __packed;

struct smb_mnt_tcon_info {
	__u32	tid;
	__u64	session_id;
} __packed;

struct smb_snapshot_array {
	__u32	number_of_snapshots;
	__u32	number_of_snapshots_returned;
@@ -108,6 +113,7 @@ struct smb3_notify_info {
#define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify)
#define CIFS_DUMP_FULL_KEY _IOWR(CIFS_IOCTL_MAGIC, 10, struct smb3_full_key_debug_info)
#define CIFS_IOC_NOTIFY_INFO _IOWR(CIFS_IOCTL_MAGIC, 11, struct smb3_notify_info)
#define CIFS_IOC_GET_TCON_INFO _IOR(CIFS_IOCTL_MAGIC, 12, struct smb_mnt_tcon_info)
#define CIFS_IOC_SHUTDOWN _IOR('X', 125, __u32)

/*
+2 −2
Original line number Diff line number Diff line
@@ -152,6 +152,6 @@ extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */

/* when changing internal version - update following two lines at same time */
#define SMB3_PRODUCT_BUILD 45
#define CIFS_VERSION   "2.45"
#define SMB3_PRODUCT_BUILD 46
#define CIFS_VERSION   "2.46"
#endif				/* _CIFSFS_H */
+13 −3
Original line number Diff line number Diff line
@@ -650,6 +650,7 @@ struct TCP_Server_Info {
	bool noautotune;		/* do not autotune send buf sizes */
	bool nosharesock;
	bool tcp_nodelay;
	bool terminate;
	unsigned int credits;  /* send no more requests at once */
	unsigned int max_credits; /* can override large 32000 default at mnt */
	unsigned int in_flight;  /* number of requests on the wire to server */
@@ -969,6 +970,8 @@ struct cifs_server_iface {
	struct list_head iface_head;
	struct kref refcount;
	size_t speed;
	size_t weight_fulfilled;
	unsigned int num_channels;
	unsigned int rdma_capable : 1;
	unsigned int rss_capable : 1;
	unsigned int is_active : 1; /* unset if non existent */
@@ -1050,6 +1053,7 @@ struct cifs_ses {
	spinlock_t chan_lock;
	/* ========= begin: protected by chan_lock ======== */
#define CIFS_MAX_CHANNELS 16
#define CIFS_INVAL_CHAN_INDEX (-1)
#define CIFS_ALL_CHANNELS_SET(ses)	\
	((1UL << (ses)->chan_count) - 1)
#define CIFS_ALL_CHANS_GOOD(ses)		\
@@ -2143,6 +2147,7 @@ static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
	unsigned int len, skip;
	unsigned int nents = 0;
	unsigned long addr;
	size_t data_size;
	int i, j;

	/*
@@ -2158,17 +2163,21 @@ static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
	 */
	for (i = 0; i < num_rqst; i++) {
		data_size = iov_iter_count(&rqst[i].rq_iter);

		/* We really don't want a mixture of pinned and unpinned pages
		 * in the sglist.  It's hard to keep track of which is what.
		 * Instead, we convert to a BVEC-type iterator higher up.
		 */
		if (WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
		if (data_size &&
		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
			return -EIO;

		/* We also don't want to have any extra refs or pins to clean
		 * up in the sglist.
		 */
		if (WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
		if (data_size &&
		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
			return -EIO;

		for (j = 0; j < rqst[i].rq_nvec; j++) {
@@ -2184,6 +2193,7 @@ static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
			}
			skip = 0;
		}
		if (data_size)
			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
	}
	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
+5 −2
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
			struct smb_hdr *in_buf,
			struct smb_hdr *out_buf,
			int *bytes_returned);

void
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
				      bool all_channels);
@@ -610,13 +611,13 @@ void cifs_free_hash(struct shash_desc **sdesc);

struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
int cifs_try_adding_channels(struct cifs_ses *ses);
bool is_server_using_iface(struct TCP_Server_Info *server,
			   struct cifs_server_iface *iface);
bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
void cifs_ses_mark_for_reconnect(struct cifs_ses *ses);

unsigned int
int
cifs_ses_get_chan_index(struct cifs_ses *ses,
			struct TCP_Server_Info *server);
void
@@ -640,6 +641,8 @@ cifs_chan_needs_reconnect(struct cifs_ses *ses,
bool
cifs_chan_is_iface_active(struct cifs_ses *ses,
			  struct TCP_Server_Info *server);
void
cifs_disable_secondary_channels(struct cifs_ses *ses);
int
cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
int
Loading