int rc;
ENTRY;
- if (OBD_FAIL_CHECK(OBD_FAIL_MDS_ALLOC_OBDO)) {
- /* failed to create striping, let's reset
- * config so that others don't get confused */
- lod_object_free_striping(env, lo);
+ if (OBD_FAIL_CHECK(OBD_FAIL_MDS_ALLOC_OBDO))
GOTO(out, rc = -ENOMEM);
- }
if (!dt_object_remote(next)) {
/* choose OST and generate appropriate objects */
rc = lod_qos_prep_create(env, lo, attr, lovea, th);
- if (rc) {
- /* failed to create striping, let's reset
- * config so that others don't get confused */
- lod_object_free_striping(env, lo);
+ if (rc)
GOTO(out, rc);
- }
/*
* declare storage for striping data
rc = lod_declare_init_size(env, dt, th);
out:
+ /* failed to create striping or to set initial size, let's reset
+ * config so that others don't get confused */
+ if (rc)
+ lod_object_free_striping(env, lo);
+
RETURN(rc);
}
* XXX: decide how do we do here with resend
* if we don't resend, then client may see wrong file size
* if we do resend, then MDS thread can get stuck for quite long
+ * and if we don't resend, then client will also get -EWOULDBLOCK !!
+ * (see LU-7975 and sanity/test_27F use cases)
+ * but let's decide not to resend/delay this truncate request to OST
+ * and allow Client to decide to resend, in a less agressive way from
+ * after_reply(), by returning -EINPROGRESS instead of
+ * -EAGAIN/-EWOULDBLOCK upon return from ptlrpc_queue_wait() at the
+ * end of this routine
*/
req->rq_no_resend = req->rq_no_delay = 1;
ptlrpc_request_set_replen(req);
rc = ptlrpc_queue_wait(req);
- if (rc)
- CERROR("can't punch object: %d\n", rc);
+ if (rc) {
+ /* -EWOULDBLOCK/-EAGAIN means OST is unreachable at the moment
+ * since we have decided not to resend/delay, but this could
+ * lead to wrong size to be seen at Client side and even process
+ * trying to open to exit/fail if not itself handling -EAGAIN.
+ * So it should be better to return -EINPROGRESS instead and
+ * leave the decision to resend at Client side in after_reply()
+ */
+ if (rc == -EWOULDBLOCK) {
+ rc = -EINPROGRESS;
+ CDEBUG(D_HA, "returning -EINPROGRESS instead of "
+ "-EWOULDBLOCK/-EAGAIN to allow Client to "
+ "resend\n");
+ } else {
+ CERROR("can't punch object: %d\n", rc);
+ }
+ }
out:
ptlrpc_req_finished(req);
if (oa)
}
run_test 27E "check that default extended attribute size properly increases"
+test_27F() { # LU-5346/LU-7975
+
+ [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
+
+ [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.51) ]] &&
+ skip "Need MDS version at least 2.8.51" && return
+
+ test_mkdir -p $DIR/$tdir
+ rm -f $DIR/$tdir/f0
+ $SETSTRIPE -c 2 $DIR/$tdir
+
+ # stop all OSTs to reproduce situation for LU-7975 ticket
+ for num in $(seq $OSTCOUNT); do
+ stop ost$num
+ done
+
+ # open/create f0 with O_LOV_DELAY_CREATE
+ # truncate f0 to a non-0 size
+ # close
+ multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
+
+ $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
+ # open/write it again to force delayed layout creation
+ cat /etc/hosts > $DIR/$tdir/f0 &
+ catpid=$!
+
+ # restart OSTs
+ for num in $(seq $OSTCOUNT); do
+ start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
+ error "ost$num failed to start"
+ done
+
+ wait $catpid || error "cat failed"
+
+ cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
+ [[ $($GETSTRIPE -c $DIR/$tdir/f0) == 2 ]] || error "wrong stripecount"
+
+}
+run_test 27F "Client resend delayed layout creation with non-zero size"
+
# createtest also checks that device nodes are created and
# then visible correctly (#2091)
test_28() { # bug 2091