Skip to content

Commit 3f2533b

Browse files
Luis Henriquesgregkh
authored andcommitted
ceph: fix directories inode i_blkbits initialization
[ Upstream commit 7506703 ] When filling an inode with info from the MDS, i_blkbits is being initialized using fl_stripe_unit, which contains the stripe unit in bytes. Unfortunately, this doesn't make sense for directories as they have fl_stripe_unit set to '0'. This means that i_blkbits will be set to 0xff, causing an UBSAN undefined behaviour in i_blocksize(): UBSAN: Undefined behaviour in ./include/linux/fs.h:731:12 shift exponent 255 is too large for 32-bit type 'int' Fix this by initializing i_blkbits to CEPH_BLOCK_SHIFT if fl_stripe_unit is zero. Signed-off-by: Luis Henriques <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 6fdcfc0 commit 3f2533b

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

fs/ceph/inode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,12 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
800800
ci->i_version = le64_to_cpu(info->version);
801801
inode->i_version++;
802802
inode->i_rdev = le32_to_cpu(info->rdev);
803-
inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
803+
/* directories have fl_stripe_unit set to zero */
804+
if (le32_to_cpu(info->layout.fl_stripe_unit))
805+
inode->i_blkbits =
806+
fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
807+
else
808+
inode->i_blkbits = CEPH_BLOCK_SHIFT;
804809

805810
if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
806811
(issued & CEPH_CAP_AUTH_EXCL) == 0) {

0 commit comments

Comments
 (0)