~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to fs/block_dev.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
static void bdev_inode_switch_bdi(struct inode *inode,
56
56
                        struct backing_dev_info *dst)
57
57
{
58
 
        spin_lock(&inode_lock);
 
58
        spin_lock(&inode_wb_list_lock);
 
59
        spin_lock(&inode->i_lock);
59
60
        inode->i_data.backing_dev_info = dst;
60
61
        if (inode->i_state & I_DIRTY)
61
62
                list_move(&inode->i_wb_list, &dst->wb.b_dirty);
62
 
        spin_unlock(&inode_lock);
 
63
        spin_unlock(&inode->i_lock);
 
64
        spin_unlock(&inode_wb_list_lock);
63
65
}
64
66
 
65
67
static sector_t max_block(struct block_device *bdev)
651
653
 * @whole: whole block device containing @bdev, may equal @bdev
652
654
 * @holder: holder trying to claim @bdev
653
655
 *
654
 
 * Test whther @bdev can be claimed by @holder.
 
656
 * Test whether @bdev can be claimed by @holder.
655
657
 *
656
658
 * CONTEXT:
657
659
 * spin_lock(&bdev_lock).
760
762
        if (!disk)
761
763
                return ERR_PTR(-ENXIO);
762
764
 
763
 
        whole = bdget_disk(disk, 0);
 
765
        /*
 
766
         * Normally, @bdev should equal what's returned from bdget_disk()
 
767
         * if partno is 0; however, some drivers (floppy) use multiple
 
768
         * bdev's for the same physical device and @bdev may be one of the
 
769
         * aliases.  Keep @bdev if partno is 0.  This means claimer
 
770
         * tracking is broken for those devices but it has always been that
 
771
         * way.
 
772
         */
 
773
        if (partno)
 
774
                whole = bdget_disk(disk, 0);
 
775
        else
 
776
                whole = bdgrab(bdev);
 
777
 
764
778
        module_put(disk->fops->owner);
765
779
        put_disk(disk);
766
780
        if (!whole)
1087
1101
        if (!disk)
1088
1102
                goto out;
1089
1103
 
 
1104
        disk_block_events(disk);
1090
1105
        mutex_lock_nested(&bdev->bd_mutex, for_part);
1091
1106
        if (!bdev->bd_openers) {
1092
1107
                bdev->bd_disk = disk;
1099
1114
                        if (!bdev->bd_part)
1100
1115
                                goto out_clear;
1101
1116
 
 
1117
                        ret = 0;
1102
1118
                        if (disk->fops->open) {
1103
1119
                                ret = disk->fops->open(bdev, mode);
1104
1120
                                if (ret == -ERESTARTSYS) {
1108
1124
                                         */
1109
1125
                                        disk_put_part(bdev->bd_part);
1110
1126
                                        bdev->bd_part = NULL;
 
1127
                                        bdev->bd_disk = NULL;
 
1128
                                        mutex_unlock(&bdev->bd_mutex);
 
1129
                                        disk_unblock_events(disk);
1111
1130
                                        module_put(disk->fops->owner);
1112
1131
                                        put_disk(disk);
1113
 
                                        bdev->bd_disk = NULL;
1114
 
                                        mutex_unlock(&bdev->bd_mutex);
1115
1132
                                        goto restart;
1116
1133
                                }
1117
 
                                if (ret)
1118
 
                                        goto out_clear;
1119
1134
                        }
1120
 
                        if (!bdev->bd_openers) {
 
1135
 
 
1136
                        if (!ret && !bdev->bd_openers) {
1121
1137
                                bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
1122
1138
                                bdi = blk_get_backing_dev_info(bdev);
1123
1139
                                if (bdi == NULL)
1124
1140
                                        bdi = &default_backing_dev_info;
1125
1141
                                bdev_inode_switch_bdi(bdev->bd_inode, bdi);
1126
1142
                        }
1127
 
                        if (bdev->bd_invalidated)
 
1143
 
 
1144
                        /*
 
1145
                         * If the device is invalidated, rescan partition
 
1146
                         * if open succeeded or failed with -ENOMEDIUM.
 
1147
                         * The latter is necessary to prevent ghost
 
1148
                         * partitions on a removed medium.
 
1149
                         */
 
1150
                        if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
1128
1151
                                rescan_partitions(disk, bdev);
 
1152
                        if (ret)
 
1153
                                goto out_clear;
1129
1154
                } else {
1130
1155
                        struct block_device *whole;
1131
1156
                        whole = bdget_disk(disk, 0);
1148
1173
                        bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9);
1149
1174
                }
1150
1175
        } else {
1151
 
                module_put(disk->fops->owner);
1152
 
                put_disk(disk);
1153
 
                disk = NULL;
1154
1176
                if (bdev->bd_contains == bdev) {
1155
 
                        if (bdev->bd_disk->fops->open) {
 
1177
                        ret = 0;
 
1178
                        if (bdev->bd_disk->fops->open)
1156
1179
                                ret = bdev->bd_disk->fops->open(bdev, mode);
1157
 
                                if (ret)
1158
 
                                        goto out_unlock_bdev;
1159
 
                        }
1160
 
                        if (bdev->bd_invalidated)
 
1180
                        /* the same as first opener case, read comment there */
 
1181
                        if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
1161
1182
                                rescan_partitions(bdev->bd_disk, bdev);
 
1183
                        if (ret)
 
1184
                                goto out_unlock_bdev;
1162
1185
                }
 
1186
                /* only one opener holds refs to the module and disk */
 
1187
                module_put(disk->fops->owner);
 
1188
                put_disk(disk);
1163
1189
        }
1164
1190
        bdev->bd_openers++;
1165
1191
        if (for_part)
1166
1192
                bdev->bd_part_count++;
1167
1193
        mutex_unlock(&bdev->bd_mutex);
 
1194
        disk_unblock_events(disk);
1168
1195
        return 0;
1169
1196
 
1170
1197
 out_clear:
1177
1204
        bdev->bd_contains = NULL;
1178
1205
 out_unlock_bdev:
1179
1206
        mutex_unlock(&bdev->bd_mutex);
 
1207
        disk_unblock_events(disk);
 
1208
        module_put(disk->fops->owner);
 
1209
        put_disk(disk);
1180
1210
 out:
1181
 
        if (disk)
1182
 
                module_put(disk->fops->owner);
1183
 
        put_disk(disk);
1184
1211
        bdput(bdev);
1185
1212
 
1186
1213
        return ret;
1223
1250
        res = __blkdev_get(bdev, mode, 0);
1224
1251
 
1225
1252
        if (whole) {
 
1253
                struct gendisk *disk = whole->bd_disk;
 
1254
 
1226
1255
                /* finish claiming */
1227
1256
                mutex_lock(&bdev->bd_mutex);
1228
1257
                spin_lock(&bdev_lock);
1249
1278
                spin_unlock(&bdev_lock);
1250
1279
 
1251
1280
                /*
1252
 
                 * Block event polling for write claims.  Any write
1253
 
                 * holder makes the write_holder state stick until all
1254
 
                 * are released.  This is good enough and tracking
1255
 
                 * individual writeable reference is too fragile given
1256
 
                 * the way @mode is used in blkdev_get/put().
 
1281
                 * Block event polling for write claims if requested.  Any
 
1282
                 * write holder makes the write_holder state stick until
 
1283
                 * all are released.  This is good enough and tracking
 
1284
                 * individual writeable reference is too fragile given the
 
1285
                 * way @mode is used in blkdev_get/put().
1257
1286
                 */
1258
 
                if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) {
 
1287
                if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder &&
 
1288
                    (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) {
1259
1289
                        bdev->bd_write_holder = true;
1260
 
                        disk_block_events(bdev->bd_disk);
 
1290
                        disk_block_events(disk);
1261
1291
                }
1262
1292
 
1263
1293
                mutex_unlock(&bdev->bd_mutex);
1446
1476
                if (bdev_free) {
1447
1477
                        if (bdev->bd_write_holder) {
1448
1478
                                disk_unblock_events(bdev->bd_disk);
 
1479
                                disk_check_events(bdev->bd_disk);
1449
1480
                                bdev->bd_write_holder = false;
1450
 
                        } else
1451
 
                                disk_check_events(bdev->bd_disk);
 
1481
                        }
1452
1482
                }
1453
1483
 
1454
1484
                mutex_unlock(&bdev->bd_mutex);
1455
 
        } else
1456
 
                disk_check_events(bdev->bd_disk);
 
1485
        }
1457
1486
 
1458
1487
        return __blkdev_put(bdev, mode, 0);
1459
1488
}
1527
1556
static const struct address_space_operations def_blk_aops = {
1528
1557
        .readpage       = blkdev_readpage,
1529
1558
        .writepage      = blkdev_writepage,
1530
 
        .sync_page      = block_sync_page,
1531
1559
        .write_begin    = blkdev_write_begin,
1532
1560
        .write_end      = blkdev_write_end,
1533
1561
        .writepages     = generic_writepages,