diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-14 13:43:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-14 13:43:18 -0700 |
commit | 18553c38bcdef9b0cc69a784cd033a8a21bfa012 (patch) | |
tree | 03b2b4f92a5ccb3416adb69196248751e3a1d0c2 | |
parent | 326d8519fc97be186c55ac605c3a7c957c758ae1 (diff) | |
parent | bfbd442f69ec9c58590ffc6e93ac8d6809caa48b (diff) | |
download | op-kernel-dev-18553c38bcdef9b0cc69a784cd033a8a21bfa012.zip op-kernel-dev-18553c38bcdef9b0cc69a784cd033a8a21bfa012.tar.gz |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
Fix Xilinx SystemACE driver to handle empty CF slot
block: fix memory leak in bio_clone()
block: Add gfp_mask parameter to bio_integrity_clone()
-rw-r--r-- | drivers/block/xsysace.c | 22 | ||||
-rw-r--r-- | fs/bio-integrity.c | 5 | ||||
-rw-r--r-- | fs/bio.c | 6 | ||||
-rw-r--r-- | include/linux/bio.h | 4 |
4 files changed, 31 insertions, 6 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 381d686..119be34 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -489,6 +489,28 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state, ace->id_req_count); #endif + /* Verify that there is actually a CF in the slot. If not, then + * bail out back to the idle state and wake up all the waiters */ + status = ace_in32(ace, ACE_STATUS); + if ((status & ACE_STATUS_CFDETECT) == 0) { + ace->fsm_state = ACE_FSM_STATE_IDLE; + ace->media_change = 1; + set_capacity(ace->gd, 0); + dev_info(ace->dev, "No CF in slot\n"); + + /* Drop all pending requests */ + while ((req = elv_next_request(ace->queue)) != NULL) + end_request(req, 0); + + /* Drop back to IDLE state and notify waiters */ + ace->fsm_state = ACE_FSM_STATE_IDLE; + ace->id_result = -EIO; + while (ace->id_req_count) { + complete(&ace->id_completion); + ace->id_req_count--; + } + } + switch (ace->fsm_state) { case ACE_FSM_STATE_IDLE: /* See if there is anything to do */ diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 549b014..fe2b1aa 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c @@ -685,19 +685,20 @@ EXPORT_SYMBOL(bio_integrity_split); * bio_integrity_clone - Callback for cloning bios with integrity metadata * @bio: New bio * @bio_src: Original bio + * @gfp_mask: Memory allocation mask * @bs: bio_set to allocate bip from * * Description: Called to allocate a bip when cloning a bio */ int bio_integrity_clone(struct bio *bio, struct bio *bio_src, - struct bio_set *bs) + gfp_t gfp_mask, struct bio_set *bs) { struct bio_integrity_payload *bip_src = bio_src->bi_integrity; struct bio_integrity_payload *bip; BUG_ON(bip_src == NULL); - bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); + bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); if (bip == NULL) return -EIO; @@ -463,10 +463,12 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) if (bio_integrity(bio)) { int ret; - ret = bio_integrity_clone(b, bio, fs_bio_set); + ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); - if (ret < 0) + if (ret < 0) { + bio_put(b); return NULL; + } } return b; diff --git a/include/linux/bio.h b/include/linux/bio.h index 1b16108..d8bd43b 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -531,7 +531,7 @@ extern void bio_integrity_endio(struct bio *, int); extern void bio_integrity_advance(struct bio *, unsigned int); extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); extern void bio_integrity_split(struct bio *, struct bio_pair *, int); -extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *); +extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *); extern int bioset_integrity_create(struct bio_set *, int); extern void bioset_integrity_free(struct bio_set *); extern void bio_integrity_init_slab(void); @@ -542,7 +542,7 @@ extern void bio_integrity_init_slab(void); #define bioset_integrity_create(a, b) (0) #define bio_integrity_prep(a) (0) #define bio_integrity_enabled(a) (0) -#define bio_integrity_clone(a, b, c) (0) +#define bio_integrity_clone(a, b, c,d ) (0) #define bioset_integrity_free(a) do { } while (0) #define bio_integrity_free(a, b) do { } while (0) #define bio_integrity_endio(a, b) do { } while (0) |