Mesa (staging/21.2): drm-shim: implement stat/fstat when xstat variants are not there
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Aug 2 20:34:15 UTC 2021
Module: Mesa
Branch: staging/21.2
Commit: 97955560fd223228a66a65bb50f8276de2631a0d
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=97955560fd223228a66a65bb50f8276de2631a0d
Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date: Thu Jul 29 17:35:19 2021 +0300
drm-shim: implement stat/fstat when xstat variants are not there
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Fixes: 027095065dfb79 ("drm-shim: fix compile with glibc >= 2.33")
Acked-by: Emma Anholt <emma at anholt.net>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12129>
(cherry picked from commit f86faee9f4925c0c90ef27518c570a4282b46d4c)
---
.pick_status.json | 2 +-
src/drm-shim/drm_shim.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/.pick_status.json b/.pick_status.json
index 2305225dbe4..47b42b29da0 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -220,7 +220,7 @@
"description": "drm-shim: implement stat/fstat when xstat variants are not there",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "027095065dfb79c05f08e8da2052c407c4d66aaa"
},
diff --git a/src/drm-shim/drm_shim.c b/src/drm-shim/drm_shim.c
index 61967ec66b1..9566d42eeb3 100644
--- a/src/drm-shim/drm_shim.c
+++ b/src/drm-shim/drm_shim.c
@@ -77,11 +77,18 @@ REAL_FUNCTION_POINTER(readdir64);
REAL_FUNCTION_POINTER(readlink);
REAL_FUNCTION_POINTER(realpath);
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 33
+#define HAS_XSTAT __GLIBC__ == 2 && __GLIBC_MINOR__ < 33
+
+#if HAS_XSTAT
REAL_FUNCTION_POINTER(__xstat);
REAL_FUNCTION_POINTER(__xstat64);
REAL_FUNCTION_POINTER(__fxstat);
REAL_FUNCTION_POINTER(__fxstat64);
+#else
+REAL_FUNCTION_POINTER(stat);
+REAL_FUNCTION_POINTER(stat64);
+REAL_FUNCTION_POINTER(fstat);
+REAL_FUNCTION_POINTER(fstat64);
#endif
/* Full path of /dev/dri/renderD* */
@@ -209,11 +216,16 @@ init_shim(void)
GET_FUNCTION_POINTER(readlink);
GET_FUNCTION_POINTER(realpath);
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 33
+#if HAS_XSTAT
GET_FUNCTION_POINTER(__xstat);
GET_FUNCTION_POINTER(__xstat64);
GET_FUNCTION_POINTER(__fxstat);
GET_FUNCTION_POINTER(__fxstat64);
+#else
+ GET_FUNCTION_POINTER(stat);
+ GET_FUNCTION_POINTER(stat64);
+ GET_FUNCTION_POINTER(fstat);
+ GET_FUNCTION_POINTER(fstat64);
#endif
get_dri_render_node_minor();
@@ -278,7 +290,7 @@ PUBLIC int open(const char *path, int flags, ...)
}
PUBLIC int open64(const char*, int, ...) __attribute__((alias("open")));
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 33
+#if HAS_XSTAT
/* Fakes stat to return character device stuff for our fake render node. */
PUBLIC int __xstat(int ver, const char *path, struct stat *st)
{
@@ -379,6 +391,106 @@ PUBLIC int __fxstat64(int ver, int fd, struct stat64 *st)
return 0;
}
+
+#else
+
+PUBLIC int stat(const char* path, struct stat* stat_buf)
+{
+ init_shim();
+
+ /* Note: call real stat if we're in the process of probing for a free
+ * render node!
+ */
+ if (render_node_minor == -1)
+ return real_stat(path, stat_buf);
+
+ /* Fool libdrm's probe of whether the /sys dir for this char dev is
+ * there.
+ */
+ char *sys_dev_drm_dir;
+ nfasprintf(&sys_dev_drm_dir,
+ "/sys/dev/char/%d:%d/device/drm",
+ DRM_MAJOR, render_node_minor);
+ if (strcmp(path, sys_dev_drm_dir) == 0) {
+ free(sys_dev_drm_dir);
+ return 0;
+ }
+ free(sys_dev_drm_dir);
+
+ if (strcmp(path, render_node_path) != 0)
+ return real_stat(path, stat_buf);
+
+ memset(stat_buf, 0, sizeof(*stat_buf));
+ stat_buf->st_rdev = makedev(DRM_MAJOR, render_node_minor);
+ stat_buf->st_mode = S_IFCHR;
+
+ return 0;
+}
+
+PUBLIC int stat64(const char* path, struct stat64* stat_buf)
+{
+ init_shim();
+
+ /* Note: call real stat if we're in the process of probing for a free
+ * render node!
+ */
+ if (render_node_minor == -1)
+ return real_stat64(path, stat_buf);
+
+ /* Fool libdrm's probe of whether the /sys dir for this char dev is
+ * there.
+ */
+ char *sys_dev_drm_dir;
+ nfasprintf(&sys_dev_drm_dir,
+ "/sys/dev/char/%d:%d/device/drm",
+ DRM_MAJOR, render_node_minor);
+ if (strcmp(path, sys_dev_drm_dir) == 0) {
+ free(sys_dev_drm_dir);
+ return 0;
+ }
+ free(sys_dev_drm_dir);
+
+ if (strcmp(path, render_node_path) != 0)
+ return real_stat64(path, stat_buf);
+
+ memset(stat_buf, 0, sizeof(*stat_buf));
+ stat_buf->st_rdev = makedev(DRM_MAJOR, render_node_minor);
+ stat_buf->st_mode = S_IFCHR;
+
+ return 0;
+}
+
+PUBLIC int fstat(int fd, struct stat* stat_buf)
+{
+ init_shim();
+
+ struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
+
+ if (!shim_fd)
+ return real_fstat(fd, stat_buf);
+
+ memset(stat_buf, 0, sizeof(*stat_buf));
+ stat_buf->st_rdev = makedev(DRM_MAJOR, render_node_minor);
+ stat_buf->st_mode = S_IFCHR;
+
+ return 0;
+}
+
+PUBLIC int fstat64(int fd, struct stat64* stat_buf)
+{
+ init_shim();
+
+ struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
+
+ if (!shim_fd)
+ return real_fstat64(fd, stat_buf);
+
+ memset(stat_buf, 0, sizeof(*stat_buf));
+ stat_buf->st_rdev = makedev(DRM_MAJOR, render_node_minor);
+ stat_buf->st_mode = S_IFCHR;
+
+ return 0;
+}
#endif
/* Tracks if the opendir was on /dev/dri. */
More information about the mesa-commit
mailing list