From: "Randy.Dunlap" This changes/fixes the optcd.c stack reduction patch from last week to 2.5.65. Alan and Jens objected to the kmalloc() in cdromread(), suggesting that the read buffer should be allocated one time and held onto, so this patch does that. Jens has acked this patch. drivers/cdrom/optcd.c | 37 +++++++++++++++++++------------------ 1 files changed, 19 insertions(+), 18 deletions(-) diff -puN drivers/cdrom/optcd.c~cdrom-stack-usage drivers/cdrom/optcd.c --- 25/drivers/cdrom/optcd.c~cdrom-stack-usage 2003-03-31 21:29:45.000000000 -0800 +++ 25-akpm/drivers/cdrom/optcd.c 2003-03-31 21:29:45.000000000 -0800 @@ -1598,19 +1598,17 @@ static int cdromsubchnl(unsigned long ar } +static struct gendisk *optcd_disk; + + static int cdromread(unsigned long arg, int blocksize, int cmd) { - int status, ret = 0; + int status; struct cdrom_msf msf; - char *buf; if (copy_from_user(&msf, (void *) arg, sizeof msf)) return -EFAULT; - buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL); - if (!buf) - return -ENOMEM; - bin2bcd(&msf); msf.cdmsf_min1 = 0; msf.cdmsf_sec1 = 0; @@ -1619,19 +1617,15 @@ static int cdromread(unsigned long arg, DEBUG((DEBUG_VFS, "read cmd status 0x%x", status)); - if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT)) { - ret = -EIO; - goto cdr_free; - } + if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT)) + return -EIO; - fetch_data(buf, blocksize); + fetch_data(optcd_disk->private_data, blocksize); - if (copy_to_user((void *)arg, &buf, blocksize)) - ret = -EFAULT; + if (copy_to_user((void *)arg, optcd_disk->private_data, blocksize)) + return -EFAULT; -cdr_free: - kfree(buf); - return ret; + return 0; } @@ -1857,6 +1851,14 @@ static int opt_open(struct inode *ip, st if (!open_count && state == S_IDLE) { int status; + char *buf; + + buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL); + if (!buf) { + printk(KERN_INFO "optcd: cannot allocate read buffer\n"); + return -ENOMEM; + } + optcd_disk->private_data = buf; /* save read buffer */ toc_uptodate = 0; opt_invalidate_buffers(); @@ -1922,6 +1924,7 @@ static int opt_release(struct inode *ip, status = exec_cmd(COMOPEN); DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status)); } + kfree(optcd_disk->private_data); del_timer(&delay_timer); del_timer(&req_timer); } @@ -2010,8 +2013,6 @@ __setup("optcd=", optcd_setup); #endif /* MODULE */ -static struct gendisk *optcd_disk; - /* Test for presence of drive and initialize it. Called at boot time or during module initialisation. */ static int __init optcd_init(void) _