182 changes: 90 additions & 92 deletions fs/ext4/fast_commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,47 +1227,36 @@ static void ext4_fc_cleanup(journal_t *journal, int full)

/* Ext4 Replay Path Routines */

/* Get length of a particular tlv */
static inline int ext4_fc_tag_len(struct ext4_fc_tl *tl)
{
return le16_to_cpu(tl->fc_len);
}

/* Get a pointer to "value" of a tlv */
static inline u8 *ext4_fc_tag_val(struct ext4_fc_tl *tl)
{
return (u8 *)tl + sizeof(*tl);
}

/* Helper struct for dentry replay routines */
struct dentry_info_args {
int parent_ino, dname_len, ino, inode_len;
char *dname;
};

static inline void tl_to_darg(struct dentry_info_args *darg,
struct ext4_fc_tl *tl)
struct ext4_fc_tl *tl, u8 *val)
{
struct ext4_fc_dentry_info *fcd;
struct ext4_fc_dentry_info fcd;

fcd = (struct ext4_fc_dentry_info *)ext4_fc_tag_val(tl);
memcpy(&fcd, val, sizeof(fcd));

darg->parent_ino = le32_to_cpu(fcd->fc_parent_ino);
darg->ino = le32_to_cpu(fcd->fc_ino);
darg->dname = fcd->fc_dname;
darg->dname_len = ext4_fc_tag_len(tl) -
sizeof(struct ext4_fc_dentry_info);
darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
darg->ino = le32_to_cpu(fcd.fc_ino);
darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
darg->dname_len = le16_to_cpu(tl->fc_len) -
sizeof(struct ext4_fc_dentry_info);
}

/* Unlink replay function */
static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl)
static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{
struct inode *inode, *old_parent;
struct qstr entry;
struct dentry_info_args darg;
int ret = 0;

tl_to_darg(&darg, tl);
tl_to_darg(&darg, tl, val);

trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino,
darg.parent_ino, darg.dname_len);
Expand Down Expand Up @@ -1357,13 +1346,14 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
}

/* Link replay function */
static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl)
static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{
struct inode *inode;
struct dentry_info_args darg;
int ret = 0;

tl_to_darg(&darg, tl);
tl_to_darg(&darg, tl, val);
trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino,
darg.parent_ino, darg.dname_len);

Expand Down Expand Up @@ -1408,19 +1398,20 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
/*
* Inode replay function
*/
static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{
struct ext4_fc_inode *fc_inode;
struct ext4_fc_inode fc_inode;
struct ext4_inode *raw_inode;
struct ext4_inode *raw_fc_inode;
struct inode *inode = NULL;
struct ext4_iloc iloc;
int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
struct ext4_extent_header *eh;

fc_inode = (struct ext4_fc_inode *)ext4_fc_tag_val(tl);
memcpy(&fc_inode, val, sizeof(fc_inode));

ino = le32_to_cpu(fc_inode->fc_ino);
ino = le32_to_cpu(fc_inode.fc_ino);
trace_ext4_fc_replay(sb, tag, ino, 0, 0);

inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
Expand All @@ -1432,12 +1423,13 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)

ext4_fc_record_modified_inode(sb, ino);

raw_fc_inode = (struct ext4_inode *)fc_inode->fc_raw_inode;
raw_fc_inode = (struct ext4_inode *)
(val + offsetof(struct ext4_fc_inode, fc_raw_inode));
ret = ext4_get_fc_inode_loc(sb, ino, &iloc);
if (ret)
goto out;

inode_len = ext4_fc_tag_len(tl) - sizeof(struct ext4_fc_inode);
inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
raw_inode = ext4_raw_inode(&iloc);

memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
Expand Down Expand Up @@ -1505,14 +1497,15 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
* inode for which we are trying to create a dentry here, should already have
* been replayed before we start here.
*/
static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl)
static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{
int ret = 0;
struct inode *inode = NULL;
struct inode *dir = NULL;
struct dentry_info_args darg;

tl_to_darg(&darg, tl);
tl_to_darg(&darg, tl, val);

trace_ext4_fc_replay(sb, EXT4_FC_TAG_CREAT, darg.ino,
darg.parent_ino, darg.dname_len);
Expand Down Expand Up @@ -1591,9 +1584,9 @@ static int ext4_fc_record_regions(struct super_block *sb, int ino,

/* Replay add range tag */
static int ext4_fc_replay_add_range(struct super_block *sb,
struct ext4_fc_tl *tl)
struct ext4_fc_tl *tl, u8 *val)
{
struct ext4_fc_add_range *fc_add_ex;
struct ext4_fc_add_range fc_add_ex;
struct ext4_extent newex, *ex;
struct inode *inode;
ext4_lblk_t start, cur;
Expand All @@ -1603,15 +1596,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
struct ext4_ext_path *path = NULL;
int ret;

fc_add_ex = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl);
ex = (struct ext4_extent *)&fc_add_ex->fc_ex;
memcpy(&fc_add_ex, val, sizeof(fc_add_ex));
ex = (struct ext4_extent *)&fc_add_ex.fc_ex;

trace_ext4_fc_replay(sb, EXT4_FC_TAG_ADD_RANGE,
le32_to_cpu(fc_add_ex->fc_ino), le32_to_cpu(ex->ee_block),
le32_to_cpu(fc_add_ex.fc_ino), le32_to_cpu(ex->ee_block),
ext4_ext_get_actual_len(ex));

inode = ext4_iget(sb, le32_to_cpu(fc_add_ex->fc_ino),
EXT4_IGET_NORMAL);
inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL);
if (IS_ERR(inode)) {
jbd_debug(1, "Inode not found.");
return 0;
Expand Down Expand Up @@ -1720,32 +1712,33 @@ static int ext4_fc_replay_add_range(struct super_block *sb,

/* Replay DEL_RANGE tag */
static int
ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl)
ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
u8 *val)
{
struct inode *inode;
struct ext4_fc_del_range *lrange;
struct ext4_fc_del_range lrange;
struct ext4_map_blocks map;
ext4_lblk_t cur, remaining;
int ret;

lrange = (struct ext4_fc_del_range *)ext4_fc_tag_val(tl);
cur = le32_to_cpu(lrange->fc_lblk);
remaining = le32_to_cpu(lrange->fc_len);
memcpy(&lrange, val, sizeof(lrange));
cur = le32_to_cpu(lrange.fc_lblk);
remaining = le32_to_cpu(lrange.fc_len);

trace_ext4_fc_replay(sb, EXT4_FC_TAG_DEL_RANGE,
le32_to_cpu(lrange->fc_ino), cur, remaining);
le32_to_cpu(lrange.fc_ino), cur, remaining);

inode = ext4_iget(sb, le32_to_cpu(lrange->fc_ino), EXT4_IGET_NORMAL);
inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL);
if (IS_ERR(inode)) {
jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange->fc_ino));
jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino));
return 0;
}

ret = ext4_fc_record_modified_inode(sb, inode->i_ino);

jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n",
inode->i_ino, le32_to_cpu(lrange->fc_lblk),
le32_to_cpu(lrange->fc_len));
inode->i_ino, le32_to_cpu(lrange.fc_lblk),
le32_to_cpu(lrange.fc_len));
while (remaining > 0) {
map.m_lblk = cur;
map.m_len = remaining;
Expand All @@ -1766,8 +1759,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl)
}

ret = ext4_punch_hole(inode,
le32_to_cpu(lrange->fc_lblk) << sb->s_blocksize_bits,
le32_to_cpu(lrange->fc_len) << sb->s_blocksize_bits);
le32_to_cpu(lrange.fc_lblk) << sb->s_blocksize_bits,
le32_to_cpu(lrange.fc_len) << sb->s_blocksize_bits);
if (ret)
jbd_debug(1, "ext4_punch_hole returned %d", ret);
ext4_ext_replay_shrink_inode(inode,
Expand Down Expand Up @@ -1909,11 +1902,11 @@ static int ext4_fc_replay_scan(journal_t *journal,
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_fc_replay_state *state;
int ret = JBD2_FC_REPLAY_CONTINUE;
struct ext4_fc_add_range *ext;
struct ext4_fc_tl *tl;
struct ext4_fc_tail *tail;
__u8 *start, *end;
struct ext4_fc_head *head;
struct ext4_fc_add_range ext;
struct ext4_fc_tl tl;
struct ext4_fc_tail tail;
__u8 *start, *end, *cur, *val;
struct ext4_fc_head head;
struct ext4_extent *ex;

state = &sbi->s_fc_replay_state;
Expand All @@ -1940,15 +1933,17 @@ static int ext4_fc_replay_scan(journal_t *journal,
}

state->fc_replay_expected_off++;
fc_for_each_tl(start, end, tl) {
for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
memcpy(&tl, cur, sizeof(tl));
val = cur + sizeof(tl);
jbd_debug(3, "Scan phase, tag:%s, blk %lld\n",
tag2str(le16_to_cpu(tl->fc_tag)), bh->b_blocknr);
switch (le16_to_cpu(tl->fc_tag)) {
tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
switch (le16_to_cpu(tl.fc_tag)) {
case EXT4_FC_TAG_ADD_RANGE:
ext = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl);
ex = (struct ext4_extent *)&ext->fc_ex;
memcpy(&ext, val, sizeof(ext));
ex = (struct ext4_extent *)&ext.fc_ex;
ret = ext4_fc_record_regions(sb,
le32_to_cpu(ext->fc_ino),
le32_to_cpu(ext.fc_ino),
le32_to_cpu(ex->ee_block), ext4_ext_pblock(ex),
ext4_ext_get_actual_len(ex));
if (ret < 0)
Expand All @@ -1962,18 +1957,18 @@ static int ext4_fc_replay_scan(journal_t *journal,
case EXT4_FC_TAG_INODE:
case EXT4_FC_TAG_PAD:
state->fc_cur_tag++;
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
sizeof(*tl) + ext4_fc_tag_len(tl));
state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(tl) + le16_to_cpu(tl.fc_len));
break;
case EXT4_FC_TAG_TAIL:
state->fc_cur_tag++;
tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl);
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
sizeof(*tl) +
memcpy(&tail, val, sizeof(tail));
state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(tl) +
offsetof(struct ext4_fc_tail,
fc_crc));
if (le32_to_cpu(tail->fc_tid) == expected_tid &&
le32_to_cpu(tail->fc_crc) == state->fc_crc) {
if (le32_to_cpu(tail.fc_tid) == expected_tid &&
le32_to_cpu(tail.fc_crc) == state->fc_crc) {
state->fc_replay_num_tags = state->fc_cur_tag;
state->fc_regions_valid =
state->fc_regions_used;
Expand All @@ -1984,19 +1979,19 @@ static int ext4_fc_replay_scan(journal_t *journal,
state->fc_crc = 0;
break;
case EXT4_FC_TAG_HEAD:
head = (struct ext4_fc_head *)ext4_fc_tag_val(tl);
if (le32_to_cpu(head->fc_features) &
memcpy(&head, val, sizeof(head));
if (le32_to_cpu(head.fc_features) &
~EXT4_FC_SUPPORTED_FEATURES) {
ret = -EOPNOTSUPP;
break;
}
if (le32_to_cpu(head->fc_tid) != expected_tid) {
if (le32_to_cpu(head.fc_tid) != expected_tid) {
ret = JBD2_FC_REPLAY_STOP;
break;
}
state->fc_cur_tag++;
state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
sizeof(*tl) + ext4_fc_tag_len(tl));
state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
sizeof(tl) + le16_to_cpu(tl.fc_len));
break;
default:
ret = state->fc_replay_num_tags ?
Expand All @@ -2020,11 +2015,11 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
{
struct super_block *sb = journal->j_private;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_fc_tl *tl;
__u8 *start, *end;
struct ext4_fc_tl tl;
__u8 *start, *end, *cur, *val;
int ret = JBD2_FC_REPLAY_CONTINUE;
struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state;
struct ext4_fc_tail *tail;
struct ext4_fc_tail tail;

if (pass == PASS_SCAN) {
state->fc_current_pass = PASS_SCAN;
Expand All @@ -2051,49 +2046,52 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
start = (u8 *)bh->b_data;
end = (__u8 *)bh->b_data + journal->j_blocksize - 1;

fc_for_each_tl(start, end, tl) {
for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
memcpy(&tl, cur, sizeof(tl));
val = cur + sizeof(tl);

if (state->fc_replay_num_tags == 0) {
ret = JBD2_FC_REPLAY_STOP;
ext4_fc_set_bitmaps_and_counters(sb);
break;
}
jbd_debug(3, "Replay phase, tag:%s\n",
tag2str(le16_to_cpu(tl->fc_tag)));
tag2str(le16_to_cpu(tl.fc_tag)));
state->fc_replay_num_tags--;
switch (le16_to_cpu(tl->fc_tag)) {
switch (le16_to_cpu(tl.fc_tag)) {
case EXT4_FC_TAG_LINK:
ret = ext4_fc_replay_link(sb, tl);
ret = ext4_fc_replay_link(sb, &tl, val);
break;
case EXT4_FC_TAG_UNLINK:
ret = ext4_fc_replay_unlink(sb, tl);
ret = ext4_fc_replay_unlink(sb, &tl, val);
break;
case EXT4_FC_TAG_ADD_RANGE:
ret = ext4_fc_replay_add_range(sb, tl);
ret = ext4_fc_replay_add_range(sb, &tl, val);
break;
case EXT4_FC_TAG_CREAT:
ret = ext4_fc_replay_create(sb, tl);
ret = ext4_fc_replay_create(sb, &tl, val);
break;
case EXT4_FC_TAG_DEL_RANGE:
ret = ext4_fc_replay_del_range(sb, tl);
ret = ext4_fc_replay_del_range(sb, &tl, val);
break;
case EXT4_FC_TAG_INODE:
ret = ext4_fc_replay_inode(sb, tl);
ret = ext4_fc_replay_inode(sb, &tl, val);
break;
case EXT4_FC_TAG_PAD:
trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
ext4_fc_tag_len(tl), 0);
le16_to_cpu(tl.fc_len), 0);
break;
case EXT4_FC_TAG_TAIL:
trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
ext4_fc_tag_len(tl), 0);
tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl);
WARN_ON(le32_to_cpu(tail->fc_tid) != expected_tid);
le16_to_cpu(tl.fc_len), 0);
memcpy(&tail, val, sizeof(tail));
WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
break;
case EXT4_FC_TAG_HEAD:
break;
default:
trace_ext4_fc_replay(sb, le16_to_cpu(tl->fc_tag), 0,
ext4_fc_tag_len(tl), 0);
trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
le16_to_cpu(tl.fc_len), 0);
ret = -ECANCELED;
break;
}
Expand Down
7 changes: 0 additions & 7 deletions fs/ext4/fast_commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,5 @@ struct ext4_fc_replay_state {

#define region_last(__region) (((__region)->lblk) + ((__region)->len) - 1)

#define fc_for_each_tl(__start, __end, __tl) \
for (tl = (struct ext4_fc_tl *)start; \
(u8 *)tl < (u8 *)end; \
tl = (struct ext4_fc_tl *)((u8 *)tl + \
sizeof(struct ext4_fc_tl) + \
+ le16_to_cpu(tl->fc_len)))


#endif /* __FAST_COMMIT_H__ */
6 changes: 4 additions & 2 deletions fs/ext4/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,16 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
if (is_directory) {
count = ext4_used_dirs_count(sb, gdp) - 1;
ext4_used_dirs_set(sb, gdp, count);
percpu_counter_dec(&sbi->s_dirs_counter);
if (percpu_counter_initialized(&sbi->s_dirs_counter))
percpu_counter_dec(&sbi->s_dirs_counter);
}
ext4_inode_bitmap_csum_set(sb, block_group, gdp, bitmap_bh,
EXT4_INODES_PER_GROUP(sb) / 8);
ext4_group_desc_csum_set(sb, block_group, gdp);
ext4_unlock_group(sb, block_group);

percpu_counter_inc(&sbi->s_freeinodes_counter);
if (percpu_counter_initialized(&sbi->s_freeinodes_counter))
percpu_counter_inc(&sbi->s_freeinodes_counter);
if (sbi->s_log_groups_per_flex) {
struct flex_groups *fg;

Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/mballoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2738,7 +2738,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
*/
if (sbi->s_es->s_log_groups_per_flex >= 32) {
ext4_msg(sb, KERN_ERR, "too many log groups per flexible block group");
goto err_freesgi;
goto err_freebuddy;
}
sbi->s_mb_prefetch = min_t(uint, 1 << sbi->s_es->s_log_groups_per_flex,
BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9));
Expand Down
11 changes: 9 additions & 2 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -4451,14 +4451,20 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
}

if (sb->s_blocksize != blocksize) {
/*
* bh must be released before kill_bdev(), otherwise
* it won't be freed and its page also. kill_bdev()
* is called by sb_set_blocksize().
*/
brelse(bh);
/* Validate the filesystem blocksize */
if (!sb_set_blocksize(sb, blocksize)) {
ext4_msg(sb, KERN_ERR, "bad block size %d",
blocksize);
bh = NULL;
goto failed_mount;
}

brelse(bh);
logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
offset = do_div(logical_sb_block, blocksize);
bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
Expand Down Expand Up @@ -5181,8 +5187,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
kfree(get_qf_name(sb, sbi, i));
#endif
fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
ext4_blkdev_remove(sbi);
/* ext4_blkdev_remove() calls kill_bdev(), release bh before it. */
brelse(bh);
ext4_blkdev_remove(sbi);
out_fail:
sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock);
Expand Down
2 changes: 2 additions & 0 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1457,9 +1457,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
glock_blocked_by_withdraw(gl) &&
gh->gh_gl != sdp->sd_jinode_gl) {
sdp->sd_glock_dqs_held++;
spin_unlock(&gl->gl_lockref.lock);
might_sleep();
wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY,
TASK_UNINTERRUPTIBLE);
spin_lock(&gl->gl_lockref.lock);
}
if (gh->gh_flags & GL_NOCACHE)
handle_callback(gl, LM_ST_UNLOCKED, 0, false);
Expand Down
6 changes: 4 additions & 2 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ struct io_statx {
struct io_completion {
struct file *file;
struct list_head list;
int cflags;
u32 cflags;
};

struct io_async_connect {
Expand Down Expand Up @@ -1711,7 +1711,8 @@ static void io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,
}
}

static void __io_cqring_fill_event(struct io_kiocb *req, long res, long cflags)
static void __io_cqring_fill_event(struct io_kiocb *req, long res,
unsigned int cflags)
{
struct io_ring_ctx *ctx = req->ctx;
struct io_uring_cqe *cqe;
Expand Down Expand Up @@ -6266,6 +6267,7 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
if (prev) {
io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME);
io_put_req_deferred(prev, 1);
io_put_req_deferred(req, 1);
} else {
io_cqring_add_event(req, -ETIME, 0);
io_put_req_deferred(req, 1);
Expand Down
55 changes: 50 additions & 5 deletions fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1855,6 +1855,45 @@ int ocfs2_remove_inode_range(struct inode *inode,
return ret;
}

/*
* zero out partial blocks of one cluster.
*
* start: file offset where zero starts, will be made upper block aligned.
* len: it will be trimmed to the end of current cluster if "start + len"
* is bigger than it.
*/
static int ocfs2_zeroout_partial_cluster(struct inode *inode,
u64 start, u64 len)
{
int ret;
u64 start_block, end_block, nr_blocks;
u64 p_block, offset;
u32 cluster, p_cluster, nr_clusters;
struct super_block *sb = inode->i_sb;
u64 end = ocfs2_align_bytes_to_clusters(sb, start);

if (start + len < end)
end = start + len;

start_block = ocfs2_blocks_for_bytes(sb, start);
end_block = ocfs2_blocks_for_bytes(sb, end);
nr_blocks = end_block - start_block;
if (!nr_blocks)
return 0;

cluster = ocfs2_bytes_to_clusters(sb, start);
ret = ocfs2_get_clusters(inode, cluster, &p_cluster,
&nr_clusters, NULL);
if (ret)
return ret;
if (!p_cluster)
return 0;

offset = start_block - ocfs2_clusters_to_blocks(sb, cluster);
p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset;
return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS);
}

/*
* Parts of this function taken from xfs_change_file_space()
*/
Expand All @@ -1865,7 +1904,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
{
int ret;
s64 llen;
loff_t size;
loff_t size, orig_isize;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct buffer_head *di_bh = NULL;
handle_t *handle;
Expand Down Expand Up @@ -1896,14 +1935,15 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
goto out_inode_unlock;
}

orig_isize = i_size_read(inode);
switch (sr->l_whence) {
case 0: /*SEEK_SET*/
break;
case 1: /*SEEK_CUR*/
sr->l_start += f_pos;
break;
case 2: /*SEEK_END*/
sr->l_start += i_size_read(inode);
sr->l_start += orig_isize;
break;
default:
ret = -EINVAL;
Expand Down Expand Up @@ -1957,6 +1997,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
default:
ret = -EINVAL;
}

/* zeroout eof blocks in the cluster. */
if (!ret && change_size && orig_isize < size) {
ret = ocfs2_zeroout_partial_cluster(inode, orig_isize,
size - orig_isize);
if (!ret)
i_size_write(inode, size);
}
up_write(&OCFS2_I(inode)->ip_alloc_sem);
if (ret) {
mlog_errno(ret);
Expand All @@ -1973,9 +2021,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
goto out_inode_unlock;
}

if (change_size && i_size_read(inode) < size)
i_size_write(inode, size);

inode->i_ctime = inode->i_mtime = current_time(inode);
ret = ocfs2_mark_inode_dirty(handle, inode, di_bh);
if (ret < 0)
Expand Down
2 changes: 2 additions & 0 deletions include/linux/mlx5/mlx5_ifc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,8 @@ enum mlx5_fc_bulk_alloc_bitmask {

#define MLX5_FC_BULK_NUM_FCS(fc_enum) (MLX5_FC_BULK_SIZE_FACTOR * (fc_enum))

#define MLX5_FT_MAX_MULTIPATH_LEVEL 63

enum {
MLX5_STEERING_FORMAT_CONNECTX_5 = 0,
MLX5_STEERING_FORMAT_CONNECTX_6DX = 1,
Expand Down
1 change: 1 addition & 0 deletions include/linux/platform_data/ti-sysc.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct sysc_regbits {
s8 emufree_shift;
};

#define SYSC_QUIRK_REINIT_ON_RESUME BIT(27)
#define SYSC_QUIRK_GPMC_DEBUG BIT(26)
#define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25)
#define SYSC_MODULE_QUIRK_PRUSS BIT(24)
Expand Down
2 changes: 2 additions & 0 deletions include/linux/usb/usbnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct usbnet {
# define EVENT_LINK_CHANGE 11
# define EVENT_SET_RX_MODE 12
# define EVENT_NO_IP_ALIGN 13
u32 rx_speed; /* in bps - NOT Mbps */
u32 tx_speed; /* in bps - NOT Mbps */
};

static inline struct usb_driver *driver_of(struct usb_interface *intf)
Expand Down
2 changes: 1 addition & 1 deletion include/net/caif/caif_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *adap_layer);
* The link_support layer is used to add any Link Layer specific
* framing.
*/
void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
struct cflayer *link_support, int head_room,
struct cflayer **layer, int (**rcv_func)(
struct sk_buff *, struct net_device *,
Expand Down
2 changes: 1 addition & 1 deletion include/net/caif/cfcnfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg);
* @fcs: Specify if checksum is used in CAIF Framing Layer.
* @head_room: Head space needed by link specific protocol.
*/
void
int
cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
struct net_device *dev, struct cflayer *phy_layer,
enum cfcnfg_phy_preference pref,
Expand Down
1 change: 1 addition & 0 deletions include/net/caif/cfserl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
#include <net/caif/caif_layer.h>

struct cflayer *cfserl_create(int instance, bool use_stx);
void cfserl_release(struct cflayer *layer);
#endif
10 changes: 9 additions & 1 deletion include/net/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,11 @@ struct tls_offload_context_tx {
(sizeof(struct tls_offload_context_tx) + TLS_DRIVER_STATE_SIZE_TX)

enum tls_context_flags {
TLS_RX_SYNC_RUNNING = 0,
/* tls_device_down was called after the netdev went down, device state
* was released, and kTLS works in software, even though rx_conf is
* still TLS_HW (needed for transition).
*/
TLS_RX_DEV_DEGRADED = 0,
/* Unlike RX where resync is driven entirely by the core in TX only
* the driver knows when things went out of sync, so we need the flag
* to be atomic.
Expand Down Expand Up @@ -265,6 +269,7 @@ struct tls_context {

/* cache cold stuff */
struct proto *sk_proto;
struct sock *sk;

void (*sk_destruct)(struct sock *sk);

Expand Down Expand Up @@ -447,6 +452,9 @@ static inline u16 tls_user_config(struct tls_context *ctx, bool tx)
struct sk_buff *
tls_validate_xmit_skb(struct sock *sk, struct net_device *dev,
struct sk_buff *skb);
struct sk_buff *
tls_validate_xmit_skb_sw(struct sock *sk, struct net_device *dev,
struct sk_buff *skb);

static inline bool tls_is_sk_tx_device_offloaded(struct sock *sk)
{
Expand Down
2 changes: 1 addition & 1 deletion init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,7 +1505,7 @@ static noinline void __init kernel_init_freeable(void)
*/
set_mems_allowed(node_states[N_MEMORY]);

cad_pid = task_pid(current);
cad_pid = get_pid(task_pid(current));

smp_prepare_cpus(setup_max_cpus);

Expand Down
19 changes: 9 additions & 10 deletions kernel/bpf/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/jiffies.h>
#include <linux/pid_namespace.h>
#include <linux/proc_ns.h>
#include <linux/security.h>

#include "../../lib/kstrtox.h"

Expand Down Expand Up @@ -707,14 +708,6 @@ bpf_base_func_proto(enum bpf_func_id func_id)
return &bpf_spin_lock_proto;
case BPF_FUNC_spin_unlock:
return &bpf_spin_unlock_proto;
case BPF_FUNC_trace_printk:
if (!perfmon_capable())
return NULL;
return bpf_get_trace_printk_proto();
case BPF_FUNC_snprintf_btf:
if (!perfmon_capable())
return NULL;
return &bpf_snprintf_btf_proto;
case BPF_FUNC_jiffies64:
return &bpf_jiffies64_proto;
case BPF_FUNC_per_cpu_ptr:
Expand All @@ -729,16 +722,22 @@ bpf_base_func_proto(enum bpf_func_id func_id)
return NULL;

switch (func_id) {
case BPF_FUNC_trace_printk:
return bpf_get_trace_printk_proto();
case BPF_FUNC_get_current_task:
return &bpf_get_current_task_proto;
case BPF_FUNC_probe_read_user:
return &bpf_probe_read_user_proto;
case BPF_FUNC_probe_read_kernel:
return &bpf_probe_read_kernel_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_kernel_proto;
case BPF_FUNC_probe_read_user_str:
return &bpf_probe_read_user_str_proto;
case BPF_FUNC_probe_read_kernel_str:
return &bpf_probe_read_kernel_str_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_kernel_str_proto;
case BPF_FUNC_snprintf_btf:
return &bpf_snprintf_btf_proto;
default:
return NULL;
}
Expand Down
32 changes: 12 additions & 20 deletions kernel/trace/bpf_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,11 @@ const struct bpf_func_proto bpf_probe_read_user_str_proto = {
static __always_inline int
bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr)
{
int ret = security_locked_down(LOCKDOWN_BPF_READ);
int ret;

if (unlikely(ret < 0))
goto fail;
ret = copy_from_kernel_nofault(dst, unsafe_ptr, size);
if (unlikely(ret < 0))
goto fail;
return ret;
fail:
memset(dst, 0, size);
memset(dst, 0, size);
return ret;
}

Expand All @@ -243,10 +238,7 @@ const struct bpf_func_proto bpf_probe_read_kernel_proto = {
static __always_inline int
bpf_probe_read_kernel_str_common(void *dst, u32 size, const void *unsafe_ptr)
{
int ret = security_locked_down(LOCKDOWN_BPF_READ);

if (unlikely(ret < 0))
goto fail;
int ret;

/*
* The strncpy_from_kernel_nofault() call will likely not fill the
Expand All @@ -259,11 +251,7 @@ bpf_probe_read_kernel_str_common(void *dst, u32 size, const void *unsafe_ptr)
*/
ret = strncpy_from_kernel_nofault(dst, unsafe_ptr, size);
if (unlikely(ret < 0))
goto fail;

return ret;
fail:
memset(dst, 0, size);
memset(dst, 0, size);
return ret;
}

Expand Down Expand Up @@ -1293,16 +1281,20 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_probe_read_user:
return &bpf_probe_read_user_proto;
case BPF_FUNC_probe_read_kernel:
return &bpf_probe_read_kernel_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_kernel_proto;
case BPF_FUNC_probe_read_user_str:
return &bpf_probe_read_user_str_proto;
case BPF_FUNC_probe_read_kernel_str:
return &bpf_probe_read_kernel_str_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_kernel_str_proto;
#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
case BPF_FUNC_probe_read:
return &bpf_probe_read_compat_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_compat_proto;
case BPF_FUNC_probe_read_str:
return &bpf_probe_read_compat_str_proto;
return security_locked_down(LOCKDOWN_BPF_READ) < 0 ?
NULL : &bpf_probe_read_compat_str_proto;
#endif
#ifdef CONFIG_CGROUPS
case BPF_FUNC_get_current_cgroup_id:
Expand Down
6 changes: 5 additions & 1 deletion lib/lz4/lz4_decompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,11 @@ static FORCE_INLINE int LZ4_decompress_generic(
}
}

LZ4_memcpy(op, ip, length);
/*
* supports overlapping memory regions; only matters
* for in-place decompression scenarios
*/
LZ4_memmove(op, ip, length);
ip += length;
op += length;

Expand Down
1 change: 1 addition & 0 deletions lib/lz4/lz4defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
* environments. This is needed when decompressing the Linux Kernel, for example.
*/
#define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
#define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size)

static FORCE_INLINE void LZ4_copy8(void *dst, const void *src)
{
Expand Down
4 changes: 2 additions & 2 deletions mm/debug_vm_pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static void __init pmd_advanced_tests(struct mm_struct *mm,

pr_debug("Validating PMD advanced\n");
/* Align the address wrt HPAGE_PMD_SIZE */
vaddr = (vaddr & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE;
vaddr &= HPAGE_PMD_MASK;

pgtable_trans_huge_deposit(mm, pmdp, pgtable);

Expand Down Expand Up @@ -285,7 +285,7 @@ static void __init pud_advanced_tests(struct mm_struct *mm,

pr_debug("Validating PUD advanced\n");
/* Align the address wrt HPAGE_PUD_SIZE */
vaddr = (vaddr & HPAGE_PUD_MASK) + HPAGE_PUD_SIZE;
vaddr &= HPAGE_PUD_MASK;

set_pud_at(mm, vaddr, pudp, pud);
pudp_set_wrprotect(mm, vaddr, pudp);
Expand Down
14 changes: 12 additions & 2 deletions mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4708,10 +4708,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
struct page *page;

if (!*pagep) {
ret = -ENOMEM;
/* If a page already exists, then it's UFFDIO_COPY for
* a non-missing case. Return -EEXIST.
*/
if (vm_shared &&
hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) {
ret = -EEXIST;
goto out;
}

page = alloc_huge_page(dst_vma, dst_addr, 0);
if (IS_ERR(page))
if (IS_ERR(page)) {
ret = -ENOMEM;
goto out;
}

ret = copy_huge_page_from_user(page,
(const void __user *) src_addr,
Expand Down
2 changes: 2 additions & 0 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8868,6 +8868,8 @@ bool take_page_off_buddy(struct page *page)
del_page_from_free_list(page_head, zone, page_order);
break_down_buddy_pages(zone, page_head, page, 0,
page_order, migratetype);
if (!is_migrate_isolate(migratetype))
__mod_zone_freepage_state(zone, -1, migratetype);
ret = true;
break;
}
Expand Down
7 changes: 6 additions & 1 deletion net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1602,8 +1602,13 @@ static int hci_dev_do_open(struct hci_dev *hdev)
} else {
/* Init failed, cleanup */
flush_work(&hdev->tx_work);
flush_work(&hdev->cmd_work);

/* Since hci_rx_work() is possible to awake new cmd_work
* it should be flushed first to avoid unexpected call of
* hci_cmd_work()
*/
flush_work(&hdev->rx_work);
flush_work(&hdev->cmd_work);

skb_queue_purge(&hdev->cmd_q);
skb_queue_purge(&hdev->rx_q);
Expand Down
4 changes: 2 additions & 2 deletions net/bluetooth/hci_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
lock_sock(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
Expand All @@ -771,7 +771,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)

hci_dev_put(hdev);
}
bh_unlock_sock(sk);
release_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
Expand Down
13 changes: 9 additions & 4 deletions net/caif/caif_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ static void dev_flowctrl(struct net_device *dev, int on)
caifd_put(caifd);
}

void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
struct cflayer *link_support, int head_room,
struct cflayer **layer,
int (**rcv_func)(struct sk_buff *, struct net_device *,
Expand All @@ -319,11 +319,12 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
enum cfcnfg_phy_preference pref;
struct cfcnfg *cfg = get_cfcnfg(dev_net(dev));
struct caif_device_entry_list *caifdevs;
int res;

caifdevs = caif_device_list(dev_net(dev));
caifd = caif_device_alloc(dev);
if (!caifd)
return;
return -ENOMEM;
*layer = &caifd->layer;
spin_lock_init(&caifd->flow_lock);

Expand All @@ -344,7 +345,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
strlcpy(caifd->layer.name, dev->name,
sizeof(caifd->layer.name));
caifd->layer.transmit = transmit;
cfcnfg_add_phy_layer(cfg,
res = cfcnfg_add_phy_layer(cfg,
dev,
&caifd->layer,
pref,
Expand All @@ -354,6 +355,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
mutex_unlock(&caifdevs->lock);
if (rcv_func)
*rcv_func = receive;
return res;
}
EXPORT_SYMBOL(caif_enroll_dev);

Expand All @@ -368,6 +370,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
struct cflayer *layer, *link_support;
int head_room = 0;
struct caif_device_entry_list *caifdevs;
int res;

cfg = get_cfcnfg(dev_net(dev));
caifdevs = caif_device_list(dev_net(dev));
Expand All @@ -393,8 +396,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
break;
}
}
caif_enroll_dev(dev, caifdev, link_support, head_room,
res = caif_enroll_dev(dev, caifdev, link_support, head_room,
&layer, NULL);
if (res)
cfserl_release(link_support);
caifdev->flowctrl = dev_flowctrl;
break;

Expand Down
14 changes: 13 additions & 1 deletion net/caif/caif_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],
return (struct cflayer *) this;
}

static void cfusbl_release(struct cflayer *layer)
{
kfree(layer);
}

static struct packet_type caif_usb_type __read_mostly = {
.type = cpu_to_be16(ETH_P_802_EX1),
};
Expand All @@ -127,6 +132,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what,
struct cflayer *layer, *link_support;
struct usbnet *usbnet;
struct usb_device *usbdev;
int res;

/* Check whether we have a NCM device, and find its VID/PID. */
if (!(dev->dev.parent && dev->dev.parent->driver &&
Expand Down Expand Up @@ -169,15 +175,21 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what,
if (dev->num_tx_queues > 1)
pr_warn("USB device uses more than one tx queue\n");

caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
&layer, &caif_usb_type.func);
if (res)
goto err;

if (!pack_added)
dev_add_pack(&caif_usb_type);
pack_added = true;

strlcpy(layer->name, dev->name, sizeof(layer->name));

return 0;
err:
cfusbl_release(link_support);
return res;
}

static struct notifier_block caif_device_notifier = {
Expand Down
16 changes: 11 additions & 5 deletions net/caif/cfcnfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
rcu_read_unlock();
}

void
int
cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
struct net_device *dev, struct cflayer *phy_layer,
enum cfcnfg_phy_preference pref,
Expand All @@ -459,7 +459,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
{
struct cflayer *frml;
struct cfcnfg_phyinfo *phyinfo = NULL;
int i;
int i, res = 0;
u8 phyid;

mutex_lock(&cnfg->lock);
Expand All @@ -473,12 +473,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
goto got_phyid;
}
pr_warn("Too many CAIF Link Layers (max 6)\n");
res = -EEXIST;
goto out;

got_phyid:
phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC);
if (!phyinfo)
if (!phyinfo) {
res = -ENOMEM;
goto out_err;
}

phy_layer->id = phyid;
phyinfo->pref = pref;
Expand All @@ -492,8 +495,10 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,

frml = cffrml_create(phyid, fcs);

if (!frml)
if (!frml) {
res = -ENOMEM;
goto out_err;
}
phyinfo->frm_layer = frml;
layer_set_up(frml, cnfg->mux);

Expand All @@ -511,11 +516,12 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
list_add_rcu(&phyinfo->node, &cnfg->phys);
out:
mutex_unlock(&cnfg->lock);
return;
return res;

out_err:
kfree(phyinfo);
mutex_unlock(&cnfg->lock);
return res;
}
EXPORT_SYMBOL(cfcnfg_add_phy_layer);

Expand Down
5 changes: 5 additions & 0 deletions net/caif/cfserl.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt);
static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
int phyid);

void cfserl_release(struct cflayer *layer)
{
kfree(layer);
}

struct cflayer *cfserl_create(int instance, bool use_stx)
{
struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC);
Expand Down
4 changes: 2 additions & 2 deletions net/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,6 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
case DEVLINK_PORT_FLAVOUR_PHYSICAL:
case DEVLINK_PORT_FLAVOUR_CPU:
case DEVLINK_PORT_FLAVOUR_DSA:
case DEVLINK_PORT_FLAVOUR_VIRTUAL:
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
attrs->phys.port_number))
return -EMSGSIZE;
Expand Down Expand Up @@ -8376,7 +8375,6 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,

switch (attrs->flavour) {
case DEVLINK_PORT_FLAVOUR_PHYSICAL:
case DEVLINK_PORT_FLAVOUR_VIRTUAL:
if (!attrs->split)
n = snprintf(name, len, "p%u", attrs->phys.port_number);
else
Expand Down Expand Up @@ -8413,6 +8411,8 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
n = snprintf(name, len, "pf%uvf%u",
attrs->pci_vf.pf, attrs->pci_vf.vf);
break;
case DEVLINK_PORT_FLAVOUR_VIRTUAL:
return -EOPNOTSUPP;
}

if (n >= len)
Expand Down
1 change: 1 addition & 0 deletions net/core/neighbour.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ static int neigh_forced_gc(struct neigh_table *tbl)

write_lock(&n->lock);
if ((n->nud_state == NUD_FAILED) ||
(n->nud_state == NUD_NOARP) ||
(tbl->is_multicast &&
tbl->is_multicast(n->primary_key)) ||
time_after(tref, n->updated))
Expand Down
16 changes: 12 additions & 4 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,10 +807,18 @@ void sock_set_rcvbuf(struct sock *sk, int val)
}
EXPORT_SYMBOL(sock_set_rcvbuf);

static void __sock_set_mark(struct sock *sk, u32 val)
{
if (val != sk->sk_mark) {
sk->sk_mark = val;
sk_dst_reset(sk);
}
}

void sock_set_mark(struct sock *sk, u32 val)
{
lock_sock(sk);
sk->sk_mark = val;
__sock_set_mark(sk, val);
release_sock(sk);
}
EXPORT_SYMBOL(sock_set_mark);
Expand Down Expand Up @@ -1118,10 +1126,10 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
case SO_MARK:
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
ret = -EPERM;
} else if (val != sk->sk_mark) {
sk->sk_mark = val;
sk_dst_reset(sk);
break;
}

__sock_set_mark(sk, val);
break;

case SO_RXQ_OVFL:
Expand Down
2 changes: 1 addition & 1 deletion net/dsa/tag_8021q.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
#define DSA_8021Q_SUBVLAN_HI_SHIFT 9
#define DSA_8021Q_SUBVLAN_HI_MASK GENMASK(9, 9)
#define DSA_8021Q_SUBVLAN_LO_SHIFT 4
#define DSA_8021Q_SUBVLAN_LO_MASK GENMASK(4, 3)
#define DSA_8021Q_SUBVLAN_LO_MASK GENMASK(5, 4)
#define DSA_8021Q_SUBVLAN_HI(x) (((x) & GENMASK(2, 2)) >> 2)
#define DSA_8021Q_SUBVLAN_LO(x) ((x) & GENMASK(1, 0))
#define DSA_8021Q_SUBVLAN(x) \
Expand Down
4 changes: 3 additions & 1 deletion net/ieee802154/nl-mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,8 +680,10 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info)
nla_put_u8(msg, IEEE802154_ATTR_LLSEC_SECLEVEL, params.out_level) ||
nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER,
be32_to_cpu(params.frame_counter)) ||
ieee802154_llsec_fill_key_id(msg, &params.out_key))
ieee802154_llsec_fill_key_id(msg, &params.out_key)) {
rc = -ENOBUFS;
goto out_free;
}

dev_put(dev);

Expand Down
4 changes: 3 additions & 1 deletion net/ieee802154/nl-phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
}

if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name))
nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) {
rc = -EMSGSIZE;
goto nla_put_failure;
}
dev_put(dev);

wpan_phy_put(phy);
Expand Down
8 changes: 6 additions & 2 deletions net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -3671,11 +3671,11 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
if (nh) {
if (rt->fib6_src.plen) {
NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
goto out;
goto out_free;
}
if (!nexthop_get(nh)) {
NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
goto out;
goto out_free;
}
rt->nh = nh;
fib6_nh = nexthop_fib6_nh(rt->nh);
Expand Down Expand Up @@ -3712,6 +3712,10 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
out:
fib6_info_release(rt);
return ERR_PTR(err);
out_free:
ip_fib_metrics_put(rt->fib6_metrics);
kfree(rt);
return ERR_PTR(err);
}

int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags,
Expand Down
17 changes: 8 additions & 9 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,21 +527,20 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,

/* if the sk is MP_CAPABLE, we try to fetch the client key */
if (subflow_req->mp_capable) {
if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) {
/* here we can receive and accept an in-window,
* out-of-order pkt, which will not carry the MP_CAPABLE
* opt even on mptcp enabled paths
*/
goto create_msk;
}

/* we can receive and accept an in-window, out-of-order pkt,
* which may not carry the MP_CAPABLE opt even on mptcp enabled
* paths: always try to extract the peer key, and fallback
* for packets missing it.
* Even OoO DSS packets coming legitly after dropped or
* reordered MPC will cause fallback, but we don't have other
* options.
*/
mptcp_get_options(skb, &mp_opt);
if (!mp_opt.mp_capable) {
fallback = true;
goto create_child;
}

create_msk:
new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req);
if (!new_msk)
fallback = true;
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/ipvs/ip_vs_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
ip_vs_addr_copy(svc->af, &svc->addr, &u->addr);
svc->port = u->port;
svc->fwmark = u->fwmark;
svc->flags = u->flags;
svc->flags = u->flags & ~IP_VS_SVC_F_HASHED;
svc->timeout = u->timeout * HZ;
svc->netmask = u->netmask;
svc->ipvs = ipvs;
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ int nf_conntrack_proto_init(void)

#if IS_ENABLED(CONFIG_IPV6)
cleanup_sockopt:
nf_unregister_sockopt(&so_getorigdst6);
nf_unregister_sockopt(&so_getorigdst);
#endif
return ret;
}
Expand Down
4 changes: 3 additions & 1 deletion net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -3263,8 +3263,10 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
if (n == NFT_RULE_MAXEXPRS)
goto err1;
err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
if (err < 0)
if (err < 0) {
NL_SET_BAD_ATTR(extack, tmp);
goto err1;
}
size += info[n].ops->size;
n++;
}
Expand Down
8 changes: 6 additions & 2 deletions net/netfilter/nfnetlink_cthelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,14 @@ static int
nfnl_cthelper_update(const struct nlattr * const tb[],
struct nf_conntrack_helper *helper)
{
u32 size;
int ret;

if (tb[NFCTH_PRIV_DATA_LEN])
return -EBUSY;
if (tb[NFCTH_PRIV_DATA_LEN]) {
size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
if (size != helper->data_len)
return -EBUSY;
}

if (tb[NFCTH_POLICY]) {
ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]);
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nft_ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
struct nf_conn *ct;

ct = nf_ct_get(pkt->skb, &ctinfo);
if (!ct || ctinfo == IP_CT_UNTRACKED) {
if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) {
regs->verdict.code = NFT_BREAK;
return;
}
Expand Down
2 changes: 2 additions & 0 deletions net/nfc/llcp_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (!llcp_sock->service_name) {
nfc_llcp_local_put(llcp_sock->local);
llcp_sock->local = NULL;
llcp_sock->dev = NULL;
ret = -ENOMEM;
goto put_dev;
}
Expand All @@ -119,6 +120,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
llcp_sock->local = NULL;
kfree(llcp_sock->service_name);
llcp_sock->service_name = NULL;
llcp_sock->dev = NULL;
ret = -EADDRINUSE;
goto put_dev;
}
Expand Down
10 changes: 4 additions & 6 deletions net/sched/act_ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
*/
cached = tcf_ct_skb_nfct_cached(net, skb, p->zone, force);
if (!cached) {
if (!commit && tcf_ct_flow_table_lookup(p, skb, family)) {
if (tcf_ct_flow_table_lookup(p, skb, family)) {
skip_add = true;
goto do_nat;
}
Expand Down Expand Up @@ -1019,10 +1019,11 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
* even if the connection is already confirmed.
*/
nf_conntrack_confirm(skb);
} else if (!skip_add) {
tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo);
}

if (!skip_add)
tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo);

out_push:
skb_push_rcsum(skb, nh_ofs);

Expand Down Expand Up @@ -1198,9 +1199,6 @@ static int tcf_ct_fill_params(struct net *net,
sizeof(p->zone));
}

if (p->zone == NF_CT_DEFAULT_ZONE_ID)
return 0;

nf_ct_zone_init(&zone, p->zone, NF_CT_DEFAULT_ZONE_DIR, 0);
tmpl = nf_ct_tmpl_alloc(net, &zone, GFP_KERNEL);
if (!tmpl) {
Expand Down
94 changes: 66 additions & 28 deletions net/tipc/bearer.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
*/
static int tipc_enable_bearer(struct net *net, const char *name,
u32 disc_domain, u32 prio,
struct nlattr *attr[])
struct nlattr *attr[],
struct netlink_ext_ack *extack)
{
struct tipc_net *tn = tipc_net(net);
struct tipc_bearer_names b_names;
Expand All @@ -245,54 +246,68 @@ static int tipc_enable_bearer(struct net *net, const char *name,
int bearer_id = 0;
int res = -EINVAL;
char *errstr = "";
u32 i;

if (!bearer_name_validate(name, &b_names)) {
errstr = "illegal name";
NL_SET_ERR_MSG(extack, "Illegal name");
goto rejected;
}

if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
errstr = "illegal priority";
NL_SET_ERR_MSG(extack, "Illegal priority");
goto rejected;
}

m = tipc_media_find(b_names.media_name);
if (!m) {
errstr = "media not registered";
NL_SET_ERR_MSG(extack, "Media not registered");
goto rejected;
}

if (prio == TIPC_MEDIA_LINK_PRI)
prio = m->priority;

/* Check new bearer vs existing ones and find free bearer id if any */
while (bearer_id < MAX_BEARERS) {
b = rtnl_dereference(tn->bearer_list[bearer_id]);
if (!b)
break;
bearer_id = MAX_BEARERS;
i = MAX_BEARERS;
while (i-- != 0) {
b = rtnl_dereference(tn->bearer_list[i]);
if (!b) {
bearer_id = i;
continue;
}
if (!strcmp(name, b->name)) {
errstr = "already enabled";
NL_SET_ERR_MSG(extack, "Already enabled");
goto rejected;
}
bearer_id++;
if (b->priority != prio)
continue;
if (++with_this_prio <= 2)
continue;
pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
name, prio);
if (prio == TIPC_MIN_LINK_PRI) {
errstr = "cannot adjust to lower";
goto rejected;

if (b->priority == prio &&
(++with_this_prio > 2)) {
pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
name, prio);

if (prio == TIPC_MIN_LINK_PRI) {
errstr = "cannot adjust to lower";
NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
goto rejected;
}

pr_warn("Bearer <%s>: trying with adjusted priority\n",
name);
prio--;
bearer_id = MAX_BEARERS;
i = MAX_BEARERS;
with_this_prio = 1;
}
pr_warn("Bearer <%s>: trying with adjusted priority\n", name);
prio--;
bearer_id = 0;
with_this_prio = 1;
}

if (bearer_id >= MAX_BEARERS) {
errstr = "max 3 bearers permitted";
NL_SET_ERR_MSG(extack, "Max 3 bearers permitted");
goto rejected;
}

Expand All @@ -306,6 +321,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
if (res) {
kfree(b);
errstr = "failed to enable media";
NL_SET_ERR_MSG(extack, "Failed to enable media");
goto rejected;
}

Expand All @@ -322,6 +338,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
if (res) {
bearer_disable(net, b);
errstr = "failed to create discoverer";
NL_SET_ERR_MSG(extack, "Failed to create discoverer");
goto rejected;
}

Expand Down Expand Up @@ -894,6 +911,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
bearer = tipc_bearer_find(net, name);
if (!bearer) {
err = -EINVAL;
NL_SET_ERR_MSG(info->extack, "Bearer not found");
goto err_out;
}

Expand Down Expand Up @@ -933,8 +951,10 @@ int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);

bearer = tipc_bearer_find(net, name);
if (!bearer)
if (!bearer) {
NL_SET_ERR_MSG(info->extack, "Bearer not found");
return -EINVAL;
}

bearer_disable(net, bearer);

Expand Down Expand Up @@ -992,7 +1012,8 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
}

return tipc_enable_bearer(net, bearer, domain, prio, attrs);
return tipc_enable_bearer(net, bearer, domain, prio, attrs,
info->extack);
}

int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
Expand Down Expand Up @@ -1031,6 +1052,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
b = tipc_bearer_find(net, name);
if (!b) {
rtnl_unlock();
NL_SET_ERR_MSG(info->extack, "Bearer not found");
return -EINVAL;
}

Expand Down Expand Up @@ -1071,8 +1093,10 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);

b = tipc_bearer_find(net, name);
if (!b)
if (!b) {
NL_SET_ERR_MSG(info->extack, "Bearer not found");
return -EINVAL;
}

if (attrs[TIPC_NLA_BEARER_PROP]) {
struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
Expand All @@ -1091,12 +1115,18 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
if (props[TIPC_NLA_PROP_WIN])
b->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
if (props[TIPC_NLA_PROP_MTU]) {
if (b->media->type_id != TIPC_MEDIA_TYPE_UDP)
if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) {
NL_SET_ERR_MSG(info->extack,
"MTU property is unsupported");
return -EINVAL;
}
#ifdef CONFIG_TIPC_MEDIA_UDP
if (tipc_udp_mtu_bad(nla_get_u32
(props[TIPC_NLA_PROP_MTU])))
(props[TIPC_NLA_PROP_MTU]))) {
NL_SET_ERR_MSG(info->extack,
"MTU value is out-of-range");
return -EINVAL;
}
b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU);
#endif
Expand Down Expand Up @@ -1224,6 +1254,7 @@ int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
rtnl_lock();
media = tipc_media_find(name);
if (!media) {
NL_SET_ERR_MSG(info->extack, "Media not found");
err = -EINVAL;
goto err_out;
}
Expand Down Expand Up @@ -1260,9 +1291,10 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);

m = tipc_media_find(name);
if (!m)
if (!m) {
NL_SET_ERR_MSG(info->extack, "Media not found");
return -EINVAL;

}
if (attrs[TIPC_NLA_MEDIA_PROP]) {
struct nlattr *props[TIPC_NLA_PROP_MAX + 1];

Expand All @@ -1278,12 +1310,18 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
if (props[TIPC_NLA_PROP_WIN])
m->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
if (props[TIPC_NLA_PROP_MTU]) {
if (m->type_id != TIPC_MEDIA_TYPE_UDP)
if (m->type_id != TIPC_MEDIA_TYPE_UDP) {
NL_SET_ERR_MSG(info->extack,
"MTU property is unsupported");
return -EINVAL;
}
#ifdef CONFIG_TIPC_MEDIA_UDP
if (tipc_udp_mtu_bad(nla_get_u32
(props[TIPC_NLA_PROP_MTU])))
(props[TIPC_NLA_PROP_MTU]))) {
NL_SET_ERR_MSG(info->extack,
"MTU value is out-of-range");
return -EINVAL;
}
m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
#endif
}
Expand Down
60 changes: 49 additions & 11 deletions net/tls/tls_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static void tls_device_gc_task(struct work_struct *work);
static DECLARE_WORK(tls_device_gc_work, tls_device_gc_task);
static LIST_HEAD(tls_device_gc_list);
static LIST_HEAD(tls_device_list);
static LIST_HEAD(tls_device_down_list);
static DEFINE_SPINLOCK(tls_device_lock);

static void tls_device_free_ctx(struct tls_context *ctx)
Expand Down Expand Up @@ -680,15 +681,13 @@ static void tls_device_resync_rx(struct tls_context *tls_ctx,
struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
struct net_device *netdev;

if (WARN_ON(test_and_set_bit(TLS_RX_SYNC_RUNNING, &tls_ctx->flags)))
return;

trace_tls_device_rx_resync_send(sk, seq, rcd_sn, rx_ctx->resync_type);
rcu_read_lock();
netdev = READ_ONCE(tls_ctx->netdev);
if (netdev)
netdev->tlsdev_ops->tls_dev_resync(netdev, sk, seq, rcd_sn,
TLS_OFFLOAD_CTX_DIR_RX);
clear_bit_unlock(TLS_RX_SYNC_RUNNING, &tls_ctx->flags);
rcu_read_unlock();
TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXDEVICERESYNC);
}

Expand Down Expand Up @@ -761,6 +760,8 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)

if (tls_ctx->rx_conf != TLS_HW)
return;
if (unlikely(test_bit(TLS_RX_DEV_DEGRADED, &tls_ctx->flags)))
return;

prot = &tls_ctx->prot_info;
rx_ctx = tls_offload_ctx_rx(tls_ctx);
Expand Down Expand Up @@ -963,6 +964,17 @@ int tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx,

ctx->sw.decrypted |= is_decrypted;

if (unlikely(test_bit(TLS_RX_DEV_DEGRADED, &tls_ctx->flags))) {
if (likely(is_encrypted || is_decrypted))
return 0;

/* After tls_device_down disables the offload, the next SKB will
* likely have initial fragments decrypted, and final ones not
* decrypted. We need to reencrypt that single SKB.
*/
return tls_device_reencrypt(sk, skb);
}

/* Return immediately if the record is either entirely plaintext or
* entirely ciphertext. Otherwise handle reencrypt partially decrypted
* record.
Expand Down Expand Up @@ -1290,22 +1302,48 @@ static int tls_device_down(struct net_device *netdev)
spin_unlock_irqrestore(&tls_device_lock, flags);

list_for_each_entry_safe(ctx, tmp, &list, list) {
/* Stop offloaded TX and switch to the fallback.
* tls_is_sk_tx_device_offloaded will return false.
*/
WRITE_ONCE(ctx->sk->sk_validate_xmit_skb, tls_validate_xmit_skb_sw);

/* Stop the RX and TX resync.
* tls_dev_resync must not be called after tls_dev_del.
*/
WRITE_ONCE(ctx->netdev, NULL);

/* Start skipping the RX resync logic completely. */
set_bit(TLS_RX_DEV_DEGRADED, &ctx->flags);

/* Sync with inflight packets. After this point:
* TX: no non-encrypted packets will be passed to the driver.
* RX: resync requests from the driver will be ignored.
*/
synchronize_net();

/* Release the offload context on the driver side. */
if (ctx->tx_conf == TLS_HW)
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
TLS_OFFLOAD_CTX_DIR_TX);
if (ctx->rx_conf == TLS_HW &&
!test_bit(TLS_RX_DEV_CLOSED, &ctx->flags))
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
TLS_OFFLOAD_CTX_DIR_RX);
WRITE_ONCE(ctx->netdev, NULL);
smp_mb__before_atomic(); /* pairs with test_and_set_bit() */
while (test_bit(TLS_RX_SYNC_RUNNING, &ctx->flags))
usleep_range(10, 200);

dev_put(netdev);
list_del_init(&ctx->list);

if (refcount_dec_and_test(&ctx->refcount))
tls_device_free_ctx(ctx);
/* Move the context to a separate list for two reasons:
* 1. When the context is deallocated, list_del is called.
* 2. It's no longer an offloaded context, so we don't want to
* run offload-specific code on this context.
*/
spin_lock_irqsave(&tls_device_lock, flags);
list_move_tail(&ctx->list, &tls_device_down_list);
spin_unlock_irqrestore(&tls_device_lock, flags);

/* Device contexts for RX and TX will be freed in on sk_destruct
* by tls_device_free_ctx. rx_conf and tx_conf stay in TLS_HW.
*/
}

up_write(&device_offload_lock);
Expand Down
7 changes: 7 additions & 0 deletions net/tls/tls_device_fallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,13 @@ struct sk_buff *tls_validate_xmit_skb(struct sock *sk,
}
EXPORT_SYMBOL_GPL(tls_validate_xmit_skb);

struct sk_buff *tls_validate_xmit_skb_sw(struct sock *sk,
struct net_device *dev,
struct sk_buff *skb)
{
return tls_sw_fallback(sk, skb);
}

struct sk_buff *tls_encrypt_skb(struct sk_buff *skb)
{
return tls_sw_fallback(skb->sk, skb);
Expand Down
1 change: 1 addition & 0 deletions net/tls/tls_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ struct tls_context *tls_ctx_create(struct sock *sk)
mutex_init(&ctx->tx_lock);
rcu_assign_pointer(icsk->icsk_ulp_data, ctx);
ctx->sk_proto = READ_ONCE(sk->sk_prot);
ctx->sk = sk;
return ctx;
}

Expand Down
13 changes: 9 additions & 4 deletions samples/vfio-mdev/mdpy-fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,27 @@ static int mdpy_fb_probe(struct pci_dev *pdev,
if (format != DRM_FORMAT_XRGB8888) {
pci_err(pdev, "format mismatch (0x%x != 0x%x)\n",
format, DRM_FORMAT_XRGB8888);
return -EINVAL;
ret = -EINVAL;
goto err_release_regions;
}
if (width < 100 || width > 10000) {
pci_err(pdev, "width (%d) out of range\n", width);
return -EINVAL;
ret = -EINVAL;
goto err_release_regions;
}
if (height < 100 || height > 10000) {
pci_err(pdev, "height (%d) out of range\n", height);
return -EINVAL;
ret = -EINVAL;
goto err_release_regions;
}
pci_info(pdev, "mdpy found: %dx%d framebuffer\n",
width, height);

info = framebuffer_alloc(sizeof(struct mdpy_fb_par), &pdev->dev);
if (!info)
if (!info) {
ret = -ENOMEM;
goto err_release_regions;
}
pci_set_drvdata(pdev, info);
par = info->par;

Expand Down
3 changes: 2 additions & 1 deletion sound/core/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
return;
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
return;
event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */
list_for_each_entry(ts, &ti->slave_active_head, active_list)
if (ts->ccallback)
ts->ccallback(ts, event + 100, &tstamp, resolution);
ts->ccallback(ts, event, &tstamp, resolution);
}

/* start/continue a master timer */
Expand Down
5 changes: 5 additions & 0 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2973,13 +2973,18 @@ static int hda_codec_runtime_resume(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int hda_codec_pm_prepare(struct device *dev)
{
dev->power.power_state = PMSG_SUSPEND;
return pm_runtime_suspended(dev);
}

static void hda_codec_pm_complete(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);

/* If no other pm-functions are called between prepare() and complete() */
if (dev->power.power_state.event == PM_EVENT_SUSPEND)
dev->power.power_state = PMSG_RESUME;

if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
hda_codec_need_resume(codec) || codec->forced_resume))
pm_request_resume(dev);
Expand Down
1 change: 1 addition & 0 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -8289,6 +8289,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
Expand Down
8 changes: 6 additions & 2 deletions tools/perf/util/dwarf-aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,9 +975,13 @@ static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
if ((tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) &&
die_compare_name(die_mem, fvp->name) &&
/* Does the DIE have location information or external instance? */
/*
* Does the DIE have location information or const value
* or external instance?
*/
(dwarf_attr(die_mem, DW_AT_external, &attr) ||
dwarf_attr(die_mem, DW_AT_location, &attr)))
dwarf_attr(die_mem, DW_AT_location, &attr) ||
dwarf_attr(die_mem, DW_AT_const_value, &attr)))
return DIE_FIND_CB_END;
if (dwarf_haspc(die_mem, fvp->addr))
return DIE_FIND_CB_CONTINUE;
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/probe-finder.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
immediate_value_is_supported()) {
Dwarf_Sword snum;

if (!tvar)
return 0;

dwarf_formsdata(&attr, &snum);
ret = asprintf(&tvar->value, "\\%ld", (long)snum);

Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/wireguard/netns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ ip1 -6 rule add table main suppress_prefixlength 0
ip1 -4 route add default dev wg0 table 51820
ip1 -4 rule add not fwmark 51820 table 51820
ip1 -4 rule add table main suppress_prefixlength 0
n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/vethc/rp_filter'
# Flood the pings instead of sending just one, to trigger routing table reference counting bugs.
n1 ping -W 1 -c 100 -f 192.168.99.7
n1 ping -W 1 -c 100 -f abab::1111
Expand Down
1 change: 0 additions & 1 deletion tools/testing/selftests/wireguard/qemu/kernel.config
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_NAT=y
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MARK=y
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_NF_NAT_IPV4=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
Expand Down