Handle the case where a new file is created with the read and write

location in a different mount.
Some more comments and a bit of cleanup (more needed).


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2214 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
meep-eep
2006-01-20 05:56:33 +00:00
parent 2055ab6888
commit 94f5fd0abe
+39 -13
View File
@@ -257,6 +257,10 @@ copyError(int error,
* Either O_RDONLY, O_RDWR, O_WRONLY. They may be * Either O_RDONLY, O_RDWR, O_WRONLY. They may be
* OR'd with other values accepted by open(). These * OR'd with other values accepted by open(). These
* are ignored. * are ignored.
* XXX: this is no longer true.
* TODO: update this doc, and check uio_open() and
* perhaps others (uio_mkdir()) for unnecessary
* checks on O_CREAT and O_EXCL.
* extraFlags - either 0 or uio_GPA_NOWRITE * extraFlags - either 0 or uio_GPA_NOWRITE
* When 0, the path will be created if it doesn't * When 0, the path will be created if it doesn't
* exist in the writing location, but does exist * exist in the writing location, but does exist
@@ -320,13 +324,18 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
// Set if the entry pointed to by path exists (including // Set if the entry pointed to by path exists (including
// the last component of the path) // the last component of the path)
// Determine the absolute path from 'path' which is relative to dirHandle. // 'path' is relative to dirHandle.
// Fill 'fullPath' with the absolute path.
if (uio_resolvePath(dirHandle, path, strlen(path), &fullPath) == -1) { if (uio_resolvePath(dirHandle, path, strlen(path), &fullPath) == -1) {
// errno is set // errno is set
return -1; return -1;
} }
// get the MountTree effective for the path // Walk the tree of mount points along 'fullPath'.
// 'tree' will be the part of the tree where we end up when we can go
// no further. tree->pLocs are all the mounts relevant there.
// 'rest' will point within 'fullPath' to what is left, after we can
// walk the tree of mountpoints no further.
uio_findMountTree(dirHandle->repository->mountTree, fullPath, uio_findMountTree(dirHandle->repository->mountTree, fullPath,
&tree, &rest); &tree, &rest);
@@ -346,7 +355,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
strlen(pRootPath), &pDirHandle, &rest); strlen(pRootPath), &pDirHandle, &rest);
// rest points inside fullPath // rest points inside fullPath
if (retVal == 0) { if (retVal == 0) {
// even the last component appeared to be a dir // Even the last component appeared to be a dir.
// As the last component did exist, we don't go on. // As the last component did exist, we don't go on.
uio_free(fullPath); uio_free(fullPath);
uio_PDirHandle_unref(pDirHandle); uio_PDirHandle_unref(pDirHandle);
@@ -359,7 +368,7 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
if (writeItem == NULL && !uio_mountInfoIsReadOnly(item->mountInfo)) if (writeItem == NULL && !uio_mountInfoIsReadOnly(item->mountInfo))
writeItem = item; writeItem = item;
if (strchr(rest, '/') == NULL) { if (strchr(rest, '/') == NULL) {
// There's only dir component that was not matched. // There's only one dir component that was not matched.
uio_PDirEntryHandle *entry; uio_PDirEntryHandle *entry;
// This MountInfo will do for reading, if the file from the last // This MountInfo will do for reading, if the file from the last
@@ -429,14 +438,31 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
uio_free(fullPath); uio_free(fullPath);
return 0; return 0;
} else { } else {
if (!entryExists && !(flags & O_CREAT)) { if (entryExists) {
// Though the path to the entry existed (readPDirHandle is set to if ((flags & O_CREAT) && (flags & O_EXCL)) {
// it), the entry itself doesn't, so we can't use it unless we // An entry should be created, but it already exists and
// intend to create it. // it may not be overwritten.
uio_PDirHandle_unref(readPDirHandle); uio_PDirHandle_unref(readPDirHandle);
uio_free(fullPath); uio_free(fullPath);
errno = ENOENT; errno = EEXIST;
return -1; return -1;
}
} else {
// Though the path to the entry existed (readPDirHandle is
// set to it), the entry itself doesn't, so we can't use it
// unless we intend to create it.
if (flags & O_CREAT) {
// The entry does not exist, but we can create it.
readItem = writeItem;
} else {
// O_CREAT was not specified, so we cannot create
// this entry.
uio_PDirHandle_unref(readPDirHandle);
uio_free(fullPath);
errno = ENOENT;
return -1;
}
} }
} }
if (writeItem == readItem) { if (writeItem == readItem) {