On Wed, May 20, 2009 at 12:01 AM, Jens Axboe <jens.axboe@xxxxxxxxxx> wrote: > > We need this in libata to ensure that we don't race between internal > tag usage and the block layer usage. > > Signed-off-by: Jens Axboe <jens.axboe@xxxxxxxxxx> > --- > block/blk-tag.c | 99 ++++++++++++++++++++++++++++++++------------- > drivers/ata/libata-core.c | 29 +++++++++---- > include/linux/blkdev.h | 3 + > 3 files changed, 95 insertions(+), 36 deletions(-) > > diff --git a/block/blk-tag.c b/block/blk-tag.c > index e9a7501..208468b 100644 > --- a/block/blk-tag.c > +++ b/block/blk-tag.c > @@ -149,6 +149,7 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct request_queue *q, > goto fail; > > atomic_set(&tags->refcnt, 1); > + init_waitqueue_head(&tags->waitq); > return tags; > fail: > kfree(tags); > @@ -264,6 +265,65 @@ int blk_queue_resize_tags(struct request_queue *q, int new_depth) > } > EXPORT_SYMBOL(blk_queue_resize_tags); > > +void blk_queue_acquire_tag(struct request_queue *q, int tag) > +{ > + struct blk_queue_tag *bqt; > + > + if (!blk_queue_tagged(q) || !q->queue_tags) > + return; > + > + bqt = q->queue_tags; > + do { > + DEFINE_WAIT(wait); > + > + if (!test_and_set_bit_lock(tag, bqt->tag_map)) > + break; > + > + prepare_to_wait(&bqt->waitq, &wait, TASK_UNINTERRUPTIBLE); > + if (test_and_set_bit_lock(tag, bqt->tag_map)) { > + spin_unlock_irq(q->queue_lock); > + schedule(); > + spin_lock_irq(q->queue_lock); > + } > + finish_wait(&bqt->waitq, &wait); > + } while (1); > +} Should blk_queue_acquire_tag() also be EXPORT_SYMBOL like blk_queue_release_tag() is? > + > +void blk_queue_release_tag(struct request_queue *q, int tag) > +{ ... > +} > +EXPORT_SYMBOL(blk_queue_release_tag); thanks, grant -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html