+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"
+
+test_155_load() {
+ local temp=$TMP/$tfile
+ local file=$DIR/$tfile
+ local list=$(comma_list $(osts_nodes))
+ local big=$(do_nodes $list grep "cache" /proc/cpuinfo | \
+ awk '{sum+=$4} END{print sum}')
+
+ log big is $big K
+
+ dd if=/dev/urandom of=$temp bs=6096 count=1 || \
+ error "dd of=$temp bs=6096 count=1 failed"
+ cp $temp $file
+ cancel_lru_locks osc
+ cmp $temp $file || error "$temp $file differ"
+
+ $TRUNCATE $temp 6000
+ $TRUNCATE $file 6000
+ cmp $temp $file || error "$temp $file differ (truncate1)"
+
+ echo "12345" >>$temp
+ echo "12345" >>$file
+ cmp $temp $file || error "$temp $file differ (append1)"
+
+ echo "12345" >>$temp
+ echo "12345" >>$file
+ cmp $temp $file || error "$temp $file differ (append2)"
+
+ dd if=/dev/urandom of=$temp bs=$((big*2)) count=1k || \
+ error "dd of=$temp bs=$((big*2)) count=1k failed"
+ cp $temp $file
+ ls -lh $temp $file
+ cancel_lru_locks osc
+ cmp $temp $file || error "$temp $file differ"
+
+ rm -f $temp
+ true
+}
+
+test_155a() {
+ set_cache read on
+ set_cache writethrough on
+ test_155_load
+}
+run_test 155a "Verification of correctness: read cache:on write_cache:on"
+
+test_155b() {
+ set_cache read on
+ set_cache writethrough off
+ test_155_load
+}
+run_test 155b "Verification of correctness: read cache:on write_cache:off"
+
+test_155c() {
+ set_cache read off
+ set_cache writethrough on
+ test_155_load
+}
+run_test 155c "Verification of correctness: read cache:off write_cache:on"
+
+test_155d() {
+ set_cache read off
+ set_cache writethrough off
+ test_155_load
+}
+run_test 155d "Verification of correctness: read cache:off write_cache:off "
+
+test_156() {
+ local CPAGES=3
+ local BEFORE
+ local AFTER
+ local file="$DIR/$tfile"
+
+ log "Turn on read and write cache"
+ set_cache read on
+ set_cache writethrough on
+
+ log "Write data and read it back."
+ log "Read should be satisfied from the cache."
+ dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
+ BEFORE=`roc_hit`
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == CPAGES"; then
+ error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ log "Read again; it should be satisfied from the cache."
+ BEFORE=$AFTER
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == CPAGES"; then
+ error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+
+ log "Turn off the read cache and turn on the write cache"
+ set_cache read off
+ set_cache writethrough on
+
+ log "Read again; it should be satisfied from the cache."
+ BEFORE=`roc_hit`
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == CPAGES"; then
+ error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ log "Read again; it should not be satisfied from the cache."
+ BEFORE=$AFTER
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == 0"; then
+ error "IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ log "Write data and read it back."
+ log "Read should be satisfied from the cache."
+ dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
+ BEFORE=`roc_hit`
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == CPAGES"; then
+ error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ log "Read again; it should not be satisfied from the cache."
+ BEFORE=$AFTER
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == 0"; then
+ error "IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+
+ log "Turn off read and write cache"
+ set_cache read off
+ set_cache writethrough off
+
+ log "Write data and read it back"
+ log "It should not be satisfied from the cache."
+ rm -f $file
+ dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
+ cancel_lru_locks osc
+ BEFORE=`roc_hit`
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == 0"; then
+ error_ignore 20762 "IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+
+ log "Turn on the read cache and turn off the write cache"
+ set_cache read on
+ set_cache writethrough off
+
+ log "Write data and read it back"
+ log "It should not be satisfied from the cache."
+ rm -f $file
+ dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
+ BEFORE=`roc_hit`
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == 0"; then
+ error_ignore 20762 "IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ log "Read again; it should be satisfied from the cache."
+ BEFORE=`roc_hit`
+ cancel_lru_locks osc
+ cat $file >/dev/null
+ AFTER=`roc_hit`
+ if ! let "AFTER - BEFORE == CPAGES"; then
+ error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
+ else
+ log "cache hits:: before: $BEFORE, after: $AFTER"
+ fi
+
+ rm -f $file
+}
+run_test 156 "Verification of tunables ============================"
+
+#Changelogs
+err17935 () {
+ if [ $MDSCOUNT -gt 1 ]; then
+ error_ignore 17935 $*
+ else
+ error $*
+ fi
+}
+test_160() {
+ 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
+
+ $LFS changelog $MDT0 | tail -5
+
+ echo "verifying changelog mask"
+ do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog_mask="-mkdir"
+ mkdir -p $DIR/$tdir/pics/2009/sofia
+ do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog_mask="+mkdir"
+ mkdir $DIR/$tdir/pics/2009/zachary
+ DIRS=$($LFS changelog $MDT0 | tail -5 | grep -c MKDIR)
+ [ $DIRS -eq 1 ] || err17935 "changelog mask count $DIRS != 1"
+
+ # verify contents
+ 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"
+
+ USER_REC1=$(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | grep $USER | awk '{print $2}')
+ $LFS changelog_clear $MDT0 $USER $(($USER_REC1 + 5))
+ USER_REC2=$(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | grep $USER | awk '{print $2}')
+ echo "verifying user clear: $(( $USER_REC1 + 5 )) == $USER_REC2"
+ [ $USER_REC2 == $(($USER_REC1 + 5)) ] || \
+ err17935 "user index should be $(($USER_REC1 + 5)); is $USER_REC2"
+
+ MIN_REC=$(do_facet $SINGLEMDS lctl get_param mdd.$MDT0.changelog_users | \
+ awk 'min == "" || $2 < min {min = $2}; END {print min}')
+ FIRST_REC=$($LFS changelog $MDT0 | head -1 | awk '{print $1}')
+ echo "verifying min purge: $(( $MIN_REC + 1 )) == $FIRST_REC"
+ [ $FIRST_REC == $(($MIN_REC + 1)) ] || \
+ err17935 "first index should be $(($MIN_REC + 1)); is $FIRST_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=$(( $(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | wc -l) - 2 ))
+ if [ $USERS -eq 0 ]; then
+ LAST_REC1=$(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | head -1 | awk '{print $3}')
+ touch $DIR/$tdir/chloe
+ LAST_REC2=$(do_facet $SINGLEMDS lctl get_param -n \
+ mdd.$MDT0.changelog_users | head -1 | awk '{print $3}')
+ echo "verify changelogs are off if we were the only user: $LAST_REC1 == $LAST_REC2"
+ [ $LAST_REC1 == $LAST_REC2 ] || error "changelogs not off"
+ else
+ echo "$USERS other changelog users; can't verify off"
+ fi
+}
+run_test 160 "changelog sanity"
+
+test_161() {
+ 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 $DIR $FID | wc -l)" != "5" ]; then
+ $LFS fid2path $DIR $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 $DIR --link 1 $FID)" != "/$tdir/foo2/maggie" ]
+ then
+ $LFS fid2path $DIR $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 $DIR $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() {
+ # 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
+ # regular file
+ FID=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[')
+ check_path "/$tdir/d2/$tfile" $DIR $FID --link 0
+
+ # softlink
+ ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
+ FID=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[')
+ check_path "/$tdir/d2/p/q/r/slink" $DIR $FID --link 0
+
+ # hardlink
+ 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 '[')
+ # fid2path dir/fsname should both work
+ check_path "/$tdir/d2/a/b/c/new_file" $FSNAME $FID --link 1
+ check_path "/$tdir/d2/p/q/r/hlink" $DIR $FID --link 0
+
+ # hardlink count: check that there are 2 links
+ # Doesnt work with CMD yet: 17935
+ ${LFS} fid2path $DIR $FID | wc -l | grep -q 2 || \
+ err17935 "expected 2 links"
+
+ # hardlink indexing: remove the first link
+ rm $DIR/$tdir/d2/p/q/r/hlink
+ check_path "/$tdir/d2/a/b/c/new_file" $DIR $FID --link 0
+
+ return 0
+}
+run_test 162 "path lookup sanity"
+
+test_163() {
+ remote_mds_nodsh && skip "remote MDS with nodsh" && return
+ copytool --test || { skip "copytool not runnable: $?" && return; }
+ copytool &
+ sleep 1
+ local uuid=$($LCTL get_param -n mdc.lustre-MDT0000-mdc-*.uuid)
+ # this proc file is temporary and linux-only
+ do_facet mds lctl set_param mdt.lustre-MDT0000.mdccomm=$uuid || error "lnl send failed"
+ kill $!
+}
+run_test 163 "LustreNetLink kernelcomms"
+
+test_169() {
+ # do directio so as not to populate the page cache
+ log "creating a 10 Mb file"
+ multiop $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
+ log "starting reads"
+ dd if=$DIR/$tfile of=/dev/null bs=4096 &
+ log "truncating the file"
+ multiop $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
+ log "killing dd"
+ kill %+ || true # reads might have finished
+ echo "wait until dd is finished"
+ wait
+ log "removing the temporary file"
+ rm -rf $DIR/$tfile || error "tmp file removal failed"
+}
+run_test 169 "parallel read and truncate should not deadlock"
+
+test_170() {
+ $LCTL clear # bug 18514
+ $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 > $TMP/${tfile}_log_bad.out 2>&1 ||
+ 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 > $TMP/${tfile}_log_good.out 2>&1
+ 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 > $TMP/${tfile}_log_bad.out 2>&1
+ 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 -f $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