Import of kernel-4.18.0-553.111.1.el8_10
This commit is contained in:
parent
815b0a2cc8
commit
4248d3d5bb
@ -12,7 +12,7 @@ RHEL_MINOR = 10
|
||||
#
|
||||
# Use this spot to avoid future merge conflicts.
|
||||
# Do not trim this comment.
|
||||
RHEL_RELEASE = 553.109.1
|
||||
RHEL_RELEASE = 553.111.1
|
||||
|
||||
#
|
||||
# ZSTREAM
|
||||
|
||||
@ -62,7 +62,7 @@ struct macvlan_port {
|
||||
|
||||
struct macvlan_source_entry {
|
||||
struct hlist_node hlist;
|
||||
struct macvlan_dev *vlan;
|
||||
struct macvlan_dev __rcu *vlan;
|
||||
unsigned char addr[6+2] __aligned(sizeof(u16));
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
@ -150,7 +150,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source(
|
||||
|
||||
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
|
||||
if (ether_addr_equal_64bits(entry->addr, addr) &&
|
||||
entry->vlan == vlan)
|
||||
rcu_access_pointer(entry->vlan) == vlan)
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
@ -172,7 +172,7 @@ static int macvlan_hash_add_source(struct macvlan_dev *vlan,
|
||||
return -ENOMEM;
|
||||
|
||||
ether_addr_copy(entry->addr, addr);
|
||||
entry->vlan = vlan;
|
||||
RCU_INIT_POINTER(entry->vlan, vlan);
|
||||
h = &port->vlan_source_hash[macvlan_eth_hash(addr)];
|
||||
hlist_add_head_rcu(&entry->hlist, h);
|
||||
vlan->macaddr_count++;
|
||||
@ -191,6 +191,7 @@ static void macvlan_hash_add(struct macvlan_dev *vlan)
|
||||
|
||||
static void macvlan_hash_del_source(struct macvlan_source_entry *entry)
|
||||
{
|
||||
RCU_INIT_POINTER(entry->vlan, NULL);
|
||||
hlist_del_rcu(&entry->hlist);
|
||||
kfree_rcu(entry, rcu);
|
||||
}
|
||||
@ -402,7 +403,7 @@ static void macvlan_flush_sources(struct macvlan_port *port,
|
||||
|
||||
entry = hlist_entry(h, struct macvlan_source_entry,
|
||||
hlist);
|
||||
if (entry->vlan == vlan)
|
||||
if (rcu_access_pointer(entry->vlan) == vlan)
|
||||
macvlan_hash_del_source(entry);
|
||||
}
|
||||
}
|
||||
@ -444,8 +445,14 @@ static void macvlan_forward_source(struct sk_buff *skb,
|
||||
struct hlist_head *h = &port->vlan_source_hash[idx];
|
||||
|
||||
hlist_for_each_entry_rcu(entry, h, hlist) {
|
||||
if (ether_addr_equal_64bits(entry->addr, addr))
|
||||
macvlan_forward_source_one(skb, entry->vlan);
|
||||
if (ether_addr_equal_64bits(entry->addr, addr)) {
|
||||
struct macvlan_dev *vlan = rcu_dereference(entry->vlan);
|
||||
|
||||
if (!vlan)
|
||||
continue;
|
||||
|
||||
macvlan_forward_source_one(skb, vlan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1677,7 +1684,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb,
|
||||
struct macvlan_source_entry *entry;
|
||||
|
||||
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
|
||||
if (entry->vlan != vlan)
|
||||
if (rcu_access_pointer(entry->vlan) != vlan)
|
||||
continue;
|
||||
if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
|
||||
return 1;
|
||||
|
||||
@ -1016,6 +1016,7 @@ static void fbcon_init(struct vc_data *vc, int init)
|
||||
fvc->vc_font.data);
|
||||
vc->vc_font.width = fvc->vc_font.width;
|
||||
vc->vc_font.height = fvc->vc_font.height;
|
||||
vc->vc_font.charcount = fvc->vc_font.charcount;
|
||||
p->userfont = t->userfont;
|
||||
|
||||
if (p->userfont)
|
||||
@ -1346,6 +1347,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
|
||||
vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
|
||||
vc->vc_font.width = (*default_mode)->vc_font.width;
|
||||
vc->vc_font.height = (*default_mode)->vc_font.height;
|
||||
vc->vc_font.charcount = (*default_mode)->vc_font.charcount;
|
||||
p->userfont = t->userfont;
|
||||
if (p->userfont)
|
||||
REFCOUNT(p->fontdata)++;
|
||||
@ -2397,6 +2399,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
|
||||
REFCOUNT(data)++;
|
||||
vc->vc_font.width = w;
|
||||
vc->vc_font.height = h;
|
||||
vc->vc_font.charcount = cnt;
|
||||
if (vc->vc_hi_font_mask && cnt == 256)
|
||||
set_vc_hi_font(vc, false);
|
||||
else if (!vc->vc_hi_font_mask && cnt == 512)
|
||||
|
||||
@ -35,17 +35,21 @@ void set_fs_root(struct fs_struct *fs, const struct path *path)
|
||||
void set_fs_pwd(struct fs_struct *fs, const struct path *path)
|
||||
{
|
||||
struct path old_pwd;
|
||||
int count;
|
||||
|
||||
path_get(path);
|
||||
spin_lock(&fs->lock);
|
||||
write_seqcount_begin(&fs->seq);
|
||||
old_pwd = fs->pwd;
|
||||
fs->pwd = *path;
|
||||
count = fs->pwd_refs + 1;
|
||||
fs->pwd_refs = 0;
|
||||
write_seqcount_end(&fs->seq);
|
||||
spin_unlock(&fs->lock);
|
||||
|
||||
if (old_pwd.dentry)
|
||||
path_put(&old_pwd);
|
||||
while (count--)
|
||||
path_put(&old_pwd);
|
||||
}
|
||||
|
||||
static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
|
||||
@ -67,11 +71,16 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
|
||||
task_lock(p);
|
||||
fs = p->fs;
|
||||
if (fs) {
|
||||
int hits = 0;
|
||||
int hits;
|
||||
|
||||
spin_lock(&fs->lock);
|
||||
write_seqcount_begin(&fs->seq);
|
||||
hits = replace_path(&fs->pwd, old_root, new_root);
|
||||
if (hits && fs->pwd_refs) {
|
||||
count += fs->pwd_refs;
|
||||
fs->pwd_refs = 0;
|
||||
}
|
||||
hits += replace_path(&fs->root, old_root, new_root);
|
||||
hits += replace_path(&fs->pwd, old_root, new_root);
|
||||
write_seqcount_end(&fs->seq);
|
||||
while (hits--) {
|
||||
count++;
|
||||
@ -88,8 +97,11 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
|
||||
|
||||
void free_fs_struct(struct fs_struct *fs)
|
||||
{
|
||||
int count = fs->pwd_refs + 1;
|
||||
|
||||
path_put(&fs->root);
|
||||
path_put(&fs->pwd);
|
||||
while (count--)
|
||||
path_put(&fs->pwd);
|
||||
kmem_cache_free(fs_cachep, fs);
|
||||
}
|
||||
|
||||
@ -117,6 +129,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
|
||||
if (fs) {
|
||||
fs->users = 1;
|
||||
fs->in_exec = 0;
|
||||
fs->pwd_refs = 0;
|
||||
spin_lock_init(&fs->lock);
|
||||
seqcount_init(&fs->seq);
|
||||
fs->umask = old->umask;
|
||||
@ -125,7 +138,10 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
|
||||
fs->root = old->root;
|
||||
path_get(&fs->root);
|
||||
fs->pwd = old->pwd;
|
||||
path_get(&fs->pwd);
|
||||
if (old->pwd_refs)
|
||||
old->pwd_refs--;
|
||||
else
|
||||
path_get(&fs->pwd);
|
||||
spin_unlock(&old->lock);
|
||||
}
|
||||
return fs;
|
||||
|
||||
@ -3302,6 +3302,14 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
|
||||
* as belonging to new namespace. We have already acquired a private
|
||||
* fs_struct, so tsk->fs->lock is not needed.
|
||||
*/
|
||||
if (new_fs)
|
||||
WARN_ON_ONCE(new_fs->users != 1);
|
||||
|
||||
/* Release the extra pwd references of new_fs, if present. */
|
||||
while (new_fs && new_fs->pwd_refs) {
|
||||
path_put(&new_fs->pwd);
|
||||
new_fs->pwd_refs--;
|
||||
}
|
||||
p = old;
|
||||
q = new;
|
||||
while (p) {
|
||||
|
||||
@ -464,7 +464,8 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
|
||||
};
|
||||
struct pnfs_layout_segment *lseg, *next;
|
||||
|
||||
set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
|
||||
if (test_and_set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags))
|
||||
return !list_empty(&lo->plh_segs);
|
||||
clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags);
|
||||
list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
|
||||
pnfs_clear_lseg_state(lseg, lseg_list);
|
||||
|
||||
@ -12,6 +12,7 @@ struct fs_struct {
|
||||
seqcount_t seq;
|
||||
int umask;
|
||||
int in_exec;
|
||||
RH_KABI_FILL_HOLE(int pwd_refs) /* A pool of extra pwd references */
|
||||
struct path root, pwd;
|
||||
} __randomize_layout;
|
||||
|
||||
@ -40,6 +41,33 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
|
||||
spin_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
/* Acquire a pwd reference from the pwd_refs pool, if available */
|
||||
static inline void get_fs_pwd_pool(struct fs_struct *fs, struct path *pwd)
|
||||
{
|
||||
spin_lock(&fs->lock);
|
||||
*pwd = fs->pwd;
|
||||
if (fs->pwd_refs)
|
||||
fs->pwd_refs--;
|
||||
else
|
||||
path_get(pwd);
|
||||
spin_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
/* Release a pwd reference back to the pwd_refs pool, if appropriate */
|
||||
static inline void put_fs_pwd_pool(struct fs_struct *fs, struct path *pwd)
|
||||
{
|
||||
bool put = false;
|
||||
|
||||
spin_lock(&fs->lock);
|
||||
if ((fs->pwd.dentry == pwd->dentry) && (fs->pwd.mnt == pwd->mnt))
|
||||
fs->pwd_refs++;
|
||||
else
|
||||
put = true;
|
||||
spin_unlock(&fs->lock);
|
||||
if (put)
|
||||
path_put(pwd);
|
||||
}
|
||||
|
||||
extern bool current_chrooted(void);
|
||||
|
||||
#endif /* _LINUX_FS_STRUCT_H */
|
||||
|
||||
@ -887,6 +887,9 @@ static inline void audit_free_names(struct audit_context *context)
|
||||
{
|
||||
struct audit_names *n, *next;
|
||||
|
||||
if (!context->name_count)
|
||||
return; /* audit_alloc_name() has not been called */
|
||||
|
||||
list_for_each_entry_safe(n, next, &context->names_list, list) {
|
||||
list_del(&n->list);
|
||||
if (n->name)
|
||||
@ -895,7 +898,7 @@ static inline void audit_free_names(struct audit_context *context)
|
||||
kfree(n);
|
||||
}
|
||||
context->name_count = 0;
|
||||
path_put(&context->pwd);
|
||||
put_fs_pwd_pool(current->fs, &context->pwd);
|
||||
context->pwd.dentry = NULL;
|
||||
context->pwd.mnt = NULL;
|
||||
}
|
||||
@ -2000,7 +2003,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
|
||||
|
||||
context->name_count++;
|
||||
if (!context->pwd.dentry)
|
||||
get_fs_pwd(current->fs, &context->pwd);
|
||||
get_fs_pwd_pool(current->fs, &context->pwd);
|
||||
return aname;
|
||||
}
|
||||
|
||||
|
||||
@ -1336,7 +1336,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
|
||||
/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
|
||||
pad = ((new_end & 4) + (end & 7)) & 7;
|
||||
len_delta = new_end - (int)end + pad;
|
||||
ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
|
||||
ret_val = skb_cow(skb,
|
||||
skb_headroom(skb) + (len_delta > 0 ? len_delta : 0));
|
||||
if (ret_val < 0)
|
||||
return ret_val;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user