[1/6] fbdev: Return number of bytes read or written
Sui Jingfeng
15330273260 at 189.cn
Wed Apr 26 09:43:56 UTC 2023
Hi,
The whole patch set is tested with fbdev of IGT, on LoongArch with
drm/radeon and efifb driver. Test results say SUCCESS. Tested-by: Sui
Jingfeng <suijingfeng at loongson.cn>
On 2023/4/25 22:28, Thomas Zimmermann wrote:
> Always return the number of bytes read or written within the
> framebuffer. Only return an errno code if framebuffer memory
> was not touched. This is the semantics required by POSIX and
> makes fb_read() and fb_write() compatible with IGT tests. [1]
>
> This bug has been fixed for fb_write() long ago by
> commit 6a2a88668e90 ("[PATCH] fbdev: Fix return error of
> fb_write"). The code in fb_read() and the corresponding fb_sys_()
> helpers was forgotten.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Link: https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tests/fbdev.c # 1
> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
> ---
> drivers/video/fbdev/core/fb_sys_fops.c | 24 ++++++++++++++----------
> drivers/video/fbdev/core/fbmem.c | 2 +-
> 2 files changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c
> index ff275d7f3eaf..cefb77b9546d 100644
> --- a/drivers/video/fbdev/core/fb_sys_fops.c
> +++ b/drivers/video/fbdev/core/fb_sys_fops.c
> @@ -19,7 +19,8 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
> unsigned long p = *ppos;
> void *src;
> int err = 0;
> - unsigned long total_size;
> + unsigned long total_size, c;
> + ssize_t ret;
>
> if (info->state != FBINFO_STATE_RUNNING)
> return -EPERM;
> @@ -43,13 +44,14 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
> if (info->fbops->fb_sync)
> info->fbops->fb_sync(info);
>
> - if (copy_to_user(buf, src, count))
> + c = copy_to_user(buf, src, count);
> + if (c)
> err = -EFAULT;
> + ret = count - c;
>
> - if (!err)
> - *ppos += count;
> + *ppos += ret;
>
> - return (err) ? err : count;
> + return ret ? ret : err;
> }
> EXPORT_SYMBOL_GPL(fb_sys_read);
>
> @@ -59,7 +61,8 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
> unsigned long p = *ppos;
> void *dst;
> int err = 0;
> - unsigned long total_size;
> + unsigned long total_size, c;
> + size_t ret;
>
> if (info->state != FBINFO_STATE_RUNNING)
> return -EPERM;
> @@ -89,13 +92,14 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
> if (info->fbops->fb_sync)
> info->fbops->fb_sync(info);
>
> - if (copy_from_user(dst, buf, count))
> + c = copy_from_user(dst, buf, count);
> + if (c)
> err = -EFAULT;
> + ret = count - c;
>
> - if (!err)
> - *ppos += count;
> + *ppos += ret;
>
> - return (err) ? err : count;
> + return ret ? ret : err;
> }
> EXPORT_SYMBOL_GPL(fb_sys_write);
>
> diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
> index 3fd95a79e4c3..abc92d79a295 100644
> --- a/drivers/video/fbdev/core/fbmem.c
> +++ b/drivers/video/fbdev/core/fbmem.c
> @@ -820,7 +820,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
>
> kfree(buffer);
>
> - return (err) ? err : cnt;
> + return cnt ? cnt : err;
> }
>
> static ssize_t
More information about the dri-devel
mailing list