aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2621ed2ce6d2..40b17d3b55a1 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1192,6 +1192,30 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
1192 return err; 1192 return err;
1193} 1193}
1194 1194
1195static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
1196{
1197 int err;
1198 sector_t sec;
1199 loff_t sz;
1200
1201 err = -ENXIO;
1202 if (unlikely(lo->lo_state != Lo_bound))
1203 goto out;
1204 err = figure_loop_size(lo);
1205 if (unlikely(err))
1206 goto out;
1207 sec = get_capacity(lo->lo_disk);
1208 /* the width of sector_t may be narrow for bit-shift */
1209 sz = sec;
1210 sz <<= 9;
1211 mutex_lock(&bdev->bd_mutex);
1212 bd_set_size(bdev, sz);
1213 mutex_unlock(&bdev->bd_mutex);
1214
1215 out:
1216 return err;
1217}
1218
1195static int lo_ioctl(struct block_device *bdev, fmode_t mode, 1219static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1196 unsigned int cmd, unsigned long arg) 1220 unsigned int cmd, unsigned long arg)
1197{ 1221{
@@ -1224,6 +1248,11 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1224 case LOOP_GET_STATUS64: 1248 case LOOP_GET_STATUS64:
1225 err = loop_get_status64(lo, (struct loop_info64 __user *) arg); 1249 err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
1226 break; 1250 break;
1251 case LOOP_SET_CAPACITY:
1252 err = -EPERM;
1253 if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
1254 err = loop_set_capacity(lo, bdev);
1255 break;
1227 default: 1256 default:
1228 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; 1257 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
1229 } 1258 }
@@ -1371,6 +1400,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
1371 lo, (struct compat_loop_info __user *) arg); 1400 lo, (struct compat_loop_info __user *) arg);
1372 mutex_unlock(&lo->lo_ctl_mutex); 1401 mutex_unlock(&lo->lo_ctl_mutex);
1373 break; 1402 break;
1403 case LOOP_SET_CAPACITY:
1374 case LOOP_CLR_FD: 1404 case LOOP_CLR_FD:
1375 case LOOP_GET_STATUS64: 1405 case LOOP_GET_STATUS64:
1376 case LOOP_SET_STATUS64: 1406 case LOOP_SET_STATUS64: