OBD_FL_SHRINK_GRANT = 0x00020000, /* object shrink the grant */
OBD_FL_MMAP = 0x00040000, /* object is mmapped on the client */
OBD_FL_RECOV_RESEND = 0x00080000, /* recoverable resent */
+ OBD_FL_NOSPC_BLK = 0x00100000, /* no more block space on OST */
OBD_FL_CKSUM_ALL = OBD_FL_CKSUM_CRC32 | OBD_FL_CKSUM_ADLER,
LPU64"\n", obd->obd_name, osfs->os_bavail <<
obd->u.obt.obt_vfsmnt->mnt_sb->s_blocksize_bits);
*num = 0;
+ if (oa->o_valid & OBD_MD_FLFLAGS)
+ oa->o_flags |= OBD_FL_NOSPC_BLK;
+ else {
+ oa->o_valid |= OBD_MD_FLFLAGS;
+ oa->o_flags = OBD_FL_NOSPC_BLK;
+ }
+
rc = -ENOSPC;
}
OBD_FREE(osfs, sizeof(*osfs));
CERROR("create failed rc = %d\n", rc);
if (rc == -ENOSPC) {
os_ffree = filter_calc_free_inodes(obd);
- if (os_ffree != -1)
+ if (os_ffree == -1)
+ GOTO(cleanup, rc);
+
+ if (obd->obd_osfs.os_bavail <
+ (obd->obd_osfs.os_blocks >> 10)) {
+ if (oa->o_valid & OBD_MD_FLFLAGS)
+ oa->o_flags |= OBD_FL_NOSPC_BLK;
+ else {
+ oa->o_valid |= OBD_MD_FLFLAGS;
+ oa->o_flags = OBD_FL_NOSPC_BLK;
+ }
+
CERROR("%s: free inode "LPU64"\n",
obd->obd_name, os_ffree);
+ }
}
GOTO(cleanup, rc);
}
if (body && rc == -ENOSPC) {
oscc->oscc_last_id = body->oa.o_id;
oscc->oscc_grow_count = OST_MIN_PRECREATE;
+
+ if ((body->oa.o_valid & OBD_MD_FLFLAGS) &&
+ (body->oa.o_flags & OBD_FL_NOSPC_BLK))
+ oscc->oscc_flags |= OSCC_FLAG_NOSPC_BLK;
+ else
+ rc = 0;
}
}
cfs_spin_unlock(&oscc->oscc_lock);
/* Handle critical states first */
cfs_spin_lock(&oscc->oscc_lock);
- if (oscc->oscc_flags & OSCC_FLAG_NOSPC ||
+ if (oscc->oscc_flags & OSCC_FLAG_NOSPC_BLK ||
oscc->oscc_flags & OSCC_FLAG_RDONLY ||
oscc->oscc_flags & OSCC_FLAG_EXITING)
GOTO(out, rc = 1000);
/* Return 0, if we have at least one object - bug 22884 */
rc = oscc_has_objects_nolock(oscc, 1) ? 0 : 1;
+ if (oscc->oscc_flags & OSCC_FLAG_NOSPC)
+ GOTO(out, (rc == 0) ? 0 : 1000);
+
/* Do not check for OSCC_FLAG_CREATING flag here, let
* osc_precreate() call oscc_internal_create() and
* adjust oscc_grow_count bug21563 */
if (oscc->oscc_flags & OSCC_FLAG_EXITING)
GOTO(out_wake, rc = -EIO);
- if (oscc->oscc_flags & OSCC_FLAG_NOSPC)
+ if (oscc->oscc_flags & OSCC_FLAG_NOSPC_BLK)
GOTO(out_wake, rc = -ENOSPC);
if (oscc->oscc_flags & OSCC_FLAG_RDONLY)
if (rc == 0 || rc == -ENOSPC) {
struct obd_connect_data *ocd;
- if (rc == -ENOSPC)
+ if (rc == -ENOSPC) {
oscc->oscc_flags |= OSCC_FLAG_NOSPC;
+ if ((oa->o_valid & OBD_MD_FLFLAGS) &&
+ (oa->o_flags & OBD_FL_NOSPC_BLK))
+ oscc->oscc_flags |= OSCC_FLAG_NOSPC_BLK;
+ }
oscc->oscc_flags &= ~OSCC_FLAG_RECOVERING;
oscc->oscc_last_id = oa->o_id;
break;
}
- if (oscc->oscc_flags & OSCC_FLAG_NOSPC) {
+ if (oscc->oscc_flags & OSCC_FLAG_NOSPC_BLK) {
rc = -ENOSPC;
cfs_spin_unlock(&oscc->oscc_lock);
break;
break;
}
+ if (oscc->oscc_flags & OSCC_FLAG_NOSPC) {
+ rc = -ENOSPC;
+ cfs_spin_unlock(&oscc->oscc_lock);
+ break;
+ }
+
cfs_spin_unlock(&oscc->oscc_lock);
}
#define OSCC_FLAG_EXITING 0x20
#define OSCC_FLAG_DEGRADED 0x40
#define OSCC_FLAG_RDONLY 0x80
+#define OSCC_FLAG_NOSPC_BLK 0x100 /* no more block space on OST */
int osc_precreate(struct obd_export *exp);
int osc_create(struct obd_export *exp, struct obdo *oa,
((msfs->os_ffree < 32) || (msfs->os_bavail < used))))
cli->cl_oscc.oscc_flags |= OSCC_FLAG_NOSPC;
else if (unlikely(((cli->cl_oscc.oscc_flags & OSCC_FLAG_NOSPC) != 0) &&
- (msfs->os_ffree > 64) && (msfs->os_bavail > (used << 1))))
- cli->cl_oscc.oscc_flags &= ~OSCC_FLAG_NOSPC;
+ (msfs->os_ffree > 64) &&
+ (msfs->os_bavail > (used << 1)))) {
+ cli->cl_oscc.oscc_flags &= ~(OSCC_FLAG_NOSPC |
+ OSCC_FLAG_NOSPC_BLK);
+ }
+
+ if (unlikely(((cli->cl_oscc.oscc_flags & OSCC_FLAG_NOSPC) != 0) &&
+ (msfs->os_bavail < used)))
+ cli->cl_oscc.oscc_flags |= OSCC_FLAG_NOSPC_BLK;
cfs_spin_unlock(&cli->cl_oscc.oscc_lock);
struct osc_creator *oscc = &obd->u.cli.cl_oscc;
cfs_spin_lock(&oscc->oscc_lock);
- oscc->oscc_flags &= ~OSCC_FLAG_NOSPC;
+ oscc->oscc_flags &= ~(OSCC_FLAG_NOSPC |
+ OSCC_FLAG_NOSPC_BLK);
cfs_spin_unlock(&oscc->oscc_lock);
}
rc = obd_notify_observer(obd, obd, OBD_NOTIFY_ACTIVE, NULL);
}
run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
+test_220() { #LU-325
+ local OSTIDX=0
+
+ mkdir -p $DIR/$tdir
+ local OST=$(lfs osts | grep ${OSTIDX}": " | \
+ awk '{print $2}' | sed -e 's/_UUID$//')
+
+ # on the mdt's osc
+ local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
+ local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
+ osc.$mdtosc_proc1.prealloc_last_id)
+ local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
+ osc.$mdtosc_proc1.prealloc_next_id)
+
+ $LFS df -i
+
+ do_facet mgs $LCTL pool_new $FSNAME.$TESTNAME || return 1
+ do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
+
+ $SETSTRIPE $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
+
+ echo "preallocated objects in MDS is $((last_id - next_id))" \
+ "($last_id - $next_id)"
+
+ count=$($LFS df -i $MOUNT | grep ^$OST | awk '{print $4}')
+ echo "OST still has $count objects"
+
+ free=$((count + last_id - next_id))
+ echo "create $free files..."
+ createmany -o $DIR/$tdir/f $next_id $free || return 3
+
+ local last_id=$(do_facet mds${MDSIDX} lctl get_param -n \
+ osc.$mdtosc_proc1.prealloc_last_id)
+ local next_id=$(do_facet mds${MDSIDX} lctl get_param -n \
+ osc.$mdtosc_proc1.prealloc_next_id)
+
+ echo "after creation, last_id=$last_id, next_id=$next_id"
+ $LFS df -i
+
+ echo "cleanup..."
+
+ do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST || return 4
+ do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME || return 5
+ rm -fr $DIR/$tdir
+}
+run_test 220 "the preallocated objects in MDS still can be used if ENOSPC is returned by OST with enough disk space"
+
#
# tests that do cleanup/setup should be run at the end
#