|  | #! /bin/bash | 
|  | # SPDX-License-Identifier: GPL-2.0 | 
|  | # Copyright (c) 2022 Oracle.  All Rights Reserved. | 
|  | # | 
|  | # FS QA Test No. 681 | 
|  | # | 
|  | # Ensure that unprivileged userspace hits EDQUOT while linking files into a | 
|  | # directory when the directory's quota limits have been exceeded. | 
|  | # | 
|  | # Regression test for commit: | 
|  | # | 
|  | # 871b9316e7a7 ("xfs: reserve quota for dir expansion when linking/unlinking files") | 
|  | # | 
|  | . ./common/preamble | 
|  | _begin_fstest auto quick quota | 
|  |  | 
|  | # Import common functions. | 
|  | . ./common/filter | 
|  | . ./common/quota | 
|  |  | 
|  |  | 
|  | # Modify as appropriate. | 
|  | _require_quota | 
|  | _require_user | 
|  | _require_scratch | 
|  |  | 
|  | _scratch_mkfs > "$seqres.full" 2>&1 | 
|  | _qmount_option usrquota | 
|  | _qmount | 
|  |  | 
|  | blocksize=$(_get_dir_block_size $SCRATCH_MNT) | 
|  | scratchdir=$SCRATCH_MNT/dir | 
|  | scratchfile=$SCRATCH_MNT/file | 
|  | mkdir $scratchdir | 
|  | touch $scratchfile | 
|  |  | 
|  | # Create a 2-block directory for our 1-block quota limit | 
|  | total_size=$((blocksize * 2)) | 
|  | dirents=$((total_size / 255)) | 
|  |  | 
|  | for ((i = 0; i < dirents; i++)); do | 
|  | name=$(printf "x%0254d" $i) | 
|  | ln $scratchfile $scratchdir/$name | 
|  | done | 
|  |  | 
|  | # Set a low quota hardlimit for an unprivileged uid and chown the files to it | 
|  | echo "set up quota" >> $seqres.full | 
|  | setquota -u $qa_user 0 "$((blocksize / 1024))" 0 0 $SCRATCH_MNT | 
|  | chown $qa_user $scratchdir $scratchfile | 
|  | repquota -upn $SCRATCH_MNT >> $seqres.full | 
|  | echo $(ls $scratchdir | wc -l) files in $scratchdir  >> $seqres.full | 
|  | ls -sld $scratchdir  >> $seqres.full | 
|  |  | 
|  | # Fail at appending the directory as qa_user to ensure quota enforcement works | 
|  | echo "fail quota" >> $seqres.full | 
|  | for ((i = 0; i < dirents; i++)); do | 
|  | name=$(printf "y%0254d" $i) | 
|  | su - "$qa_user" -c "ln $scratchfile $scratchdir/$name" 2>&1 | \ | 
|  | _filter_scratch | sed -e 's/y[0-9]*/yXXX/g' | 
|  | test "${PIPESTATUS[0]}" -ne 0 && break | 
|  | done | 
|  | repquota -upn $SCRATCH_MNT >> $seqres.full | 
|  | echo $(ls $scratchdir | wc -l) files in $scratchdir  >> $seqres.full | 
|  | ls -sld $scratchdir  >> $seqres.full | 
|  |  | 
|  | # success, all done | 
|  | echo Silence is golden | 
|  | status=0 | 
|  | exit |