Merge of master-melb:xfs-cmds:29701a by kenmcd.
Update args to use command options for multi_open_unlink.
Change a sleep to a wait as we were just sleeping to account
for the death of a process - should really wait for its death.
num_files=200
delay=5
echo "open and unlink $num_files files"
-src/multi_open_unlink $SCRATCH_MNT/test_file $num_files $delay &
+src/multi_open_unlink -f $SCRATCH_MNT/test_file -n $num_files -s $delay &
# time to create and unlink all the files
sleep 3
# time for multi_open_unlink to exit out after its delay
# so we have no references and can unmount
-sleep 3
+wait 2>/dev/null
echo "unmount"
umount $SCRATCH_MNT
--- /dev/null
+#! /bin/sh
+# FS QA Test No. 181
+#
+# Like 121 only creating large EAs
+# As part of the iunlink processing in recovery it will call VN_RELE
+# which will inactivate the inodes and if they have EAs (which they
+# will here) also call xfs_inactive_attrs.
+# We want to test out this xfs_inactive_attrs code being called in recovery.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved.
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+_cleanup()
+{
+ rm -f $tmp.*
+ [ -n "$pid" ] && kill $pid
+}
+
+pid=""
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.log
+
+# real QA test starts here
+_supported_fs xfs
+_supported_os IRIX Linux
+
+rm -f $seq.full
+rm -f $tmp.log
+
+_require_scratch
+
+echo "mkfs"
+_scratch_mkfs_xfs >>$seq.full 2>&1 \
+ || _fail "mkfs scratch failed"
+
+echo "mount"
+_scratch_mount >>$seq.full 2>&1 \
+ || _fail "mount failed: $MOUNT_OPTIONS"
+
+# num_files must be greater than 64 (XFS_AGI_UNLINKED_BUCKETS)
+# so that there will be at least one linked list from one of
+# the 64 buckets, so that we can decode a di_next_unlinked field
+num_files=200
+num_eas=1
+ea_val_size=`expr 32 \* 1024`
+
+# sleep for ages and we will kill this pid when we are ready
+delay=100
+
+echo "open and unlink $num_files files with EAs"
+src/multi_open_unlink -f $SCRATCH_MNT/test_file -n $num_files -s $delay -e $num_eas -v $ea_val_size &
+pid=$!
+
+# time to create and unlink all the files
+sleep 10
+
+echo "godown"
+src/godown -v -f $SCRATCH_MNT >> $seq.full
+
+# kill the multi_open_unlink
+kill $pid 2>/dev/null
+wait $pid 2>/dev/null
+pid=""
+
+echo "unmount"
+umount $SCRATCH_MNT
+
+echo "logprint after going down..."
+_print_logstate
+
+echo "mount with replay"
+_scratch_mount $mnt >>$seq.full 2>&1 \
+ || _fail "mount failed: $mnt $MOUNT_OPTIONS"
+
+echo "godown"
+src/godown -v -f $SCRATCH_MNT >> $seq.full
+
+echo "unmount"
+umount $SCRATCH_MNT
+
+echo "logprint after going down..."
+_print_logstate
+
+echo "logprint to check for CLEAR_AGI_BUCKET..."
+if _scratch_xfs_logprint -t | tee -a $seq.full | grep CLEAR; then
+ echo 'CLEAR_AGI_BUCKET transactions found!!'
+ echo 'Are you running with an old xfs kernel - where the bug still exists?'
+else
+ echo 'No CLEAR_AGI_BUCKET found in transactions - great - test passed :)'
+fi
+
+# clean up dirty log with log recovery on mount
+_scratch_mount >> $seq.full 2>&1 \
+ || _fail "mount failed"
+
+# should now be peaches
+_check_scratch_fs
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 181
+mkfs
+mount
+open and unlink 200 files with EAs
+godown
+unmount
+logprint after going down...
+dirty log
+mount with replay
+godown
+unmount
+logprint after going down...
+dirty log
+logprint to check for CLEAR_AGI_BUCKET...
+No CLEAR_AGI_BUCKET found in transactions - great - test passed :)
178 mkfs other auto
179 metadata rw auto
180 metadata rw auto
+181 log auto
$(LINKTEST)
multi_open_unlink: multi_open_unlink.o
- $(LINKTEST)
+ $(LINKTEST) $(LIBATTR) $(LDLIBS)
#scaleread: scaleread.o $(LDLIBS)
# $(LINKTEST)
dmiperf: dmiperf.o $(LIBATTR)
$(LINKTEST) $(LIBATTR) $(LDLIBS)
-preallo_rw_pattern_reader:
+preallo_rw_pattern_reader:
$(CC) -DREAD iopat.c -o preallo_rw_pattern_reader
-preallo_rw_pattern_writer:
+preallo_rw_pattern_writer:
$(CC) -DWRITE iopat.c -o preallo_rw_pattern_writer
ftrunc: ftrunc.o
fs_perms: fs_perms.o
$(LINKTEST)
-
+
testx: testx.o
$(LINKTEST)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <attr/attributes.h>
+
+#define MAX_EA_NAME 30
/*
* multi_open_unlink path_prefix num_files sleep_time
- * e.g.
+ * e.g.
* $ multi_open_unlink file 100 60
* Creates 100 files: file.1, file.2, ..., file.100
- * unlinks them all but doesn't close them all until after 60 seconds.
+ * unlinks them all but doesn't close them all until after 60 seconds.
*/
+void
+usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s [-e num-eas] [-f path_prefix] [-n num_files] [-s sleep_time] [-v ea-valuesize] \n", prog);
+ exit(1);
+}
+
int
main(int argc, char *argv[])
{
- char *given_path;
+ char *given_path = "file";
char path[PATH_MAX];
char *prog = argv[0];
- int sleep_time;
- int num_files;
+ int sleep_time = 60;
+ int num_files = 100;
+ int num_eas = 0;
+ int value_size = ATTR_MAX_VALUELEN;
int fd = -1;
- int i;
+ int i,j,c;
- if (argc != 4) {
- fprintf(stderr, "Usage: %s path_prefix num_files sleep_time\n", prog);
- return 1;
+ while ((c = getopt(argc, argv, "e:f:n:s:v:")) != EOF) {
+ switch (c) {
+ case 'e': /* create eas */
+ num_eas = atoi(optarg);
+ break;
+ case 'f': /* file prefix */
+ given_path = optarg;
+ break;
+ case 'n': /* number of files */
+ num_files = atoi(optarg);
+ break;
+ case 's': /* sleep time */
+ sleep_time = atoi(optarg);
+ break;
+ case 'v': /* value size on eas */
+ value_size = atoi(optarg);
+ break;
+ case '?':
+ usage(prog);
+ }
}
- given_path = argv[1];
- num_files = atoi(argv[2]);
- sleep_time = atoi(argv[3]);
-
/* create and unlink a bunch of files */
for (i = 0; i < num_files; i++) {
sprintf(path, "%s.%d", given_path, i+1);
return 1;
}
+ /* set the EAs */
+ for (j = 0; j < num_eas; j++) {
+ int sts;
+ char *attrvalue;
+ char attrname[MAX_EA_NAME];
+ int flags = 0;
+
+ snprintf(attrname, MAX_EA_NAME, "user.name.%d", j);
+
+ attrvalue = calloc(value_size, 1);
+ if (attrvalue == NULL) {
+ fprintf(stderr, "%s: failed to create EA value of size %d on path \"%s\": %s\n",
+ prog, value_size, path, strerror(errno));
+ return 1;
+ }
+
+ sts = attr_set(path, attrname, attrvalue, value_size, flags);
+ if (sts == -1) {
+ fprintf(stderr, "%s: failed to create EA \"%s\" of size %d on path \"%s\": %s\n",
+ prog, attrname, value_size, path, strerror(errno));
+ return 1;
+ }
+ }
+
if (unlink(path) == -1) {
- fprintf(stderr, "%s: failed to unlink \"%s\": %s\n", prog, path, strerror(errno));
+ fprintf(stderr, "%s: failed to unlink \"%s\": %s\n",
+ prog, path, strerror(errno));
return 1;
}
}