diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/bio.c | 23 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 9 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 5 | ||||
| -rw-r--r-- | fs/ocfs2/quota_global.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/quota_local.c | 1 | ||||
| -rw-r--r-- | fs/proc/task_mmu.c | 2 | ||||
| -rw-r--r-- | fs/smb/client/cifsfs.c | 1 | ||||
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 22 | ||||
| -rw-r--r-- | fs/smb/server/vfs.h | 1 | 
9 files changed, 51 insertions, 15 deletions
| diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 3d2376caedfa..5fd0b39d8c70 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -81,6 +81,9 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,  	bio = bio_split(&orig_bbio->bio, map_length >> SECTOR_SHIFT, GFP_NOFS,  			&btrfs_clone_bioset); +	if (IS_ERR(bio)) +		return ERR_CAST(bio); +  	bbio = btrfs_bio(bio);  	btrfs_bio_init(bbio, fs_info, NULL, orig_bbio);  	bbio->inode = orig_bbio->inode; @@ -355,7 +358,7 @@ static void btrfs_simple_end_io(struct bio *bio)  		INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work);  		queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);  	} else { -		if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status) +		if (bio_is_zone_append(bio) && !bio->bi_status)  			btrfs_record_physical_zoned(bbio);  		btrfs_bio_end_io(bbio, bbio->bio.bi_status);  	} @@ -398,7 +401,7 @@ static void btrfs_orig_write_end_io(struct bio *bio)  	else  		bio->bi_status = BLK_STS_OK; -	if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status) +	if (bio_is_zone_append(bio) && !bio->bi_status)  		stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;  	btrfs_bio_end_io(bbio, bbio->bio.bi_status); @@ -412,7 +415,7 @@ static void btrfs_clone_write_end_io(struct bio *bio)  	if (bio->bi_status) {  		atomic_inc(&stripe->bioc->error);  		btrfs_log_dev_io_error(bio, stripe->dev); -	} else if (bio_op(bio) == REQ_OP_ZONE_APPEND) { +	} else if (bio_is_zone_append(bio)) {  		stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;  	} @@ -684,7 +687,8 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  				&bioc, &smap, &mirror_num);  	if (error) {  		ret = errno_to_blk_status(error); -		goto fail; +		btrfs_bio_counter_dec(fs_info); +		goto end_bbio;  	}  	map_length = min(map_length, length); @@ -692,7 +696,15 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  		map_length = btrfs_append_map_length(bbio, map_length);  	if (map_length < length) { -		bbio = btrfs_split_bio(fs_info, bbio, map_length); +		struct btrfs_bio *split; + +		split = btrfs_split_bio(fs_info, bbio, map_length); +		if (IS_ERR(split)) { +			ret = errno_to_blk_status(PTR_ERR(split)); +			btrfs_bio_counter_dec(fs_info); +			goto end_bbio; +		} +		bbio = split;  		bio = &bbio->bio;  	} @@ -766,6 +778,7 @@ fail:  		btrfs_bio_end_io(remaining, ret);  	} +end_bbio:  	btrfs_bio_end_io(bbio, ret);  	/* Do not submit another chunk */  	return true; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 43b7b331b2da..563f106774e5 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -4264,6 +4264,15 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)  	 * already the cleaner, but below we run all pending delayed iputs.  	 */  	btrfs_flush_workqueue(fs_info->fixup_workers); +	/* +	 * Similar case here, we have to wait for delalloc workers before we +	 * proceed below and stop the cleaner kthread, otherwise we trigger a +	 * use-after-tree on the cleaner kthread task_struct when a delalloc +	 * worker running submit_compressed_extents() adds a delayed iput, which +	 * does a wake up on the cleaner kthread, which was already freed below +	 * when we call kthread_stop(). +	 */ +	btrfs_flush_workqueue(fs_info->delalloc_workers);  	/*  	 * After we parked the cleaner kthread, ordered extents may have diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4b3e256e0d0b..b5cfb85af937 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10056,6 +10056,11 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,  			bsi.block_start = physical_block_start;  			bsi.block_len = len;  		} + +		if (fatal_signal_pending(current)) { +			ret = -EINTR; +			goto out; +		}  	}  	if (bsi.block_len) diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 2b0daced98eb..3404e7a30c33 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -893,7 +893,7 @@ static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid)  	int status = 0;  	trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type); -	if (!sb_has_quota_loaded(sb, type)) { +	if (!sb_has_quota_active(sb, type)) {  		status = -ESRCH;  		goto out;  	} diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 73d3367c533b..2956d888c131 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -867,6 +867,7 @@ out:  	brelse(oinfo->dqi_libh);  	brelse(oinfo->dqi_lqi_bh);  	kfree(oinfo); +	info->dqi_priv = NULL;  	return status;  } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 7eb010de39fe..536b7dc45381 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1810,7 +1810,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,  		}  		for (; addr != end; addr += PAGE_SIZE, idx++) { -			unsigned long cur_flags = flags; +			u64 cur_flags = flags;  			pagemap_entry_t pme;  			if (folio && (flags & PM_PRESENT) && diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index bf909c2f6b96..0ceebde38f9f 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -2018,6 +2018,7 @@ exit_cifs(void)  	destroy_workqueue(decrypt_wq);  	destroy_workqueue(fileinfo_put_wq);  	destroy_workqueue(serverclose_wq); +	destroy_workqueue(cfid_put_wq);  	destroy_workqueue(cifsiod_wq);  	cifs_proc_clean();  } diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 7d01dd313351..04ffc5b158c3 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4224,6 +4224,7 @@ static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,  	/* dot and dotdot entries are already reserved */  	if (!strcmp(".", name) || !strcmp("..", name))  		return true; +	d_info->num_scan++;  	if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))  		return true;  	if (!match_pattern(name, namlen, priv->search_pattern)) @@ -4384,9 +4385,18 @@ int smb2_query_dir(struct ksmbd_work *work)  	query_dir_private.info_level		= req->FileInformationClass;  	dir_fp->readdir_data.private		= &query_dir_private;  	set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir); - +again: +	d_info.num_scan = 0;  	rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx);  	/* +	 * num_entry can be 0 if the directory iteration stops before reaching +	 * the end of the directory and no file is matched with the search +	 * pattern. +	 */ +	if (rc >= 0 && !d_info.num_entry && d_info.num_scan && +	    d_info.out_buf_len > 0) +		goto again; +	/*  	 * req->OutputBufferLength is too small to contain even one entry.  	 * In this case, it immediately returns OutputBufferLength 0 to client.  	 */ @@ -6006,15 +6016,13 @@ static int set_file_basic_info(struct ksmbd_file *fp,  		attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);  	} -	attrs.ia_valid |= ATTR_CTIME;  	if (file_info->ChangeTime) -		attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); -	else -		attrs.ia_ctime = inode_get_ctime(inode); +		inode_set_ctime_to_ts(inode, +				ksmbd_NTtimeToUnix(file_info->ChangeTime));  	if (file_info->LastWriteTime) {  		attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime); -		attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); +		attrs.ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME);  	}  	if (file_info->Attributes) { @@ -6056,8 +6064,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,  			return -EACCES;  		inode_lock(inode); -		inode_set_ctime_to_ts(inode, attrs.ia_ctime); -		attrs.ia_valid &= ~ATTR_CTIME;  		rc = notify_change(idmap, dentry, &attrs, NULL);  		inode_unlock(inode);  	} diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h index cb76f4b5bafe..06903024a2d8 100644 --- a/fs/smb/server/vfs.h +++ b/fs/smb/server/vfs.h @@ -43,6 +43,7 @@ struct ksmbd_dir_info {  	char		*rptr;  	int		name_len;  	int		out_buf_len; +	int		num_scan;  	int		num_entry;  	int		data_count;  	int		last_entry_offset; | 
