2002-08-23 05:44:21

by Peter Chubb

[permalink] [raw]
Subject: Large Block Device patch, part 2 of 9


Hi Linus,
Here's part two of the patch. This just fixes the BLKGETSIZE ioctl
to return EFBIG if the size of a block device is too large to be
represented in a long.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.509 -> 1.510
# drivers/block/blkpg.c 1.38 -> 1.39
# drivers/block/loop.c 1.55 -> 1.56
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/23 [email protected] 1.510
# Fix BLKGETSIZE ioctl to return -EFBIG if size is out of range for a long.
# --------------------------------------------
#
diff -Nru a/drivers/block/blkpg.c b/drivers/block/blkpg.c
--- a/drivers/block/blkpg.c Fri Aug 23 13:52:11 2002
+++ b/drivers/block/blkpg.c Fri Aug 23 13:52:11 2002
@@ -261,10 +261,17 @@
intval = bdev_hardsect_size(bdev);
return put_user(intval, (int *) arg);

- case BLKGETSIZE:
+ case BLKGETSIZE:
+ {
+ unsigned long ret;
/* size in sectors, works up to 2 TB */
ullval = bdev->bd_inode->i_size;
- return put_user((unsigned long)(ullval >> 9), (unsigned long *) arg);
+ ret = ullval >> 9;
+ if ((u64)ret != (ullval >> 9))
+ return -EFBIG;
+ return put_user(ret, (unsigned long *) arg);
+ }
+
case BLKGETSIZE64:
/* size in bytes */
ullval = bdev->bd_inode->i_size;
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c Fri Aug 23 13:52:11 2002
+++ b/drivers/block/loop.c Fri Aug 23 13:52:11 2002
@@ -901,18 +901,25 @@
err = loop_get_status(lo, (struct loop_info *) arg);
break;
case BLKGETSIZE:
+ {
+ unsigned long val;
if (lo->lo_state != Lo_bound) {
err = -ENXIO;
break;
}
- err = put_user((unsigned long) loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
+ val = loop_sizes[lo->lo_number] << 1;
+ if ((sector_t)val != loop_sizes[lo->lo_number] << 1)
+ err = -EFBIG;
+ else
+ err = put_user(val, (unsigned long *) arg);
break;
+ }
case BLKGETSIZE64:
if (lo->lo_state != Lo_bound) {
err = -ENXIO;
break;
}
- err = put_user((u64)loop_sizes[lo->lo_number] << 10, (u64*)arg);
+ err = put_user(((u64)loop_sizes[lo->lo_number]) << 10, (u64*)arg);
break;
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;