* Add a bit of hysteresis so this flag isn't continually flapping,
* and ensure that new files don't get extremely fragmented due to
* only a small amount of available space in the filesystem.
- * We want to set the ENOSPC when there is less than reserved size
- * free and clear it when there is at least 2*reserved size free space.
+ * We want to set the NOSPC flag when there is less than ~0.1% free
+ * and clear it when there is at least ~0.2% free space, so:
+ * avail < ~0.1% max max = avail + used
+ * 1025 * avail < avail + used used = blocks - free
+ * 1024 * avail < used
+ * 1024 * avail < blocks - free
+ * avail < ((blocks - free) >> 10)
+ *
+ * On very large disk, say 16TB 0.1% will be 16 GB. We don't want to
+ * lose that amount of space so in those cases we report no space left
+ * if their is less than 1 GB left.
* the function updates current precreation status used: functional or not
*
* \param[in] d OSP device
{
struct obd_statfs *msfs = &d->opd_statfs;
int old = d->opd_pre_status;
- __u64 available;
+ __u64 used;
d->opd_pre_status = rc;
if (rc)
goto out;
if (likely(msfs->os_type)) {
- if (d->opd_reserved_mb_high == 0 &&
- d->opd_reserved_mb_low == 0) {
- /* Use ~0.1% by default to disable object allocation,
- * and ~0.2% to enable, size in MB, set both watermark
- */
- spin_lock(&d->opd_pre_lock);
- if (d->opd_reserved_mb_high == 0 &&
- d->opd_reserved_mb_low == 0) {
- d->opd_reserved_mb_low = (msfs->os_bsize *
- msfs->os_blocks) >> 30;
- if (d->opd_reserved_mb_low == 0)
- d->opd_reserved_mb_low = 1;
- d->opd_reserved_mb_high =
- (d->opd_reserved_mb_low << 1) + 1;
- }
- spin_unlock(&d->opd_pre_lock);
- }
- /* in MB */
- available = (msfs->os_bavail * (msfs->os_bsize >> 10)) >> 10;
- if ((msfs->os_ffree < 32) ||
- (available < d->opd_reserved_mb_low)) {
+ used = min_t(__u64, (msfs->os_blocks - msfs->os_bfree) >> 10,
+ 1 << 30);
+ if ((msfs->os_ffree < 32) || (msfs->os_bavail < used)) {
d->opd_pre_status = -ENOSPC;
if (old != -ENOSPC)
CDEBUG(D_INFO, "%s: status: "LPU64" blocks, "
- LPU64" free, "LPU64" avail, "LPU64" "
- "MB avail, %u hwm -> %d: rc = %d\n",
+ LPU64" free, "LPU64" used, "LPU64" "
+ "avail -> %d: rc = %d\n",
d->opd_obd->obd_name, msfs->os_blocks,
- msfs->os_bfree, msfs->os_bavail,
- available, d->opd_reserved_mb_low,
+ msfs->os_bfree, used, msfs->os_bavail,
d->opd_pre_status, rc);
CDEBUG(D_INFO,
"non-commited changes: %lu, in progress: %u\n",
d->opd_syn_changes, d->opd_syn_rpc_in_progress);
- } else if (unlikely(old == -ENOSPC &&
- (msfs->os_ffree > 64) &&
- (available > d->opd_reserved_mb_high))) {
+ } else if (old == -ENOSPC) {
d->opd_pre_status = 0;
spin_lock(&d->opd_pre_lock);
d->opd_pre_grow_slow = 0;
spin_unlock(&d->opd_pre_lock);
wake_up(&d->opd_pre_waitq);
CDEBUG(D_INFO, "%s: no space: "LPU64" blocks, "LPU64
- " free, "LPU64" avail, "LPU64"MB avail, %u nwm"
- " -> %d: rc = %d\n", d->opd_obd->obd_name,
- msfs->os_blocks, msfs->os_bfree, msfs->os_bavail,
- available, d->opd_reserved_mb_high,
- d->opd_pre_status, rc);
+ " free, "LPU64" used, "LPU64" avail -> %d: "
+ "rc = %d\n", d->opd_obd->obd_name,
+ msfs->os_blocks, msfs->os_bfree, used,
+ msfs->os_bavail, d->opd_pre_status, rc);
}
}
+
out:
wake_up(&d->opd_pre_user_waitq);
}
d->opd_pre_grow_count = OST_MIN_PRECREATE;
d->opd_pre_min_grow_count = OST_MIN_PRECREATE;
d->opd_pre_max_grow_count = OST_MAX_PRECREATE;
- d->opd_reserved_mb_high = 0;
- d->opd_reserved_mb_low = 0;
spin_lock_init(&d->opd_pre_lock);
init_waitqueue_head(&d->opd_pre_waitq);