From dfe7fcd415fa40e2ab059c5201f7df4e2e174e54 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 27 Feb 2013 01:12:39 -0600 Subject: [PATCH] LU-2523 mdt: handle -ENOENT && !MDS_OPEN_CREAT in reint open If mdt_open_by_fid_lock() returns -ENOENT and MDS_OPEN_CREAT is not set in create flags then bail out and return -ENOENT from mdt_reint_open(). In mdt_open_by_fid_lock() if -ENOENT is returned then ensure that DISP_IT_EXECD is set in the reply disposition. Add sanity test_27B to call the LL_IOC_LOV_SETSTRIPE ioctl() on an open unlinked file, a situation which triggers the first case. In sanityn test 30, remote the requirement that opening an unlinked file via /proc/PID/exe return -ESTALE. In racer's file_create.sh, reinstate the call to 'lfs setstripe' before dd is started, effectively reverting commit 0be1c87fe2d4ffddaca9e568cc137518b7368b2d. Signed-off-by: John L. Hammond Change-Id: I74e2297c4210ff18acbf60efdf51049d9a88cbea Reviewed-on: http://review.whamcloud.com/5417 Reviewed-by: Jinshan Xiong Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_open.c | 20 +++++-- lustre/tests/multiop.c | 106 ++++++++++++++++++++++++++------------ lustre/tests/racer/file_create.sh | 4 +- lustre/tests/sanity.sh | 23 +++++++++ lustre/tests/sanityn.sh | 8 ++- 5 files changed, 117 insertions(+), 44 deletions(-) diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 46dc11e..bfb10f8 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1295,8 +1295,10 @@ int mdt_open_by_fid_lock(struct mdt_thread_info *info, struct ldlm_reply *rep, PFID(rr->rr_fid2)); GOTO(out, rc = -EREMOTE); } else if (!mdt_object_exists(o)) { - mdt_set_disposition(info, rep, (DISP_LOOKUP_EXECD | - DISP_LOOKUP_NEG)); + mdt_set_disposition(info, rep, + DISP_IT_EXECD | + DISP_LOOKUP_EXECD | + DISP_LOOKUP_NEG); GOTO(out, rc = -ENOENT); } @@ -1486,11 +1488,21 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) } else if ((rr->rr_namelen == 0 && create_flags & MDS_OPEN_LOCK) || (create_flags & MDS_OPEN_BY_FID)) { result = mdt_open_by_fid_lock(info, ldlm_rep, lhc); - if ((result != -ENOENT && !(create_flags & MDS_OPEN_CREAT)) && - result != -EREMOTE) + /* If result is 0 then open by FID has found the file + * and there is nothing left for us to do here. More + * generally if it is anything other than -ENOENT or + * -EREMOTE then we return that now. If -ENOENT and + * MDS_OPEN_CREAT is set then we must create the file + * below. If -EREMOTE then we need to return a LOOKUP + * lock to the client, which we do below. Hence this + * odd looking condition. See LU-2523. */ + if (!(result == -ENOENT && (create_flags & MDS_OPEN_CREAT)) && + result != -EREMOTE) GOTO(out, result); + if (unlikely(rr->rr_namelen == 0)) GOTO(out, result = -EINVAL); + CDEBUG(D_INFO, "No object(2), continue as regular open.\n"); } diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c index 814bd88..7a21869 100644 --- a/lustre/tests/multiop.c +++ b/lustre/tests/multiop.c @@ -64,9 +64,10 @@ sem_t sem; #define ALIGN_LEN 65535 char usage[] = -"Usage: %s filename command-sequence\n" +"Usage: %s filename command-sequence [path...]\n" " command-sequence items:\n" " c close\n" +" B[num] call setstripe ioctl to create stripes\n" " C[num] create with optional stripes\n" " d mkdir\n" " D open(O_DIRECTORY)\n" @@ -74,11 +75,13 @@ char usage[] = " F print FID\n" " G gid get grouplock\n" " g gid put grouplock\n" -" L link\n" -" l symlink\n" +" K link path to filename\n" +" L link filename to path\n" +" l symlink filename to path\n" " m mknod\n" " M rw mmap to EOF (must open and stat prior)\n" -" N rename\n" +" n rename path to filename\n" +" N rename filename to path\n" " o open(O_RDONLY)\n" " O open(O_CREAT|O_RDWR)\n" " r[num] read [optional length]\n" @@ -125,27 +128,28 @@ pop_arg(int argc, char *argv[]) } struct flag_mapping { - const char *string; - const int flag; + const char *string; + const int flag; } flag_table[] = { - {"O_RDONLY", O_RDONLY}, - {"O_WRONLY", O_WRONLY}, - {"O_RDWR", O_RDWR}, - {"O_CREAT", O_CREAT}, - {"O_EXCL", O_EXCL}, - {"O_NOCTTY", O_NOCTTY}, - {"O_TRUNC", O_TRUNC}, - {"O_APPEND", O_APPEND}, - {"O_NONBLOCK", O_NONBLOCK}, - {"O_NDELAY", O_NDELAY}, - {"O_SYNC", O_SYNC}, + {"O_RDONLY", O_RDONLY}, + {"O_WRONLY", O_WRONLY}, + {"O_RDWR", O_RDWR}, + {"O_CREAT", O_CREAT}, + {"O_EXCL", O_EXCL}, + {"O_NOCTTY", O_NOCTTY}, + {"O_TRUNC", O_TRUNC}, + {"O_APPEND", O_APPEND}, + {"O_NONBLOCK", O_NONBLOCK}, + {"O_NDELAY", O_NDELAY}, + {"O_SYNC", O_SYNC}, #ifdef O_DIRECT - {"O_DIRECT", O_DIRECT}, + {"O_DIRECT", O_DIRECT}, #endif - {"O_LARGEFILE", O_LARGEFILE}, - {"O_DIRECTORY", O_DIRECTORY}, - {"O_NOFOLLOW", O_NOFOLLOW}, - {"", -1} + {"O_LARGEFILE", O_LARGEFILE}, + {"O_DIRECTORY", O_DIRECTORY}, + {"O_NOFOLLOW", O_NOFOLLOW}, + {"O_LOV_DELAY_CREATE", O_LOV_DELAY_CREATE}, + {"", -1} }; int get_flags(char *data, int *rflags) @@ -193,6 +197,7 @@ int main(int argc, char **argv) { char *fname, *commands; const char *newfile; + const char *oldpath; struct stat st; struct statfs stfs; size_t mmap_len = 0, i; @@ -204,6 +209,7 @@ int main(int argc, char **argv) int gid = 0; lustre_fid fid; struct timespec ts; + struct lov_user_md_v3 lum; if (argc < 3) { fprintf(stderr, usage, argv[0]); @@ -240,6 +246,18 @@ int main(int argc, char **argv) } fd = -1; break; + case 'B': + lum = (struct lov_user_md_v3) { + .lmm_magic = LOV_USER_MAGIC_V3, + .lmm_stripe_count = atoi(commands + 1), + }; + + if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, &lum) < 0) { + save_errno = errno; + perror("LL_IOC_LOV_SETSTRIPE"); + exit(save_errno); + } + break; case 'C': len = atoi(commands+1); fd = llapi_file_open(fname, O_CREAT | O_WRONLY, 0644, @@ -300,6 +318,17 @@ int main(int argc, char **argv) exit(save_errno); } break; + case 'K': + oldpath = POP_ARG(); + if (oldpath == NULL) + oldpath = fname; + + if (link(oldpath, fname)) { + save_errno = errno; + perror("link()"); + exit(save_errno); + } + break; case 'l': newfile = POP_ARG(); if (!newfile) @@ -310,16 +339,17 @@ int main(int argc, char **argv) exit(save_errno); } break; - case 'L': - newfile = POP_ARG(); - if (!newfile) - newfile = fname; - if (link(fname, newfile)) { - save_errno = errno; - perror("symlink()"); - exit(save_errno); - } - break; + case 'L': + newfile = POP_ARG(); + if (newfile == NULL) + newfile = fname; + + if (link(fname, newfile)) { + save_errno = errno; + perror("link()"); + exit(save_errno); + } + break; case 'm': if (mknod(fname, S_IFREG | 0644, 0) == -1) { save_errno = errno; @@ -342,6 +372,17 @@ int main(int argc, char **argv) exit(save_errno); } break; + case 'n': + oldpath = POP_ARG(); + if (oldpath == NULL) + oldpath = fname; + + if (rename(oldpath, fname) < 0) { + save_errno = errno; + perror("rename()"); + exit(save_errno); + } + break; case 'N': newfile = POP_ARG(); if (!newfile) @@ -520,6 +561,7 @@ int main(int argc, char **argv) exit(save_errno); } break; + case '-': case '0': case '1': case '2': diff --git a/lustre/tests/racer/file_create.sh b/lustre/tests/racer/file_create.sh index 7de46b6..828e69c 100755 --- a/lustre/tests/racer/file_create.sh +++ b/lustre/tests/racer/file_create.sh @@ -4,15 +4,13 @@ DIR=$1 MAX=$2 MAX_MB=256 -# disable until LU-2523 and LU-2789 are fixed -[ -z "$RACER_SETSTRIPE" ] && RACER_SETSTRIPE=false OSTCOUNT=${OSTCOUNT:-$(lfs df $DIR 2> /dev/null | grep -c OST)} while /bin/true ; do file=$((RANDOM % MAX)) SIZE=$((RANDOM * MAX_MB / 32)) echo "file_create: FILE=$DIR/$file SIZE=$SIZE" - [ $OSTCOUNT -gt 0 ] && $RACER_SETSTRIPE && + [ $OSTCOUNT -gt 0 ] && lfs setstripe -c $((RANDOM % OSTCOUNT)) $DIR/$file 2> /dev/null dd if=/dev/zero of=$DIR/$file bs=1k count=$SIZE 2> /dev/null done diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 234dd48..f16be85 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -1781,6 +1781,29 @@ test_27A() { # b=19102 } run_test 27A "check filesystem-wide default LOV EA values" +test_27B() { # LU-2523 + test_mkdir -p $DIR/$tdir + rm -f $DIR/$tdir/f0 $DIR/$tdir/f1 + touch $DIR/$tdir/f0 + # open f1 with O_LOV_DELAY_CREATE + # rename f0 onto f1 + # call setstripe ioctl on open file descriptor for f1 + # close + multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \ + $DIR/$tdir/f0 + + rm -f $DIR/$tdir/f1 + # open f1 with O_LOV_DELAY_CREATE + # unlink f1 + # call setstripe ioctl on open file descriptor for f1 + # close + multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c + + # Allow multiop to fail in imitation of NFS's busted semantics. + true +} +run_test 27B "call setstripe on open unlinked file/rename victim" + # createtest also checks that device nodes are created and # then visible correctly (#2091) test_28() { # bug 2091 diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 63b2aa7..1944a15 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -687,16 +687,14 @@ test_29() { # bug 10999 #bug 11549 - permanently turn test off in b1_5 run_test 29 "lock put race between glimpse and enqueue =========" -test_30() { #bug #11110 +test_30() { #bug #11110, LU-2523 test_mkdir -p $DIR1/$tdir cp -f /bin/bash $DIR1/$tdir/bash /bin/sh -c 'sleep 1; rm -f $DIR2/$tdir/bash; cp /bin/bash $DIR2/$tdir' & - local err=$($DIR1/$tdir/bash -c 'sleep 2; - openfile -f O_RDONLY /proc/$$/exe >& /dev/null; echo $?') + $DIR1/$tdir/bash -c 'sleep 2; + openfile -f O_RDONLY /proc/$$/exe >& /dev/null; echo $?' wait - [ $err -ne 116 ] && - error_ignore 12900 "return code ($err) != -ESTALE" && return true } -- 1.8.3.1