+test_153() {
+ multiop $DIR/$tfile Ow4096Ycu || error "multiop failed"
+}
+run_test 153 "test if fdatasync does not crash ======================="
+
+test_154() {
+ cp /etc/hosts $DIR/$tfile
+
+ fid=$($LFS path2fid $DIR/$tfile)
+ rc=$?
+ [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
+
+ echo "open fid $fid"
+ diff /etc/hosts $DIR/.lustre/fid/$fid || error "open by fid failed: did not find expected data in file."
+
+ echo "Opening a file by FID succeeded"
+}
+run_test 154 "Opening a file by FID"
+
+#Changelogs
+err17935 () {
+ if [ $MDSCOUNT -gt 1 ]; then
+ error_ignore 17935 $*
+ else
+ error $*
+ fi
+}
+test_160() {
+ do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog on
+ USER=$(do_facet $SINGLEMDS lctl --device $MDT0 changelog_register -n)
+ echo "Registered as changelog user $USER"
+ do_facet $SINGLEMDS lctl get_param -n mdd.$MDT0.changelog_users | \
+ grep -q $USER || error "User $USER not found in changelog_users"
+
+ # change something
+ mkdir -p $DIR/$tdir/pics/2008/zachy
+ touch $DIR/$tdir/pics/2008/zachy/timestamp
+ cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
+ mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
+ ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
+ ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
+ rm $DIR/$tdir/pics/desktop.jpg
+
+ # verify contents
+ $LFS changelog $MDT0 | tail -5
+ echo "verifying target fid"
+ fidc=$($LFS changelog $MDT0 | grep timestamp | grep "CREAT" | \
+ tail -1 | awk '{print $5}')
+ fidf=$($LFS path2fid $DIR/$tdir/pics/zach/timestamp)
+ [ "$fidc" == "t=$fidf" ] || \
+ err17935 "fid in changelog $fidc != file fid $fidf"
+ echo "verifying parent fid"
+ fidc=$($LFS changelog $MDT0 | grep timestamp | grep "CREAT" | \
+ tail -1 | awk '{print $6}')
+ fidf=$($LFS path2fid $DIR/$tdir/pics/zach)
+ [ "$fidc" == "p=$fidf" ] || \
+ err17935 "pfid in changelog $fidc != dir fid $fidf"
+
+ echo "verifying user clear"
+ USERS=$(( $(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | wc -l) - 2 ))
+ FIRST_REC=$($LFS changelog $MDT0 | head -1 | awk '{print $1}')
+ $LFS changelog_clear $MDT0 $USER $(($FIRST_REC + 5))
+ USER_REC=$(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | grep $USER | awk '{print $2}')
+ [ $USER_REC == $(($FIRST_REC + 5)) ] || \
+ err17935 "user index should be $(($FIRST_REC + 5)); is $USER_REC"
+ CLEAR_REC=$($LFS changelog $MDT0 | head -1 | awk '{print $1}')
+ [ $CLEAR_REC == $(($FIRST_REC + 6)) -o $USERS -gt 1 ] || \
+ err17935 "first index should be $(($FIRST_REC + 6)); is $PURGE_REC"
+
+ echo "verifying user deregister"
+ do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $USER
+ do_facet $SINGLEMDS lctl get_param -n mdd.$MDT0.changelog_users | \
+ grep -q $USER && error "User $USER still found in changelog_users"
+
+ [ $USERS -eq 1 ] && \
+ do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog off || true
+}
+run_test 160 "changelog sanity"
+
+test_161() {
+ # need local MDT for fid2path
+ remote_mds && skip "remote MDS" && return
+
+ mkdir -p $DIR/$tdir
+ cp /etc/hosts $DIR/$tdir/$tfile
+ mkdir $DIR/$tdir/foo1
+ mkdir $DIR/$tdir/foo2
+ ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
+ ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
+ ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
+ ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
+ local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[')
+ if [ "$($LFS fid2path ${mds1_svc} $FID | wc -l)" != "5" ]; then
+ $LFS fid2path ${mds1_svc} $FID
+ err17935 "bad link ea"
+ fi
+ # middle
+ rm $DIR/$tdir/foo2/zachary
+ # last
+ rm $DIR/$tdir/foo2/thor
+ # first
+ rm $DIR/$tdir/$tfile
+ # rename
+ mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
+ if [ "$($LFS fid2path ${mds1_svc} --link 1 $FID)" != "/$tdir/foo2/maggie" ]
+ then
+ $LFS fid2path ${mds1_svc} $FID
+ err17935 "bad link rename"
+ fi
+ rm $DIR/$tdir/foo2/maggie
+
+ # overflow the EA
+ local longname=filename_avg_len_is_thirty_two_
+ createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 || \
+ error "failed to hardlink many files"
+ links=$($LFS fid2path ${mds1_svc} $FID | wc -l)
+ echo -n "${links}/1000 links in link EA"
+ [ ${links} -gt 60 ] || err17935 "expected at least 60 links in link EA"
+ unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
+ error "failed to unlink many hardlinks"
+}
+run_test 161 "link ea sanity"
+
+check_path() {
+ local expected=$1
+ shift
+ local fid=$2
+
+ local path=$(${LFS} fid2path $*)
+ RC=$?
+
+ if [ $RC -ne 0 ]; then
+ err17935 "path looked up of $expected failed. Error $RC"
+ return $RC
+ elif [ "${path}" != "${expected}" ]; then
+ err17935 "path looked up \"${path}\" instead of \"${expected}\""
+ return 2
+ fi
+ echo "fid $fid resolves to path $path"
+}
+
+test_162() {
+ # need local MDT for fid2path
+ remote_mds && skip "remote MDS" && return
+
+ # Make changes to filesystem
+ mkdir -p $DIR/$tdir/d2
+ touch $DIR/$tdir/d2/$tfile
+ touch $DIR/$tdir/d2/x1
+ touch $DIR/$tdir/d2/x2
+ mkdir -p $DIR/$tdir/d2/a/b/c
+ mkdir -p $DIR/$tdir/d2/p/q/r
+ FID=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[')
+ check_path "/$tdir/d2/$tfile" ${mds1_svc} $FID --link 0
+ ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
+ mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
+ FID=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[')
+ check_path "/$tdir/d2/a/b/c/new_file" ${mds1_svc} $FID --link 1
+ check_path "/$tdir/d2/p/q/r/hlink" ${mds1_svc} $FID --link 0
+ # check that there are 2 links
+ ${LFS} fid2path ${mds1_svc} $FID | wc -l | grep -q 2 || \
+ err17935 "expected 2 links"
+
+ rm $DIR/$tdir/d2/p/q/r/hlink
+ check_path "/$tdir/d2/a/b/c/new_file" ${mds1_svc} $FID --link 0
+ # Doesnt work with CMD yet: 17935
+ return 0
+}
+run_test 162 "path lookup sanity"
+
+test_170() {
+ $LCTL debug_daemon start $TMP/${tfile}_log_good
+ touch $DIR/$tfile
+ $LCTL debug_daemon stop
+ sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
+ error "sed failed to read log_good"
+
+ $LCTL debug_daemon start $TMP/${tfile}_log_good
+ rm -rf $DIR/$tfile
+ $LCTL debug_daemon stop
+
+ $LCTL df $TMP/${tfile}_log_bad 2&> $TMP/${tfile}_log_bad.out ||
+ error "lctl df log_bad failed"
+
+ local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
+ local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
+
+ $LCTL df $TMP/${tfile}_log_good 2&>$TMP/${tfile}_log_good.out
+ local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
+
+ [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
+ error "bad_line good_line1 good_line2 are empty"
+
+ cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
+ cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
+ cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
+
+ $LCTL df $TMP/${tfile}_logs_corrupt 2&> $TMP/${tfile}_log_bad.out
+ local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
+ local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
+
+ [ "$bad_line_new" ] && [ "$good_line_new" ] ||
+ error "bad_line_new good_line_new are empty"
+
+ local expected_good=$((good_line1 + good_line2*2))
+
+ rm -rf $TMP/${tfile}*
+ if [ $bad_line -ne $bad_line_new ]; then
+ error "expected $bad_line bad lines, but got $bad_line_new"
+ return 1
+ fi
+
+ if [ $expected_good -ne $good_line_new ]; then
+ error "expected $expected_good good lines, but got $good_line_new"
+ return 2
+ fi
+ true
+}
+run_test 170 "test lctl df to handle corrupted log ====================="
+
+# OST pools tests