[comp.unix.wizards] BSD vi/view resets inode ctime: why?

rex%erebus@adm.UUCP (03/08/87)

Why does 4.2/4.3 BSD vi/view, exited without changing the file, update the
inode change time?  Dump finds many more files to dump because of this, when
the file contents/permissions/etc. have not changed.  This makes incremental
dumps much larger than seems necessary.  Sorry if this has been asked/answered
before, but my access to unix-wizards is sporadic.

-- Rex
   rex@erebus.stanford.edu

chris@mimsy.UUCP (Chris Torek) (03/09/87)

In article <4801@brl-adm.ARPA> rex@erebus (Rex Sanders) writes:
>Why does 4.2/4.3 BSD vi/view, exited without changing the file, update the
>inode change time?

It read the file.  This changes the inode access time, which means
the inode was changed, so the inode (though not the file itself)
must be dumped.  If there were two `changed' fields in an inode,
dump could be smarter and dump just the inode.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

chris@mimsy.UUCP (Chris Torek) (03/09/87)

In article <4801@brl-adm.ARPA> rex@erebus (Rex Sanders) writes:
>Why does 4.2/4.3 BSD vi/view, exited without changing the file, update the
>inode change time?

(If you saw an earlier answer from me, ignore it.  I was suffering from
brain rot at the time.  I think I cancelled it before it got far.  This
version is right.  I think.)

In /usr/src/ucb/ex_io.c, one finds a routine called iostats().  This
routine is called just after reading or writing any file.  It does this:

	(void) fsync(io);
	close(io);

In /sys/sys/ufs_syscalls.c, we find fsync():

	fp = getinode(uap->fd);
	if (fp == NULL)
		return;
	ip = (struct inode *)fp->f_data;
	ILOCK(ip);
	syncip(ip);
	IUNLOCK(ip);

Note that there is no verification that the file is open for writing.
(Perhaps this is by design.)  In /sys/sys/ufs_inode.c, at the end of
syncip(), there is this code:

	ip->i_flag |= ICHG;
	iupdat(ip, &time, &time, 1);

which sets to `now' the inode change time (and, if the inode has
been previously marked, the access and update times).  One might
argue that this is unnecessary: but I am uncertain.  Again, this
may be by design.

By far the easiest fix is to change vi.  In ex_io.c, find the two
calls to iostats(), and add a `dosync' parameter, or move the
fsync() call to just before the call from the file-writing code.
Another possible fix, if it is deemed correct, would be to ensure
that (fp->f_flag & FWRITE) != 0.  Then vi's fsync() in the read
case would silently fail.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

lkc@hpirs.UUCP (03/10/87)

> Why does 4.2/4.3 BSD vi/view, exited without changing the file, update the
> inode change time?  Dump finds many more files to dump because of this, when
> the file contents/permissions/etc. have not changed.  This makes incremental
> dumps much larger than seems necessary.  Sorry if this has been asked/answered
> before, but my access to unix-wizards is sporadic.
> 
> -- Rex
>    rex@erebus.stanford.edu

As soon as you read a file, the access time is changed. If the access
time changes, the kernel has no choice but to update the change
status time.

Lee Casuto
...ucbvax!hpda!lkc

aegl@root.co.uk (Tony Luck) (03/13/87)

Under 4.2 it did this because vi uses fsync(2) whenever it reads or
writes a file. The fsync system call updates the ctime field in the
stat structure. I guess this is still the case in 4.3.

I never understood why vi 'fsync'd while *reading* a file, nor why
fsync had any effect on a file descriptor that was only open for
reading, nor what real reliability gain was produced by using fsync
in vi at all.

I "fixed" this by just removing the call from vi.

Tony Luck - Technical manager (aegl@root.co.uk or ...!ukc!root44!aegl)

guy@gorodish.UUCP (03/14/87)

>As soon as you read a file, the access time is changed. If the access
>time changes, the kernel has no choice but to update the change
>status time.

Wrong.  The kernel can leave the change time alone, if it wants.  It does
not consider changing the access time to be a "change".