Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18

Peter Hartley
2002-03-19T18:24:35Z

Andreas Dilger wrote:
> On Mar 19, 2002 17:45 -0000, Peter Hartley wrote:
> > In particular, this means that an e2fsck 1.27 built against such a glibc
> > will fail with SIGXFS every time on any block device bigger than
2Gbytes.
> > This is because:
> >
> > * e2fsck calls setrlimit(RLIMIT_FSIZE, RLIM_INFINITY) in
> > an attempt to unset the limit. RLIM_INFINITY here is
> > 0xFFFFFFFF. This is IMO the Right Thing.
>
> It is only the right thing if the original limit was not 0xFFFFFFFF.
> Otherwise, it is just adding to the problem, because the problem only
> happens when you try to SET the limit.

True. (Old programs *will* perceive the value as 0xFFFFFFFF if it is
RLIM_INFINITY; the kernel clips it to 0x7FFFFFFF in sys_old_getrlimit() but
glibc expands it again in __new_getrlimit().)

> > Surely the only Right Things to do in the kernel are (a) invent a new
> > setrlimit call that corrects the RLIM_INFINITY value, or (b) have the
> > current setrlimit call correct the RLIM_INFINITY value unconditionally.
>
> (c) rlimit should not apply to block devices.
>
> There were patches for this floating around, and I thought they made it
> into 2.4.18, but they did not.

Looking a bit closer at the particular SIGXFS that kills fsck (in
generic_file_write) there's some S_ISBLK stuff going on just below.

Is the fix just as simple as: (untested) (and with a mailer than mangles
tabs)

--- filemap.c~ Mon Feb 25 19:38:13 2002
+++ filemap.c Tue Mar 19 18:20:40 2002
@@ -2885,9 +2885,9 @@
* Check whether we've reached the file size limit.
*/
err = -EFBIG;

- if (limit != RLIM_INFINITY) {
+ if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) {
if (pos >= limit) {
send_sig(SIGXFSZ, current, 0);
goto out;
}

All this rlimit stuff is a bit wonky in the presence of 64-bit file sizes
anyway. Perhaps if we fix just the block-device case we can brush the rest
under the carpet?

Peter