ihandle: Avoid FD cache in ih_sync_all

If an ihandle is IH_REALLYCLOSE'd immediately before or during the
IH_OPEN call in ih_sync_all, ih_sync_all can open a new file handle
after the IH_REALLYCLOSE is complete. For a volume that has gone
offline, this means that ih_sync_all can hold a file open for a volume
that has gone offline, and is possibly being manipulated or deleted by
an external program (e.g. the volserver for a clone operation).

While the FdHandle_t is open, or after the handle has been closed and
returned to the FD cache, another caller in the fileserver could try
to open the same file and get back the cached FdHandle_t. If the file
has been deleted by the volserver, this means the fileserver is
writing to the 'wrong' file, as it has been deleted. This can result
in a CopyOnWrite operation causing a file from the clients' point of
view to suddenly become empty, or to revert to a previous version.

To avoid this, prevent ih_sync_all from interacting with the FD cache
entirely, and just open a file descriptor directly from the IHandle_t.
This should prevent it from causing any problems with other users of
the FD cache.

This change is not intended for the master branch. The current
intention for the master branch and future versions is to eliminate
ih_sync_all entirely.

FIXES 131530

Change-Id: I809a0e3ebfe4692eab01671fdf83bf58676453f6
Reviewed-on: http://gerrit.openafs.org/8796
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
Reviewed-by: Paul Smeddle <paul.smeddle@gmail.com>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
Tested-by: Stephan Wiesand <stephan.wiesand@desy.de>
This commit is contained in:
Andrew Deason 2012-12-19 16:57:20 -06:00 committed by Stephan Wiesand
parent 140fb74331
commit aeb42c44bc

View File

@ -981,15 +981,15 @@ ih_sync_all(void) {
for (; ihP; ihP = ihPnext) {
if (ihP->ih_synced) {
FdHandle_t *fdP;
FD_t fd;
ihP->ih_synced = 0;
IH_UNLOCK;
fdP = IH_OPEN(ihP);
if (fdP) {
OS_SYNC(fdP->fd_fd);
FDH_CLOSE(fdP);
fd = OS_IOPEN(ihP);
if (fd != INVALID_FD) {
OS_SYNC(fd);
OS_CLOSE(fd);
}
IH_LOCK;