Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / block / blk-ia-ranges.c
index 47c89e65b57fac0c11052a364c3738286cd2db3e..2bd1d311033b541856d6876e24154b0418a59770 100644 (file)
@@ -102,31 +102,18 @@ static struct kobj_type blk_ia_ranges_ktype = {
  * disk_register_independent_access_ranges - register with sysfs a set of
  *             independent access ranges
  * @disk:      Target disk
- * @new_iars:  New set of independent access ranges
  *
  * Register with sysfs a set of independent access ranges for @disk.
- * If @new_iars is not NULL, this set of ranges is registered and the old set
- * specified by q->ia_ranges is unregistered. Otherwise, q->ia_ranges is
- * registered if it is not already.
  */
-int disk_register_independent_access_ranges(struct gendisk *disk,
-                               struct blk_independent_access_ranges *new_iars)
+int disk_register_independent_access_ranges(struct gendisk *disk)
 {
+       struct blk_independent_access_ranges *iars = disk->ia_ranges;
        struct request_queue *q = disk->queue;
-       struct blk_independent_access_ranges *iars;
        int i, ret;
 
        lockdep_assert_held(&q->sysfs_dir_lock);
        lockdep_assert_held(&q->sysfs_lock);
 
-       /* If a new range set is specified, unregister the old one */
-       if (new_iars) {
-               if (q->ia_ranges)
-                       disk_unregister_independent_access_ranges(disk);
-               q->ia_ranges = new_iars;
-       }
-
-       iars = q->ia_ranges;
        if (!iars)
                return 0;
 
@@ -138,7 +125,7 @@ int disk_register_independent_access_ranges(struct gendisk *disk,
        ret = kobject_init_and_add(&iars->kobj, &blk_ia_ranges_ktype,
                                   &q->kobj, "%s", "independent_access_ranges");
        if (ret) {
-               q->ia_ranges = NULL;
+               disk->ia_ranges = NULL;
                kobject_put(&iars->kobj);
                return ret;
        }
@@ -164,7 +151,7 @@ int disk_register_independent_access_ranges(struct gendisk *disk,
 void disk_unregister_independent_access_ranges(struct gendisk *disk)
 {
        struct request_queue *q = disk->queue;
-       struct blk_independent_access_ranges *iars = q->ia_ranges;
+       struct blk_independent_access_ranges *iars = disk->ia_ranges;
        int i;
 
        lockdep_assert_held(&q->sysfs_dir_lock);
@@ -182,7 +169,7 @@ void disk_unregister_independent_access_ranges(struct gendisk *disk)
                kfree(iars);
        }
 
-       q->ia_ranges = NULL;
+       disk->ia_ranges = NULL;
 }
 
 static struct blk_independent_access_range *
@@ -210,6 +197,9 @@ static bool disk_check_ia_ranges(struct gendisk *disk,
        sector_t sector = 0;
        int i;
 
+       if (WARN_ON_ONCE(!iars->nr_ia_ranges))
+               return false;
+
        /*
         * While sorting the ranges in increasing LBA order, check that the
         * ranges do not overlap, that there are no sector holes and that all
@@ -242,7 +232,7 @@ static bool disk_check_ia_ranges(struct gendisk *disk,
 static bool disk_ia_ranges_changed(struct gendisk *disk,
                                   struct blk_independent_access_ranges *new)
 {
-       struct blk_independent_access_ranges *old = disk->queue->ia_ranges;
+       struct blk_independent_access_ranges *old = disk->ia_ranges;
        int i;
 
        if (!old)
@@ -298,25 +288,15 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
 {
        struct request_queue *q = disk->queue;
 
-       if (WARN_ON_ONCE(iars && !iars->nr_ia_ranges)) {
+       mutex_lock(&q->sysfs_dir_lock);
+       mutex_lock(&q->sysfs_lock);
+       if (iars && !disk_check_ia_ranges(disk, iars)) {
                kfree(iars);
                iars = NULL;
        }
-
-       mutex_lock(&q->sysfs_dir_lock);
-       mutex_lock(&q->sysfs_lock);
-
-       if (iars) {
-               if (!disk_check_ia_ranges(disk, iars)) {
-                       kfree(iars);
-                       iars = NULL;
-                       goto reg;
-               }
-
-               if (!disk_ia_ranges_changed(disk, iars)) {
-                       kfree(iars);
-                       goto unlock;
-               }
+       if (iars && !disk_ia_ranges_changed(disk, iars)) {
+               kfree(iars);
+               goto unlock;
        }
 
        /*
@@ -324,17 +304,12 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
         * revalidation. If that is the case, we need to unregister the old
         * set of independent access ranges and register the new set. If the
         * queue is not registered, registration of the device request queue
-        * will register the independent access ranges, so only swap in the
-        * new set and free the old one.
+        * will register the independent access ranges.
         */
-reg:
-       if (blk_queue_registered(q)) {
-               disk_register_independent_access_ranges(disk, iars);
-       } else {
-               swap(q->ia_ranges, iars);
-               kfree(iars);
-       }
-
+       disk_unregister_independent_access_ranges(disk);
+       disk->ia_ranges = iars;
+       if (blk_queue_registered(q))
+               disk_register_independent_access_ranges(disk);
 unlock:
        mutex_unlock(&q->sysfs_lock);
        mutex_unlock(&q->sysfs_dir_lock);