if (fid_is_norm(lu_object_fid(&dt->do_lu))) {
OSD_DECLARE_OP(oh, insert);
oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_INSERT];
+ /* Reuse idle OI block may cause additional one OI block
+ * to be changed. */
+ oh->ot_credits += 1;
}
/* If this is directory, then we expect . and .. to be inserted as
* well. The one directory block always needs to be created for the
OSD_DECLARE_OP(oh, destroy);
OSD_DECLARE_OP(oh, delete);
oh->ot_credits += osd_dto_credits_noquota[DTO_OBJECT_DELETE];
- oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_DELETE];
+ /* XXX: So far, only normal fid needs to be inserted into the OI,
+ * so only normal fid needs to be removed from the OI also. */
+ if (fid_is_norm(lu_object_fid(&dt->do_lu))) {
+ oh->ot_credits += osd_dto_credits_noquota[DTO_INDEX_DELETE];
+ /* Recycle idle OI leaf may cause additional three OI blocks
+ * to be changed. */
+ oh->ot_credits += 3;
+ }
osd_declare_qid(dt, oh, USRQUOTA, inode->i_uid, inode);
osd_declare_qid(dt, oh, GRPQUOTA, inode->i_gid, inode);
for (i = 0; i < ARRAY_SIZE(path->ip_frames); i++) {
if (path->ip_frames[i].bh != NULL) {
+ path->ip_frames[i].at_shifted = 0;
brelse(path->ip_frames[i].bh);
path->ip_frames[i].bh = NULL;
}
goto newblock;
cfs_down(&c->ic_idle_sem);
- if (unlikely(c->ic_idle_failed || c->ic_idle_bh == NULL)) {
+ if (unlikely(c->ic_idle_bh == NULL)) {
cfs_up(&c->ic_idle_sem);
goto newblock;
}
return 0;
}
+ entries = frame->entries;
+ count = dx_get_count(entries);
+ /* NOT shrink the last entry in the index node, which can be reused
+ * directly by next new node. */
+ if (count == 2) {
+ iam_unlock_htree(c, lh);
+ return 0;
+ }
+
rc = iam_txn_add(h, p, frame->bh);
if (rc != 0) {
iam_unlock_htree(c, lh);
}
iam_lock_bh(frame->bh);
- entries = frame->entries;
- count = dx_get_count(entries);
if (frame->at < iam_entry_shift(p, entries, count - 1)) {
struct iam_entry *n = iam_entry_shift(p, frame->at, 1);
frame->at_shifted = 1;
}
dx_set_count(entries, count - 1);
- rc = iam_txn_dirty(h, p, frame->bh);
iam_unlock_bh(frame->bh);
+ rc = iam_txn_dirty(h, p, frame->bh);
iam_unlock_htree(c, lh);
if (rc != 0)
return 0;
LASSERT((keysize + ptrsize) >=
(sizeof(struct dx_countlimit) + sizeof(__u32)));
- entry = limit + 1;
+ entry = (void *)(limit + 1);
/* Put "idle_blocks" just after the limit. There was padding after
* the limit, the "idle_blocks" re-uses part of the padding, so no
* compatibility issues with old layout.
*/
*(__u32 *)entry = 0;
- entry = root + 1;
- /*
- * Skip over @limit.
- */
- entry += keysize + ptrsize;
-
- /*
- * Entry format is <key> followed by <ptr>. In the minimal tree
- * consisting of a root and single node, <key> is a minimal possible
- * key.
- *
- * XXX: this key is hard-coded to be a sequence of 0's.
- */
+ /*
+ * Skip over @limit.
+ */
+ entry = (void *)(root + 1) + keysize + ptrsize;
+
+ /*
+ * Entry format is <key> followed by <ptr>. In the minimal tree
+ * consisting of a root and single node, <key> is a minimal possible
+ * key.
+ *
+ * XXX: this key is hard-coded to be a sequence of 0's.
+ */
memset(entry, 0, keysize);
entry += keysize;
cut -c11-20)
# don't return an error
- [ $OSTIO_post -eq $OSTIO_pre ] && echo \
- "WARNING: No new ll_ost_io threads were created ($OSTIO_pre)" &&\
- echo "This may be fine, depending on what ran before this test" &&\
+ [ $OSTIO_post == $OSTIO_pre ] && echo \
+ "WARNING: No new ll_ost_io threads were created ($OSTIO_pre)" &&
+ echo "This may be fine, depending on what ran before this test" &&
echo "and how fast this system is." && return
echo "Started with $OSTIO_pre threads, ended with $OSTIO_post"
run_test 227 "running truncated executable does not cause OOM"
# LU-1512 try to reuse idle OI blocks
-test_228() {
+test_228a() {
[ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
[ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
}
-run_test 228 "try to reuse idle OI blocks"
+run_test 228a "try to reuse idle OI blocks"
+
+test_228b() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
+
+ local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
+ local myDIR=$DIR/$tdir
+
+ mkdir -p $myDIR
+ #define OBD_FAIL_SEQ_EXHAUST 0x1002
+ $LCTL set_param fail_loc=0x80001002
+ createmany -o $myDIR/t- 10000
+ $LCTL set_param fail_loc=0
+ # The guard is current the largest FID holder
+ touch $myDIR/guard
+ local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
+ tr -d '[')
+ local IDX=$(($SEQ % 64))
+
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk1=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ # Remove old files, some OI blocks will become idle.
+ unlinkmany $myDIR/t- 10000
+
+ # stop the MDT
+ stop $SINGLEMDS || error "Fail to stop MDT."
+ # remount the MDT
+ start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
+
+ df $MOUNT || error "Fail to df."
+ # Create new files, idle OI blocks should be reused.
+ createmany -o $myDIR/t- 2000
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk2=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
+}
+run_test 228b "idle OI blocks can be reused after MDT restart"
+
+#LU-1881
+test_228c() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "non-ldiskfs backend" && return
+
+ local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
+ local myDIR=$DIR/$tdir
+
+ mkdir -p $myDIR
+ #define OBD_FAIL_SEQ_EXHAUST 0x1002
+ $LCTL set_param fail_loc=0x80001002
+ # 20000 files can guarantee there are index nodes in the OI file
+ createmany -o $myDIR/t- 20000
+ $LCTL set_param fail_loc=0
+ # The guard is current the largest FID holder
+ touch $myDIR/guard
+ local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
+ tr -d '[')
+ local IDX=$(($SEQ % 64))
+
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk1=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ # Remove old files, some OI blocks will become idle.
+ unlinkmany $myDIR/t- 20000
+ rm -f $myDIR/guard
+ # The OI file should become empty now
+
+ # Create new files, idle OI blocks should be reused.
+ createmany -o $myDIR/t- 2000
+ do_facet $SINGLEMDS sync
+ # Make sure journal flushed.
+ sleep 6
+ local blk2=$(do_facet $SINGLEMDS \
+ "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
+ grep Blockcount | awk '{print $4}')
+
+ [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
+}
+run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
#
# tests that do cleanup/setup should be run at the end