[S390] dasd: add enhanced DASD statistics interface
[pandora-kernel.git] / drivers / s390 / block / dasd_ioctl.c
index 72261e4..eb4e034 100644 (file)
@@ -239,7 +239,7 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
  */
 static int dasd_ioctl_reset_profile(struct dasd_block *block)
 {
-       memset(&block->profile, 0, sizeof(struct dasd_profile_info_t));
+       dasd_profile_reset(&block->profile);
        return 0;
 }
 
@@ -248,10 +248,40 @@ static int dasd_ioctl_reset_profile(struct dasd_block *block)
  */
 static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp)
 {
-       if (dasd_profile_level == DASD_PROFILE_OFF)
+       struct dasd_profile_info_t *data;
+
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       spin_lock_bh(&block->profile.lock);
+       if (block->profile.data) {
+               data->dasd_io_reqs = block->profile.data->dasd_io_reqs;
+               data->dasd_io_sects = block->profile.data->dasd_io_sects;
+               memcpy(data->dasd_io_secs, block->profile.data->dasd_io_secs,
+                      sizeof(data->dasd_io_secs));
+               memcpy(data->dasd_io_times, block->profile.data->dasd_io_times,
+                      sizeof(data->dasd_io_times));
+               memcpy(data->dasd_io_timps, block->profile.data->dasd_io_timps,
+                      sizeof(data->dasd_io_timps));
+               memcpy(data->dasd_io_time1, block->profile.data->dasd_io_time1,
+                      sizeof(data->dasd_io_time1));
+               memcpy(data->dasd_io_time2, block->profile.data->dasd_io_time2,
+                      sizeof(data->dasd_io_time2));
+               memcpy(data->dasd_io_time2ps,
+                      block->profile.data->dasd_io_time2ps,
+                      sizeof(data->dasd_io_time2ps));
+               memcpy(data->dasd_io_time3, block->profile.data->dasd_io_time3,
+                      sizeof(data->dasd_io_time3));
+               memcpy(data->dasd_io_nr_req,
+                      block->profile.data->dasd_io_nr_req,
+                      sizeof(data->dasd_io_nr_req));
+               spin_unlock_bh(&block->profile.lock);
+       } else {
+               spin_unlock_bh(&block->profile.lock);
                return -EIO;
-       if (copy_to_user(argp, &block->profile,
-                        sizeof(struct dasd_profile_info_t)))
+       }
+       if (copy_to_user(argp, data, sizeof(*data)))
                return -EFAULT;
        return 0;
 }