OBD_RACE||CFS_RACE
OS_STATE_DEGRADED||OS_STATFS_DEGRADED
OS_STATE_READONLY||OS_STATFS_READONLY
-OS_STATE_NOPRECREATE||OS_STATFS_NOPRECREATE
+OS_STATE_NOPRECREATE||OS_STATFS_NOCREATE
OS_STATE_ENOSPC||OS_STATFS_ENOSPC
OS_STATE_ENOINO||OS_STATFS_ENOINO
OS_STATE_SUM||OS_STATFS_SUM
OS_STATE_NONROT||OS_STATFS_NONROT
+OS_STATFS_NOPRECREATE||OS_STATFS_NOCREATE
page_cache_get||get_page
PAGE_CACHE_MASK||PAGE_MASK
page_cache_release||put_page
lut_no_reconstruct:1,
/* enforce recovery for local clients */
lut_local_recovery:1,
- lut_cksum_t10pi_enforce:1;
+ lut_cksum_t10pi_enforce:1,
+ lut_no_create:1;
/* checksum types supported on this node */
enum cksum_types lut_cksum_types_supported;
/** last_rcvd file */
#define LMD_PARAMS_MAXLEN 4096
enum lmd_flags {
- LMD_FLG_SERVER = 0, /* Mounting a server */
LMD_FLG_CLIENT, /* Mounting a client */
LMD_FLG_SKIP_LFSCK, /* NOT auto resume LFSCK when mount */
LMD_FLG_ABORT_RECOV, /* Abort recovery */
*/
LMD_FLG_WRITECONF, /* Rewrite config log */
LMD_FLG_NOIR, /* NO imperative recovery */
- LMD_FLG_NOSCRUB, /* Do not trigger scrub automatically */
+ LMD_FLG_NOSCRUB, /* Do not trigger scrub automatically */
LMD_FLG_MGS, /* Also start MGS along with server */
- LMD_FLG_IAM, /* IAM dir */
LMD_FLG_NO_PRIMNODE, /* all nodes are service nodes */
LMD_FLG_VIRGIN, /* the service registers first time */
LMD_FLG_UPDATE, /* update parameters */
LMD_FLG_HSM, /* Start coordinator */
LMD_FLG_DEV_RDONLY, /* discard modification quitely */
- LMD_FLG_NO_PRECREATE, /* do not allow OST object creation */
+ LMD_FLG_NO_CREATE, /* prevent MDT/OST object creation */
LMD_FLG_LOCAL_RECOV, /* force recovery for local clients */
LMD_FLG_ABORT_RECOV_MDT, /* Abort recovery between MDTs */
LMD_FLG_NO_LOCAL_LOGS, /* Use config logs from MGS */
struct kobject *lmv_tgts_kobj;
void *lmv_cache;
- __u32 lmv_qos_rr_index;
+ __u32 lmv_qos_rr_index; /* next round-robin MDT idx */
};
#define lmv_mdt_count lmv_mdt_descs.ltd_lmv_desc.ld_tgt_count
enum obd_statfs_state {
OS_STATFS_DEGRADED = 0x00000001, /**< RAID degraded/rebuilding */
OS_STATFS_READONLY = 0x00000002, /**< filesystem is read-only */
- OS_STATFS_NOPRECREATE = 0x00000004, /**< no object precreation */
+ OS_STATFS_NOCREATE = 0x00000004, /**< no object creation */
OS_STATFS_UNUSED1 = 0x00000008, /**< obsolete 1.6, was EROFS=30 */
OS_STATFS_UNUSED2 = 0x00000010, /**< obsolete 1.6, was EROFS=30 */
OS_STATFS_ENOSPC = 0x00000020, /**< not enough free space */
OS_STATFS_SUM = 0x00000100, /**< aggregated for all tagrets */
OS_STATFS_NONROT = 0x00000200, /**< non-rotational device */
};
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 20, 53, 0)
+#define OS_STATFS_NOPRECREATE OS_STATFS_NOCREATE
+#endif
/** filesystem statistics/attributes for target device */
struct obd_statfs {
RETURN(rc);
}
+static void lmv_statfs_update(struct lmv_obd *lmv, struct lmv_tgt_desc *tgt,
+ struct obd_statfs *osfs)
+{
+ spin_lock(&lmv->lmv_lock);
+ tgt->ltd_statfs = *osfs;
+ tgt->ltd_statfs_age = ktime_get_seconds();
+ spin_unlock(&lmv->lmv_lock);
+ set_bit(LQ_DIRTY, &lmv->lmv_qos.lq_flags);
+}
+
static int lmv_fid2path(struct obd_export *exp, int len, void *karg,
void __user *uarg)
{
0);
if (rc)
RETURN(rc);
+ lmv_statfs_update(lmv, tgt, &stat_buf);
if (copy_to_user(data->ioc_pbuf1, &stat_buf,
- min((int) data->ioc_plen1,
- (int) sizeof(stat_buf))))
+ min_t(int, data->ioc_plen1, sizeof(stat_buf))))
RETURN(-EFAULT);
break;
}
RETURN(rc);
}
-static int lmv_statfs_update(void *cookie, int rc)
+static int lmv_statfs_cb(void *cookie, int rc)
{
struct obd_info *oinfo = cookie;
struct obd_device *obd = oinfo->oi_obd;
* NB: don't deactivate TGT upon error, because we may not trigger async
* statfs any longer, then there is no chance to activate TGT.
*/
- if (!rc) {
- spin_lock(&lmv->lmv_lock);
- tgt->ltd_statfs = *osfs;
- tgt->ltd_statfs_age = ktime_get_seconds();
- spin_unlock(&lmv->lmv_lock);
- set_bit(LQ_DIRTY, &lmv->lmv_qos.lq_flags);
- }
+ if (!rc)
+ lmv_statfs_update(lmv, tgt, osfs);
return rc;
}
struct obd_info oinfo = {
.oi_obd = obd,
.oi_tgt = tgt,
- .oi_cb_up = lmv_statfs_update,
+ .oi_cb_up = lmv_statfs_cb,
};
int rc;
GOTO(unlock, tgt = ERR_PTR(rc));
lmv_foreach_tgt(lmv, tgt) {
- if (!tgt->ltd_exp || !tgt->ltd_active) {
+ if (!tgt->ltd_exp || !tgt->ltd_active ||
+ (tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE)) {
tgt->ltd_qos.ltq_usable = 0;
continue;
}
total_usable++;
}
- /* If current MDT has above-average space and dir is not aleady using
+ /* If current MDT has above-average space and dir is not already using
* round-robin to spread across more MDTs, stay on the parent MDT
* to avoid creating needless remote MDT directories. Remote dirs
* close to the root balance space more effectively than bottom dirs,
index = (i + lmv->lmv_qos_rr_index) %
lmv->lmv_mdt_descs.ltd_tgts_size;
tgt = lmv_tgt(lmv, index);
- if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
+ if (!tgt || !tgt->ltd_exp || !tgt->ltd_active ||
+ (tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE))
continue;
lmv->lmv_qos_rr_index = (tgt->ltd_index + 1) %
GOTO(unlock, tgt = ERR_PTR(-EAGAIN));
lmv_foreach_tgt(lmv, tgt) {
- if (!tgt->ltd_exp || !tgt->ltd_active) {
+ if (!tgt->ltd_exp || !tgt->ltd_active ||
+ (tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE)) {
tgt->ltd_qos.ltq_usable = 0;
continue;
}
* which is set outside, and if dir is migrating, 'op_data->op_new_layout'
* indicates whether old or new layout is used to locate.
*
- * For plain direcotry, it just locate the MDT of op_data->op_fid1.
+ * For plain directory, it just locate the MDT of op_data->op_fid1.
*
* \param[in] lmv LMV device
* \param[in/out] op_data client MD stack parameters, name, namelen etc,
if (tgt == ERR_PTR(-EAGAIN)) {
if (ltd_qos_is_balanced(&lmv->lmv_mdt_descs) &&
!lmv_op_default_rr_mkdir(op_data) &&
- !lmv_op_user_qos_mkdir(op_data))
+ !lmv_op_user_qos_mkdir(op_data) &&
+ !(tmp->ltd_statfs.os_state & OS_STATFS_NOCREATE))
/* if not necessary, don't create remote directory. */
tgt = tmp;
else
if (!IS_ERR(tgt))
op_data->op_mds = tgt->ltd_index;
+ /* If space balance was called because the original target was marked
+ * NOCREATE, periodically check whether the state has changed.
+ */
+ if (tmp != tgt && tmp->ltd_statfs.os_state & OS_STATFS_NOCREATE)
+ lmv_statfs_check_update(lmv2obd_dev(lmv), tmp);
+
return tgt;
}
* 2. is "lfs mkdir -i -1"? mkdir by space usage.
* 3. is starting MDT specified in default LMV? mkdir on MDT N.
* 4. is default LMV space balanced? mkdir by space usage.
+ *
+ * If the existing parent or specific MDT selected is deactivated
+ * with OS_STATFS_NOCREATE then select a different MDT by QOS.
*/
if (lmv_op_user_specific_mkdir(op_data)) {
struct lmv_user_md *lum = op_data->op_data;
tgt = lmv_tgt(lmv, op_data->op_mds);
if (!tgt)
RETURN(-ENODEV);
+ if (unlikely(tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE))
+ GOTO(new_tgt, -EAGAIN);
} else if (lmv_op_user_qos_mkdir(op_data)) {
tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt);
if (IS_ERR(tgt))
tgt = lmv_tgt(lmv, op_data->op_mds);
if (!tgt)
RETURN(-ENODEV);
- } else if (lmv_op_default_qos_mkdir(op_data)) {
+ if (unlikely(tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE))
+ GOTO(new_tgt, -EAGAIN);
+ } else if (lmv_op_default_qos_mkdir(op_data) ||
+ tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE) {
+new_tgt:
tgt = lmv_locate_tgt_by_space(lmv, op_data, tgt);
if (IS_ERR(tgt))
RETURN(PTR_ERR(tgt));
/* this OSP doesn't feel well */
continue;
+ if (tgt->ltd_statfs.os_state & OS_STATFS_NOCREATE)
+ continue;
+
rc = dt_fid_alloc(env, tgt_dt, &fid, NULL, NULL);
if (rc < 0)
continue;
if (sfs->os_state & OS_STATFS_ENOSPC ||
sfs->os_state & OS_STATFS_READONLY ||
+ sfs->os_state & OS_STATFS_NOCREATE ||
sfs->os_state & OS_STATFS_DEGRADED) {
- CDEBUG(D_LAYOUT, "ost %d is not availble for SEL "
- "extension, state %u\n", index, sfs->os_state);
+ CDEBUG(D_LAYOUT,
+ "OST%04x unusable for SEL extension, state %x\n",
+ index, sfs->os_state);
ret = false;
break;
}
if (sfs->os_state & OS_STATFS_READONLY)
return -EROFS;
- /* object precreation is skipped on targets with max_create_count=0 */
- if (sfs->os_state & OS_STATFS_NOPRECREATE)
+ /* object creation is skipped on the OST with max_create_count=0 */
+ if (!ltd->ltd_is_mdt && sfs->os_state & OS_STATFS_NOCREATE)
return -ENOBUFS;
return 0;
if (lod_statfs_check(ltd, mdt))
continue;
+ if (mdt->ltd_statfs.os_state & OS_STATFS_NOCREATE)
+ continue;
+
/* try to use another OSP if this one is degraded */
if (mdt->ltd_statfs.os_state & OS_STATFS_DEGRADED &&
!use_degraded) {
if (mdt->ltd_discon || lod_statfs_check(ltd, mdt))
continue;
- if (mdt->ltd_statfs.os_state & OS_STATFS_DEGRADED)
+ if (mdt->ltd_statfs.os_state &
+ (OS_STATFS_DEGRADED | OS_STATFS_NOCREATE))
continue;
mdt->ltd_qos.ltq_usable = 1;
osfs->os_bsize - 1) >> current_blockbits));
tgt_grant_sanity_check(mdt->mdt_lu_dev.ld_obd, __func__);
+ if (mdt->mdt_lut.lut_no_create)
+ osfs->os_state |= OS_STATFS_NOCREATE;
CDEBUG(D_CACHE, "%llu blocks: %llu free, %llu avail; "
"%llu objects: %llu free; state %x\n",
osfs->os_blocks, osfs->os_bfree, osfs->os_bavail,
obd_obt_init(obd);
if (test_bit(LMD_FLG_SKIP_LFSCK, lsi->lsi_lmd->lmd_flags))
m->mdt_skip_lfsck = 1;
+ if (test_bit(LMD_FLG_NO_CREATE, lsi->lsi_lmd->lmd_flags))
+ m->mdt_lut.lut_no_create = 1;
}
/* Just try to get a DoM lock by default. Otherwise, having a group
LUSTRE_RW_ATTR(enable_dir_auto_split);
/**
+ * Show if the MDT is in no create mode.
+ *
+ * This means MDT has been adminstratively disabled to prevent it
+ * from creating any new directories on the MDT, though existing files
+ * and directories can still be read, written, and unlinked.
+ *
+ * \retval number of bytes written
+ */
+static ssize_t no_create_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_lut.lut_no_create);
+}
+
+/**
+ * Set MDT to no create mode.
+ *
+ * This is used to interface to userspace administrative tools to
+ * disable new directory creation on the MDT.
+ *
+ * \param[in] count \a buffer length
+ *
+ * \retval \a count on success
+ * \retval negative number on error
+ */
+static ssize_t no_create_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ bool val;
+ int rc;
+
+ rc = kstrtobool(buffer, &val);
+ if (rc)
+ return rc;
+
+ mdt->mdt_lut.lut_no_create = val;
+
+ return count;
+}
+LUSTRE_RW_ATTR(no_create);
+
+/**
* Show MDT async commit count.
*
* @m seq_file handle
&lustre_attr_enable_striped_dir.attr,
&lustre_attr_commit_on_sharing.attr,
&lustre_attr_local_recovery.attr,
+ &lustre_attr_no_create.attr,
&lustre_attr_async_commit_count.attr,
&lustre_attr_sync_count.attr,
&lustre_attr_dom_lock.attr,
* Calculate penalties per-tgt and per-server
*
* Re-calculate penalties when the configuration changes, active targets
- * change and after statfs refresh (all these are reflected by lq_dirty flag).
+ * change and after statfs refresh (all these are reflected by LQ_DIRTY flag).
* On every tgt and server: decay the penalty by half for every 8x the update
* interval that the device has been idle. That gives lots of time for the
* statfs information to be updated (which the penalty is only a proxy for),
max_t(int, simple_strtoul(s1 + 19, NULL, 10),
time_min);
clear++;
- } else if (strncmp(s1, "no_precreate", 12) == 0) {
- set_bit(LMD_FLG_NO_PRECREATE, lmd->lmd_flags);
+ } else if (strncmp(s1, "no_create", 9) == 0 ||
+ /* no_precreate kept for 2.16 compatibility */
+ strncmp(s1, "no_precreate", 12) == 0) {
+ set_bit(LMD_FLG_NO_CREATE, lmd->lmd_flags);
clear++;
} else if (strncmp(s1, "noir", 4) == 0) { /* test case only */
set_bit(LMD_FLG_NOIR, lmd->lmd_flags);
*
* \retval number of bytes written
*/
-static ssize_t no_precreate_show(struct kobject *kobj, struct attribute *attr,
+static ssize_t no_create_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct obd_device *obd = container_of(kobj, struct obd_device,
obd_kset.kobj);
struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- return scnprintf(buf, PAGE_SIZE, "%u\n", ofd->ofd_no_precreate);
+ return scnprintf(buf, PAGE_SIZE, "%u\n", ofd->ofd_lut.lut_no_create);
}
/**
- * Set OFD to no precreate mode.
+ * Set OFD to no create mode.
*
* This is used to interface to userspace administrative tools to
* disable new object creation on the OST.
* \retval \a count on success
* \retval negative number on error
*/
-static ssize_t no_precreate_store(struct kobject *kobj, struct attribute *attr,
+static ssize_t no_create_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
struct obd_device *obd = container_of(kobj, struct obd_device,
return rc;
spin_lock(&ofd->ofd_flags_lock);
- ofd->ofd_no_precreate = val;
+ ofd->ofd_lut.lut_no_create = val;
spin_unlock(&ofd->ofd_flags_lock);
return count;
}
+LUSTRE_RW_ATTR(no_create);
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 20, 53, 0)
+/* compatibility entry for a few releases */
+#define no_precreate_show no_create_show
+#define no_precreate_store no_create_store
LUSTRE_RW_ATTR(no_precreate);
+#endif
/**
* Show OFD filesystem type.
LUSTRE_OBD_UINT_PARAM_ATTR(at_history);
static struct attribute *ofd_attrs[] = {
- &lustre_attr_tot_dirty.attr,
- &lustre_attr_tot_granted.attr,
- &lustre_attr_tot_pending.attr,
+ &lustre_attr_access_log_mask.attr,
+ &lustre_attr_access_log_size.attr,
+ &lustre_attr_atime_diff.attr,
+ &lustre_attr_checksum_t10pi_enforce.attr,
+ &lustre_attr_degraded.attr,
+ &lustre_attr_eviction_count.attr,
+ &lustre_attr_fstype.attr,
+ &lustre_attr_grant_check_threshold.attr,
&lustre_attr_grant_compat_disable.attr,
+ &lustre_attr_grant_precreate.attr,
&lustre_attr_instance.attr,
- &lustre_attr_recovery_time_hard.attr,
- &lustre_attr_recovery_time_soft.attr,
&lustre_attr_ir_factor.attr,
+ &lustre_attr_job_cleanup_interval.attr,
+ &lustre_attr_lfsck_speed_limit.attr,
+ &lustre_attr_no_create.attr,
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 20, 53, 0)
+ &lustre_attr_no_precreate.attr,
+#endif
&lustre_attr_num_exports.attr,
- &lustre_attr_grant_check_threshold.attr,
- &lustre_attr_eviction_count.attr,
- &lustre_attr_seqs_allocated.attr,
- &lustre_attr_grant_precreate.attr,
&lustre_attr_precreate_batch.attr,
- &lustre_attr_atime_diff.attr,
- &lustre_attr_degraded.attr,
- &lustre_attr_fstype.attr,
- &lustre_attr_no_precreate.attr,
+ &lustre_attr_recovery_time_hard.attr,
+ &lustre_attr_recovery_time_soft.attr,
+ &lustre_attr_seqs_allocated.attr,
+ &lustre_attr_tot_dirty.attr,
+ &lustre_attr_tot_granted.attr,
+ &lustre_attr_tot_pending.attr,
+ &lustre_attr_soft_sync_limit.attr,
&lustre_attr_sync_journal.attr,
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
&lustre_attr_sync_on_lock_cancel.attr,
#endif
- &lustre_attr_soft_sync_limit.attr,
- &lustre_attr_lfsck_speed_limit.attr,
- &lustre_attr_access_log_mask.attr,
- &lustre_attr_access_log_size.attr,
- &lustre_attr_job_cleanup_interval.attr,
- &lustre_attr_checksum_t10pi_enforce.attr,
&lustre_attr_at_min.attr,
&lustre_attr_at_max.attr,
&lustre_attr_at_history.attr,
if (lmd) {
if (test_bit(LMD_FLG_SKIP_LFSCK, lmd->lmd_flags))
m->ofd_skip_lfsck = 1;
- if (test_bit(LMD_FLG_NO_PRECREATE, lmd->lmd_flags))
- m->ofd_no_precreate = 1;
+ if (test_bit(LMD_FLG_NO_CREATE, lmd->lmd_flags))
+ m->ofd_lut.lut_no_create = 1;
bitmap_copy(lmd_flags, lmd->lmd_flags, LMD_FLG_NUM_FLAGS);
}
if (CFS_FAIL_CHECK(OBD_FAIL_OST_EROFS))
RETURN(-EROFS);
- if (ofd->ofd_no_precreate)
+ if (ofd->ofd_lut.lut_no_create)
return -EPERM;
repbody = req_capsule_server_get(tsi->tsi_pill, &RMF_OST_BODY);
ofd_lastid_rebuilding:1,
ofd_record_fid_accessed:1,
ofd_lfsck_verify_pfid:1,
- ofd_no_precreate:1,
ofd_skip_lfsck:1;
struct seq_server_site ofd_seq_site;
/* the limit of SOFT_SYNC RPCs that will trigger a soft sync */
osfs->os_ffree -= osfs->os_ffree;
}
- /* OS_STATFS_READONLY can be set by OSD already */
+ /* OS_STATFS_READONLY can be set by OSD already, only add flags */
if (ofd->ofd_raid_degraded)
osfs->os_state |= OS_STATFS_DEGRADED;
- if (ofd->ofd_no_precreate)
- osfs->os_state |= OS_STATFS_NOPRECREATE;
+ if (ofd->ofd_lut.lut_no_create)
+ osfs->os_state |= OS_STATFS_NOCREATE;
if (obd->obd_self_export != exp && !exp_grant_param_supp(exp) &&
current_blockbits > COMPAT_BSIZE_SHIFT) {
ENTRY;
- if (ofd->ofd_no_precreate)
+ if (ofd->ofd_lut.lut_no_create)
return -EPERM;
ofd_info_init(env, exp);
/* Object precreation skipped on OST if manually disabled */
if (d->opd_pre_max_create_count == 0)
- msfs->os_state |= OS_STATFS_NOPRECREATE;
+ msfs->os_state |= OS_STATFS_NOCREATE;
/* else don't clear flags in new msfs->os_state sent from OST */
update:
(unsigned)OS_STATFS_DEGRADED);
LASSERTF(OS_STATFS_READONLY == 0x00000002UL, "found 0x%.8xUL\n",
(unsigned)OS_STATFS_READONLY);
- LASSERTF(OS_STATFS_NOPRECREATE == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)OS_STATFS_NOPRECREATE);
+ LASSERTF(OS_STATFS_NOCREATE == 0x00000004UL, "found 0x%.8xUL\n",
+ (unsigned)OS_STATFS_NOCREATE);
LASSERTF(OS_STATFS_ENOSPC == 0x00000020UL, "found 0x%.8xUL\n",
(unsigned)OS_STATFS_ENOSPC);
LASSERTF(OS_STATFS_ENOINO == 0x00000040UL, "found 0x%.8xUL\n",
}
start_mds() {
+ local mdscount=$MDSCOUNT
local num
- for num in $(seq $MDSCOUNT); do
+ [[ "$1" == "--mdscount" ]] && mdscount=$2 && shift 2
+
+ for ((num=1; num <= $mdscount; num++ )); do
start_mdt $num "$@" || return 94
done
- for num in $(seq $MDSCOUNT); do
+ for ((num=1; num <= $mdscount; num++ )); do
wait_clients_import_state ${CLIENTS:-$HOSTNAME} mds${num} FULL
done
}
}
run_test 111 "Adding large_dir with over 2GB directory"
-test_112() {
+test_112a() {
+ local param="no_create"
+
+ (( $OST1_VERSION > $(version_code 2.14.0) )) ||
+ skip "need OSS at least 2.14.0"
+ (( $OST1_VERSION >= $(version_code 2.15.56.125) )) ||
+ param="no_precreate"
+
start_mds || error "MDS start failed"
start_ost || error "OSS start failed"
echo "start ost2 service on $(facet_active_host ost2)"
- start ost2 $(ostdevname 2) $(csa_add "$OST_MOUNT_OPTS" -o no_precreate) ||
+ start ost2 $(ostdevname 2) $(csa_add "$OST_MOUNT_OPTS" -o $param) ||
error "start ost2 facet failed"
local val=$(do_facet ost2 \
- "$LCTL get_param -n obdfilter.$FSNAME-OST0001*.no_precreate")
- (( $val == 1 )) || error "obdfilter.$FSNAME-OST0001*.no_precreate=$val"
+ "$LCTL get_param -n obdfilter.$FSNAME-OST0001*.$param")
+ (( $val == 1 )) || error "obdfilter.$FSNAME-OST0001*.$param=$val"
mount_client $MOUNT || error "mount client failed"
wait_osc_import_state mds1 ost1 FULL
$LFS setstripe -i 1 $DIR/$tfile.1 && $LFS getstripe $DIR/$tfile.1 &&
(( $($LFS getstripe -i $DIR/$tfile.1) == 1 )) &&
error "allowed to create $tfile.1 on OST0001"
- do_facet ost2 $LCTL set_param obdfilter.*.no_precreate=0
+ $LFS df -v $MOUNT
+ $LFS df -v $MOUNT | grep -q "OST:1.*N" ||
+ error "NOCREATE not in 'lfs df'"
+
+ do_facet ost2 $LCTL set_param obdfilter.$FSNAME-OST0001*.$param=0
sleep_maxage
$LFS setstripe -i 1 $DIR/$tfile.2 ||
error "failed to create $tfile.2 on ost1 facet"
stop_ost2 || error "stop ost2 facet failed"
cleanup
}
-run_test 112 "mount OST with nocreate option"
+run_test 112a "mount OST with no_create option"
+
+test_112b() {
+ (( MDSCOUNT >= 2 )) || skip "need at least 2 MDTs"
+ (( $MDS1_VERSION >= $(version_code 2.15.56.125) )) ||
+ skip "need MDS >= 2.15.56.125"
+ local mdsnum=$MDSCOUNT
+ local facet=mds$mdsnum
+ local mdtidx=$((mdsnum - 1))
+ local mdtname=$FSNAME-MDT$(printf %04x $mdtidx)
+
+ start_mds --mdscount $((mdsnum - 1)) || error "MDS start failed"
+ start_mdt $mdsnum -o no_create || error "start $facet failed"
+ local val=$(do_facet $facet \
+ "$LCTL get_param -n mdt.$mdtname*.no_create")
+ (( $val == 1 )) || error "mdt.$mdtname*.no_create=$val"
+ start_ost || error "ost1 start failed"
+ start_ost2 || error "ost1 start failed"
+
+ mount_client $MOUNT || error "mount client failed"
+ wait_osc_import_ready $facet ost2
+
+ $LFS df -v $MOUNT
+ $LFS df -v $MOUNT | grep -q "MDT:$mdtidx.*N" ||
+ error "NOCREATE not in 'lfs df'"
+
+ $LFS mkdir -i $mdtidx $DIR/$tdir ||
+ $LFS setdirstripe -D -c 1 -i -1 --max-inherit-rr 2 $DIR/$tdir ||
+ error "error creating $tdir on $mdtname"
+ stack_trap "rm -rf $DIR/$tdir"
+
+ mkdir $DIR/$tdir/d1.{1..100} || error "mkdir $tdir/d1.{1..100} failed"
+ $LFS getdirstripe -i $DIR/$tdir/d1.* | sort | uniq -c
+ do_facet $facet $LCTL set_param mdt.$mdtname*.no_create=0
+ # allow one initial create for delayed statfs on client
+ (( $($LFS getdirstripe -i $DIR/$tdir/d1.* | grep -c $mdtidx) < 2 )) ||
+ error "allowed create on $mdtname"
+ sleep_maxage_lmv
+
+ mkdir $DIR/$tdir/d2.{1..100} || error "mkdir $tdir/d2.{1..100} failed"
+ $LFS getdirstripe -i $DIR/$tdir/d2.{1..100} | sort | uniq -c
+ (( $($LFS getdirstripe -i $DIR/$tdir/d2.* | grep -c $mdtidx) > 10 )) ||
+ error "no create on $mdtname"
+ # files not cleaned with ONLY_REPEAT because of client unmount below
+ rm -r $DIR/$tdir
+ stop_ost2 || error "ost1 start failed"
+ cleanup
+}
+run_test 112b "mount MDT with no_create option"
# Global for 113
SAVE_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
}
sleep_maxage() {
- local delay=$(do_facet $SINGLEMDS lctl get_param -n lo[vd].*.qos_maxage |
- awk '{ print $1 * 2; exit; }')
+ local delay=$(do_facet mds1 lctl get_param -n lod.*.qos_maxage |
+ awk '{ print $1 + 5; exit; }')
+ sleep $delay
+}
+
+sleep_maxage_lmv() {
+ local delay=$(lctl get_param -n lmv.*.qos_maxage |
+ awk '{ print $1 + 5; exit; }')
sleep $delay
}
} oss_names[] = {
{ .osn_state = OS_STATFS_DEGRADED, .osn_name = 'D', .osn_err = true },
{ .osn_state = OS_STATFS_READONLY, .osn_name = 'R', .osn_err = true },
- { .osn_state = OS_STATFS_NOPRECREATE,.osn_name = 'N', .osn_err = true },
+ { .osn_state = OS_STATFS_NOCREATE, .osn_name = 'N', .osn_err = true },
{ .osn_state = OS_STATFS_UNUSED1, .osn_name = '?', .osn_err = true },
{ .osn_state = OS_STATFS_UNUSED2, .osn_name = '?', .osn_err = true },
{ .osn_state = OS_STATFS_ENOSPC, .osn_name = 'S', .osn_err = true },
CHECK_VALUE_X(OS_STATFS_DEGRADED);
CHECK_VALUE_X(OS_STATFS_READONLY);
- CHECK_VALUE_X(OS_STATFS_NOPRECREATE);
+ CHECK_VALUE_X(OS_STATFS_NOCREATE);
CHECK_VALUE_X(OS_STATFS_ENOSPC);
CHECK_VALUE_X(OS_STATFS_ENOINO);
CHECK_VALUE_X(OS_STATFS_SUM);
(unsigned)OS_STATFS_DEGRADED);
LASSERTF(OS_STATFS_READONLY == 0x00000002UL, "found 0x%.8xUL\n",
(unsigned)OS_STATFS_READONLY);
- LASSERTF(OS_STATFS_NOPRECREATE == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)OS_STATFS_NOPRECREATE);
+ LASSERTF(OS_STATFS_NOCREATE == 0x00000004UL, "found 0x%.8xUL\n",
+ (unsigned)OS_STATFS_NOCREATE);
LASSERTF(OS_STATFS_ENOSPC == 0x00000020UL, "found 0x%.8xUL\n",
(unsigned)OS_STATFS_ENOSPC);
LASSERTF(OS_STATFS_ENOINO == 0x00000040UL, "found 0x%.8xUL\n",