From 1d10ce2d5abc5e607001407125b7c98f9cce9070 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 31 Dec 2008 12:59:19 +0100 Subject: [PATCH] test 197, add a testcase for d_off truncation Make sure our directory offsets fit into a 32 bit value. Based on a report by John Stanley. Signed-off-by: Christoph Hellwig Reviewed-by: Eric Sandeen --- 197 | 50 +++++++++++++++++++++++++++++++++++++ 197.out | 2 ++ group | 1 + src/Makefile | 2 +- src/t_dir_offset.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 197 create mode 100644 197.out create mode 100644 src/t_dir_offset.c diff --git a/197 b/197 new file mode 100644 index 00000000..4c81941f --- /dev/null +++ b/197 @@ -0,0 +1,50 @@ +#! /bin/sh +# FS QA Test No. 197 +# +# Check that d_off can be represented in a 32 bit long type without +# truncation. Note that this test will always succeed on a 64 bit +# systems where there is no smaller off_t. +# +# Based on a testcase from John Stanley . +# +# http://oss.sgi.com/bugzilla/show_bug.cgi?id=808 +# +#----------------------------------------------------------------------- +# Copyright (c) 2008 Christoph Hellwig. +#----------------------------------------------------------------------- +# +# creator +owner=hch@lst.de + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + rm -rf $TEST_DIR/ttt +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# real QA test starts here +_supported_fs xfs +_supported_os Linux + + +mkdir $TEST_DIR/ttt +for n in {1..168}; do + touch $TEST_DIR/ttt/$n; +done +src/t_dir_offset $TEST_DIR/ttt + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/197.out b/197.out new file mode 100644 index 00000000..2b4213e7 --- /dev/null +++ b/197.out @@ -0,0 +1,2 @@ +QA output created by 197 +*** done diff --git a/group b/group index ea8a0a3a..fdacc726 100644 --- a/group +++ b/group @@ -299,3 +299,4 @@ atime 194 rw auto 195 ioctl dump auto 196 quota auto +197 dir auto diff --git a/src/Makefile b/src/Makefile index 4b95fdcd..4a3113ab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,7 +15,7 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \ LINUX_TARGETS = loggen xfsctl bstat t_mtab getdevicesize \ preallo_rw_pattern_reader preallo_rw_pattern_writer ftrunc trunc \ fs_perms testx looptest locktest unwritten_mmap \ - bulkstat_unlink_test bulkstat_unlink_test_modified + bulkstat_unlink_test bulkstat_unlink_test_modified t_dir_offset IRIX_TARGETS = open_unlink diff --git a/src/t_dir_offset.c b/src/t_dir_offset.c new file mode 100644 index 00000000..eeec3f3f --- /dev/null +++ b/src/t_dir_offset.c @@ -0,0 +1,62 @@ + +#include +#include +#include +#include +#include +#include +#include + +struct linux_dirent64 { + uint64_t d_ino; + int64_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[0]; +}; + + +#define BUF_SIZE 4096 + +int +main(int argc, char *argv[]) +{ + int fd, nread; + char buf[BUF_SIZE]; + struct linux_dirent64 *d; + int bpos; + + fd = open(argv[1], O_RDONLY | O_DIRECTORY); + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + for ( ; ; ) { + nread = syscall(SYS_getdents64, fd, buf, BUF_SIZE); + if (nread == -1) { + perror("getdents"); + exit(EXIT_FAILURE); + } + + if (nread == 0) + break; + + for (bpos = 0; bpos < nread;) { + d = (struct linux_dirent64 *) (buf + bpos); + /* + * Can't use off_t here xfsqa is compiled with + * -D_FILE_OFFSET_BITS=64 + */ + if (d->d_off != (long)d->d_off) { + fprintf(stderr, "detected d_off truncation " + "d_name = %s, d_off = %lld\n", + d->d_name, (long long)d->d_off); + exit(EXIT_FAILURE); + } + bpos += d->d_reclen; + } + } + + exit(EXIT_SUCCESS); +} -- 2.39.5