4.3BSD rename() changes ctime

Brandon S. Allbery allbery at ncoast.UUCP
Mon Aug 8 10:26:55 AEST 1988


As quoted from <2167 at pixar.UUCP> by rta at pixar.UUCP (Rick Ace):
+---------------
| The principal purpose of the ctime field in the I-node is to alert
| /etc/dump that the file has changed in *some way* and must be backed up.
| In the case of "rename", the file's name has changed; thus the file has
| changed in some way, and that fact must be recorded by /etc/dump.
+---------------

We have a misunderstanding here.  Inodes do not have names, they have
i-numbers!!!  A "filename" is a key used by an index (the directory
mechanism and namei()) to determine the i-number of the file.  As a result,
the file itself has not changed but the directories (index pages) searched
to find the i-number have changed; so the directories should be backed up,
but the file shouldn't.

If this is not clear, here's a simplified example of the situation:

	struct inode {
		int i_nlink;
		int i_ctime;
		int i_data;		/* could be anything */
	} *x, *y;

	/* This function is invoked by the kernel whenever anything in the */
	/* inode pointed to by "ip" changes. */
	iupdat(ip)
	struct inode *ip; {
		extern int now;

		ip->i_ctime = now;
	}

	rename(xp, yp)
	char **xp, **yp; {
	/* unlink old "yp" */
		if (--(*yp)->i_nlink == 0)	/* dex causes an iupdat() */
			free(*yp);
		*yp = (char *) NULL;
	/* link "xp" to "yp" */
		(*yp = *xp)->i_nlink++;		/* inx causes an iupdat() */
	/* Things are consistent if the system crashes here! */
	/* unlink old "xp" */
		--(*xp)->i_nlink;		/* dex causes an iupdat() */
		/* should be like yp above, but nlink == 0 "can't happen" */
		*xp = (char *) NULL;		/* unlink old "x" */
	}

	main() {
		rename(&x, &y);
	}

The problem is that the object originally pointed to by "xp" has a value
incremented and immediately decremented; this causes the kernel to change
the ctime (the iupdat() comment).  It's actually unnecessary overhead
because it *is* immediately undone; however, note the comment above about a
crash "here".  fsck would not appreciate the incomplete rename() in the
slightest if the nlink value weren't changed for the duration of the link.
So the price of making the filesystem a bit more resistant to crashes is
having unnecessary data in the next incremental dump.

A fix would be to have rename() save and restore the ctime of the inode
pointed to by "xp" above....

++Brandon

[DISCLAIMER:  The above code is not taken from AT&T or Berkeley source code,
it is merely a C version of a simplification of what I understand to be
going on, with commonly-known function and structure element names used
to make things clearer.  I sincerely doubt that the code actually looks
anything like that....]
-- 
Brandon S. Allbery, uunet!marque!ncoast!allbery			DELPHI: ALLBERY
	    For comp.sources.misc send mail to ncoast!sources-misc



More information about the Comp.unix.wizards mailing list