wl1251: do quick poll for cmd complete interrupt
[pandora-kernel.git] / fs / block_dev.c
index 95f786e..53ab273 100644 (file)
@@ -68,7 +68,7 @@ static void bdev_inode_switch_bdi(struct inode *inode,
        spin_unlock(&dst->wb.list_lock);
 }
 
-static sector_t max_block(struct block_device *bdev)
+sector_t blkdev_max_block(struct block_device *bdev)
 {
        sector_t retval = ~((sector_t)0);
        loff_t sz = i_size_read(bdev->bd_inode);
@@ -82,13 +82,14 @@ static sector_t max_block(struct block_device *bdev)
 }
 
 /* Kill _all_ buffers and pagecache , dirty or not.. */
-static void kill_bdev(struct block_device *bdev)
+void kill_bdev(struct block_device *bdev)
 {
        if (bdev->bd_inode->i_mapping->nrpages == 0)
                return;
        invalidate_bh_lrus();
        truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 }      
+EXPORT_SYMBOL(kill_bdev);
 
 int set_blocksize(struct block_device *bdev, int size)
 {
@@ -139,7 +140,7 @@ static int
 blkdev_get_block(struct inode *inode, sector_t iblock,
                struct buffer_head *bh, int create)
 {
-       if (iblock >= max_block(I_BDEV(inode))) {
+       if (iblock >= blkdev_max_block(I_BDEV(inode))) {
                if (create)
                        return -EIO;
 
@@ -161,7 +162,7 @@ static int
 blkdev_get_blocks(struct inode *inode, sector_t iblock,
                struct buffer_head *bh, int create)
 {
-       sector_t end_block = max_block(I_BDEV(inode));
+       sector_t end_block = blkdev_max_block(I_BDEV(inode));
        unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
 
        if ((iblock + max_blocks) > end_block) {
@@ -586,6 +587,7 @@ struct block_device *bdgrab(struct block_device *bdev)
        ihold(bdev->bd_inode);
        return bdev;
 }
+EXPORT_SYMBOL(bdgrab);
 
 long nr_blockdev_pages(void)
 {
@@ -971,7 +973,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty)
 
        if (!bdev->bd_disk)
                return;
-       if (disk_partitionable(bdev->bd_disk))
+       if (disk_part_scan_enabled(bdev->bd_disk))
                bdev->bd_invalidated = 1;
 }
 
@@ -1024,6 +1026,7 @@ int revalidate_disk(struct gendisk *disk)
 
        mutex_lock(&bdev->bd_mutex);
        check_disk_size_change(disk, bdev);
+       bdev->bd_invalidated = 0;
        mutex_unlock(&bdev->bd_mutex);
        bdput(bdev);
        return ret;
@@ -1062,7 +1065,9 @@ void bd_set_size(struct block_device *bdev, loff_t size)
 {
        unsigned bsize = bdev_logical_block_size(bdev);
 
-       bdev->bd_inode->i_size = size;
+       mutex_lock(&bdev->bd_inode->i_mutex);
+       i_size_write(bdev->bd_inode, size);
+       mutex_unlock(&bdev->bd_inode->i_mutex);
        while (bsize < PAGE_CACHE_SIZE) {
                if (size & bsize)
                        break;
@@ -1085,6 +1090,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
 static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
 {
        struct gendisk *disk;
+       struct module *owner;
        int ret;
        int partno;
        int perm = 0;
@@ -1110,6 +1116,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
        disk = get_gendisk(bdev->bd_dev, &partno);
        if (!disk)
                goto out;
+       owner = disk->fops->owner;
 
        disk_block_events(disk);
        mutex_lock_nested(&bdev->bd_mutex, for_part);
@@ -1137,8 +1144,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                                        bdev->bd_disk = NULL;
                                        mutex_unlock(&bdev->bd_mutex);
                                        disk_unblock_events(disk);
-                                       module_put(disk->fops->owner);
                                        put_disk(disk);
+                                       module_put(owner);
                                        goto restart;
                                }
                        }
@@ -1157,8 +1164,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                         * The latter is necessary to prevent ghost
                         * partitions on a removed medium.
                         */
-                       if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
-                               rescan_partitions(disk, bdev);
+                       if (bdev->bd_invalidated) {
+                               if (!ret)
+                                       rescan_partitions(disk, bdev);
+                               else if (ret == -ENOMEDIUM)
+                                       invalidate_partitions(disk, bdev);
+                       }
                        if (ret)
                                goto out_clear;
                } else {
@@ -1188,14 +1199,18 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                        if (bdev->bd_disk->fops->open)
                                ret = bdev->bd_disk->fops->open(bdev, mode);
                        /* the same as first opener case, read comment there */
-                       if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
-                               rescan_partitions(bdev->bd_disk, bdev);
+                       if (bdev->bd_invalidated) {
+                               if (!ret)
+                                       rescan_partitions(bdev->bd_disk, bdev);
+                               else if (ret == -ENOMEDIUM)
+                                       invalidate_partitions(bdev->bd_disk, bdev);
+                       }
                        if (ret)
                                goto out_unlock_bdev;
                }
                /* only one opener holds refs to the module and disk */
-               module_put(disk->fops->owner);
                put_disk(disk);
+               module_put(owner);
        }
        bdev->bd_openers++;
        if (for_part)
@@ -1215,8 +1230,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
  out_unlock_bdev:
        mutex_unlock(&bdev->bd_mutex);
        disk_unblock_events(disk);
-       module_put(disk->fops->owner);
        put_disk(disk);
+       module_put(owner);
  out:
        bdput(bdev);
 
@@ -1442,14 +1457,15 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
        if (!bdev->bd_openers) {
                struct module *owner = disk->fops->owner;
 
-               put_disk(disk);
-               module_put(owner);
                disk_put_part(bdev->bd_part);
                bdev->bd_part = NULL;
                bdev->bd_disk = NULL;
                if (bdev != bdev->bd_contains)
                        victim = bdev->bd_contains;
                bdev->bd_contains = NULL;
+
+               put_disk(disk);
+               module_put(owner);
        }
        mutex_unlock(&bdev->bd_mutex);
        bdput(bdev);