Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 19799
b: refs/heads/master
c: e1bc89b
h: refs/heads/master
i:
  19797: 8484e7c
  19795: e7623b2
  19791: 560ff2e
v: v3
  • Loading branch information
Peter Osterlund authored and Linus Torvalds committed Feb 5, 2006
1 parent 2c81e6a commit b27b575
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b566ccefd7814e4fa403de81aea299bdc11ceed5
refs/heads/master: e1bc89bc9991e994f2b3c60d9ad2fdb5ad9b10fc
4 changes: 2 additions & 2 deletions trunk/drivers/block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,8 @@ config CDROM_PKTCDVD_BUFFERS
This controls the maximum number of active concurrent packets. More
concurrent packets can increase write performance, but also require
more memory. Each concurrent packet will require approximately 64Kb
of non-swappable kernel memory, memory which will be allocated at
pktsetup time.
of non-swappable kernel memory, memory which will be allocated when
a disc is opened for writing.

config CDROM_PKTCDVD_WCACHE
bool "Enable write caching (EXPERIMENTAL)"
Expand Down
53 changes: 28 additions & 25 deletions trunk/drivers/block/pktcdvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
/*
* Allocate a packet_data struct
*/
static struct packet_data *pkt_alloc_packet_data(void)
static struct packet_data *pkt_alloc_packet_data(int frames)
{
int i;
struct packet_data *pkt;
Expand All @@ -138,19 +138,20 @@ static struct packet_data *pkt_alloc_packet_data(void)
if (!pkt)
goto no_pkt;

pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
pkt->frames = frames;
pkt->w_bio = pkt_bio_alloc(frames);
if (!pkt->w_bio)
goto no_bio;

for (i = 0; i < PAGES_PER_PACKET; i++) {
for (i = 0; i < frames / FRAMES_PER_PAGE; i++) {
pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
if (!pkt->pages[i])
goto no_page;
}

spin_lock_init(&pkt->lock);

for (i = 0; i < PACKET_MAX_SIZE; i++) {
for (i = 0; i < frames; i++) {
struct bio *bio = pkt_bio_alloc(1);
if (!bio)
goto no_rd_bio;
Expand All @@ -160,14 +161,14 @@ static struct packet_data *pkt_alloc_packet_data(void)
return pkt;

no_rd_bio:
for (i = 0; i < PACKET_MAX_SIZE; i++) {
for (i = 0; i < frames; i++) {
struct bio *bio = pkt->r_bios[i];
if (bio)
bio_put(bio);
}

no_page:
for (i = 0; i < PAGES_PER_PACKET; i++)
for (i = 0; i < frames / FRAMES_PER_PAGE; i++)
if (pkt->pages[i])
__free_page(pkt->pages[i]);
bio_put(pkt->w_bio);
Expand All @@ -184,12 +185,12 @@ static void pkt_free_packet_data(struct packet_data *pkt)
{
int i;

for (i = 0; i < PACKET_MAX_SIZE; i++) {
for (i = 0; i < pkt->frames; i++) {
struct bio *bio = pkt->r_bios[i];
if (bio)
bio_put(bio);
}
for (i = 0; i < PAGES_PER_PACKET; i++)
for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++)
__free_page(pkt->pages[i]);
bio_put(pkt->w_bio);
kfree(pkt);
Expand All @@ -204,17 +205,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd)
list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) {
pkt_free_packet_data(pkt);
}
INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
}

static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
{
struct packet_data *pkt;

INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
spin_lock_init(&pd->cdrw.active_list_lock);
BUG_ON(!list_empty(&pd->cdrw.pkt_free_list));

while (nr_packets > 0) {
pkt = pkt_alloc_packet_data();
pkt = pkt_alloc_packet_data(pd->settings.size >> 2);
if (!pkt) {
pkt_shrink_pktlist(pd);
return 0;
Expand Down Expand Up @@ -949,7 +950,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)

pd->current_sector = zone + pd->settings.size;
pkt->sector = zone;
pkt->frames = pd->settings.size >> 2;
BUG_ON(pkt->frames != pd->settings.size >> 2);
pkt->write_size = 0;

/*
Expand Down Expand Up @@ -1985,8 +1986,14 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
if ((ret = pkt_set_segment_merging(pd, q)))
goto out_unclaim;

if (write)
if (write) {
if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
printk("pktcdvd: not enough memory for buffers\n");
ret = -ENOMEM;
goto out_unclaim;
}
printk("pktcdvd: %lukB available on disc\n", lba << 1);
}

return 0;

Expand All @@ -2012,6 +2019,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
bd_release(pd->bdev);
blkdev_put(pd->bdev);

pkt_shrink_pktlist(pd);
}

static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
Expand Down Expand Up @@ -2377,12 +2386,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
/* This is safe, since we have a reference from open(). */
__module_get(THIS_MODULE);

if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
printk("pktcdvd: not enough memory for buffers\n");
ret = -ENOMEM;
goto out_mem;
}

pd->bdev = bdev;
set_blocksize(bdev, CD_FRAMESIZE);

Expand All @@ -2393,7 +2396,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
if (IS_ERR(pd->cdrw.thread)) {
printk("pktcdvd: can't start kernel thread\n");
ret = -ENOMEM;
goto out_thread;
goto out_mem;
}

proc = create_proc_entry(pd->name, 0, pkt_proc);
Expand All @@ -2404,8 +2407,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
return 0;

out_thread:
pkt_shrink_pktlist(pd);
out_mem:
blkdev_put(bdev);
/* This is safe: open() is still holding a reference. */
Expand Down Expand Up @@ -2501,6 +2502,10 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
goto out_mem;
pd->disk = disk;

INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
spin_lock_init(&pd->cdrw.active_list_lock);

spin_lock_init(&pd->lock);
spin_lock_init(&pd->iosched.lock);
sprintf(pd->name, "pktcdvd%d", idx);
Expand Down Expand Up @@ -2565,8 +2570,6 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)

blkdev_put(pd->bdev);

pkt_shrink_pktlist(pd);

remove_proc_entry(pd->name, pkt_proc);
DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);

Expand Down
4 changes: 2 additions & 2 deletions trunk/include/linux/pktcdvd.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ struct packet_iosched
#error "PAGE_SIZE must be a multiple of CD_FRAMESIZE"
#endif
#define PACKET_MAX_SIZE 32
#define PAGES_PER_PACKET (PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE)
#define FRAMES_PER_PAGE (PAGE_SIZE / CD_FRAMESIZE)
#define PACKET_MAX_SECTORS (PACKET_MAX_SIZE * CD_FRAMESIZE >> 9)

enum packet_data_state {
Expand Down Expand Up @@ -219,7 +219,7 @@ struct packet_data
atomic_t io_errors; /* Number of read/write errors during IO */

struct bio *r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */
struct page *pages[PAGES_PER_PACKET];
struct page *pages[PACKET_MAX_SIZE / FRAMES_PER_PAGE];

int cache_valid; /* If non-zero, the data for the zone defined */
/* by the sector variable is completely cached */
Expand Down

0 comments on commit b27b575

Please sign in to comment.