[PATCH] FRV: Use the correct preemption primitives in kmap_atomic() and co
[safe/jmp/linux-2.6] / block / ll_rw_blk.c
index e3980ec..c847e17 100644 (file)
@@ -840,12 +840,7 @@ EXPORT_SYMBOL(blk_queue_dma_alignment);
  **/
 struct request *blk_queue_find_tag(request_queue_t *q, int tag)
 {
-       struct blk_queue_tag *bqt = q->queue_tags;
-
-       if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
-               return NULL;
-
-       return bqt->tag_index[tag];
+       return blk_map_queue_find_tag(q->queue_tags, tag);
 }
 
 EXPORT_SYMBOL(blk_queue_find_tag);
@@ -1171,11 +1166,16 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq)
                BUG();
        }
 
-       tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
-       if (tag >= bqt->max_depth)
-               return 1;
+       /*
+        * Protect against shared tag maps, as we may not have exclusive
+        * access to the tag map.
+        */
+       do {
+               tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
+               if (tag >= bqt->max_depth)
+                       return 1;
 
-       __set_bit(tag, bqt->tag_map);
+       } while (test_and_set_bit(tag, bqt->tag_map));
 
        rq->cmd_flags |= REQ_QUEUED;
        rq->tag = tag;
@@ -2884,6 +2884,8 @@ static void init_request_from_bio(struct request *req, struct bio *bio)
 
        if (bio_sync(bio))
                req->cmd_flags |= REQ_RW_SYNC;
+       if (bio_rw_meta(bio))
+               req->cmd_flags |= REQ_RW_META;
 
        req->errors = 0;
        req->hard_sector = req->sector = bio->bi_sector;
@@ -3627,25 +3629,22 @@ EXPORT_SYMBOL(put_io_context);
 /* Called by the exitting task */
 void exit_io_context(void)
 {
-       unsigned long flags;
        struct io_context *ioc;
        struct cfq_io_context *cic;
 
-       local_irq_save(flags);
        task_lock(current);
        ioc = current->io_context;
        current->io_context = NULL;
-       ioc->task = NULL;
        task_unlock(current);
-       local_irq_restore(flags);
 
+       ioc->task = NULL;
        if (ioc->aic && ioc->aic->exit)
                ioc->aic->exit(ioc->aic);
        if (ioc->cic_root.rb_node != NULL) {
                cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node);
                cic->exit(ioc);
        }
+
        put_io_context(ioc);
 }