obd_support.h \
obd_target.h \
obj_update.h \
+ range_lock.h \
upcall_cache.h \
lustre_kernelcomm.h \
seq_range.h
EXTRA_DIST = ldlm_extent.c ldlm_flock.c ldlm_internal.h ldlm_lib.c \
ldlm_lock.c ldlm_lockd.c ldlm_plain.c ldlm_request.c \
ldlm_resource.c l_lock.c ldlm_inodebits.c ldlm_pool.c \
- interval_tree.c ldlm_reclaim.c
+ ldlm_reclaim.c
lustre-objs += lcommon_cl.o
lustre-objs += lcommon_misc.o
lustre-objs += vvp_dev.o vvp_page.o vvp_io.o vvp_object.o
-lustre-objs += range_lock.o pcc.o crypto.o
+lustre-objs += pcc.o crypto.o
EXTRA_DIST := $(lustre-objs:.o=.c) xattr.c rw26.c super25.c
-EXTRA_DIST += llite_internal.h vvp_internal.h range_lock.h pcc.h
+EXTRA_DIST += llite_internal.h vvp_internal.h pcc.h
@INCLUDE_RULES@
#include <linux/aio.h>
#include <lustre_compat.h>
#include <lustre_crypto.h>
+#include <range_lock.h>
#include "vvp_internal.h"
-#include "range_lock.h"
#include "pcc.h"
#ifndef FMODE_EXEC
obdclass-all-objs += kernelcomm.o jobid.o
obdclass-all-objs += integrity.o obd_cksum.o
obdclass-all-objs += lu_tgt_descs.o
+obdclass-all-objs += range_lock.o interval_tree.o
@SERVER_TRUE@obdclass-all-objs += acl.o
@SERVER_TRUE@obdclass-all-objs += idmap.o
EXTRA_DIST = $(obdclass-all-objs:.o=.c) llog_test.c llog_internal.h
EXTRA_DIST += cl_internal.h local_storage.h
+EXTRA_DIST += range_lock.c interval_tree.c
@SERVER_FALSE@EXTRA_DIST += acl.c
@SERVER_FALSE@EXTRA_DIST += idmap.c
ext->end = interval_expand_high(root, ext->end);
LASSERT(interval_is_overlapped(root, ext) == 0);
}
+EXPORT_SYMBOL(interval_expand);
#ifdef HAVE_SCHED_HEADERS
#include <linux/sched/signal.h>
#endif
-#include "range_lock.h"
#include <uapi/linux/lustre/lustre_user.h>
+#include <range_lock.h>
/**
* Initialize a range lock tree
tree->rlt_sequence = 0;
spin_lock_init(&tree->rlt_lock);
}
+EXPORT_SYMBOL(range_lock_tree_init);
/**
* Intialize a range lock node
lock->rl_sequence = 0;
return rc;
}
+EXPORT_SYMBOL(range_lock_init);
static inline struct range_lock *next_lock(struct range_lock *lock)
{
EXIT;
}
+EXPORT_SYMBOL(range_unlock);
/**
* Helper function of range_lock()
out:
RETURN(rc);
}
+EXPORT_SYMBOL(range_lock);
lu_object_init(o, h, d);
lu_object_add_top(h, o);
o->lo_ops = &ofd_obj_ops;
+ range_lock_tree_init(&of->ofo_write_tree);
RETURN(o);
} else {
RETURN(NULL);
#include <dt_object.h>
#include <md_object.h>
#include <lustre_fid.h>
+#include <range_lock.h>
#define OFD_INIT_OBJID 0
#define OFD_PRECREATE_BATCH_DEFAULT (OBJ_SUBDIR_COUNT * 4)
time64_t ofo_atime_ondisk;
unsigned int ofo_pfid_checking:1,
ofo_pfid_verified:1;
+ struct range_lock_tree ofo_write_tree;
};
static inline struct ofd_object *ofd_obj(struct lu_object *o)
struct lfsck_req_local fti_lrl;
struct obd_connect_data fti_ocd;
};
+ struct range_lock fti_write_range;
+ unsigned fti_range_locked:1;
};
extern void target_recovery_fini(struct obd_device *obd);
int maxlnb = *nr_local;
__u64 begin, end;
ktime_t kstart = ktime_get();
+ struct range_lock *range = &ofd_info(env)->fti_write_range;
ENTRY;
LASSERT(env != NULL);
obj->ioo_bufcnt,
WRITE);
+ /*
+ * Reordering precautions: make sure that request processing that
+ * was able to receive its bulk data should not get reordered with
+ * overlapping BRW requests, e.g.
+ * 1) BRW1 sent, bulk data received, but disk I/O delayed
+ * 2) BRW1 resent and fully processed
+ * 3) the page was unlocked on the client and its writeback bit reset
+ * 4) BRW2 sent and fully processed
+ * 5) BRW1 processing wakes up and writes stale data to disk
+ * If on step 1 bulk data was not received, client resend will invalidate
+ * its bulk descriptor and the RPC will be dropped due to failed bulk
+ * transfer, which is just fine.
+ */
+ range_lock_init(range,
+ rnb[0].rnb_offset,
+ rnb[obj->ioo_bufcnt - 1].rnb_offset +
+ rnb[obj->ioo_bufcnt - 1].rnb_len - 1);
+ range_lock(&fo->ofo_write_tree, range);
+ ofd_info(env)->fti_range_locked = 1;
+
ofd_counter_incr(exp, LPROC_OFD_STATS_WRITE_BYTES, jobid, tot_bytes);
ofd_counter_incr(exp, LPROC_OFD_STATS_WRITE, jobid,
ktime_us_delta(ktime_get(), kstart));
bool soft_sync = false;
bool cb_registered = false;
bool fake_write = false;
+ struct range_lock *range = &ofd_info(env)->fti_write_range;
ENTRY;
dt_commit_async(env, ofd->ofd_osd);
out:
+ if (info->fti_range_locked) {
+ range_unlock(&fo->ofo_write_tree, range);
+ info->fti_range_locked = 0;
+ }
dt_bufs_put(env, o, lnb, niocount);
ofd_object_put(env, fo);
if (granted > 0)
ldlm_objs += $(LDLM)ldlm_plain.o $(LDLM)ldlm_extent.o
ldlm_objs += $(LDLM)ldlm_request.o $(LDLM)ldlm_lockd.o
ldlm_objs += $(LDLM)ldlm_flock.o $(LDLM)ldlm_inodebits.o
-ldlm_objs += $(LDLM)ldlm_pool.o $(LDLM)interval_tree.o
-ldlm_objs += $(LDLM)ldlm_reclaim.o
+ldlm_objs += $(LDLM)ldlm_pool.o $(LDLM)ldlm_reclaim.o
target_objs := $(TARGET)tgt_main.o $(TARGET)tgt_lastrcvd.o
target_objs += $(TARGET)tgt_handler.o $(TARGET)out_handler.o
l_lock.c: @LUSTRE@/ldlm/l_lock.c
ln -sf $< $@
-interval_tree.c: @LUSTRE@/ldlm/interval_tree.c
- ln -sf $< $@
-
tgt_%.c: @LUSTRE@/target/tgt_%.c
ln -sf $< $@
SUBDIRS = gss
endif
-MOSTLYCLEANFILES := @MOSTLYCLEANFILES@ ldlm_*.c l_lock.c interval_tree.c
+MOSTLYCLEANFILES := @MOSTLYCLEANFILES@ ldlm_*.c l_lock.c
}
}
+ OBD_FAIL_TIMEOUT(OBD_FAIL_OST_BRW_PAUSE_BULK2, cfs_fail_val);
+
out_commitrw:
/* Must commit after prep above in all cases */
rc = obd_commitrw(tsi->tsi_env, OBD_BRW_WRITE, exp, &repbody->oa,
}
run_test 147 "Check client reconnect"
+test_148() {
+ local wce_param="obdfilter.$FSNAME-OST0000.writethrough_cache_enable"
+ local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+ local amc=$(at_max_get client)
+ local amo=$(at_max_get ost1)
+ local timeout
+
+ at_max_set 0 client
+ at_max_set 0 ost1
+ timeout=$(request_timeout client)
+
+ [ "$(facet_fstype ost1)" = "ldiskfs" ] && {
+ # save old r/o cache settings
+ save_lustre_params ost1 $wce_param > $p
+
+ # disable r/o cache
+ do_facet ost1 "$LCTL set_param -n $wce_param=0"
+ }
+
+ $LFS setstripe -i 0 -c 1 $DIR/$tfile
+ dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 oflag=direct
+ cp $DIR/$tfile $TMP/$tfile
+ #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
+ do_facet ost1 $LCTL set_param fail_loc=0x80000227
+ do_facet ost1 $LCTL set_param fail_val=$((timeout+2))
+ dd if=/dev/urandom of=$DIR/$tfile bs=4096 count=1 conv=notrunc,fdatasync
+ dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=notrunc,fdatasync
+ sleep 2
+ cancel_lru_locks osc
+ cmp -b $DIR/$tfile $TMP/$tfile || error "wrong data"
+
+ rm -f $DIR/$tfile $TMP/$tfile
+
+ at_max_set $amc client
+ at_max_set $amo ost1
+
+ [ "$(facet_fstype ost1)" = "ldiskfs" ] && {
+ # restore initial r/o cache settings
+ restore_lustre_params < $p
+ }
+
+ return 0
+}
+run_test 148 "data corruption through resend"
+
complete $SECONDS
check_and_cleanup_lustre
exit_status