diff --git a/src/basic/devnum-util.h b/src/basic/devnum-util.h index e109de99136..0efca567809 100644 --- a/src/basic/devnum-util.h +++ b/src/basic/devnum-util.h @@ -9,6 +9,9 @@ int parse_devnum(const char *s, dev_t *ret); +#define DEVNUM_MAJOR_MAX ((UINT32_C(1) << 12) - 1U) +#define DEVNUM_MINOR_MAX ((UINT32_C(1) << 20) - 1U) + /* glibc and the Linux kernel have different ideas about the major/minor size. These calls will check whether the * specified major is valid by the Linux kernel's standards, not by glibc's. Linux has 20bits of minor, and 12 bits of * major space. See MINORBITS in linux/kdev_t.h in the kernel sources. (If you wonder why we define _y here, instead of @@ -18,14 +21,14 @@ int parse_devnum(const char *s, dev_t *ret); #define DEVICE_MAJOR_VALID(x) \ ({ \ typeof(x) _x = (x), _y = 0; \ - _x >= _y && _x < (UINT32_C(1) << 12); \ + _x >= _y && _x <= DEVNUM_MAJOR_MAX; \ \ }) #define DEVICE_MINOR_VALID(x) \ ({ \ typeof(x) _x = (x), _y = 0; \ - _x >= _y && _x < (UINT32_C(1) << 20); \ + _x >= _y && _x <= DEVNUM_MINOR_MAX; \ }) int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret); @@ -54,3 +57,6 @@ static inline char *format_devnum(dev_t d, char buf[static DEVNUM_STR_MAX]) { static inline bool devnum_is_zero(dev_t d) { return major(d) == 0 && minor(d) == 0; } + +#define DEVNUM_TO_PTR(u) ((void*) (uintptr_t) (u)) +#define PTR_TO_DEVNUM(p) ((dev_t) ((uintptr_t) (p))) diff --git a/src/test/test-devnum-util.c b/src/test/test-devnum-util.c index ebef794001b..782f15d86ff 100644 --- a/src/test/test-devnum-util.c +++ b/src/test/test-devnum-util.c @@ -121,4 +121,21 @@ TEST(devnum_format_str) { test_devnum_format_str_one(makedev(4095, 1048575), "4095:1048575"); } +TEST(devnum_to_ptr) { + dev_t m = makedev(0, 0); + ASSERT_EQ(major(m), 0U); + ASSERT_EQ(minor(m), 0U); + ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m))); + + m = makedev(DEVNUM_MAJOR_MAX, DEVNUM_MINOR_MAX); + ASSERT_EQ(major(m), DEVNUM_MAJOR_MAX); + ASSERT_EQ(minor(m), DEVNUM_MINOR_MAX); + ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m))); + + m = makedev(5, 8); + ASSERT_EQ(major(m), 5U); + ASSERT_EQ(minor(m), 8U); + ASSERT_EQ(m, PTR_TO_DEVNUM(DEVNUM_TO_PTR(m))); +} + DEFINE_TEST_MAIN(LOG_INFO);