diff options
author | Greg Kroah-Hartman <gregkh@google.com> | 2019-02-07 09:24:50 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2019-02-07 09:24:50 +0100 |
commit | 64b564428faa872686215f9a410558ebb1b7ccf4 (patch) | |
tree | 9be9f88db27c7a7ba5f42e272f14972e223dd070 /fs | |
parent | 6d1e42fb1a284de71e619fdb22cfb55e64e0c8ee (diff) | |
parent | 343f981c760801e7cd4715bcdb54fb075f59335a (diff) |
Merge 4.4.173 into android-4.4
Changes in 4.4.173
net: Fix usage of pskb_trim_rcsum
openvswitch: Avoid OOB read when parsing flow nlattrs
net: ipv4: Fix memory leak in network namespace dismantle
net_sched: refetch skb protocol for each filter
net: bridge: Fix ethernet header pointer before check skb forwardable
USB: serial: simple: add Motorola Tetra TPG2200 device id
USB: serial: pl2303: add new PID to support PL2303TB
ASoC: atom: fix a missing check of snd_pcm_lib_malloc_pages
ARC: perf: map generic branches to correct hardware condition
s390/early: improve machine detection
s390/smp: fix CPU hotplug deadlock with CPU rescan
char/mwave: fix potential Spectre v1 vulnerability
staging: rtl8188eu: Add device code for D-Link DWA-121 rev B1
tty: Handle problem if line discipline does not have receive_buf
tty/n_hdlc: fix __might_sleep warning
CIFS: Fix possible hang during async MTU reads and writes
Input: xpad - add support for SteelSeries Stratus Duo
KVM: x86: Fix single-step debugging
x86/kaslr: Fix incorrect i8254 outb() parameters
can: dev: __can_get_echo_skb(): fix bogous check for non-existing skb by removing it
can: bcm: check timer values before ktime conversion
vt: invoke notifier on screen size change
perf unwind: Unwind with libdw doesn't take symfs into account
perf unwind: Take pgoff into account when reporting elf to libdwfl
irqchip/gic-v3-its: Align PCI Multi-MSI allocation on their size
arm64: mm: remove page_mapping check in __sync_icache_dcache
f2fs: read page index before freeing
Revert "loop: Fix double mutex_unlock(&loop_ctl_mutex) in loop_control_ioctl()"
Revert "loop: Get rid of loop_index_mutex"
Revert "loop: Fold __loop_release into loop_release"
s390/smp: Fix calling smp_call_ipl_cpu() from ipl CPU
fs: add the fsnotify call to vfs_iter_write
ipv6: Consider sk_bound_dev_if when binding a socket to an address
l2tp: copy 4 more bytes to linear part if necessary
net/mlx4_core: Add masking for a few queries on HCA caps
netrom: switch to sock timer API
net/rose: fix NULL ax25_cb kernel panic
ucc_geth: Reset BQL queue when stopping device
l2tp: remove l2specific_len dependency in l2tp_core
l2tp: fix reading optional fields of L2TPv3
CIFS: Do not count -ENODATA as failure for query directory
fs/dcache: Fix incorrect nr_dentry_unused accounting in shrink_dcache_sb()
ARM: cns3xxx: Fix writing to wrong PCI config registers after alignment
arm64: hyp-stub: Forbid kprobing of the hyp-stub
gfs2: Revert "Fix loop in gfs2_rbm_find"
platform/x86: asus-nb-wmi: Map 0x35 to KEY_SCREENLOCK
platform/x86: asus-nb-wmi: Drop mapping of 0x33 and 0x34 scan codes
mmc: sdhci-iproc: handle mmc_of_parse() errors during probe
kernel/exit.c: release ptraced tasks before zap_pid_ns_processes
mm, oom: fix use-after-free in oom_kill_process
cifs: Always resolve hostname before reconnecting
drivers: core: Remove glue dirs from sysfs earlier
mm: migrate: don't rely on __PageMovable() of newpage after unlocking it
fs: don't scan the inode cache before SB_BORN is set
Linux 4.4.173
Change-Id: Ifc01c8b56016e9145bb67258f91dfc6b6983354c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/connect.c | 53 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 6 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 4 | ||||
-rw-r--r-- | fs/dcache.c | 6 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | fs/read_write.c | 4 | ||||
-rw-r--r-- | fs/super.c | 30 |
7 files changed, 87 insertions, 18 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 1eeb4780c3ed..eacf57c24ca9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -48,6 +48,7 @@ #include "cifs_unicode.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" +#include "dns_resolve.h" #include "ntlmssp.h" #include "nterr.h" #include "rfc1002pdu.h" @@ -304,6 +305,53 @@ static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, const char *devname); /* + * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may + * get their ip addresses changed at some point. + * + * This should be called with server->srv_mutex held. + */ +#ifdef CONFIG_CIFS_DFS_UPCALL +static int reconn_set_ipaddr(struct TCP_Server_Info *server) +{ + int rc; + int len; + char *unc, *ipaddr = NULL; + + if (!server->hostname) + return -EINVAL; + + len = strlen(server->hostname) + 3; + + unc = kmalloc(len, GFP_KERNEL); + if (!unc) { + cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__); + return -ENOMEM; + } + snprintf(unc, len, "\\\\%s", server->hostname); + + rc = dns_resolve_server_name_to_ip(unc, &ipaddr); + kfree(unc); + + if (rc < 0) { + cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n", + __func__, server->hostname, rc); + return rc; + } + + rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr, + strlen(ipaddr)); + kfree(ipaddr); + + return !rc ? -1 : 0; +} +#else +static inline int reconn_set_ipaddr(struct TCP_Server_Info *server) +{ + return 0; +} +#endif + +/* * cifs tcp session reconnection * * mark tcp session as reconnecting so temporarily locked @@ -400,6 +448,11 @@ cifs_reconnect(struct TCP_Server_Info *server) rc = generic_ip_connect(server); if (rc) { cifs_dbg(FYI, "reconnect error %d\n", rc); + rc = reconn_set_ipaddr(server); + if (rc) { + cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n", + __func__, rc); + } mutex_unlock(&server->srv_mutex); msleep(3000); } else { diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 2725085a3f9f..eae3cdffaf7f 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -143,14 +143,14 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, scredits = server->credits; /* can deadlock with reopen */ - if (scredits == 1) { + if (scredits <= 8) { *num = SMB2_MAX_BUFFER_SIZE; *credits = 0; break; } - /* leave one credit for a possible reopen */ - scredits--; + /* leave some credits for reopen and other ops */ + scredits -= 8; *num = min_t(unsigned int, size, scredits * SMB2_MAX_BUFFER_SIZE); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index f7111bb88ec1..5e21d58c49ef 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2523,8 +2523,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) { srch_inf->endOfSearch = true; rc = 0; - } - cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); + } else + cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); goto qdir_exit; } diff --git a/fs/dcache.c b/fs/dcache.c index b056cf8271a5..760f997fe8c6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1155,15 +1155,11 @@ static enum lru_status dentry_lru_isolate_shrink(struct list_head *item, */ void shrink_dcache_sb(struct super_block *sb) { - long freed; - do { LIST_HEAD(dispose); - freed = list_lru_walk(&sb->s_dentry_lru, + list_lru_walk(&sb->s_dentry_lru, dentry_lru_isolate_shrink, &dispose, 1024); - - this_cpu_sub(nr_dentry_unused, freed); shrink_dentry_list(&dispose); cond_resched(); } while (list_lru_count(&sb->s_dentry_lru) > 0); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 763fe7737065..ef24894edecc 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1720,9 +1720,9 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext, goto next_iter; } if (ret == -E2BIG) { - n += rbm->bii - initial_bii; rbm->bii = 0; rbm->offset = 0; + n += (rbm->bii - initial_bii); goto res_covered_end_of_rgrp; } return ret; diff --git a/fs/read_write.c b/fs/read_write.c index bfd1a5dddf6e..16e554ba885d 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -363,8 +363,10 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) iter->type |= WRITE; ret = file->f_op->write_iter(&kiocb, iter); BUG_ON(ret == -EIOCBQUEUED); - if (ret > 0) + if (ret > 0) { *ppos = kiocb.ki_pos; + fsnotify_modify(file); + } return ret; } EXPORT_SYMBOL(vfs_iter_write); diff --git a/fs/super.c b/fs/super.c index 652c9e6b6b92..eb27955a229a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -118,13 +118,23 @@ static unsigned long super_cache_count(struct shrinker *shrink, sb = container_of(shrink, struct super_block, s_shrink); /* - * Don't call trylock_super as it is a potential - * scalability bottleneck. The counts could get updated - * between super_cache_count and super_cache_scan anyway. - * Call to super_cache_count with shrinker_rwsem held - * ensures the safety of call to list_lru_shrink_count() and - * s_op->nr_cached_objects(). + * We don't call trylock_super() here as it is a scalability bottleneck, + * so we're exposed to partial setup state. The shrinker rwsem does not + * protect filesystem operations backing list_lru_shrink_count() or + * s_op->nr_cached_objects(). Counts can change between + * super_cache_count and super_cache_scan, so we really don't need locks + * here. + * + * However, if we are currently mounting the superblock, the underlying + * filesystem might be in a state of partial construction and hence it + * is dangerous to access it. trylock_super() uses a MS_BORN check to + * avoid this situation, so do the same here. The memory barrier is + * matched with the one in mount_fs() as we don't hold locks here. */ + if (!(sb->s_flags & MS_BORN)) + return 0; + smp_rmb(); + if (sb->s_op && sb->s_op->nr_cached_objects) total_objects = sb->s_op->nr_cached_objects(sb, sc); @@ -1151,6 +1161,14 @@ mount_fs(struct file_system_type *type, int flags, const char *name, struct vfsm sb = root->d_sb; BUG_ON(!sb); WARN_ON(!sb->s_bdi); + + /* + * Write barrier is for super_cache_count(). We place it before setting + * MS_BORN as the data dependency between the two functions is the + * superblock structure contents that we just set up, not the MS_BORN + * flag. + */ + smp_wmb(); sb->s_flags |= MS_BORN; error = security_sb_kern_mount(sb, flags, secdata); |