- added test 0c to replay-single which tests that fld create is replied in recovery;
- fixes in lmv amd in llite, return fld lookup errors;
- added fld_cache_flush(), using it from fld lproc;
- some cleanups in mdt.
if (rc)
RETURN(rc);
- if (val <= LUSTRE_SEQ_MAX_WIDTH) {
+ if (val <= LUSTRE_SEQ_MAX_WIDTH && val > 0) {
seq->lcs_width = val;
if (rc == 0) {
CDEBUG(D_WARNING, "%s: sequence width "
- "has changed to "LPU64"\n", seq->lcs_name,
- seq->lcs_width);
+ "has changed to "LPU64"\n",
+ seq->lcs_name, seq->lcs_width);
}
}
{ NULL }};
struct lprocfs_vars seq_client_proc_list[] = {
- { "range", seq_proc_read_range, seq_proc_write_range, NULL },
- { "server", seq_proc_read_server, NULL, NULL },
- { "next_fid" , seq_proc_read_next_fid, NULL, NULL },
- { "seq_width", seq_proc_read_seq_width, seq_proc_write_seq_width, NULL },
+ { "range", seq_proc_read_range, seq_proc_write_range, NULL },
+ { "server", seq_proc_read_server, NULL, NULL },
+ { "next_fid" , seq_proc_read_next_fid, NULL, NULL },
+ { "seq_width", seq_proc_read_seq_width, seq_proc_write_seq_width, NULL },
{ NULL }};
#endif
return (__u32)seq;
}
+void fld_cache_flush(struct fld_cache_info *cache)
+{
+ struct fld_cache_entry *flde;
+ struct hlist_head *bucket;
+ struct hlist_node *scan;
+ struct hlist_node *next;
+ int i;
+ ENTRY;
+
+ /* Free all cache entries. */
+ spin_lock(&cache->fci_lock);
+ for (i = 0; i < cache->fci_hash_size; i++) {
+ bucket = cache->fci_hash_table + i;
+ hlist_for_each_entry_safe(flde, scan, next, bucket, fce_list) {
+ hlist_del_init(&flde->fce_list);
+ list_del_init(&flde->fce_lru);
+ cache->fci_cache_count--;
+ OBD_FREE_PTR(flde);
+ }
+ }
+ spin_unlock(&cache->fci_lock);
+ EXIT;
+}
+
struct fld_cache_info *fld_cache_init(int hash_size, int cache_size,
int cache_threshold)
{
void fld_cache_fini(struct fld_cache_info *cache)
{
- struct fld_cache_entry *flde;
- struct hlist_head *bucket;
- struct hlist_node *scan;
- struct hlist_node *next;
- int i;
ENTRY;
LASSERT(cache != NULL);
+ fld_cache_flush(cache);
- /* free all cache entries */
- spin_lock(&cache->fci_lock);
- for (i = 0; i < cache->fci_hash_size; i++) {
- bucket = cache->fci_hash_table + i;
- hlist_for_each_entry_safe(flde, scan, next, bucket, fce_list) {
- hlist_del_init(&flde->fce_list);
- list_del_init(&flde->fce_lru);
- cache->fci_cache_count--;
- OBD_FREE_PTR(flde);
- }
- }
- spin_unlock(&cache->fci_lock);
-
- /* free cache hash table and cache itself */
OBD_FREE(cache->fci_hash_table, cache->fci_hash_size *
sizeof(*cache->fci_hash_table));
OBD_FREE_PTR(cache);
}
/*
- * check if cache needs to be shrinked. If so - do it. Tries to keep all
- * collision lists wel balanced. That is, checks all of them and removes one
+ * Check if cache needs to be shrinked. If so - do it. Tries to keep all
+ * collision lists well balanced. That is, checks all of them and removes one
* entry in list and so on.
*/
static int fld_cache_shrink(struct fld_cache_info *cache)
if (flde->fce_seq == seq) {
*mds = flde->fce_mds;
- /* move found entry to the head of lru list */
+ /* Move found entry to the head of lru list. */
list_del(&flde->fce_lru);
list_add(&flde->fce_lru, &cache->fci_lru);
RETURN(count);
}
+static int
+fld_proc_write_cache_flush(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct lu_client_fld *fld = (struct lu_client_fld *)data;
+ ENTRY;
+
+ LASSERT(fld != NULL);
+
+ fld_cache_flush(fld->lcf_cache);
+
+ CDEBUG(D_WARNING, "%s: lookup cache is flushed\n",
+ fld->lcf_name);
+
+ RETURN(count);
+}
+
struct lprocfs_vars fld_server_proc_list[] = {
{ NULL }};
struct lprocfs_vars fld_client_proc_list[] = {
- { "targets", fld_proc_read_targets, NULL, NULL },
- { "hash", fld_proc_read_hash, fld_proc_write_hash, NULL },
+ { "targets", fld_proc_read_targets, NULL, NULL },
+ { "hash", fld_proc_read_hash, fld_proc_write_hash, NULL },
+ { "cache_flush", NULL, fld_proc_write_cache_flush, NULL },
{ NULL }};
#endif
void fld_cache_fini(struct fld_cache_info *cache);
+void fld_cache_flush(struct fld_cache_info *cache);
+
int fld_cache_insert(struct fld_cache_info *cache,
seqno_t seq, mdsno_t mds);
RETURN(rc);
}
-static void ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
- struct lookup_intent *it, struct obd_client_handle *och)
+static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli,
+ struct lookup_intent *it, struct obd_client_handle *och)
{
struct ptlrpc_request *req = it->d.lustre.it_data;
struct mdt_body *body;
och->och_fid = &lli->lli_fid;
lli->lli_ioepoch = body->ioepoch;
- md_set_open_replay_data(md_exp, och, req);
+ return md_set_open_replay_data(md_exp, och, req);
}
int ll_local_open(struct file *file, struct lookup_intent *it,
if (och) {
struct ptlrpc_request *req = it->d.lustre.it_data;
struct mdt_body *body;
+ int rc;
- ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli, it, och);
+ rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli, it, och);
+ if (rc)
+ RETURN(rc);
body = lustre_msg_buf(req->rq_repmsg,
DLM_REPLY_REC_OFF, sizeof(*body));
(*och_usecount)++;
rc = ll_local_open(file, it, fd, NULL);
-
- LASSERTF(rc == 0, "rc = %d\n", rc);
+ if (rc) {
+ up(&lli->lli_och_sem);
+ ll_file_data_put(fd);
+ RETURN(rc);
+ }
} else {
LASSERT(*och_usecount == 0);
OBD_ALLOC(*och_p, sizeof (struct obd_client_handle));
lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
rc = ll_local_open(file, it, fd, *och_p);
- LASSERTF(rc == 0, "rc = %d\n", rc);
+ if (rc) {
+ up(&lli->lli_och_sem);
+ ll_file_data_put(fd);
+ GOTO(out_och_free, rc);
+ }
}
up(&lli->lli_och_sem);
LASSERT(fid_is_sane(fid));
rc = fld_client_lookup(&lmv->lmv_fld, fid_seq(fid), mds, NULL);
if (rc) {
- CERROR("error while looking for mds number. Seq "LPU64
- ", rc %d\n", fid_seq(fid), rc);
+ CERROR("Error while looking for mds number. Seq "LPU64
+ ", err = %d\n", fid_seq(fid), rc);
RETURN(rc);
}
- CDEBUG(D_INFO, "got mds "LPU64" for sequence: "LPU64"\n",
+ CDEBUG(D_INFO, "Got mds "LPU64" for sequence: "LPU64"\n",
*mds, fid_seq(fid));
if (*mds >= lmv->desc.ld_tgt_count) {
- CERROR("got invalid mds: "LPU64" (max: %d)\n",
+ CERROR("Got invalid mds: "LPU64" (max: %d)\n",
*mds, lmv->desc.ld_tgt_count);
rc = -EINVAL;
}
RETURN(1);
}
+#if 0
static int lmv_all_chars_policy(int count, struct qstr *name)
{
unsigned int c = 0;
c = c % count;
return c;
}
+#endif
static int lmv_placement_policy(struct obd_device *obd,
struct lu_placement_hint *hint,
/* stress policy for tests - to use non-parent MDS */
LASSERT(fid_is_sane(hint->ph_pfid));
rc = lmv_fld_lookup(lmv, hint->ph_pfid, mds);
+ if (rc)
+ RETURN(rc);
*mds = (int)(*mds + 1) % lmv->desc.ld_tgt_count;
#endif
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct obd_export *tgt_exp;
-
ENTRY;
-
+
tgt_exp = lmv_get_export(lmv, och->och_fid);
-
+ if (IS_ERR(tgt_exp))
+ RETURN(PTR_ERR(tgt_exp));
+
RETURN(md_set_open_replay_data(tgt_exp, och, open_req));
}
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct obd_export *tgt_exp;
-
ENTRY;
tgt_exp = lmv_get_export(lmv, och->och_fid);
+ if (IS_ERR(tgt_exp))
+ RETURN(PTR_ERR(tgt_exp));
RETURN(md_clear_open_replay_data(tgt_exp, och));
}
* If the xid matches, then we know this is a resent request, and allow
* it. (It's probably an OPEN, for which we don't send a lock.
*/
- if (req->rq_xid ==
- le64_to_cpu(exp->exp_mdt_data.med_mcd->mcd_last_xid))
+ if (req->rq_xid == req_exp_last_xid(req))
return;
- if (req->rq_xid ==
- le64_to_cpu(exp->exp_mdt_data.med_mcd->mcd_last_close_xid))
+ if (req->rq_xid == req_exp_last_close_xid(req))
return;
/*
mkdir -p $DIR
-
test_0() {
replay_barrier mds
fail mds
}
run_test 0b "ensure object created after recover exists. (3284)"
-test_1() {
- replay_barrier mds
- mcreate $DIR/$tfile
- fail mds
- $CHECKSTAT -t file $DIR/$tfile || return 1
- rm $DIR/$tfile
+seq_set_width()
+{
+ local fn=`ls /proc/fs/lustre/seq-cli-srv*/seq_width`
+ echo $1 > $fn
}
-run_test 1 "simple create"
-test_1a() {
- do_facet ost1 "sysctl -w lustre.fail_loc=0"
+seq_get_width()
+{
+ local fn=`ls /proc/fs/lustre/seq-cli-srv*/seq_width`
+ cat $fn
+}
- rm -fr $DIR/$tfile
- local old_last_id=`cat $LPROC/obdfilter/*/last_id`
- touch -o $DIR/$tfile 1
- sync
- local new_last_id=`cat $LPROC/obdfilter/*/last_id`
+test_0c() {
+ replay_barrier mds
+
+ local seq_width
- test "$old_last_id" = "$new_last_id" || {
- echo "OST object create is caused by MDS"
- return 1
- }
+ # make seq manager switch to next sequence each
+ # time as new fid is needed.
+ seq_width=`seq_get_width`
+ seq_set_width 1
- old_last_id=`cat $LPROC/obdfilter/*/last_id`
- echo "data" > $DIR/$tfile
- sync
- new_last_id=`cat $LPROC/obdfilter/*/last_id`
- test "$old_last_id" = "$new_last_id "&& {
- echo "CROW does not work on write"
- return 1
- }
+ # make sure that fld has created atleast one new
+ # entry on server
+ touch $DIR/$tfile || return 1
+ seq_set_width $seq_width
- rm -fr $DIR/$tfile
-
-#define OBD_FAIL_OST_CROW_EIO | OBD_FAIL_ONCE
- do_facet ost1 "sysctl -w lustre.fail_loc=0x80000801"
-
- rm -fr $DIR/1a1
- old_last_id=`cat $LPROC/obdfilter/*/last_id`
- echo "data" > $DIR/1a1
- sync
- new_last_id=`cat $LPROC/obdfilter/*/last_id`
- test "$old_last_id" = "$new_last_id" || {
- echo "CROW does work with fail_loc=0x80000801"
- return 1
- }
+ # fail mds and start recovery, replay RPCs, etc.
+ fail mds
- rm -fr $DIR/1a1
+ # wait for recovery finish
+ sleep 20
+ df $MOUNT
- do_facet ost1 "sysctl -w lustre.fail_loc=0"
+ # flush fld cache and dentry cache to make it lookup
+ # created entry instead of revalidating existent one
+ umount $MOUNT
+ zconf_mount `hostname` $MOUNT
+
+ # issue lookup which should call fld lookup which
+ # should fail if client did not replay fld create
+ # correctly and server has no fld entry
+ touch $DIR/$tfile || return 2
+ rm $DIR/$tfile || return 2
+}
+run_test 0c "fld create"
+
+test_1() {
+ replay_barrier mds
+ mcreate $DIR/$tfile
+ fail mds
+ $CHECKSTAT -t file $DIR/$tfile || return 1
+ rm $DIR/$tfile
}
-#CROW run_test 1a "CROW object create (check OST last_id)"
+run_test 1 "simple create"
test_2a() {
replay_barrier mds