Greetings, My I2C sensor driver has a debugfs entry for development purposes. Everything works fine with the exception of the read operation. When 'cat' is used, the read operation is called repeatedly and indefinitely. If the read() is changed to return 0 then, as expected, nothing is displayed. The pattern for the implementation is (AFAICT) right out of the book (shown below). What am I missing? Any thoughts much appreciated. TAIA. RDQ static ssize_t sc031gs_reg_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char *buf = 0; ssize_t total = 0; struct sc031gs_dev *sensor = file->private_data; if (!sensor) return -EINVAL; if (*ppos < 0 || !count) return -EINVAL; buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; total = snprintf(buf,count,"Hello world\n"); if (total >= 0) { if (copy_to_user(user_buf, buf, total)) { kfree(buf); return -EFAULT; } *ppos += total; } kfree(buf); return total; }
On Tue, Apr 30, 2019 at 12:45:08PM +0100, rdq@metamail.co wrote:
Greetings,
My I2C sensor driver has a debugfs entry for development purposes. Everything works fine with the exception of the read operation. When 'cat' is used, the read operation is called repeatedly and indefinitely. If the read() is changed to return 0 then, as expected, nothing is displayed.
The pattern for the implementation is (AFAICT) right out of the book (shown below).
What am I missing? Any thoughts much appreciated.
TAIA.
RDQ
static ssize_t sc031gs_reg_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char *buf = 0; ssize_t total = 0; struct sc031gs_dev *sensor = file->private_data; if (!sensor) return -EINVAL; if (*ppos < 0 || !count) return -EINVAL; buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; total = snprintf(buf,count,"Hello world\n"); if (total >= 0) { if (copy_to_user(user_buf, buf, total)) { kfree(buf); return -EFAULT; } *ppos += total; } kfree(buf); return total; }
You are returning a "short" read, and then disallowing ppos to be set to a non-zero value? That's a recipie for disaster :( Also, you allow userspace to allocate as much memory as it asks for? Not good :( Why not just use the simple_read_from_buffer() call? That handles all of the "housekeeping" for you, and your function can be _much_ simpler. good luck! greg k-h
Hi, my guess is your are not returning EOF (= 0). User space expects a return value of 0 (EOF) to terminate reading. But your code will always return sizeof("Hello world\n"). A fix would be to not only increment ppos, but also check if it's already behind your data. Regards, Martin Am 30.04.19 um 13:45 schrieb rdq@metamail.co:
Greetings,
My I2C sensor driver has a debugfs entry for development purposes. Everything works fine with the exception of the read operation. When 'cat' is used, the read operation is called repeatedly and indefinitely. If the read() is changed to return 0 then, as expected, nothing is displayed.
The pattern for the implementation is (AFAICT) right out of the book (shown below).
What am I missing? Any thoughts much appreciated.
TAIA.
RDQ
static ssize_t sc031gs_reg_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { char *buf = 0; ssize_t total = 0; struct sc031gs_dev *sensor = file->private_data; if (!sensor) return -EINVAL; if (*ppos < 0 || !count) return -EINVAL; buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; total = snprintf(buf,count,"Hello world\n"); if (total >= 0) { if (copy_to_user(user_buf, buf, total)) { kfree(buf); return -EFAULT; } *ppos += total; } kfree(buf); return total; }
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Dipl.-Inf. Martin Christian Senior Berater Entwicklung Hardware secunet Security Networks AG Tel.: +49 201 5454-3612, Fax +49 201 5454-1323 E-Mail: martin.christian@secunet.com Ammonstraße 74, 01067 Dresden www.secunet.com
my guess is your are not returning EOF (= 0). User space expects a return value of 0 (EOF) to terminate reading. But your code will always return sizeof("Hello world\n"). A fix would be to not only increment ppos, but also check if it's already behind your data.
Regards,
Martin
Thank you, Martin, help much appreciated. It's a bit of a mystery but neither works for me. More detail in my reply to Greg KH.
participants (3)
-
Greg KH -
Martin Christian -
rdq@metamail.co