Message ID | 20221130070500.28664-1-akumar@suse.de |
---|---|
State | Superseded |
Headers | show |
Series | [v2] statvfs01: Convert to new LTP API | expand |
Hi Avinesh, > Removed the TINFO statements, > Added a validation of statvfs.f_namemax field by trying to create > files of valid and invalid length names. Very nice rewrite, thanks for adding this veryfication. It'd be nice to update this in docparse description. > + > +/*\ > + * [Description] > + * > + * Verify that statvfs() executes successfully for all > + * available filesystems. e.g.: Verify that statvfs() executes successfully for all available filesystems. Verify statvfs.f_namemax field by trying to create files of valid and invalid length names. I can merge it with this change. Reviewed-by: Petr Vorel <pvorel@suse.cz> ... > +static struct tst_test test = { > + .test_all = run, > + .setup = setup, > + .needs_root = 1, > + .mount_device = 1, > + .mntpoint = MNT_POINT, > + .all_filesystems = 1, > + .skip_filesystems = (const char *const[]) { > + "vfat", > + "exfat", I was looking what's wrong with vfat and exfat. statvfs.f_namemax returns 1530, which is obviously too long, thus valid_fname obviously returns ENAMETOOLONG (36). Tested on 6.1.0-rc6-1.g4c01546-default. I wonder why, isn't that a bug? Kind regards, Petr
Hi all, ... > > +static struct tst_test test = { > > + .test_all = run, > > + .setup = setup, > > + .needs_root = 1, > > + .mount_device = 1, > > + .mntpoint = MNT_POINT, > > + .all_filesystems = 1, > > + .skip_filesystems = (const char *const[]) { > > + "vfat", > > + "exfat", > I was looking what's wrong with vfat and exfat. > statvfs.f_namemax returns 1530, which is obviously too long, thus valid_fname > obviously returns ENAMETOOLONG (36). Tested on 6.1.0-rc6-1.g4c01546-default. > I wonder why, isn't that a bug? To reply myself, both glibc and musl defines: statvfs->f_namemax = statfs->f_namelen; TL;DR: 6 * 255 = 1530 due names being in UTF-8: Therefore looking into kernel sources for statfs->f_namelen: include/linux/nls.h #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ === exfat === exfat/exfat_raw.h #define EXFAT_MAX_FILE_LEN 255 exfat/super.c static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) { ... /* Unicode utf16 255 characters */ buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; === vfat === include/uapi/linux/msdos_fs.h #define FAT_LFN_LEN 255 /* maximum long name length */ fat/inode.c static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) { ... buf->f_namelen = (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; => i.e. for vfat without long filename support it'd be 72. How about 1) don't skip exfat and vfat but just skip creating file with valid name? or 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? Kind regards, Petr
On Wed, Nov 30, 2022 at 5:50 PM Petr Vorel <pvorel@suse.cz> wrote: > Hi all, > > ... > > > +static struct tst_test test = { > > > + .test_all = run, > > > + .setup = setup, > > > + .needs_root = 1, > > > + .mount_device = 1, > > > + .mntpoint = MNT_POINT, > > > + .all_filesystems = 1, > > > + .skip_filesystems = (const char *const[]) { > > > + "vfat", > > > + "exfat", > > I was looking what's wrong with vfat and exfat. > > statvfs.f_namemax returns 1530, which is obviously too long, thus > valid_fname > > obviously returns ENAMETOOLONG (36). Tested on > 6.1.0-rc6-1.g4c01546-default. > > I wonder why, isn't that a bug? > > To reply myself, both glibc and musl defines: > statvfs->f_namemax = statfs->f_namelen; > > TL;DR: 6 * 255 = 1530 due names being in UTF-8: > > Therefore looking into kernel sources for statfs->f_namelen: > > include/linux/nls.h > #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ > > === exfat === > exfat/exfat_raw.h > #define EXFAT_MAX_FILE_LEN 255 > > exfat/super.c > static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) > { > ... > /* Unicode utf16 255 characters */ > buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; > > === vfat === > include/uapi/linux/msdos_fs.h > #define FAT_LFN_LEN 255 /* maximum long name length */ > > fat/inode.c > static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) > { > ... > buf->f_namelen = > (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; > > => i.e. for vfat without long filename support it'd be 72. > > How about > 1) don't skip exfat and vfat but just skip creating file with valid name? > or > Sure, I think this method is better. > > 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > > Kind regards, > Petr > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp > >
Hi Petr, On Wednesday, November 30, 2022 3:20:37 PM IST Petr Vorel wrote: > Hi all, > > ... > > > +static struct tst_test test = { > > > + .test_all = run, > > > + .setup = setup, > > > + .needs_root = 1, > > > + .mount_device = 1, > > > + .mntpoint = MNT_POINT, > > > + .all_filesystems = 1, > > > + .skip_filesystems = (const char *const[]) { > > > + "vfat", > > > + "exfat", > > I was looking what's wrong with vfat and exfat. > > statvfs.f_namemax returns 1530, which is obviously too long, thus valid_fname > > obviously returns ENAMETOOLONG (36). Tested on 6.1.0-rc6-1.g4c01546-default. > > I wonder why, isn't that a bug? > > To reply myself, both glibc and musl defines: > statvfs->f_namemax = statfs->f_namelen; > > TL;DR: 6 * 255 = 1530 due names being in UTF-8: > > Therefore looking into kernel sources for statfs->f_namelen: > > include/linux/nls.h > #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ > > === exfat === > exfat/exfat_raw.h > #define EXFAT_MAX_FILE_LEN 255 > > exfat/super.c > static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) > { > ... > /* Unicode utf16 255 characters */ > buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; > > === vfat === > include/uapi/linux/msdos_fs.h > #define FAT_LFN_LEN 255 /* maximum long name length */ > > fat/inode.c > static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) > { > ... > buf->f_namelen = > (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; > > => i.e. for vfat without long filename support it'd be 72. > > How about > 1) don't skip exfat and vfat but just skip creating file with valid name? or > > 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > > Kind regards, > Petr > Thank you for the review and research on vfat, exfat scenarios. I have adopted the option 1 for now and sent a v3 of this patch. Regards, Avinesh
Avinesh Kumar <akumar@suse.de> wrote: > How about > > 1) don't skip exfat and vfat but just skip creating file with valid > name? or > > > > 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > > length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > > Thank you for the review and research on vfat, exfat scenarios. > I have adopted the option 1 for now and sent a v3 of this patch. > I thought option_1 meant to skip creating a valide-file when detecting on "vfat,exfat" FS, but not skip for others. Or probably I misunderstood Petr's words. Anyway, don't hurry to send V3 until we get an agreement :). --- a/testcases/kernel/syscalls/statvfs/statvfs01.c +++ b/testcases/kernel/syscalls/statvfs/statvfs01.c @@ -30,7 +30,10 @@ static void run(void) memset(valid_fname, 'a', buf.f_namemax - 1); memset(invalid_fname, 'b', buf.f_namemax + 1); - TST_EXP_FD(creat(valid_fname, 0444)); + long fs_type = tst_fs_type(TEST_PATH); + if (fs_type != TST_VFAT_MAGIC && fs_type != TST_EXFAT_MAGIC) + TST_EXP_FD(creat(valid_fname, 0444)); + TST_EXP_FAIL(creat(invalid_fname, 0444), ENAMETOOLONG); } @@ -46,9 +49,4 @@ static struct tst_test test = { .mount_device = 1, .mntpoint = MNT_POINT, .all_filesystems = 1, - .skip_filesystems = (const char *const[]) { - "vfat", - "exfat", - NULL - } };
Hello, Li Wang <liwang@redhat.com> writes: > On Wed, Nov 30, 2022 at 5:50 PM Petr Vorel <pvorel@suse.cz> wrote: > >> Hi all, >> >> ... >> > > +static struct tst_test test = { >> > > + .test_all = run, >> > > + .setup = setup, >> > > + .needs_root = 1, >> > > + .mount_device = 1, >> > > + .mntpoint = MNT_POINT, >> > > + .all_filesystems = 1, >> > > + .skip_filesystems = (const char *const[]) { >> > > + "vfat", >> > > + "exfat", >> > I was looking what's wrong with vfat and exfat. >> > statvfs.f_namemax returns 1530, which is obviously too long, thus >> valid_fname >> > obviously returns ENAMETOOLONG (36). Tested on >> 6.1.0-rc6-1.g4c01546-default. >> > I wonder why, isn't that a bug? This is the kind of issue which made me think it should be a separate patch. Because maybe it is a bug. >> >> To reply myself, both glibc and musl defines: >> statvfs->f_namemax = statfs->f_namelen; >> >> TL;DR: 6 * 255 = 1530 due names being in UTF-8: >> >> Therefore looking into kernel sources for statfs->f_namelen: >> >> include/linux/nls.h >> #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ >> >> === exfat === >> exfat/exfat_raw.h >> #define EXFAT_MAX_FILE_LEN 255 >> >> exfat/super.c >> static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) >> { >> ... >> /* Unicode utf16 255 characters */ >> buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; >> >> === vfat === >> include/uapi/linux/msdos_fs.h >> #define FAT_LFN_LEN 255 /* maximum long name length */ >> >> fat/inode.c >> static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) >> { >> ... >> buf->f_namelen = >> (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; >> >> => i.e. for vfat without long filename support it'd be 72. >> >> How about >> 1) don't skip exfat and vfat but just skip creating file with valid name? >> or >> > > Sure, I think this method is better. Is it supposed to return the length in bytes or unicode 'characters'? If it's the later then things get really complicated so I guess it's bytes. However BTRFS also supports unicode (and bigger file names in theory) and just reports 255. If you look at the BTRFS code comments, it says that they limited it to 255 because other things might break. So will creating a file with > 255 chars ever work, even if we use UTF-16 symbols? In the meantime could we just read the data into a guarded buffer and check it's not all zero's or all one's (for e.g.)? > > >> >> 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate >> length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? >> >> Kind regards, >> Petr >> >> -- >> Mailing list info: https://lists.linux.it/listinfo/ltp >> >>
Hi all, > Avinesh Kumar <akumar@suse.de> wrote: > > How about > > > 1) don't skip exfat and vfat but just skip creating file with valid > > name? or > > > 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > > > length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > > Thank you for the review and research on vfat, exfat scenarios. > > I have adopted the option 1 for now and sent a v3 of this patch. > I thought option_1 meant to skip creating a valide-file when > detecting on "vfat,exfat" FS, but not skip for others. > Or probably I misunderstood Petr's words. No, you understood me well. I wanted this to be in v3, but it's not there :). Kind regards, Petr > Anyway, don't hurry to send V3 until we get an agreement :). > --- a/testcases/kernel/syscalls/statvfs/statvfs01.c > +++ b/testcases/kernel/syscalls/statvfs/statvfs01.c > @@ -30,7 +30,10 @@ static void run(void) > memset(valid_fname, 'a', buf.f_namemax - 1); > memset(invalid_fname, 'b', buf.f_namemax + 1); > - TST_EXP_FD(creat(valid_fname, 0444)); > + long fs_type = tst_fs_type(TEST_PATH); > + if (fs_type != TST_VFAT_MAGIC && fs_type != TST_EXFAT_MAGIC) > + TST_EXP_FD(creat(valid_fname, 0444)); > + > TST_EXP_FAIL(creat(invalid_fname, 0444), ENAMETOOLONG); > } > @@ -46,9 +49,4 @@ static struct tst_test test = { > .mount_device = 1, > .mntpoint = MNT_POINT, > .all_filesystems = 1, > - .skip_filesystems = (const char *const[]) { > - "vfat", > - "exfat", > - NULL > - } > };
On Thursday, December 1, 2022 4:15:46 PM IST Petr Vorel wrote: > Hi all, > > > Avinesh Kumar <akumar@suse.de> wrote: > > > > How about > > > > 1) don't skip exfat and vfat but just skip creating file with valid > > > name? or > > > > > 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > > > > length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > > > > > > Thank you for the review and research on vfat, exfat scenarios. > > > I have adopted the option 1 for now and sent a v3 of this patch. > > > > I thought option_1 meant to skip creating a valide-file when > > detecting on "vfat,exfat" FS, but not skip for others. > > > Or probably I misunderstood Petr's words. > No, you understood me well. I wanted this to be in v3, > but it's not there :). > > Kind regards, > Petr > > > Anyway, don't hurry to send V3 until we get an agreement :). Hi Petr, Li, Sorry, I misunderstood and had removed the valid filename creation altogether, I am correcting the patch in v4, as suggested by Li. Thanks, Avinesh > > > --- a/testcases/kernel/syscalls/statvfs/statvfs01.c > > +++ b/testcases/kernel/syscalls/statvfs/statvfs01.c > > @@ -30,7 +30,10 @@ static void run(void) > > memset(valid_fname, 'a', buf.f_namemax - 1); > > memset(invalid_fname, 'b', buf.f_namemax + 1); > > > - TST_EXP_FD(creat(valid_fname, 0444)); > > + long fs_type = tst_fs_type(TEST_PATH); > > + if (fs_type != TST_VFAT_MAGIC && fs_type != TST_EXFAT_MAGIC) > > + TST_EXP_FD(creat(valid_fname, 0444)); > > + > > TST_EXP_FAIL(creat(invalid_fname, 0444), ENAMETOOLONG); > > } > > > @@ -46,9 +49,4 @@ static struct tst_test test = { > > .mount_device = 1, > > .mntpoint = MNT_POINT, > > .all_filesystems = 1, > > - .skip_filesystems = (const char *const[]) { > > - "vfat", > > - "exfat", > > - NULL > > - } > > }; >
Hi all, ... > >> To reply myself, both glibc and musl defines: > >> statvfs->f_namemax = statfs->f_namelen; > >> TL;DR: 6 * 255 = 1530 due names being in UTF-8: > >> Therefore looking into kernel sources for statfs->f_namelen: > >> include/linux/nls.h > >> #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ > >> === exfat === > >> exfat/exfat_raw.h > >> #define EXFAT_MAX_FILE_LEN 255 > >> exfat/super.c > >> static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) > >> { > >> ... > >> /* Unicode utf16 255 characters */ > >> buf->f_namelen = EXFAT_MAX_FILE_LEN * NLS_MAX_CHARSET_SIZE; > >> === vfat === > >> include/uapi/linux/msdos_fs.h > >> #define FAT_LFN_LEN 255 /* maximum long name length */ > >> fat/inode.c > >> static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) > >> { > >> ... > >> buf->f_namelen = > >> (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; > >> => i.e. for vfat without long filename support it'd be 72. > >> How about > >> 1) don't skip exfat and vfat but just skip creating file with valid name? > >> or > > Sure, I think this method is better. > Is it supposed to return the length in bytes or unicode 'characters'? If > it's the later then things get really complicated so I guess it's bytes. Yes. TL;DR: I'd test vfat and exfat for valid filename with (f_namelen / 6) + 1. > However BTRFS also supports unicode (and bigger file names in theory) > and just reports 255. If you look at the BTRFS code comments, it says > that they limited it to 255 because other things might break. > So will creating a file with > 255 chars ever work, even if we use > UTF-16 symbols? Wrote some testing code (see below), vfat and exfat behaves differently: $ gcc -Wall statvfs-test-ms.c -o statvfs-test-ms && ./statvfs-test-ms /tmp/vfat/ === filesystem: vfat === file: test_ϴ_12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 strlen: 256, mblen: 255 buf.f_namelen: 1530 file: test_ϴ_12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678_ strlen: 257, mblen: 256 creat() failed: File name too long file: ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ strlen: 510, mblen: 255 buf.f_namelen: 1530 Also NTFS over fuse behaves the same (allows 256 length), but (probably due fuse) f_namelen is only 255: === filesystem: fuse === file: test_ϴ_12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 strlen: 256, mblen: 255 buf.f_namelen: 255 file: test_ϴ_12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678_ strlen: 257, mblen: 256 creat() failed: File name too long file: ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ strlen: 510, mblen: 255 buf.f_namelen: 255 NOTE: they both allow strlen 256 as max character multibyte length is in that case just 255 (not counting terminating null byte \0 ?). When testing on normal linux filesystems (btrfs, ext4, xfs, tmpfs, ...) they all allow only strlen 255 and obviously does not work with multibyte (output on shortened filenames): === filesystem: btrfs === file: test_ϴ_1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 strlen: 255, mblen: 254 buf.f_namelen: 255 file: test_ϴ_1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567_ strlen: 256, mblen: 255 creat() failed: File name too long file: ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ strlen: 508, mblen: 254 creat() failed: File name too long Kind regards, Petr > In the meantime could we just read the data into a guarded buffer and > check it's not all zero's or all one's (for e.g.)? > >> 2) Add #define NLS_MAX_CHARSET_SIZE 6 and for vfat and exfat calculate > >> length as: buf.f_namemax / NLS_MAX_CHARSET_SIZE - 1 ? > >> Kind regards, > >> Petr #include <fcntl.h> #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/statfs.h> #include <unistd.h> /* test requires C.utf8 locale */ #define LOCALE "C.utf8" /* here for vfat, exfat, which allow 256, Linux filesystems (btrfs, ext4, tmpfs xfs, ...) allow only 255 */ #define MAX_FILENAME_PATH "test_ϴ_" \ "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" \ "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" \ "123456789012345678901234567890123456789012345678" #define TOO_LONG_FILENAME MAX_FILENAME_PATH "_" /* here for vfat, exfat, which allow 256, Linux filesystems (btrfs, ext4, tmpfs xfs, ...) allow only 255 */ #define MAX_FILENAME_PATH_UTF16 \ "ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ" \ "ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ" \ "ϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴϴ" /* man 2 statfs or kernel-source/include/linux/magic.h */ #define TST_BTRFS_MAGIC 0x9123683E #define TST_NFS_MAGIC 0x6969 #define TST_RAMFS_MAGIC 0x858458f6 #define TST_TMPFS_MAGIC 0x01021994 #define TST_V9FS_MAGIC 0x01021997 #define TST_XFS_MAGIC 0x58465342 #define TST_EXT2_OLD_MAGIC 0xEF51 /* ext2, ext3, ext4 have the same magic number */ #define TST_EXT234_MAGIC 0xEF53 #define TST_MINIX_MAGIC 0x137F #define TST_MINIX_MAGIC2 0x138F #define TST_MINIX2_MAGIC 0x2468 #define TST_MINIX2_MAGIC2 0x2478 #define TST_MINIX3_MAGIC 0x4D5A #define TST_UDF_MAGIC 0x15013346 #define TST_SYSV2_MAGIC 0x012FF7B6 #define TST_SYSV4_MAGIC 0x012FF7B5 #define TST_UFS_MAGIC 0x00011954 #define TST_UFS2_MAGIC 0x19540119 #define TST_F2FS_MAGIC 0xF2F52010 #define TST_NILFS_MAGIC 0x3434 #define TST_EXOFS_MAGIC 0x5DF5 #define TST_OVERLAYFS_MAGIC 0x794c7630 #define TST_FUSE_MAGIC 0x65735546 #define TST_VFAT_MAGIC 0x4d44 /* AKA MSDOS */ #define TST_EXFAT_MAGIC 0x2011BAB0UL long tst_fs_type(const char *path) { struct statfs sbuf; if (statfs(path, &sbuf)) { perror("statfs"); exit(EXIT_FAILURE); return 0; } return sbuf.f_type; } const char *tst_fs_type_name(long f_type) { switch (f_type) { case TST_TMPFS_MAGIC: return "tmpfs"; case TST_NFS_MAGIC: return "nfs"; case TST_V9FS_MAGIC: return "9p"; case TST_RAMFS_MAGIC: return "ramfs"; case TST_BTRFS_MAGIC: return "btrfs"; case TST_XFS_MAGIC: return "xfs"; case TST_EXT2_OLD_MAGIC: return "ext2"; case TST_EXT234_MAGIC: return "ext2/ext3/ext4"; case TST_MINIX_MAGIC: case TST_MINIX_MAGIC2: case TST_MINIX2_MAGIC: case TST_MINIX2_MAGIC2: case TST_MINIX3_MAGIC: return "minix"; case TST_UDF_MAGIC: return "udf"; case TST_SYSV2_MAGIC: case TST_SYSV4_MAGIC: return "sysv"; case TST_UFS_MAGIC: case TST_UFS2_MAGIC: return "ufs"; case TST_F2FS_MAGIC: return "f2fs"; case TST_NILFS_MAGIC: return "nilfs"; case TST_EXOFS_MAGIC: return "exofs"; case TST_OVERLAYFS_MAGIC: return "overlayfs"; case TST_FUSE_MAGIC: return "fuse"; case TST_VFAT_MAGIC: return "vfat"; case TST_EXFAT_MAGIC: return "exfat"; default: return "unknown"; } } int creat_file_print_len(char *str) { int fd; struct statfs buf; printf("\nfile: %s\nstrlen: %zu, mblen: %zu\n", str, strlen(str), mbstowcs(NULL, str, 0)); if ((fd = creat(str, 0666)) < 0) { perror("creat() failed"); return 1; } close(fd); if (statfs(str, &buf) < 0) { perror("statfs() failed"); return 1; } printf("buf.f_namelen: %zu\n", buf.f_namelen); return 0; } int main(int argc, char *argv[]) { int ret = 0; if (argc < 2) { fprintf(stderr, "Usage: %s DIR\n", argv[0]); exit(EXIT_FAILURE); } if (chdir(argv[1]) > 0) { perror("chdir() failed"); exit(EXIT_FAILURE); } printf("=== filesystem: %s ===\n", tst_fs_type_name(tst_fs_type("."))); if (setlocale(LC_ALL, LOCALE) == NULL) { perror("setlocale"); exit(EXIT_FAILURE); } ret |= creat_file_print_len(MAX_FILENAME_PATH); ret |= creat_file_print_len(TOO_LONG_FILENAME); ret |= creat_file_print_len(MAX_FILENAME_PATH_UTF16); return ret; }
diff --git a/testcases/kernel/syscalls/statvfs/statvfs01.c b/testcases/kernel/syscalls/statvfs/statvfs01.c index e3b356c93..94e17ba1d 100644 --- a/testcases/kernel/syscalls/statvfs/statvfs01.c +++ b/testcases/kernel/syscalls/statvfs/statvfs01.c @@ -1,92 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) Wipro Technologies Ltd, 2005. All Rights Reserved. * AUTHOR: Prashant P Yendigeri <prashant.yendigeri@wipro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * + * Copyright (c) 2022 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com> */ -/* - * DESCRIPTION - * This is a Phase I test for the statvfs(2) system call. - * It is intended to provide a limited exposure of the system call. - * This call behaves similar to statfs. + +/*\ + * [Description] + * + * Verify that statvfs() executes successfully for all + * available filesystems. */ -#include <stdio.h> -#include <unistd.h> -#include <errno.h> #include <sys/statvfs.h> -#include <stdint.h> - -#include "test.h" - -#define TEST_PATH "/" +#include "tst_test.h" -static void setup(void); -static void cleanup(void); +#define MNT_POINT "mntpoint" +#define TEST_PATH MNT_POINT"/testfile" -char *TCID = "statvfs01"; -int TST_TOTAL = 1; - -int main(int ac, char **av) +static void run(void) { struct statvfs buf; - int lc; - - tst_parse_opts(ac, av, NULL, NULL); + char *valid_fname, *invalid_fname; - setup(); + TST_EXP_PASS(statvfs(TEST_PATH, &buf)); - for (lc = 0; TEST_LOOPING(lc); lc++) { + valid_fname = SAFE_MALLOC(buf.f_namemax - 1); + invalid_fname = SAFE_MALLOC(buf.f_namemax + 1); + memset(valid_fname, 'a', buf.f_namemax - 1); + memset(invalid_fname, 'b', buf.f_namemax + 1); - tst_count = 0; - - TEST(statvfs(TEST_PATH, &buf)); - - if (TEST_RETURN == -1) { - tst_resm(TFAIL | TTERRNO, "statvfs(%s, ...) failed", - TEST_PATH); - } else { - tst_resm(TPASS, "statvfs(%s, ...) passed", TEST_PATH); - } - - } - - tst_resm(TINFO, "This call is similar to statfs"); - tst_resm(TINFO, "Extracting info about the '%s' file system", - TEST_PATH); - tst_resm(TINFO, "file system block size = %lu bytes", buf.f_bsize); - tst_resm(TINFO, "file system fragment size = %lu bytes", buf.f_frsize); - tst_resm(TINFO, "file system free blocks = %ju", - (uintmax_t) buf.f_bfree); - tst_resm(TINFO, "file system total inodes = %ju", - (uintmax_t) buf.f_files); - tst_resm(TINFO, "file system free inodes = %ju", - (uintmax_t) buf.f_ffree); - tst_resm(TINFO, "file system id = %lu", buf.f_fsid); - tst_resm(TINFO, "file system max filename length = %lu", buf.f_namemax); - - cleanup(); - tst_exit(); + TST_EXP_FD(creat(valid_fname, 0444)); + TST_EXP_FAIL(creat(invalid_fname, 0444), ENAMETOOLONG); } static void setup(void) { - tst_sig(NOFORK, DEF_HANDLER, cleanup); - - TEST_PAUSE; + SAFE_TOUCH(TEST_PATH, 0666, NULL); } -static void cleanup(void) -{ -} +static struct tst_test test = { + .test_all = run, + .setup = setup, + .needs_root = 1, + .mount_device = 1, + .mntpoint = MNT_POINT, + .all_filesystems = 1, + .skip_filesystems = (const char *const[]) { + "vfat", + "exfat", + NULL + } +};
Removed the TINFO statements, Added a validation of statvfs.f_namemax field by trying to create files of valid and invalid length names. Signed-off-by: Avinesh Kumar <akumar@suse.de> --- testcases/kernel/syscalls/statvfs/statvfs01.c | 106 ++++++------------ 1 file changed, 34 insertions(+), 72 deletions(-)