aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-29 10:49:28 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-29 10:49:28 -0400
commitcbf67812b2f1431c5e432ddecd202984c6882f2a (patch)
treea6c6fc3d65fdababe7af31433038dcc32ec05ebb
parent20dc9f01a867318ac0bc3ea9185d71f05076aeb0 (diff)
parent33013a881104304fcffe817f17f22a1588908037 (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: compat_ioctl: fix block device compat ioctl regression [BLOCK] Fix bad sharing of tag busy list on queues with shared tag maps Fix a build error when BLOCK=n block: use lock bitops for the tag map. cciss: update copyright notices cfq_get_queue: fix possible NULL pointer access blk_sync_queue() should cancel request_queue->unplug_work cfq_exit_queue() should cancel cfq_data->unplug_work block layer: remove a unused argument of drive_stat_acct()
-rw-r--r--block/cfq-iosched.c7
-rw-r--r--block/compat_ioctl.c2
-rw-r--r--block/ll_rw_blk.c41
-rw-r--r--drivers/block/cciss.c14
-rw-r--r--drivers/block/cciss_scsi.c14
-rw-r--r--drivers/block/cciss_scsi.h14
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--mm/filemap.c1
8 files changed, 48 insertions, 47 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 54dc0543900..e47a9309eb4 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1443,8 +1443,11 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
1443 cfqq = *async_cfqq; 1443 cfqq = *async_cfqq;
1444 } 1444 }
1445 1445
1446 if (!cfqq) 1446 if (!cfqq) {
1447 cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); 1447 cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
1448 if (!cfqq)
1449 return NULL;
1450 }
1448 1451
1449 /* 1452 /*
1450 * pin the queue now that it's allocated, scheduler exit will prune it 1453 * pin the queue now that it's allocated, scheduler exit will prune it
@@ -2053,7 +2056,7 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
2053{ 2056{
2054 del_timer_sync(&cfqd->idle_slice_timer); 2057 del_timer_sync(&cfqd->idle_slice_timer);
2055 del_timer_sync(&cfqd->idle_class_timer); 2058 del_timer_sync(&cfqd->idle_class_timer);
2056 blk_sync_queue(cfqd->queue); 2059 kblockd_flush_work(&cfqd->unplug_work);
2057} 2060}
2058 2061
2059static void cfq_put_async_queues(struct cfq_data *cfqd) 2062static void cfq_put_async_queues(struct cfq_data *cfqd)
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f84093b97f7..cae0a852619 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -581,7 +581,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
581{ 581{
582 int ret; 582 int ret;
583 583
584 switch (arg) { 584 switch (cmd) {
585 case HDIO_GET_UNMASKINTR: 585 case HDIO_GET_UNMASKINTR:
586 case HDIO_GET_MULTCOUNT: 586 case HDIO_GET_MULTCOUNT:
587 case HDIO_GET_KEEPSETTINGS: 587 case HDIO_GET_KEEPSETTINGS:
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index b01dee3ae7f..56f2646612e 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -39,7 +39,7 @@
39 39
40static void blk_unplug_work(struct work_struct *work); 40static void blk_unplug_work(struct work_struct *work);
41static void blk_unplug_timeout(unsigned long data); 41static void blk_unplug_timeout(unsigned long data);
42static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io); 42static void drive_stat_acct(struct request *rq, int new_io);
43static void init_request_from_bio(struct request *req, struct bio *bio); 43static void init_request_from_bio(struct request *req, struct bio *bio);
44static int __make_request(struct request_queue *q, struct bio *bio); 44static int __make_request(struct request_queue *q, struct bio *bio);
45static struct io_context *current_io_context(gfp_t gfp_flags, int node); 45static struct io_context *current_io_context(gfp_t gfp_flags, int node);
@@ -791,7 +791,6 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)
791 retval = atomic_dec_and_test(&bqt->refcnt); 791 retval = atomic_dec_and_test(&bqt->refcnt);
792 if (retval) { 792 if (retval) {
793 BUG_ON(bqt->busy); 793 BUG_ON(bqt->busy);
794 BUG_ON(!list_empty(&bqt->busy_list));
795 794
796 kfree(bqt->tag_index); 795 kfree(bqt->tag_index);
797 bqt->tag_index = NULL; 796 bqt->tag_index = NULL;
@@ -903,7 +902,6 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct request_queue *q,
903 if (init_tag_map(q, tags, depth)) 902 if (init_tag_map(q, tags, depth))
904 goto fail; 903 goto fail;
905 904
906 INIT_LIST_HEAD(&tags->busy_list);
907 tags->busy = 0; 905 tags->busy = 0;
908 atomic_set(&tags->refcnt, 1); 906 atomic_set(&tags->refcnt, 1);
909 return tags; 907 return tags;
@@ -954,6 +952,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
954 */ 952 */
955 q->queue_tags = tags; 953 q->queue_tags = tags;
956 q->queue_flags |= (1 << QUEUE_FLAG_QUEUED); 954 q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
955 INIT_LIST_HEAD(&q->tag_busy_list);
957 return 0; 956 return 0;
958fail: 957fail:
959 kfree(tags); 958 kfree(tags);
@@ -1057,18 +1056,16 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
1057 1056
1058 bqt->tag_index[tag] = NULL; 1057 bqt->tag_index[tag] = NULL;
1059 1058
1060 /* 1059 if (unlikely(!test_bit(tag, bqt->tag_map))) {
1061 * We use test_and_clear_bit's memory ordering properties here.
1062 * The tag_map bit acts as a lock for tag_index[bit], so we need
1063 * a barrer before clearing the bit (precisely: release semantics).
1064 * Could use clear_bit_unlock when it is merged.
1065 */
1066 if (unlikely(!test_and_clear_bit(tag, bqt->tag_map))) {
1067 printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n", 1060 printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
1068 __FUNCTION__, tag); 1061 __FUNCTION__, tag);
1069 return; 1062 return;
1070 } 1063 }
1071 1064 /*
1065 * The tag_map bit acts as a lock for tag_index[bit], so we need
1066 * unlock memory barrier semantics.
1067 */
1068 clear_bit_unlock(tag, bqt->tag_map);
1072 bqt->busy--; 1069 bqt->busy--;
1073} 1070}
1074 1071
@@ -1114,17 +1111,17 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
1114 if (tag >= bqt->max_depth) 1111 if (tag >= bqt->max_depth)
1115 return 1; 1112 return 1;
1116 1113
1117 } while (test_and_set_bit(tag, bqt->tag_map)); 1114 } while (test_and_set_bit_lock(tag, bqt->tag_map));
1118 /* 1115 /*
1119 * We rely on test_and_set_bit providing lock memory ordering semantics 1116 * We need lock ordering semantics given by test_and_set_bit_lock.
1120 * (could use test_and_set_bit_lock when it is merged). 1117 * See blk_queue_end_tag for details.
1121 */ 1118 */
1122 1119
1123 rq->cmd_flags |= REQ_QUEUED; 1120 rq->cmd_flags |= REQ_QUEUED;
1124 rq->tag = tag; 1121 rq->tag = tag;
1125 bqt->tag_index[tag] = rq; 1122 bqt->tag_index[tag] = rq;
1126 blkdev_dequeue_request(rq); 1123 blkdev_dequeue_request(rq);
1127 list_add(&rq->queuelist, &bqt->busy_list); 1124 list_add(&rq->queuelist, &q->tag_busy_list);
1128 bqt->busy++; 1125 bqt->busy++;
1129 return 0; 1126 return 0;
1130} 1127}
@@ -1145,11 +1142,10 @@ EXPORT_SYMBOL(blk_queue_start_tag);
1145 **/ 1142 **/
1146void blk_queue_invalidate_tags(struct request_queue *q) 1143void blk_queue_invalidate_tags(struct request_queue *q)
1147{ 1144{
1148 struct blk_queue_tag *bqt = q->queue_tags;
1149 struct list_head *tmp, *n; 1145 struct list_head *tmp, *n;
1150 struct request *rq; 1146 struct request *rq;
1151 1147
1152 list_for_each_safe(tmp, n, &bqt->busy_list) { 1148 list_for_each_safe(tmp, n, &q->tag_busy_list) {
1153 rq = list_entry_rq(tmp); 1149 rq = list_entry_rq(tmp);
1154 1150
1155 if (rq->tag == -1) { 1151 if (rq->tag == -1) {
@@ -1738,6 +1734,7 @@ EXPORT_SYMBOL(blk_stop_queue);
1738void blk_sync_queue(struct request_queue *q) 1734void blk_sync_queue(struct request_queue *q)
1739{ 1735{
1740 del_timer_sync(&q->unplug_timer); 1736 del_timer_sync(&q->unplug_timer);
1737 kblockd_flush_work(&q->unplug_work);
1741} 1738}
1742EXPORT_SYMBOL(blk_sync_queue); 1739EXPORT_SYMBOL(blk_sync_queue);
1743 1740
@@ -2341,7 +2338,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq,
2341 if (blk_rq_tagged(rq)) 2338 if (blk_rq_tagged(rq))
2342 blk_queue_end_tag(q, rq); 2339 blk_queue_end_tag(q, rq);
2343 2340
2344 drive_stat_acct(rq, rq->nr_sectors, 1); 2341 drive_stat_acct(rq, 1);
2345 __elv_add_request(q, rq, where, 0); 2342 __elv_add_request(q, rq, where, 0);
2346 blk_start_queueing(q); 2343 blk_start_queueing(q);
2347 spin_unlock_irqrestore(q->queue_lock, flags); 2344 spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2736,7 +2733,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2736 2733
2737EXPORT_SYMBOL(blkdev_issue_flush); 2734EXPORT_SYMBOL(blkdev_issue_flush);
2738 2735
2739static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) 2736static void drive_stat_acct(struct request *rq, int new_io)
2740{ 2737{
2741 int rw = rq_data_dir(rq); 2738 int rw = rq_data_dir(rq);
2742 2739
@@ -2758,7 +2755,7 @@ static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
2758 */ 2755 */
2759static inline void add_request(struct request_queue * q, struct request * req) 2756static inline void add_request(struct request_queue * q, struct request * req)
2760{ 2757{
2761 drive_stat_acct(req, req->nr_sectors, 1); 2758 drive_stat_acct(req, 1);
2762 2759
2763 /* 2760 /*
2764 * elevator indicated where it wants this request to be 2761 * elevator indicated where it wants this request to be
@@ -3015,7 +3012,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
3015 req->biotail = bio; 3012 req->biotail = bio;
3016 req->nr_sectors = req->hard_nr_sectors += nr_sectors; 3013 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
3017 req->ioprio = ioprio_best(req->ioprio, prio); 3014 req->ioprio = ioprio_best(req->ioprio, prio);
3018 drive_stat_acct(req, nr_sectors, 0); 3015 drive_stat_acct(req, 0);
3019 if (!attempt_back_merge(q, req)) 3016 if (!attempt_back_merge(q, req))
3020 elv_merged_request(q, req, el_ret); 3017 elv_merged_request(q, req, el_ret);
3021 goto out; 3018 goto out;
@@ -3042,7 +3039,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
3042 req->sector = req->hard_sector = bio->bi_sector; 3039 req->sector = req->hard_sector = bio->bi_sector;
3043 req->nr_sectors = req->hard_nr_sectors += nr_sectors; 3040 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
3044 req->ioprio = ioprio_best(req->ioprio, prio); 3041 req->ioprio = ioprio_best(req->ioprio, prio);
3045 drive_stat_acct(req, nr_sectors, 0); 3042 drive_stat_acct(req, 0);
3046 if (!attempt_front_merge(q, req)) 3043 if (!attempt_front_merge(q, req))
3047 elv_merged_request(q, req, el_ret); 3044 elv_merged_request(q, req, el_ret);
3048 goto out; 3045 goto out;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5a6fe17fc63..7d704968765 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1,20 +1,20 @@
1/* 1/*
2 * Disk Array driver for HP SA 5xxx and 6xxx Controllers 2 * Disk Array driver for HP Smart Array controllers.
3 * Copyright 2000, 2006 Hewlett-Packard Development Company, L.P. 3 * (C) Copyright 2000, 2007 Hewlett-Packard Development Company, L.P.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; version 2 of the License.
8 * (at your option) any later version.
9 * 8 *
10 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * NON INFRINGEMENT. See the GNU General Public License for more details. 12 * General Public License for more details.
14 * 13 *
15 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 * 02111-1307, USA.
18 * 18 *
19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com 19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com
20 * 20 *
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 4aca7ddfddd..63ee6c076cb 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1,20 +1,20 @@
1/* 1/*
2 * Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module 2 * Disk Array driver for HP Smart Array controllers, SCSI Tape module.
3 * Copyright 2001 Compaq Computer Corporation 3 * (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; version 2 of the License.
8 * (at your option) any later version.
9 * 8 *
10 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * NON INFRINGEMENT. See the GNU General Public License for more details. 12 * General Public License for more details.
14 * 13 *
15 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Foundation, Inc., 59 Temple Place, Suite 300, Boston, MA
17 * 02111-1307, USA.
18 * 18 *
19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com 19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com
20 * 20 *
diff --git a/drivers/block/cciss_scsi.h b/drivers/block/cciss_scsi.h
index 5e7e06c07d6..d9c2c586502 100644
--- a/drivers/block/cciss_scsi.h
+++ b/drivers/block/cciss_scsi.h
@@ -1,20 +1,20 @@
1/* 1/*
2 * Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module 2 * Disk Array driver for HP Smart Array controllers, SCSI Tape module.
3 * Copyright 2001 Compaq Computer Corporation 3 * (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 * the Free Software Foundation; version 2 of the License.
8 * (at your option) any later version.
9 * 8 *
10 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * NON INFRINGEMENT. See the GNU General Public License for more details. 12 * General Public License for more details.
14 * 13 *
15 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Foundation, Inc., 59 Temple Place, Suite 300, Boston, MA
17 * 02111-1307, USA.
18 * 18 *
19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com 19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com
20 * 20 *
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index bbf906a0b41..8396db24d01 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -341,7 +341,6 @@ enum blk_queue_state {
341struct blk_queue_tag { 341struct blk_queue_tag {
342 struct request **tag_index; /* map of busy tags */ 342 struct request **tag_index; /* map of busy tags */
343 unsigned long *tag_map; /* bit map of free/busy tags */ 343 unsigned long *tag_map; /* bit map of free/busy tags */
344 struct list_head busy_list; /* fifo list of busy tags */
345 int busy; /* current depth */ 344 int busy; /* current depth */
346 int max_depth; /* what we will send to device */ 345 int max_depth; /* what we will send to device */
347 int real_max_depth; /* what the array can hold */ 346 int real_max_depth; /* what the array can hold */
@@ -435,6 +434,7 @@ struct request_queue
435 unsigned int dma_alignment; 434 unsigned int dma_alignment;
436 435
437 struct blk_queue_tag *queue_tags; 436 struct blk_queue_tag *queue_tags;
437 struct list_head tag_busy_list;
438 438
439 unsigned int nr_sorted; 439 unsigned int nr_sorted;
440 unsigned int in_flight; 440 unsigned int in_flight;
diff --git a/mm/filemap.c b/mm/filemap.c
index 5209e47b7fe..7c864363002 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -28,6 +28,7 @@
28#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/pagevec.h> 29#include <linux/pagevec.h>
30#include <linux/blkdev.h> 30#include <linux/blkdev.h>
31#include <linux/backing-dev.h>
31#include <linux/security.h> 32#include <linux/security.h>
32#include <linux/syscalls.h> 33#include <linux/syscalls.h>
33#include <linux/cpuset.h> 34#include <linux/cpuset.h>