When a process attempts to allocate space on a full filesystem, a

filesystem full message is sent to the offending process or the
kernel log if the offending process cannot be identified.

To prevent an explotion of messages, the kernel ppsratecheck()
function is used to limit the messages to one per second. This
revision changes the variable that tracks the rate of these messages
from a systemwide limit to a per-filesystem limit by moving it from
a global variable to a variable in the ufsmount structure.

Suggested by: kib
Reviewed by:  kib
Sponsored by: Netflix
This commit is contained in:
Kirk McKusick 2019-07-16 23:12:27 +00:00
parent caa449b635
commit 1fd136ec5e
3 changed files with 42 additions and 26 deletions

View File

@ -158,8 +158,6 @@ ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp)
struct ufsmount *ump;
ufs2_daddr_t bno;
u_int cg, reclaimed;
static struct timeval lastfail;
static int curfail;
int64_t delta;
#ifdef QUOTA
int error;
@ -224,11 +222,14 @@ ffs_alloc(ip, lbn, bpref, size, flags, cred, bnp)
softdep_request_cleanup(fs, ITOV(ip), cred, FLUSH_BLOCKS_WAIT);
goto retry;
}
UFS_UNLOCK(ump);
if (reclaimed > 0 && ppsratecheck(&lastfail, &curfail, 1)) {
if (reclaimed > 0 &&
ppsratecheck(&ump->um_last_fullmsg, &ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem is full\n",
fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
return (ENOSPC);
}
@ -258,8 +259,6 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp)
u_int cg, request, reclaimed;
int error, gbflags;
ufs2_daddr_t bno;
static struct timeval lastfail;
static int curfail;
int64_t delta;
vp = ITOV(ip);
@ -449,14 +448,17 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp)
softdep_request_cleanup(fs, vp, cred, FLUSH_BLOCKS_WAIT);
goto retry;
}
UFS_UNLOCK(ump);
if (bp)
brelse(bp);
if (reclaimed > 0 && ppsratecheck(&lastfail, &curfail, 1)) {
if (reclaimed > 0 &&
ppsratecheck(&ump->um_last_fullmsg, &ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem is full\n",
fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
if (bp)
brelse(bp);
return (ENOSPC);
}
@ -1101,8 +1103,6 @@ ffs_valloc(pvp, mode, cred, vpp)
ino_t ino, ipref;
u_int cg;
int error, error1, reclaimed;
static struct timeval lastfail;
static int curfail;
*vpp = NULL;
pip = VTOI(pvp);
@ -1193,11 +1193,13 @@ ffs_valloc(pvp, mode, cred, vpp)
softdep_request_cleanup(fs, pvp, cred, FLUSH_INODES_WAIT);
goto retry;
}
UFS_UNLOCK(ump);
if (ppsratecheck(&lastfail, &curfail, 1)) {
if (ppsratecheck(&ump->um_last_fullmsg, &ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, pip->i_number, "out of inodes");
uprintf("\n%s: create/symlink failed, no inodes free\n",
fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
return (ENOSPC);
}

View File

@ -108,8 +108,6 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1];
int unwindidx = -1;
int saved_inbdflush;
static struct timeval lastfail;
static int curfail;
int gbflags, reclaimed;
ip = VTOI(vp);
@ -315,17 +313,21 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
flags | IO_BUFLOCKED, cred, &newb)) != 0) {
brelse(bp);
UFS_LOCK(ump);
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
UFS_LOCK(ump);
softdep_request_cleanup(fs, vp, cred,
FLUSH_BLOCKS_WAIT);
UFS_UNLOCK(ump);
goto retry;
}
if (ppsratecheck(&lastfail, &curfail, 1)) {
if (ppsratecheck(&ump->um_last_fullmsg,
&ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem "
"is full\n", fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
goto fail;
}
@ -394,17 +396,21 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size,
flags | IO_BUFLOCKED, cred, &newb);
if (error) {
brelse(bp);
UFS_LOCK(ump);
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
UFS_LOCK(ump);
softdep_request_cleanup(fs, vp, cred,
FLUSH_BLOCKS_WAIT);
UFS_UNLOCK(ump);
goto retry;
}
if (ppsratecheck(&lastfail, &curfail, 1)) {
if (ppsratecheck(&ump->um_last_fullmsg,
&ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem "
"is full\n", fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
goto fail;
}
@ -582,8 +588,6 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
int deallocated, osize, nsize, num, i, error;
int unwindidx = -1;
int saved_inbdflush;
static struct timeval lastfail;
static int curfail;
int gbflags, reclaimed;
ip = VTOI(vp);
@ -902,17 +906,21 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
flags | IO_BUFLOCKED, cred, &newb)) != 0) {
brelse(bp);
UFS_LOCK(ump);
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
UFS_LOCK(ump);
softdep_request_cleanup(fs, vp, cred,
FLUSH_BLOCKS_WAIT);
UFS_UNLOCK(ump);
goto retry;
}
if (ppsratecheck(&lastfail, &curfail, 1)) {
if (ppsratecheck(&ump->um_last_fullmsg,
&ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem "
"is full\n", fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
goto fail;
}
@ -982,17 +990,21 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size,
flags | IO_BUFLOCKED, cred, &newb);
if (error) {
brelse(bp);
UFS_LOCK(ump);
if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
UFS_LOCK(ump);
softdep_request_cleanup(fs, vp, cred,
FLUSH_BLOCKS_WAIT);
UFS_UNLOCK(ump);
goto retry;
}
if (ppsratecheck(&lastfail, &curfail, 1)) {
if (ppsratecheck(&ump->um_last_fullmsg,
&ump->um_secs_fullmsg, 1)) {
UFS_UNLOCK(ump);
ffs_fserr(fs, ip->i_number, "filesystem full");
uprintf("\n%s: write failed, filesystem "
"is full\n", fs->fs_fsmnt);
} else {
UFS_UNLOCK(ump);
}
goto fail;
}

View File

@ -100,6 +100,8 @@ struct ufsmount {
char um_qflags[MAXQUOTAS]; /* (i) quota specific flags */
int64_t um_savedmaxfilesize; /* (c) track maxfilesize */
u_int um_flags; /* (i) filesystem flags */
struct timeval um_last_fullmsg; /* (i) last full msg time */
int um_secs_fullmsg; /* (i) seconds since full msg */
u_int um_trim_inflight; /* (i) outstanding trim count */
u_int um_trim_inflight_blks; /* (i) outstanding trim blks */
u_long um_trim_total; /* (i) total trim count */