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
27/* buffer for information */27/* buffer for information */
28struct snd_info_buffer {28struct snd_info_buffer {
29 char *buffer; /* pointer to begin of buffer */29 char *buffer; /* pointer to begin of buffer */
30 char *curr; /* current position in buffer */30 unsigned int curr; /* current position in buffer */
31 unsigned long size; /* current size */31 unsigned int size; /* current size */
32 unsigned long len; /* total length of buffer */32 unsigned int len; /* total length of buffer */
33 int stop; /* stop flag */33 int stop; /* stop flag */
34 int error; /* error code */34 int error; /* error code */
35};35};
sound/core/info.c+79−70
@@ -21,7 +21,6 @@ · 20 unmodified lines
21 21
22#include <sound/driver.h>22#include <sound/driver.h>
23#include <linux/init.h>23#include <linux/init.h>
24#include <linux/vmalloc.h>
25#include <linux/time.h>24#include <linux/time.h>
26#include <linux/smp_lock.h>25#include <linux/smp_lock.h>
27#include <linux/string.h>26#include <linux/string.h>
@@ -82,6 +81,24 @@ static int snd_info_version_init(void); · 54 unmodified lines
82static int snd_info_version_done(void);81static int snd_info_version_done(void);
83 82
84 83
84/* resize the proc r/w buffer */
85static 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
85/**102/**
86 * snd_iprintf - printf on the procfs buffer103 * snd_iprintf - printf on the procfs buffer
87 * @buffer: the procfs buffer104 * @buffer: the procfs buffer
@@ -95,17 +112,25 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) · 7 unmodified lines
95{112{
96 va_list args;113 va_list args;
97 int len, res;114 int len, res;
115 int err = 0;
98 116
99 if (buffer->stop || buffer->error)117 if (buffer->stop || buffer->error)
100 return 0;118 return 0;
101 len = buffer->len - buffer->size;119 len = buffer->len - buffer->size;
102 va_start(args, fmt);120 va_start(args, fmt);
103 res = vsnprintf(buffer->curr, len, fmt, args);121 for (;;) {
104 va_end(args);122 res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
105 if (res >= len) {123 if (res < len)
106 buffer->stop = 1;124 break;
107 return 0;125 err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
126 if (err < 0)
127 break;
128 len = buffer->len - buffer->size;
108 }129 }
130 va_end(args);
131
132 if (err < 0)
133 return err;
109 buffer->curr += res;134 buffer->curr += res;
110 buffer->size += res;135 buffer->size += res;
111 return res;136 return res;
@@ -225,7 +250,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer · 113 unmodified lines
225 struct snd_info_private_data *data;250 struct snd_info_private_data *data;
226 struct snd_info_entry *entry;251 struct snd_info_entry *entry;
227 struct snd_info_buffer *buf;252 struct snd_info_buffer *buf;
228 size_t size = 0;253 ssize_t size = 0;
229 loff_t pos;254 loff_t pos;
230 255
231 data = file->private_data;256 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
241 buf = data->wbuffer;266 buf = data->wbuffer;
242 if (buf == NULL)267 if (buf == NULL)
243 return -EIO;268 return -EIO;
244 if (pos >= buf->len)269 mutex_unlock(&entry->access);
245 return -ENOMEM;270 if (pos + count >= buf->len) {
246 size = buf->len - pos;271 if (resize_info_buffer(buf, pos + count)) {
247 size = min(count, size);272 mutex_unlock(&entry->access);
248 if (copy_from_user(buf->buffer + pos, buffer, size))273 return -ENOMEM;
274 }
275 }
276 if (copy_from_user(buf->buffer + pos, buffer, count)) {
277 mutex_unlock(&entry->access);
249 return -EFAULT;278 return -EFAULT;
250 if ((long)buf->size < pos + size)279 }
251 buf->size = pos + size;280 buf->size = pos + count;
281 mutex_unlock(&entry->access);
282 size = count;
252 break;283 break;
253 case SNDRV_INFO_CONTENT_DATA:284 case SNDRV_INFO_CONTENT_DATA:
254 if (entry->c.ops->write)285 if (entry->c.ops->write)
@@ -283,18 +314,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) · 28 unmodified lines
283 }314 }
284 mode = file->f_flags & O_ACCMODE;315 mode = file->f_flags & O_ACCMODE;
285 if (mode == O_RDONLY || mode == O_RDWR) {316 if (mode == O_RDONLY || mode == O_RDWR) {
286 if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&317 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
287 !entry->c.text.read_size) ||
288 (entry->content == SNDRV_INFO_CONTENT_DATA &&
289 entry->c.ops->read == NULL)) {318 entry->c.ops->read == NULL)) {
290 err = -ENODEV;319 err = -ENODEV;
291 goto __error;320 goto __error;
292 }321 }
293 }322 }
294 if (mode == O_WRONLY || mode == O_RDWR) {323 if (mode == O_WRONLY || mode == O_RDWR) {
295 if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&324 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
296 !entry->c.text.write_size) ||
297 (entry->content == SNDRV_INFO_CONTENT_DATA &&
298 entry->c.ops->write == NULL)) {325 entry->c.ops->write == NULL)) {
299 err = -ENODEV;326 err = -ENODEV;
300 goto __error;327 goto __error;
@@ -310,49 +337,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) · 9 unmodified lines
310 case SNDRV_INFO_CONTENT_TEXT:337 case SNDRV_INFO_CONTENT_TEXT:
311 if (mode == O_RDONLY || mode == O_RDWR) {338 if (mode == O_RDONLY || mode == O_RDWR) {
312 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);339 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
313 if (buffer == NULL) {340 if (buffer == NULL)
314 kfree(data);341 goto __nomem;
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;
328 data->rbuffer = buffer;342 data->rbuffer = buffer;
343 buffer->len = PAGE_SIZE;
344 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
345 if (buffer->buffer == NULL)
346 goto __nomem;
329 }347 }
330 if (mode == O_WRONLY || mode == O_RDWR) {348 if (mode == O_WRONLY || mode == O_RDWR) {
331 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);349 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
332 if (buffer == NULL) {350 if (buffer == NULL)
333 if (mode == O_RDWR) {351 goto __nomem;
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;
355 data->wbuffer = buffer;352 data->wbuffer = buffer;
353 buffer->len = PAGE_SIZE;
354 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
355 if (buffer->buffer == NULL)
356 goto __nomem;
356 }357 }
357 break;358 break;
358 case SNDRV_INFO_CONTENT_DATA: /* data */359 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
377 }378 }
378 return 0;379 return 0;
379 380
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;
380 __error:392 __error:
381 module_put(entry->module);393 module_put(entry->module);
382 __error1:394 __error1:
@@ -395,11 +407,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) · 12 unmodified lines
395 entry = data->entry;407 entry = data->entry;
396 switch (entry->content) {408 switch (entry->content) {
397 case SNDRV_INFO_CONTENT_TEXT:409 case SNDRV_INFO_CONTENT_TEXT:
398 if (mode == O_RDONLY || mode == O_RDWR) {410 if (data->rbuffer) {
399 vfree(data->rbuffer->buffer);411 kfree(data->rbuffer->buffer);
400 kfree(data->rbuffer);412 kfree(data->rbuffer);
401 }413 }
402 if (mode == O_WRONLY || mode == O_RDWR) {414 if (data->wbuffer) {
403 if (entry->c.text.write) {415 if (entry->c.text.write) {
404 entry->c.text.write(entry, data->wbuffer);416 entry->c.text.write(entry, data->wbuffer);
405 if (data->wbuffer->error) {417 if (data->wbuffer->error) {
@@ -408,7 +420,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file) · 2 unmodified lines
408 data->wbuffer->error);420 data->wbuffer->error);
409 }421 }
410 }422 }
411 vfree(data->wbuffer->buffer);423 kfree(data->wbuffer->buffer);
412 kfree(data->wbuffer);424 kfree(data->wbuffer);
413 }425 }
414 break;426 break;
@@ -668,24 +680,22 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) · 253 unmodified lines
668 if (len <= 0 || buffer->stop || buffer->error)680 if (len <= 0 || buffer->stop || buffer->error)
669 return 1;681 return 1;
670 while (--len > 0) {682 while (--len > 0) {
671 c = *buffer->curr++;683 c = buffer->buffer[buffer->curr++];
672 if (c == '\n') {684 if (c == '\n') {
673 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {685 if (buffer->curr >= buffer->size)
674 buffer->stop = 1;686 buffer->stop = 1;
675 }
676 break;687 break;
677 }688 }
678 *line++ = c;689 *line++ = c;
679 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {690 if (buffer->curr >= buffer->size) {
680 buffer->stop = 1;691 buffer->stop = 1;
681 break;692 break;
682 }693 }
683 }694 }
684 while (c != '\n' && !buffer->stop) {695 while (c != '\n' && !buffer->stop) {
685 c = *buffer->curr++;696 c = buffer->buffer[buffer->curr++];
686 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {697 if (buffer->curr >= buffer->size)
687 buffer->stop = 1;698 buffer->stop = 1;
688 }
689 }699 }
690 *line = '\0';700 *line = '\0';
691 return 0;701 return 0;
@@ -978,7 +988,6 @@ static int __init snd_info_version_init(void) · 286 unmodified lines
978 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);988 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
979 if (entry == NULL)989 if (entry == NULL)
980 return -ENOMEM;990 return -ENOMEM;
981 entry->c.text.read_size = 256;
982 entry->c.text.read = snd_info_version_read;991 entry->c.text.read = snd_info_version_read;
983 if (snd_info_register(entry) < 0) {992 if (snd_info_register(entry) < 0) {
984 snd_info_free_entry(entry);993 snd_info_free_entry(entry);