Commit d10a88ce authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull nilfs2 updates from Viacheslav Dubeyko:

 - Fix potential block overflow that cause system hang

   When executing the FITRIM command, an underflow can occur in the
   calculation of nblocks. This ultimately leads to the block layer
   function __blkdev_issue_discard() taking an excessively long time
   to process the bio chain, and the ns_segctor_sem lock remains held
   for a long period.

   This prevents other tasks from acquiring the ns_segctor_sem lock,
   resulting in a hang reported by syzbot (Edward Adam Davis)

 - Fix missing struct keywords in nilfs2_api.h kernel-doc (Ryusuke
   Konishi)

 - Convert nilfs_super_block to kernel-doc

   Eliminate 40+ kernel-doc warnings in nilfs2_ondisk.h by converting
   all of the struct member comments to kernel-doc comments (Randy
   Dunlap)

* tag 'nilfs2-v7.0-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/vdubeyko/nilfs2:
  nilfs2: fix missing struct keywords in nilfs2_api.h kernel-doc
  nilfs2: convert nilfs_super_block to kernel-doc
  nilfs2: Fix potential block overflow that cause system hang
parents 8912c2fd 6fd8a09f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1093,6 +1093,9 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct fstrim_range *range)
	else
		end_block = start_block + len - 1;

	if (end_block < nilfs->ns_first_data_block)
		goto out;

	segnum = nilfs_get_segnum_of_block(nilfs, start_block);
	segnum_end = nilfs_get_segnum_of_block(nilfs, end_block);

@@ -1191,6 +1194,7 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct fstrim_range *range)
out_sem:
	up_read(&NILFS_MDT(sufile)->mi_sem);

out:
	range->len = ndiscarded << nilfs->ns_blocksize_bits;
	return ret;
}
+2 −2
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ NILFS_CPINFO_FNS(INVALID, invalid)
NILFS_CPINFO_FNS(MINOR, minor)

/**
 * nilfs_suinfo - segment usage information
 * struct nilfs_suinfo - segment usage information
 * @sui_lastmod: timestamp of last modification
 * @sui_nblocks: number of written blocks in segment
 * @sui_flags: segment usage flags
@@ -93,7 +93,7 @@ static inline int nilfs_suinfo_clean(const struct nilfs_suinfo *si)
}

/**
 * nilfs_suinfo_update - segment usage information update
 * struct nilfs_suinfo_update - segment usage information update
 * @sup_segnum: segment number
 * @sup_flags: flags for which fields are active in sup_sui
 * @sup_reserved: reserved necessary for alignment
+97 −66
Original line number Diff line number Diff line
@@ -133,73 +133,104 @@ struct nilfs_super_root {

/**
 * struct nilfs_super_block - structure of super block on disk
 * @s_rev_level:		Revision level
 * @s_minor_rev_level:		minor revision level
 * @s_magic:			Magic signature
 * @s_bytes:			Bytes count of CRC calculation for
 *				  this structure.  s_reserved is excluded.
 * @s_flags:			flags
 * @s_crc_seed:			Seed value of CRC calculation
 * @s_sum:			Check sum of super block
 * @s_log_block_size:		Block size represented as follows:
 *				  blocksize = 1 << (s_log_block_size + 10)
 * @s_nsegments:		Number of segments in filesystem
 * @s_dev_size:			block device size in bytes
 * @s_first_data_block:		1st seg disk block number
 * @s_blocks_per_segment:	number of blocks per full segment
 * @s_r_segments_percentage:	Reserved segments percentage
 * @s_last_cno:			Last checkpoint number
 * @s_last_pseg:		disk block addr pseg written last
 * @s_last_seq:			seq. number of seg written last
 * @s_free_blocks_count:	Free blocks count
 * @s_ctime:			Creation time (execution time of newfs)
 * @s_mtime:			Mount time
 * @s_wtime:			Write time
 * @s_mnt_count:		Mount count
 * @s_max_mnt_count:		Maximal mount count
 * @s_state:			File system state
 * @s_errors:			Behaviour when detecting errors
 * @s_lastcheck:		time of last check
 * @s_checkinterval:		max. time between checks
 * @s_creator_os:		OS
 * @s_def_resuid:		Default uid for reserved blocks
 * @s_def_resgid:		Default gid for reserved blocks
 * @s_first_ino:		First non-reserved inode
 * @s_inode_size:		Size of an inode
 * @s_dat_entry_size:		Size of a dat entry
 * @s_checkpoint_size:		Size of a checkpoint
 * @s_segment_usage_size:	Size of a segment usage
 * @s_uuid:			128-bit uuid for volume
 * @s_volume_name:		volume name
 * @s_c_interval:		Commit interval of segment
 * @s_c_block_max:		Threshold of data amount for the
 *				  segment construction
 * @s_feature_compat:		Compatible feature set
 * @s_feature_compat_ro:	Read-only compatible feature set
 * @s_feature_incompat:		Incompatible feature set
 * @s_reserved:			padding to the end of the block
 */
struct nilfs_super_block {
/*00*/	__le32	s_rev_level;		/* Revision level */
	__le16	s_minor_rev_level;	/* minor revision level */
	__le16	s_magic;		/* Magic signature */

	__le16  s_bytes;		/*
					 * Bytes count of CRC calculation
					 * for this structure. s_reserved
					 * is excluded.
					 */
	__le16  s_flags;		/* flags */
	__le32  s_crc_seed;		/* Seed value of CRC calculation */
/*10*/	__le32	s_sum;			/* Check sum of super block */

	__le32	s_log_block_size;	/*
					 * Block size represented as follows
					 * blocksize =
					 *     1 << (s_log_block_size + 10)
					 */
	__le64  s_nsegments;		/* Number of segments in filesystem */
/*20*/	__le64  s_dev_size;		/* block device size in bytes */
	__le64	s_first_data_block;	/* 1st seg disk block number */
/*30*/	__le32  s_blocks_per_segment;   /* number of blocks per full segment */
	__le32	s_r_segments_percentage; /* Reserved segments percentage */

	__le64  s_last_cno;		/* Last checkpoint number */
/*40*/	__le64  s_last_pseg;		/* disk block addr pseg written last */
	__le64  s_last_seq;             /* seq. number of seg written last */
/*50*/	__le64	s_free_blocks_count;	/* Free blocks count */

	__le64	s_ctime;		/*
					 * Creation time (execution time of
					 * newfs)
					 */
/*60*/	__le64	s_mtime;		/* Mount time */
	__le64	s_wtime;		/* Write time */
/*70*/	__le16	s_mnt_count;		/* Mount count */
	__le16	s_max_mnt_count;	/* Maximal mount count */
	__le16	s_state;		/* File system state */
	__le16	s_errors;		/* Behaviour when detecting errors */
	__le64	s_lastcheck;		/* time of last check */

/*80*/	__le32	s_checkinterval;	/* max. time between checks */
	__le32	s_creator_os;		/* OS */
	__le16	s_def_resuid;		/* Default uid for reserved blocks */
	__le16	s_def_resgid;		/* Default gid for reserved blocks */
	__le32	s_first_ino;		/* First non-reserved inode */

/*90*/	__le16  s_inode_size;		/* Size of an inode */
	__le16  s_dat_entry_size;       /* Size of a dat entry */
	__le16  s_checkpoint_size;      /* Size of a checkpoint */
	__le16	s_segment_usage_size;	/* Size of a segment usage */

/*98*/	__u8	s_uuid[16];		/* 128-bit uuid for volume */
/*A8*/	char	s_volume_name[80]	/* volume name */
			__kernel_nonstring;

/*F8*/	__le32  s_c_interval;           /* Commit interval of segment */
	__le32  s_c_block_max;          /*
					 * Threshold of data amount for
					 * the segment construction
					 */
/*100*/	__le64  s_feature_compat;	/* Compatible feature set */
	__le64  s_feature_compat_ro;	/* Read-only compatible feature set */
	__le64  s_feature_incompat;	/* Incompatible feature set */
	__u32	s_reserved[186];	/* padding to the end of the block */
/*00*/	__le32	s_rev_level;
	__le16	s_minor_rev_level;
	__le16	s_magic;

	__le16  s_bytes;
	__le16  s_flags;
	__le32  s_crc_seed;
/*10*/	__le32	s_sum;

	__le32	s_log_block_size;
	__le64  s_nsegments;
/*20*/	__le64  s_dev_size;
	__le64	s_first_data_block;
/*30*/	__le32  s_blocks_per_segment;
	__le32	s_r_segments_percentage;

	__le64  s_last_cno;
/*40*/	__le64  s_last_pseg;
	__le64  s_last_seq;
/*50*/	__le64	s_free_blocks_count;

	__le64	s_ctime;
/*60*/	__le64	s_mtime;
	__le64	s_wtime;
/*70*/	__le16	s_mnt_count;
	__le16	s_max_mnt_count;
	__le16	s_state;
	__le16	s_errors;
	__le64	s_lastcheck;

/*80*/	__le32	s_checkinterval;
	__le32	s_creator_os;
	__le16	s_def_resuid;
	__le16	s_def_resgid;
	__le32	s_first_ino;

/*90*/	__le16  s_inode_size;
	__le16  s_dat_entry_size;
	__le16  s_checkpoint_size;
	__le16	s_segment_usage_size;

/*98*/	__u8	s_uuid[16];
/*A8*/	char	s_volume_name[80]	__kernel_nonstring;

/*F8*/	__le32  s_c_interval;
	__le32  s_c_block_max;

/*100*/	__le64  s_feature_compat;
	__le64  s_feature_compat_ro;
	__le64  s_feature_incompat;
	__u32	s_reserved[186];
};

/*
@@ -449,7 +480,7 @@ struct nilfs_btree_node {
/**
 * struct nilfs_direct_node - header of built-in bmap array
 * @dn_flags: flags
 * @dn_pad: padding
 * @pad: padding
 */
struct nilfs_direct_node {
	__u8 dn_flags;