History

[ALSA] Make buffer size of proc text interface variable

Make the read/write buffer size of proc text interface variable.

Takashi Iwai committed 20 years ago

Commit 7e4eeec1 parent 2f4ca8e2 files · +82 −73Browse files

Unified · Split

2 files
  1. include/sound/info.h +3 −3
  2. sound/core/info.c +79 −70
include/sound/info.h+3−3
@@ -27,9 +27,9 @@ · 26 unmodified lines
2727 /* buffer for information */
2828 struct snd_info_buffer {
2929 char *buffer; /* pointer to begin of buffer */
30− char *curr; /* current position in buffer */
31− unsigned long size; /* current size */
32− unsigned long len; /* total length of buffer */
30+ unsigned int curr; /* current position in buffer */
31+ unsigned int size; /* current size */
32+ unsigned int len; /* total length of buffer */
3333 int stop; /* stop flag */
3434 int error; /* error code */
3535 };
sound/core/info.c+79−70
@@ -21,7 +21,6 @@ · 20 unmodified lines
2121
2222 #include <sound/driver.h>
2323 #include <linux/init.h>
24−#include <linux/vmalloc.h>
2524 #include <linux/time.h>
2625 #include <linux/smp_lock.h>
2726 #include <linux/string.h>
@@ -82,6 +81,24 @@ static int snd_info_version_init(void); · 54 unmodified lines
8281 static int snd_info_version_done(void);
8382
8483
84+/* resize the proc r/w buffer */
85+static int resize_info_buffer(struct snd_info_buffer *buffer,
86+ unsigned int nsize)
87+{
88+ char *nbuf;
89+
90+ nsize = PAGE_ALIGN(nsize);
91+ nbuf = kmalloc(nsize, GFP_KERNEL);
92+ if (! nbuf)
93+ return -ENOMEM;
94+
95+ memcpy(nbuf, buffer->buffer, buffer->len);
96+ kfree(buffer->buffer);
97+ buffer->buffer = nbuf;
98+ buffer->len = nsize;
99+ return 0;
100+}
101+
85102 /**
86103 * snd_iprintf - printf on the procfs buffer
87104 * @buffer: the procfs buffer
@@ -95,17 +112,25 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) · 7 unmodified lines
95112 {
96113 va_list args;
97114 int len, res;
115+ int err = 0;
98116
99117 if (buffer->stop || buffer->error)
100118 return 0;
101119 len = buffer->len - buffer->size;
102120 va_start(args, fmt);
103− res = vsnprintf(buffer->curr, len, fmt, args);
104− va_end(args);
105− if (res >= len) {
106− buffer->stop = 1;
107− return 0;
121+ for (;;) {
122+ res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
123+ if (res < len)
124+ break;
125+ err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
126+ if (err < 0)
127+ break;
128+ len = buffer->len - buffer->size;
108129 }
130+ va_end(args);
131+
132+ if (err < 0)
133+ return err;
109134 buffer->curr += res;
110135 buffer->size += res;
111136 return res;
@@ -225,7 +250,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer · 113 unmodified lines
225250 struct snd_info_private_data *data;
226251 struct snd_info_entry *entry;
227252 struct snd_info_buffer *buf;
228− size_t size = 0;
253+ ssize_t size = 0;
229254 loff_t pos;
230255
231256 data = file->private_data;
@@ -241,14 +266,20 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer · 9 unmodified lines
241266 buf = data->wbuffer;
242267 if (buf == NULL)
243268 return -EIO;
244− if (pos >= buf->len)
245− return -ENOMEM;
246− size = buf->len - pos;
247− size = min(count, size);
248− if (copy_from_user(buf->buffer + pos, buffer, size))
269+ mutex_unlock(&entry->access);
270+ if (pos + count >= buf->len) {
271+ if (resize_info_buffer(buf, pos + count)) {
272+ mutex_unlock(&entry->access);
273+ return -ENOMEM;
274+ }
275+ }
276+ if (copy_from_user(buf->buffer + pos, buffer, count)) {
277+ mutex_unlock(&entry->access);
249278 return -EFAULT;
250− if ((long)buf->size < pos + size)
251− buf->size = pos + size;
279+ }
280+ buf->size = pos + count;
281+ mutex_unlock(&entry->access);
282+ size = count;
252283 break;
253284 case SNDRV_INFO_CONTENT_DATA:
254285 if (entry->c.ops->write)
@@ -283,18 +314,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) · 28 unmodified lines
283314 }
284315 mode = file->f_flags & O_ACCMODE;
285316 if (mode == O_RDONLY || mode == O_RDWR) {
286− if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
287− !entry->c.text.read_size) ||
288− (entry->content == SNDRV_INFO_CONTENT_DATA &&
317+ if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
289318 entry->c.ops->read == NULL)) {
290319 err = -ENODEV;
291320 goto __error;
292321 }
293322 }
294323 if (mode == O_WRONLY || mode == O_RDWR) {
295− if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
296− !entry->c.text.write_size) ||
297− (entry->content == SNDRV_INFO_CONTENT_DATA &&
324+ if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
298325 entry->c.ops->write == NULL)) {
299326 err = -ENODEV;
300327 goto __error;
@@ -310,49 +337,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) · 9 unmodified lines
310337 case SNDRV_INFO_CONTENT_TEXT:
311338 if (mode == O_RDONLY || mode == O_RDWR) {
312339 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
313− if (buffer == NULL) {
314− kfree(data);
315− err = -ENOMEM;
316− goto __error;
317− }
318− buffer->len = (entry->c.text.read_size +
319− (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
320− buffer->buffer = vmalloc(buffer->len);
321− if (buffer->buffer == NULL) {
322− kfree(buffer);
323− kfree(data);
324− err = -ENOMEM;
325− goto __error;
326− }
327− buffer->curr = buffer->buffer;
340+ if (buffer == NULL)
341+ goto __nomem;
328342 data->rbuffer = buffer;
343+ buffer->len = PAGE_SIZE;
344+ buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
345+ if (buffer->buffer == NULL)
346+ goto __nomem;
329347 }
330348 if (mode == O_WRONLY || mode == O_RDWR) {
331349 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
332− if (buffer == NULL) {
333− if (mode == O_RDWR) {
334− vfree(data->rbuffer->buffer);
335− kfree(data->rbuffer);
336− }
337− kfree(data);
338− err = -ENOMEM;
339− goto __error;
340− }
341− buffer->len = (entry->c.text.write_size +
342− (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
343− buffer->buffer = vmalloc(buffer->len);
344− if (buffer->buffer == NULL) {
345− if (mode == O_RDWR) {
346− vfree(data->rbuffer->buffer);
347− kfree(data->rbuffer);
348− }
349− kfree(buffer);
350− kfree(data);
351− err = -ENOMEM;
352− goto __error;
353− }
354− buffer->curr = buffer->buffer;
350+ if (buffer == NULL)
351+ goto __nomem;
355352 data->wbuffer = buffer;
353+ buffer->len = PAGE_SIZE;
354+ buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
355+ if (buffer->buffer == NULL)
356+ goto __nomem;
356357 }
357358 break;
358359 case SNDRV_INFO_CONTENT_DATA: /* data */
@@ -377,6 +378,17 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) · 18 unmodified lines
377378 }
378379 return 0;
379380
381+ __nomem:
382+ if (data->rbuffer) {
383+ kfree(data->rbuffer->buffer);
384+ kfree(data->rbuffer);
385+ }
386+ if (data->wbuffer) {
387+ kfree(data->wbuffer->buffer);
388+ kfree(data->wbuffer);
389+ }
390+ kfree(data);
391+ err = -ENOMEM;
380392 __error:
381393 module_put(entry->module);
382394 __error1:
@@ -395,11 +407,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) · 12 unmodified lines
395407 entry = data->entry;
396408 switch (entry->content) {
397409 case SNDRV_INFO_CONTENT_TEXT:
398− if (mode == O_RDONLY || mode == O_RDWR) {
399− vfree(data->rbuffer->buffer);
410+ if (data->rbuffer) {
411+ kfree(data->rbuffer->buffer);
400412 kfree(data->rbuffer);
401413 }
402− if (mode == O_WRONLY || mode == O_RDWR) {
414+ if (data->wbuffer) {
403415 if (entry->c.text.write) {
404416 entry->c.text.write(entry, data->wbuffer);
405417 if (data->wbuffer->error) {
@@ -408,7 +420,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) · 2 unmodified lines
408420 data->wbuffer->error);
409421 }
410422 }
411− vfree(data->wbuffer->buffer);
423+ kfree(data->wbuffer->buffer);
412424 kfree(data->wbuffer);
413425 }
414426 break;
@@ -668,24 +680,22 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) · 253 unmodified lines
668680 if (len <= 0 || buffer->stop || buffer->error)
669681 return 1;
670682 while (--len > 0) {
671− c = *buffer->curr++;
683+ c = buffer->buffer[buffer->curr++];
672684 if (c == '\n') {
673− if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
685+ if (buffer->curr >= buffer->size)
674686 buffer->stop = 1;
675− }
676687 break;
677688 }
678689 *line++ = c;
679− if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
690+ if (buffer->curr >= buffer->size) {
680691 buffer->stop = 1;
681692 break;
682693 }
683694 }
684695 while (c != '\n' && !buffer->stop) {
685− c = *buffer->curr++;
686− if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
696+ c = buffer->buffer[buffer->curr++];
697+ if (buffer->curr >= buffer->size)
687698 buffer->stop = 1;
688− }
689699 }
690700 *line = '\0';
691701 return 0;
@@ -978,7 +988,6 @@ static int __init snd_info_version_init(void) · 286 unmodified lines
978988 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
979989 if (entry == NULL)
980990 return -ENOMEM;
981− entry->c.text.read_size = 256;
982991 entry->c.text.read = snd_info_version_read;
983992 if (snd_info_register(entry) < 0) {
984993 snd_info_free_entry(entry);