/* * test-writehints.c: test file/inode write hint setting/getting */ #include #include #include #include #include #include #include #ifndef F_GET_RW_HINT #define F_LINUX_SPECIFIC_BASE 1024 #define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11) #define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12) #define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13) #define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14) #define RWH_WRITE_LIFE_NOT_SET 0 #define RWH_WRITE_LIFE_NONE 1 #define RWH_WRITE_LIFE_SHORT 2 #define RWH_WRITE_LIFE_MEDIUM 3 #define RWH_WRITE_LIFE_LONG 4 #define RWH_WRITE_LIFE_EXTREME 5 #endif static int __get_write_hint(int fd, int cmd) { uint64_t hint; int ret; ret = fcntl(fd, cmd, &hint); if (ret < 0) { perror("fcntl: F_GET_RW_FILE_HINT"); return -1; } return hint; } static int get_file_write_hint(int fd) { return __get_write_hint(fd, F_GET_FILE_RW_HINT); } static int get_inode_write_hint(int fd) { return __get_write_hint(fd, F_GET_RW_HINT); } static void set_file_write_hint(int fd, uint64_t hint) { uint64_t set_hint = hint; int ret; ret = fcntl(fd, F_SET_FILE_RW_HINT, &set_hint); if (ret < 0) { perror("fcntl: F_RW_SET_HINT"); return; } } static void set_inode_write_hint(int fd, uint64_t hint) { uint64_t set_hint = hint; int ret; ret = fcntl(fd, F_SET_RW_HINT, &set_hint); if (ret < 0) { perror("fcntl: F_RW_SET_HINT"); return; } } int main(int argc, char *argv[]) { char filename[] = "/tmp/writehintsXXXXXX"; int ihint, fhint, fd, dupfd; fd = mkstemp(filename); if (fd < 0) { perror("open"); return 2; } /* * Default hints for both file and inode should be NOT_SET */ fhint = get_file_write_hint(fd); if (fhint < 0) return 0; ihint = get_inode_write_hint(fd); assert(fhint == ihint); assert(fhint == RWH_WRITE_LIFE_NOT_SET); /* * Set inode hint, check file hint returns the right hint */ set_inode_write_hint(fd, RWH_WRITE_LIFE_SHORT); fhint = get_file_write_hint(fd); ihint = get_inode_write_hint(fd); assert(fhint == ihint); assert(fhint == RWH_WRITE_LIFE_SHORT); /* * Check that a duped descriptor returns the right hint */ dupfd = dup(fd); fhint = get_file_write_hint(dupfd); ihint = get_inode_write_hint(dupfd); assert(fhint == RWH_WRITE_LIFE_SHORT); assert(ihint == RWH_WRITE_LIFE_SHORT); /* * Now set file hint, ensure that this is now the hint we get */ set_file_write_hint(fd, RWH_WRITE_LIFE_LONG); fhint = get_file_write_hint(fd); ihint = get_inode_write_hint(fd); assert(fhint == RWH_WRITE_LIFE_LONG); assert(ihint == RWH_WRITE_LIFE_SHORT); /* * Clear inode write hint, ensure that file still returns the set hint */ set_inode_write_hint(fd, RWH_WRITE_LIFE_NOT_SET); fhint = get_file_write_hint(fd); ihint = get_inode_write_hint(fd); assert(fhint == RWH_WRITE_LIFE_LONG); assert(ihint == RWH_WRITE_LIFE_NOT_SET); /* * Clear file write hint, ensure that now returns cleared */ set_file_write_hint(fd, RWH_WRITE_LIFE_NOT_SET); fhint = get_file_write_hint(fd); assert(fhint == RWH_WRITE_LIFE_NOT_SET); close(fd); close(dupfd); unlink(filename); return 0; }