From 6c2cca48c1307b3d30a46b16ffb2290b8ddf590b Mon Sep 17 00:00:00 2001 From: adilger Date: Thu, 10 Jun 2004 18:54:53 +0000 Subject: [PATCH] Land b1_2_smallfix onto b1_2 (20040610_1244) - dynamic ptlrpc request buffer allocation (b=2102) - don't allow unlinking open directory if it isn't empty (b=2904) - set MDS/OST threads to umask 0 to not clobber client modes (b=3359) --- lustre/ChangeLog | 3 + lustre/configure.in | 2 +- lustre/include/linux/lustre_mds.h | 1 + lustre/include/linux/lustre_net.h | 34 +++++------- lustre/include/linux/lvfs.h | 1 + lustre/lov/lov_obd.c | 4 +- lustre/lvfs/lvfs_linux.c | 3 + lustre/mds/mds_open.c | 3 +- lustre/mds/mds_reint.c | 17 +++--- lustre/mds/mds_unlink_open.c | 27 ++++++--- lustre/ptlrpc/lproc_ptlrpc.c | 6 +- lustre/ptlrpc/ptlrpc_internal.h | 2 + lustre/ptlrpc/service.c | 113 ++++++++++++++++++++++++++------------ lustre/tests/Makefile.am | 3 +- lustre/tests/sanity.sh | 14 +++++ 15 files changed, 154 insertions(+), 79 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3f1aa28..df7d863 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -7,6 +7,9 @@ tbd Cluster File Systems, Inc. - change init script to fail more clearly if not run as root (1528) - fix ns_lock/i_sem lock ordering deadlock for kms update (3477) - don't do DNS lookups on NIDs too small for IP addresses (3442) + - dynamic ptlrpc request buffer allocation (2102) + - don't allow unlinking open directory if it isn't empty (2904) + - set MDS/OST threads to umask 0 to not clobber client modes (3359) * miscellania - servers can dump a log evicting a client - lustre.dump_on_timeout=1 diff --git a/lustre/configure.in b/lustre/configure.in index 88e9012..7b14e69 100644 --- a/lustre/configure.in +++ b/lustre/configure.in @@ -5,7 +5,7 @@ AC_INIT AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(lustre, 1.2.2.2) +AM_INIT_AUTOMAKE(lustre, 1.2.2.3) # AM_MAINTAINER_MODE # Four main targets: lustre kernel modules, utilities, tests, and liblustre diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index a1f333a..05f736e 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -96,6 +96,7 @@ struct mds_update_record { #define ur_cap ur_uc.ouc_cap #define ur_suppgid1 ur_uc.ouc_suppgid1 #define ur_suppgid2 ur_uc.ouc_suppgid2 +#define ur_umask ur_uc.ouc_umask /* i_attr_flags holds the open count in the inode in 2.4 */ //XXX Alex implement on 2.4 with i_attr_flags and find soln for 2.5 please diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index 9b33c3e9..489b5a1 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -67,32 +67,29 @@ * buffers */ #define SVC_BUF_VMALLOC_THRESHOLD (2*PAGE_SIZE) -/* The following constants determine how much memory is devoted to - * buffering in the lustre services. +/* The following constants determine how memory is used to buffer incoming + * service requests. * - * ?_NEVENTS # event queue entries - * - * ?_NBUFS # request buffers + * ?_NBUFS # buffers to allocate when growing the pool * ?_BUFSIZE # bytes in a single request buffer - * total memory = ?_NBUFS * ?_BUFSIZE - * * ?_MAXREQSIZE # maximum request service will receive - * messages larger than ?_MAXREQSIZE are dropped. - * request buffers are auto-unlinked when less than ?_MAXREQSIZE - * is left in them. + * + * When fewer than ?_NBUFS/2 buffers are posted for receive, another chunk + * of ?_NBUFS is added to the pool. + * + * Messages larger than ?_MAXREQSIZE are dropped. Request buffers are + * considered full when less than ?_MAXREQSIZE is left in them. */ #define LDLM_NUM_THREADS min(smp_num_cpus * smp_num_cpus * 8, 64) -#define LDLM_NBUF_MAX 512UL +#define LDLM_NBUFS 64 #define LDLM_BUFSIZE (8 * 1024) #define LDLM_MAXREQSIZE (5 * 1024) -#define LDLM_MAXMEM (num_physpages*(PAGE_SIZE/1024)) -#define LDLM_NBUFS min(LDLM_MAXMEM/LDLM_BUFSIZE, LDLM_NBUF_MAX) #define MDT_MAX_THREADS 32UL #define MDT_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \ MDT_MAX_THREADS), 2UL) -#define MDS_NBUF_MAX 4096UL +#define MDS_NBUFS 64 #define MDS_BUFSIZE (8 * 1024) /* Assume file name length = FNAME_MAX = 256 (true for extN). * path name length = PATH_MAX = 4096 @@ -109,13 +106,11 @@ * except in the open case where there are a large number of OSTs in a LOV. */ #define MDS_MAXREQSIZE (5 * 1024) -#define MDS_MAXMEM (num_physpages*(PAGE_SIZE/128)) -#define MDS_NBUFS min(MDS_MAXMEM/MDS_BUFSIZE, MDS_NBUF_MAX) #define OST_MAX_THREADS 36UL #define OST_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \ OST_MAX_THREADS), 2UL) -#define OST_NBUF_MAX 5000UL +#define OST_NBUFS 64 #define OST_BUFSIZE (8 * 1024) /* OST_MAXREQSIZE ~= 1640 bytes = * lustre_msg + obdo + 16 * obd_ioobj + 64 * niobuf_remote @@ -124,11 +119,9 @@ * - OST_MAXREQSIZE must be at least 1 page of cookies plus some spillover */ #define OST_MAXREQSIZE (5 * 1024) -#define OST_MAXMEM (num_physpages*(PAGE_SIZE/128)) -#define OST_NBUFS min(OST_MAXMEM/OST_BUFSIZE, OST_NBUF_MAX) #define PTLBD_NUM_THREADS 4 -#define PTLBD_NBUFS 20 +#define PTLBD_NBUFS 64 #define PTLBD_BUFSIZE (32 * 1024) #define PTLBD_MAXREQSIZE 1024 @@ -459,6 +452,7 @@ struct ptlrpc_service { struct list_head srv_list; /* chain thru all services */ int srv_max_req_size; /* biggest request to receive */ int srv_buf_size; /* size of individual buffers */ + int srv_nbuf_per_group; /* # buffers to allocate in 1 group */ int srv_nbufs; /* total # req buffer descs allocated */ int srv_nthreads; /* # running threads */ int srv_n_difficult_replies; /* # 'difficult' replies */ diff --git a/lustre/include/linux/lvfs.h b/lustre/include/linux/lvfs.h index b18769f..61f0cfc 100644 --- a/lustre/include/linux/lvfs.h +++ b/lustre/include/linux/lvfs.h @@ -20,6 +20,7 @@ struct obd_ucred { __u32 ouc_cap; __u32 ouc_suppgid1; __u32 ouc_suppgid2; + __u32 ouc_umask; }; struct lvfs_callback_ops { diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 9470466..526eeb3 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2650,7 +2650,7 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen, } -/* Merge rss if kms == 0 +/* Merge rss if @kms_only == 0 * * Even when merging RSS, we will take the KMS value if it's larger. * This prevents getattr from stomping on dirty cached pages which @@ -2665,8 +2665,6 @@ __u64 lov_merge_size(struct lov_stripe_md *lsm, int kms_only) i++, loi++) { obd_size lov_size, tmpsize; - CDEBUG(D_DLMTRACE, "stripe %u ost %u kms "LPU64" rss "LPU64"\n", - i, loi->loi_ost_idx, loi->loi_kms, loi->loi_rss); tmpsize = loi->loi_kms; if (kms_only == 0 && loi->loi_rss > tmpsize) tmpsize = loi->loi_rss; diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c index 1e58081..ce5ac40 100644 --- a/lustre/lvfs/lvfs_linux.c +++ b/lustre/lvfs/lvfs_linux.c @@ -110,11 +110,13 @@ void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, save->ouc.ouc_cap = current->cap_effective; save->ouc.ouc_suppgid1 = current_groups[0]; save->ouc.ouc_suppgid2 = current_groups[1]; + save->ouc.ouc_umask = current->fs->umask; current->fsuid = uc->ouc_fsuid; current->fsgid = uc->ouc_fsgid; current->cap_effective = uc->ouc_cap; current_ngroups = 0; + current->fs->umask = 0; /* umask already applied on client */ if (uc->ouc_suppgid1 != -1) current_groups[current_ngroups++] = uc->ouc_suppgid1; @@ -171,6 +173,7 @@ void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, current_ngroups = saved->ngroups; current_groups[0] = saved->ouc.ouc_suppgid1; current_groups[1] = saved->ouc.ouc_suppgid2; + current->fs->umask = saved->ouc.ouc_umask; } /* diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index e012323..adabb10 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -942,8 +942,7 @@ int mds_open(struct mds_update_record *rec, int offset, if (rc) CERROR("error on parent setattr: rc = %d\n", rc); - rc = mds_finish_transno(mds, dchild->d_inode, handle, req, 0, - rep ? rep->lock_policy_res1 : 0); + rc = fsfilt_commit(obd, dchild->d_inode, handle, 0); handle = NULL; acc_mode = 0; /* Don't check for permissions */ } diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 7a43ffb..ac15d0c 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -1137,6 +1137,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, cleanup_phase = 1; /* dchild, dparent, locks */ + dget(dchild); child_inode = dchild->d_inode; if (child_inode == NULL) { CDEBUG(D_INODE, "child doesn't exist (dir %lu, name %s)\n", @@ -1196,13 +1197,6 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, GOTO(cleanup, rc = -EISDIR); } - if (child_inode->i_nlink == (S_ISDIR(child_inode->i_mode) ? 2 : 1) && - mds_open_orphan_count(child_inode) > 0) { - rc = mds_open_unlink_rename(rec, obd, dparent, dchild, &handle); - cleanup_phase = 4; /* transaction */ - GOTO(cleanup, rc); - } - /* Step 4: Do the unlink: we already verified ur_mode above (bug 72) */ switch (child_inode->i_mode & S_IFMT) { case S_IFDIR: @@ -1273,6 +1267,14 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, switch(cleanup_phase) { case 4: + LASSERT(dchild != NULL && dchild->d_inode != NULL); + LASSERT(atomic_read(&dchild->d_inode->i_count) > 0); + if (rc == 0 && dchild->d_inode->i_nlink == 0 && + mds_open_orphan_count(dchild->d_inode) > 0) { + /* filesystem is really going to destroy an inode + * we have to delay this till inode is opened -bzzz */ + mds_open_unlink_rename(rec, obd, dparent, dchild, NULL); + } rc = mds_finish_transno(mds, dparent->d_inode, handle, req, rc, 0); if (!rc) @@ -1295,6 +1297,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, else ptlrpc_save_lock(req, &parent_lockh, LCK_PW); l_dput(dchild); + l_dput(dchild); l_dput(dparent); case 0: break; diff --git a/lustre/mds/mds_unlink_open.c b/lustre/mds/mds_unlink_open.c index 87e9a27..a79e44c 100644 --- a/lustre/mds/mds_unlink_open.c +++ b/lustre/mds/mds_unlink_open.c @@ -60,6 +60,7 @@ int mds_open_unlink_rename(struct mds_update_record *rec, struct dentry *pending_child; char fidname[LL_FID_NAMELEN]; int fidlen = 0, rc; + unsigned mode; ENTRY; LASSERT(!mds_inode_is_orphan(dchild->d_inode)); @@ -81,18 +82,26 @@ int mds_open_unlink_rename(struct mds_update_record *rec, GOTO(out_dput, rc = 0); } - *handle = fsfilt_start(obd, pending_dir, FSFILT_OP_RENAME, NULL); - if (IS_ERR(*handle)) - GOTO(out_dput, rc = PTR_ERR(*handle)); - - lock_kernel(); - rc = vfs_rename(dparent->d_inode, dchild, pending_dir, pending_child); - unlock_kernel(); + /* link() is semanticaly-wrong for S_IFDIR, so we set S_IFREG + * for linking and return real mode back then -bzzz */ + mode = dchild->d_inode->i_mode; + dchild->d_inode->i_mode = S_IFREG; + rc = vfs_link(dchild, pending_dir, pending_child); if (rc) - CERROR("error renaming orphan %lu/%s to PENDING: rc = %d\n", - dparent->d_inode->i_ino, rec->ur_name, rc); + CERROR("error linking orphan %s to PENDING: rc = %d\n", + rec->ur_name, rc); else mds_inode_set_orphan(dchild->d_inode); + + /* return mode and correct i_nlink if inode is directory */ + LASSERT(dchild->d_inode->i_nlink == 1); + dchild->d_inode->i_mode = mode; + if ((mode & S_IFMT) == S_IFDIR) { + dchild->d_inode->i_nlink++; + pending_dir->i_nlink++; + } + mark_inode_dirty(dchild->d_inode); + out_dput: dput(pending_child); out_lock: diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 0075860..e567185 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -108,7 +108,7 @@ void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, struct proc_dir_entry *svc_procroot; struct lprocfs_stats *svc_stats; int i, rc; - unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX | + unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV; LASSERT(*procroot_ret == NULL); @@ -134,6 +134,10 @@ void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, svc_counter_config, "req_qdepth", "reqs"); lprocfs_counter_init(svc_stats, PTLRPC_REQACTIVE_CNTR, svc_counter_config, "req_active", "reqs"); + lprocfs_counter_init(svc_stats, PTLRPC_REQBUF_AVAIL_CNTR, + svc_counter_config, "reqbuf_avail", "bufs"); + lprocfs_counter_init(svc_stats, PTLRPC_REQBUF_TOTAL_CNTR, + svc_counter_config, "reqbuf_total", "bufs"); for (i = 0; i < LUSTRE_MAX_OPCODES; i++) { __u32 opcode = ll_rpc_opcode_table[i].opcode; lprocfs_counter_init(svc_stats, PTLRPC_LAST_CNTR + i, diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h index 89c6cc0..9e51595 100644 --- a/lustre/ptlrpc/ptlrpc_internal.h +++ b/lustre/ptlrpc/ptlrpc_internal.h @@ -101,6 +101,8 @@ enum { PTLRPC_REQWAIT_CNTR = 0, PTLRPC_REQQDEPTH_CNTR, PTLRPC_REQACTIVE_CNTR, + PTLRPC_REQBUF_AVAIL_CNTR, + PTLRPC_REQBUF_TOTAL_CNTR, PTLRPC_LAST_CNTR }; diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 4a13771..c541e30 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -31,6 +31,9 @@ #include #include "ptlrpc_internal.h" +/* forward ref */ +static int ptlrpc_server_post_idle_rqbds (struct ptlrpc_service *svc); + static LIST_HEAD (ptlrpc_all_services); static spinlock_t ptlrpc_all_services_lock = SPIN_LOCK_UNLOCKED; @@ -116,6 +119,29 @@ ptlrpc_free_rqbd (struct ptlrpc_request_buffer_desc *rqbd) OBD_FREE (rqbd, sizeof (*rqbd)); } +int +ptlrpc_grow_req_bufs(struct ptlrpc_srv_ni *srv_ni) +{ + struct ptlrpc_service *svc = srv_ni->sni_service; + struct ptlrpc_request_buffer_desc *rqbd; + int i; + + for (i = 0; i < svc->srv_nbuf_per_group; i++) { + rqbd = ptlrpc_alloc_rqbd(srv_ni); + + if (rqbd == NULL) { + CERROR ("%s/%s: Can't allocate request buffer\n", + svc->srv_name, srv_ni->sni_ni->pni_name); + return (-ENOMEM); + } + + if (ptlrpc_server_post_idle_rqbds(svc) < 0) + return (-EAGAIN); + } + + return (0); +} + void ptlrpc_save_lock (struct ptlrpc_request *req, struct lustre_handle *lock, int mode) @@ -198,28 +224,34 @@ ptlrpc_server_post_idle_rqbds (struct ptlrpc_service *svc) struct ptlrpc_request_buffer_desc *rqbd; unsigned long flags; int rc; + int posted = 0; - spin_lock_irqsave(&svc->srv_lock, flags); - if (list_empty (&svc->srv_idle_rqbds)) { - spin_unlock_irqrestore(&svc->srv_lock, flags); - return (0); - } + for (;;) { + spin_lock_irqsave(&svc->srv_lock, flags); - rqbd = list_entry(svc->srv_idle_rqbds.next, - struct ptlrpc_request_buffer_desc, - rqbd_list); - list_del (&rqbd->rqbd_list); + if (list_empty (&svc->srv_idle_rqbds)) { + spin_unlock_irqrestore(&svc->srv_lock, flags); + return (posted); + } - /* assume we will post successfully */ - srv_ni = rqbd->rqbd_srv_ni; - srv_ni->sni_nrqbd_receiving++; - list_add (&rqbd->rqbd_list, &srv_ni->sni_active_rqbds); + rqbd = list_entry(svc->srv_idle_rqbds.next, + struct ptlrpc_request_buffer_desc, + rqbd_list); + list_del (&rqbd->rqbd_list); - spin_unlock_irqrestore(&svc->srv_lock, flags); + /* assume we will post successfully */ + srv_ni = rqbd->rqbd_srv_ni; + srv_ni->sni_nrqbd_receiving++; + list_add (&rqbd->rqbd_list, &srv_ni->sni_active_rqbds); - rc = ptlrpc_register_rqbd(rqbd); - if (rc == 0) - return (1); + spin_unlock_irqrestore(&svc->srv_lock, flags); + + rc = ptlrpc_register_rqbd(rqbd); + if (rc != 0) + break; + + posted = 1; + } spin_lock_irqsave(&svc->srv_lock, flags); @@ -248,11 +280,10 @@ ptlrpc_init_svc(int nbufs, int bufsize, int max_req_size, struct proc_dir_entry *proc_entry) { int i; - int j; + int rc; int ssize; struct ptlrpc_service *service; struct ptlrpc_srv_ni *srv_ni; - struct ptlrpc_request_buffer_desc *rqbd; ENTRY; LASSERT (ptlrpc_ninterfaces > 0); @@ -270,6 +301,7 @@ ptlrpc_init_svc(int nbufs, int bufsize, int max_req_size, INIT_LIST_HEAD(&service->srv_threads); init_waitqueue_head(&service->srv_waitq); + service->srv_nbuf_per_group = nbufs; service->srv_max_req_size = max_req_size; service->srv_buf_size = bufsize; service->srv_rep_portal = rep_portal; @@ -301,22 +333,11 @@ ptlrpc_init_svc(int nbufs, int bufsize, int max_req_size, CDEBUG (D_NET, "%s: initialising interface %s\n", name, srv_ni->sni_ni->pni_name); - for (j = 0; j < nbufs; j++) { - rqbd = ptlrpc_alloc_rqbd (srv_ni); - - if (rqbd == NULL) { - CERROR ("%s.%d: Can't allocate request %d " - "on %s\n", name, i, j, - srv_ni->sni_ni->pni_name); - GOTO(failed, NULL); - } - - /* We shouldn't be under memory pressure at - * startup, so fail if we can't post all our - * buffers at this time. */ - if (ptlrpc_server_post_idle_rqbds(service) <= 0) - GOTO(failed, NULL); - } + rc = ptlrpc_grow_req_bufs(srv_ni); + /* We shouldn't be under memory pressure at startup, so + * fail if we can't post all our buffers at this time. */ + if (rc != 0) + GOTO(failed, NULL); } if (proc_entry != NULL) @@ -638,6 +659,26 @@ void ptlrpc_daemonize(void) reparent_to_init(); } +static void +ptlrpc_check_rqbd_pools(struct ptlrpc_service *svc) +{ + struct ptlrpc_srv_ni *sni; + int i, avail = 0; + int low_water = svc->srv_nbuf_per_group/2; + + for (i = 0; i < ptlrpc_ninterfaces; i++) { + sni = &svc->srv_interfaces[i]; + + avail += sni->sni_nrqbd_receiving; + /* NB I'm not locking; just looking. */ + if (sni->sni_nrqbd_receiving <= low_water) + ptlrpc_grow_req_bufs(sni); + } + lprocfs_counter_add(svc->srv_stats, PTLRPC_REQBUF_AVAIL_CNTR, avail); + lprocfs_counter_add(svc->srv_stats, PTLRPC_REQBUF_TOTAL_CNTR, + svc->srv_nbufs); +} + static int ptlrpc_retry_rqbds(void *arg) { @@ -697,6 +738,8 @@ static int ptlrpc_main(void *arg) (svc->srv_nthreads - 1))), &lwi); + ptlrpc_check_rqbd_pools(svc); + if (!list_empty (&svc->srv_reply_queue)) ptlrpc_server_handle_reply (svc); diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index c11c89c..13abda9 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -20,7 +20,7 @@ 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 += ll_sparseness_write mrename ll_dirstripe_verify -noinst_PROGRAMS += rename_many +noinst_PROGRAMS += openfilleddirunlink rename_many # noinst_PROGRAMS += ldaptest bin_PROGRAMS = mcreate munlink mkdirmany iopentest1 iopentest2 endif # TESTS @@ -57,6 +57,7 @@ wantedi_SOURCES = wantedi.c createtest_SOURCES = createtest.c open_delay_SOURCES = open_delay.c opendirunlink_SOURCES = opendirunlink.c +openfilleddirunlink_SOURCES = openfilleddirunlink.c opendevunlink_SOURCES = opendevunlink.c fchdir_test_SOURCES = fchdir_test.c getdents_SOURCES=getdents.c diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 7960b5f..7739263 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -195,6 +195,8 @@ EXT2_DEV=${EXT2_DEV:-/tmp/SANITY.LOOP} touch $EXT2_DEV mke2fs -j -F $EXT2_DEV 8000 > /dev/null +umask 022 + test_0() { touch $DIR/f $CHECKSTAT -t file $DIR/f || error @@ -203,6 +205,12 @@ test_0() { } run_test 0 "touch .../f ; rm .../f =============================" +test_0b() { + chmod 0755 $DIR || error + $CHECKSTAT -p 0755 $DIR || error +} +run_test 0b "chmod 0755 $DIR =============================" + test_1a() { mkdir $DIR/d1 mkdir $DIR/d1/d2 @@ -894,6 +902,12 @@ test_31d() { } run_test 31d "remove of open directory =========================" +test_31e() { # bug 2904 + check_kernel_version 34 || return 0 + openfilleddirunlink $DIR/d31e || error +} +run_test 31e "remove of open non-empty directory ===============" + test_32a() { echo "== more mountpoints and symlinks =================" [ -e $DIR/d32a ] && rm -fr $DIR/d32a -- 1.8.3.1