From: adilger Date: Wed, 19 May 2004 18:26:13 +0000 (+0000) Subject: Land b1_2_smallfix onto b1_2 (20040519_1118) X-Git-Tag: v1_8_0_110~486^5~214 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=9e9994968766e4f656f085c363ce184a69f32f50;p=fs%2Flustre-release.git Land b1_2_smallfix onto b1_2 (20040519_1118) - loop device shouldn't call sync_dev() for nul device (3092) - push lock cancellation to blocking thread for glimpse ASTs (3409) - don't call osc_set_data_with_check() for TEST_LOCK matches (3159) --- diff --git a/lnet/include/linux/kp30.h b/lnet/include/linux/kp30.h index b27eaa0..8f572de 100644 --- a/lnet/include/linux/kp30.h +++ b/lnet/include/linux/kp30.h @@ -711,27 +711,34 @@ void kportal_put_ni (int nal); # endif #endif +#if BITS_PER_LONG > 32 +# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a) +#else +# define LI_POISON ((int)0x5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a) +#endif + #if defined(__x86_64__) # define LPU64 "%Lu" # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPSZ "%lu" # define LPSSZ "%ld" -# define LP_POISON ((void *)0x5a5a5a5a5a5a5a5a) #elif (BITS_PER_LONG == 32 || __WORDSIZE == 32) # define LPU64 "%Lu" # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPSZ "%u" # define LPSSZ "%d" -# define LP_POISON ((void *)0x5a5a5a5a) #elif (BITS_PER_LONG == 64 || __WORDSIZE == 64) # define LPU64 "%lu" # define LPD64 "%ld" # define LPX64 "%#lx" # define LPSZ "%lu" # define LPSSZ "%ld" -# define LP_POISON ((void *)0x5a5a5a5a5a5a5a5a) #endif #ifndef LPU64 # error "No word size defined" diff --git a/lustre/ChangeLog b/lustre/ChangeLog index f0f0e20..ebc62d9 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -35,6 +35,9 @@ tbd Cluster File Systems, Inc. - serialize filter_precreate and filter_destroy_precreated (3329) - clear page cache after eviction (2766) - resynchronize MDS->OST in background (2824) + - loop device shouldn't call sync_dev() for nul device (3092) + - push lock cancellation to blocking thread for glimpse ASTs (3409) + - don't call osc_set_data_with_check() for TEST_LOCK matches (3159) * miscellania - allow default OST striping configuration per directory (1414) - fix compilation for qswnal for 2.6 kernels (3125) diff --git a/lustre/configure.in b/lustre/configure.in index 5de965c..1800a4f 100644 --- a/lustre/configure.in +++ b/lustre/configure.in @@ -5,7 +5,7 @@ AC_INIT AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(lustre, 1.2.1.12) +AM_INIT_AUTOMAKE(lustre, 1.2.1.13) # AM_MAINTAINER_MODE # Four main targets: lustre kernel modules, utilities, tests, and liblustre diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index ebdfdf6..a529860 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -40,18 +40,28 @@ #include #include +#ifndef LP_POISON +#if BITS_PER_LONG > 32 +# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a) +#else +# define LI_POISON ((int)0x5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a) +#endif +#endif + #ifndef LPU64 /* x86_64 has 64bit longs and defines u64 as long long */ #if BITS_PER_LONG > 32 && !defined(__x86_64__) #define LPU64 "%lu" #define LPD64 "%ld" #define LPX64 "%#lx" -#define LP_POISON ((void *)0x5a5a5a5a5a5a5a5a) #else #define LPU64 "%Lu" #define LPD64 "%Ld" #define LPX64 "%#Lx" -#define LP_POISON ((void *)0x5a5a5a5a) #endif #endif diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index fdd3ebb..879a56b 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -53,10 +53,10 @@ struct lov_oinfo { /* per-stripe data structure */ /* used by the osc to keep track of what objects to build into rpcs */ struct loi_oap_pages loi_read_lop; struct loi_oap_pages loi_write_lop; - struct list_head loi_read_item; /* _cli_ is poorly named, it should be _ready_ */ struct list_head loi_cli_item; struct list_head loi_write_item; + struct list_head loi_read_item; int loi_kms_valid:1; __u64 loi_kms; /* known minimum size */ diff --git a/lustre/kernel_patches/patches/loop-sync-2.4.21-suse.patch b/lustre/kernel_patches/patches/loop-sync-2.4.21-suse.patch new file mode 100644 index 0000000..73372b9 --- /dev/null +++ b/lustre/kernel_patches/patches/loop-sync-2.4.21-suse.patch @@ -0,0 +1,11 @@ +--- drivers/block/loop.c.bu 2004-05-11 16:27:23.000000000 -0700 ++++ drivers/block/loop.c 2004-05-11 16:28:50.000000000 -0700 +@@ -978,7 +978,7 @@ static int lo_release(struct inode *inod + + lo = &loop_dev[dev]; + +- if (!(lo->lo_flags & LO_FLAGS_READ_ONLY)) { ++ if (!(lo->lo_flags & LO_FLAGS_READ_ONLY) && lo->lo_device != 0) { + fsync_dev(lo->lo_device); + invalidate_buffers(lo->lo_device); + } diff --git a/lustre/kernel_patches/series/suse-2.4.21-2 b/lustre/kernel_patches/series/suse-2.4.21-2 index 3593126..65339b1 100644 --- a/lustre/kernel_patches/series/suse-2.4.21-2 +++ b/lustre/kernel_patches/series/suse-2.4.21-2 @@ -30,3 +30,4 @@ ext3-xattr-ptr-arith-fix.patch kernel_text_address-2.4.20-vanilla.patch procfs-ndynamic-2.4.21-suse2.patch ext3-truncate-buffer-head.patch +loop-sync-2.4.21-suse.patch diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index 9f25d99..4bf42dd 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -44,8 +44,6 @@ extern kmem_cache_t *ldlm_resource_slab; extern kmem_cache_t *ldlm_lock_slab; extern struct lustre_lock ldlm_handle_lock; extern struct list_head ldlm_namespace_list; -extern int (*mds_reint_p)(int offset, struct ptlrpc_request *req); -extern int (*mds_getattr_name_p)(int offset, struct ptlrpc_request *req); static DECLARE_MUTEX(ldlm_ref_sem); static int ldlm_refcount = 0; @@ -894,8 +892,13 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, if (lock->l_granted_mode == LCK_PW && !lock->l_readers && !lock->l_writers && time_after(jiffies, lock->l_last_used + 10 * HZ)) { +#ifdef __KERNEL__ + ldlm_bl_to_thread(ns, NULL, lock); + l_unlock(&ns->ns_lock); +#else l_unlock(&ns->ns_lock); ldlm_handle_bl_callback(ns, NULL, lock); +#endif EXIT; return; } diff --git a/lustre/llite/file.c b/lustre/llite/file.c index b311349..c4b0d97 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -181,6 +181,8 @@ int ll_file_open(struct inode *inode, struct file *file) struct lookup_intent *it; struct lov_stripe_md *lsm; struct ptlrpc_request *req; + struct lookup_intent oit = { .it_op = IT_OPEN, + .it_flags = file->f_flags }; int rc = 0; ENTRY; @@ -193,9 +195,7 @@ int ll_file_open(struct inode *inode, struct file *file) it = file->f_it; - if (!it->d.lustre.it_disposition) { - struct lookup_intent oit = { .it_op = IT_OPEN, - .it_flags = file->f_flags }; + if (!it || !it->d.lustre.it_disposition) { it = &oit; rc = ll_intent_file_open(file, NULL, 0, it); if (rc) diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c index e401266..a7be61a 100644 --- a/lustre/llite/symlink.c +++ b/lustre/llite/symlink.c @@ -51,7 +51,8 @@ static int ll_readlink_internal(struct inode *inode, rc = mdc_getattr(sbi->ll_mdc_exp, &fid, OBD_MD_LINKNAME, symlen, request); if (rc) { - CERROR("inode %lu: rc = %d\n", inode->i_ino, rc); + if (rc != -ENOENT) + CERROR("inode %lu: rc = %d\n", inode->i_ino, rc); RETURN(rc); } diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 52aa135..208256f 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -366,7 +366,7 @@ void mdc_clear_open_replay_data(struct obd_client_handle *och) * we're sure we won't need to fix up the close request in the future), * but make sure that replay doesn't poke at the och, which is about to * be freed. */ - LASSERT(mod != (void *)0x5a5a5a5a); + LASSERT(mod != LP_POISON); if (mod != NULL) mod->mod_och = NULL; och->och_mod = NULL; @@ -388,7 +388,8 @@ static void mdc_commit_close(struct ptlrpc_request *req) open_req = mod->mod_open_req; LASSERT(open_req != NULL); - LASSERT(open_req != (void *)0x5a5a5a5a); + LASSERT(open_req != LP_POISON); + LASSERT(open_req->rq_type != LI_POISON); DEBUG_REQ(D_HA, open_req, "open req balanced"); LASSERT(open_req->rq_transno != 0); @@ -464,8 +465,8 @@ int mdc_close(struct obd_export *exp, struct obdo *oa, mod = och->och_mod; if (likely(mod != NULL)) { mod->mod_close_req = req; - DEBUG_REQ(D_HA, mod->mod_open_req, "matched open req %p", - mod->mod_open_req); + LASSERT(mod->mod_open_req->rq_type != LI_POISON); + DEBUG_REQ(D_HA, mod->mod_open_req, "matched open"); } else { CDEBUG(D_HA, "couldn't find open req; expecting close error\n"); } @@ -514,7 +515,7 @@ int mdc_close(struct obd_export *exp, struct obdo *oa, if (req->rq_async_args.pointer_arg[0] != NULL) { CERROR("returned without dropping rpc_lock: rc %d\n", rc); mdc_close_interpret(req, &req->rq_async_args, rc); - portals_debug_dumplog(); + //portals_debug_dumplog(); } EXIT; diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 99e5699..104c009 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -607,23 +607,25 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, if ((S_ISREG(inode->i_mode) && (body->valid & OBD_MD_FLEASIZE)) || (S_ISDIR(inode->i_mode) && (body->valid & OBD_MD_FLDIREA))) { - int rc; + int ret; down(&inode->i_sem); - rc = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0); + ret = fsfilt_get_md(req->rq_export->exp_obd, inode, NULL, 0); up(&inode->i_sem); CDEBUG(D_INODE, "got %d bytes MD data for inode %lu\n", rc, inode->i_ino); - if (rc < 0) { - if (rc != -ENODATA) + if (ret < 0) { + if (ret != -ENODATA) { CERROR("error getting inode %lu MD: rc = %d\n", - inode->i_ino, rc); + inode->i_ino, ret); + /* should we return ret in req->rq_status? */ + } size[bufcount] = 0; - } else if (rc > mds->mds_max_mdsize) { + } else if (ret > mds->mds_max_mdsize) { size[bufcount] = 0; CERROR("MD size %d larger than maximum possible %u\n", - rc, mds->mds_max_mdsize); + ret, mds->mds_max_mdsize); } else { - size[bufcount] = rc; + size[bufcount] = ret; } bufcount++; } else if (S_ISLNK(inode->i_mode) && (body->valid & OBD_MD_LINKNAME)) { @@ -644,7 +646,7 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct inode *inode, rc = lustre_pack_reply(req, bufcount, size, NULL); if (rc) { - CERROR("out of memory\n"); + CERROR("lustre_pack_reply failed: rc %d\n", rc); GOTO(out, req->rq_status = rc); } diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index ca0fd3b..e012323 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -854,7 +854,8 @@ int mds_open(struct mds_update_record *rec, int offset, rec->ur_namelen - 1); if (IS_ERR(dparent)) { rc = PTR_ERR(dparent); - CERROR("parent lookup error %d\n", rc); + if (rc != -ENOENT) + CERROR("parent lookup error %d\n", rc); GOTO(cleanup, rc); } LASSERT(dparent->d_inode != NULL); @@ -947,7 +948,9 @@ int mds_open(struct mds_update_record *rec, int offset, acc_mode = 0; /* Don't check for permissions */ } - LASSERT(!mds_inode_is_orphan(dchild->d_inode)); + LASSERTF(!mds_inode_is_orphan(dchild->d_inode), + "dchild %*s (%p) inode %p\n", dchild->d_name.len, + dchild->d_name.name, dchild, dchild->d_inode); mds_pack_inode2fid(&body->fid1, dchild->d_inode); mds_pack_inode2body(body, dchild->d_inode); diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 8880a74..7a43ffb 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -565,7 +565,8 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, rec->ur_name, rec->ur_namelen - 1); if (IS_ERR(dparent)) { rc = PTR_ERR(dparent); - CERROR("parent lookup error %d\n", rc); + if (rc != -ENOENT) + CERROR("parent lookup error %d\n", rc); GOTO(cleanup, rc); } cleanup_phase = 1; /* locked parent dentry */ @@ -1445,8 +1446,10 @@ static int mds_add_link_orphan(struct mds_update_record *rec, fidlen = ll_fid2str(fidname, dentry->d_inode->i_ino, dentry->d_inode->i_generation); - CDEBUG(D_ERROR, "pending destroy of %dx open file %s = %s\n", + CDEBUG(D_ERROR, "pending destroy of %dx open %s %s = %s\n", mds_open_orphan_count(dentry->d_inode), + S_ISDIR(dentry->d_inode->i_mode) ? "dir" : + S_ISREG(dentry->d_inode->i_mode) ? "file" : "other", rec->ur_name, fidname); pending_child = lookup_one_len(fidname, mds->mds_pending_dir, fidlen); diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c index 26d923e..754b46e 100644 --- a/lustre/osc/osc_create.c +++ b/lustre/osc/osc_create.c @@ -192,7 +192,7 @@ static int oscc_precreate(struct osc_creator *oscc, int wait) RETURN(rc); } -int oscc_recovering(struct osc_creator *oscc) +int oscc_recovering(struct osc_creator *oscc) { int recov = 0; @@ -217,7 +217,7 @@ int osc_create(struct obd_export *exp, struct obdo *oa, RETURN(osc_real_create(exp, oa, ea, oti)); if ((oa->o_valid & OBD_MD_FLFLAGS) && - oa->o_flags == OBD_FL_RECREATE_OBJS) { + oa->o_flags == OBD_FL_RECREATE_OBJS) { RETURN(osc_real_create(exp, oa, ea, oti)); } @@ -231,7 +231,7 @@ int osc_create(struct obd_export *exp, struct obdo *oa, /* this is the special case where create removes orphans */ if ((oa->o_valid & OBD_MD_FLFLAGS) && oa->o_flags == OBD_FL_DELORPHAN) { - CDEBUG(D_HA, "%s: oscc recovery started\n", + CDEBUG(D_HA, "%s: oscc recovery started\n", exp->exp_obd->obd_name); LASSERT(oscc->oscc_flags & OSCC_FLAG_RECOVERING); @@ -239,7 +239,7 @@ int osc_create(struct obd_export *exp, struct obdo *oa, oa->o_valid |= OBD_MD_FLID; oa->o_id = oscc->oscc_next_id - 1; - CDEBUG(D_HA, "%s: deleting to next_id: "LPU64"\n", + CDEBUG(D_HA, "%s: deleting to next_id: "LPU64"\n", exp->exp_obd->obd_name, oa->o_id); rc = osc_real_create(exp, oa, ea, NULL); @@ -261,16 +261,16 @@ int osc_create(struct obd_export *exp, struct obdo *oa, spin_unlock(&oscc->oscc_lock); - RETURN(rc); - } + RETURN(rc); + } while (try_again) { - /* If orphans are being recovered, then we must wait until + /* If orphans are being recovered, then we must wait until it is finished before we can continue with create. */ if (oscc_recovering(oscc)) { struct l_wait_info lwi; - CDEBUG(D_HA,"%p: oscc recovery in progress, waiting\n", + CDEBUG(D_HA,"%p: oscc recovery in progress, waiting\n", oscc); lwi = LWI_TIMEOUT(MAX(obd_timeout*HZ/4, 1), NULL, NULL); @@ -282,7 +282,7 @@ int osc_create(struct obd_export *exp, struct obdo *oa, oscc); RETURN(rc); } - CDEBUG(D_HA, "%p: oscc recovery over, waking up\n", + CDEBUG(D_HA, "%p: oscc recovery over, waking up\n", oscc); } @@ -306,8 +306,8 @@ int osc_create(struct obd_export *exp, struct obdo *oa, } if (rc == 0) - CDEBUG(D_HA, "%s: returning objid "LPU64"\n", - oscc->oscc_obd->u.cli.cl_import->imp_target_uuid.uuid, + CDEBUG(D_HA, "%s: returning objid "LPU64"\n", + oscc->oscc_obd->u.cli.cl_import->imp_target_uuid.uuid, lsm->lsm_object_id); else if (*ea == NULL) obd_free_memmd(exp, &lsm); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 3e06638..66a06d2 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2466,7 +2466,8 @@ static int osc_match(struct obd_export *exp, struct lov_stripe_md *lsm, rc = ldlm_lock_match(obd->obd_namespace, *flags, &res_id, type, policy, mode, lockh); if (rc) { - osc_set_data_with_check(lockh, data); + if (!(*flags & LDLM_FL_TEST_LOCK)) + osc_set_data_with_check(lockh, data); RETURN(rc); } /* If we're trying to read, we also search for an existing PW lock. The diff --git a/lustre/portals/include/linux/kp30.h b/lustre/portals/include/linux/kp30.h index b27eaa0..8f572de 100644 --- a/lustre/portals/include/linux/kp30.h +++ b/lustre/portals/include/linux/kp30.h @@ -711,27 +711,34 @@ void kportal_put_ni (int nal); # endif #endif +#if BITS_PER_LONG > 32 +# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a) +#else +# define LI_POISON ((int)0x5a5a5a5a) +# define LL_POISON ((long)0x5a5a5a5a) +# define LP_POISON ((void *)(long)0x5a5a5a5a) +#endif + #if defined(__x86_64__) # define LPU64 "%Lu" # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPSZ "%lu" # define LPSSZ "%ld" -# define LP_POISON ((void *)0x5a5a5a5a5a5a5a5a) #elif (BITS_PER_LONG == 32 || __WORDSIZE == 32) # define LPU64 "%Lu" # define LPD64 "%Ld" # define LPX64 "%#Lx" # define LPSZ "%u" # define LPSSZ "%d" -# define LP_POISON ((void *)0x5a5a5a5a) #elif (BITS_PER_LONG == 64 || __WORDSIZE == 64) # define LPU64 "%lu" # define LPD64 "%ld" # define LPX64 "%#lx" # define LPSZ "%lu" # define LPSSZ "%ld" -# define LP_POISON ((void *)0x5a5a5a5a5a5a5a5a) #endif #ifndef LPU64 # error "No word size defined" diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index f313234..2081271 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -15,11 +15,12 @@ noinst_SCRIPTS += runfailure-ost runiozone runregression-net.sh runtests noinst_SCRIPTS += sanity.sh rundbench noinst_PROGRAMS = openunlink testreq truncate directio openme writeme open_delay noinst_PROGRAMS += tchmod toexcl fsx test_brw openclose createdestroy -noinst_PROGRAMS += stat createmany statmany multifstat createtest mlink utime cmknod +noinst_PROGRAMS += stat createmany statmany multifstat createtest mlink utime noinst_PROGRAMS += opendirunlink opendevunlink unlinkmany fchdir_test checkstat noinst_PROGRAMS += wantedi statone runas openfile getdents mkdirdeep o_directory -noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify +noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify cmknod noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify +noinst_PROGRAMS += rename_many # noinst_PROGRAMS += ldaptest bin_PROGRAMS = mcreate munlink mkdirmany iopentest1 iopentest2 endif # TESTS diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index 6fce04c..5fb43c2 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -885,9 +885,6 @@ test_45() { pid=$! sleep 1 - # allow the open to complete - usleep 500 - # This will cause the CLOSE to fail before even # allocating a reply buffer $LCTL --device $mdcdev deactivate diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 818b49b..be5c5a2 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -1581,7 +1581,7 @@ test_48c() { # bug 2350 $TRACE mkdir . && error "'mkdir .' worked after removing cwd" $TRACE rmdir . && error "'rmdir .' worked after removing cwd" $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd" ||true - $TRACE cd .. || error "'cd ..' failed after removing cwd" + $TRACE cd .. || true #bug 3415 error "'cd ..' failed after removing cwd" } run_test 48c "Access removed working subdir (should return errors)" @@ -1595,7 +1595,7 @@ test_48d() { # bug 2350 $TRACE touch foo && error "'touch foo' worked after removing cwd" $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd" $TRACE ls . && error "'ls .' worked after removing cwd" - $TRACE ls .. && error "'ls ..' worked after removing cwd" + $TRACE ls .. #bug 3415 && error "'ls ..' worked after removing cwd" $TRACE cd . && error "'cd .' worked after recreate cwd" $TRACE mkdir . && error "'mkdir .' worked after removing cwd" $TRACE rmdir . && error "'rmdir .' worked after removing cwd"