nfs4: Update FileInfo at rename
This commit is contained in:
@@ -267,27 +267,11 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
|
|||||||
FileInfo fi;
|
FileInfo fi;
|
||||||
fi.fFileId = newCurrent->fNode;
|
fi.fFileId = newCurrent->fNode;
|
||||||
fi.fParent = fInode->fInfo.fHandle;
|
fi.fParent = fInode->fInfo.fHandle;
|
||||||
fi.fName = strdup(newCurrent->fName);
|
status_t result = fi.CreateName(fInode->fInfo.fPath,
|
||||||
if (fi.fName == NULL)
|
newCurrent->fName);
|
||||||
|
if (result != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (fInode->fInfo.fPath != NULL) {
|
|
||||||
size_t pathLength = strlen(newCurrent->fName) + 2 +
|
|
||||||
strlen(fInode->fInfo.fPath);
|
|
||||||
char* path = reinterpret_cast<char*>(pathLength);
|
|
||||||
if (path == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
strcpy(path, fInode->fInfo.fPath);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, newCurrent->fName);
|
|
||||||
fi.fPath = path;
|
|
||||||
} else {
|
|
||||||
fi.fPath = strdup(newCurrent->fName);
|
|
||||||
if (fi.fPath == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fInode->GetFileSystem()->InoIdMap()->AddEntry(fi,
|
fInode->GetFileSystem()->InoIdMap()->AddEntry(fi,
|
||||||
Inode::FileIdToInoT(newCurrent->fNode), true);
|
Inode::FileIdToInoT(newCurrent->fNode), true);
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|||||||
@@ -46,6 +46,38 @@ FileInfo::ParsePath(RequestBuilder& req, uint32& count, const char* _path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FileInfo::CreateName(const char* dirPath, const char* name)
|
||||||
|
{
|
||||||
|
free(const_cast<char*>(fName));
|
||||||
|
fName = strdup(name);
|
||||||
|
if (fName == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
if (dirPath != NULL) {
|
||||||
|
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
||||||
|
strlen(dirPath)));
|
||||||
|
if (path == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
strcpy(path, dirPath);
|
||||||
|
strcat(path, "/");
|
||||||
|
strcat(path, name);
|
||||||
|
|
||||||
|
free(const_cast<char*>(fPath));
|
||||||
|
fPath = path;
|
||||||
|
} else {
|
||||||
|
free(const_cast<char*>(fPath));
|
||||||
|
fPath = strdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fPath == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FileInfo::UpdateFileHandles(FileSystem* fs)
|
FileInfo::UpdateFileHandles(FileSystem* fs)
|
||||||
{
|
{
|
||||||
@@ -56,7 +88,7 @@ FileInfo::UpdateFileHandles(FileSystem* fs)
|
|||||||
|
|
||||||
uint32 lookupCount = 0;
|
uint32 lookupCount = 0;
|
||||||
status_t result;
|
status_t result;
|
||||||
dprintf("%s %s\n", fs->Path(), fPath);
|
|
||||||
result = ParsePath(req, lookupCount, fs->Path());
|
result = ParsePath(req, lookupCount, fs->Path());
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ struct FileInfo {
|
|||||||
|
|
||||||
static status_t ParsePath(RequestBuilder& req, uint32& count,
|
static status_t ParsePath(RequestBuilder& req, uint32& count,
|
||||||
const char* _path);
|
const char* _path);
|
||||||
|
|
||||||
|
status_t CreateName(const char* dirPath, const char* name);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileSystemId {
|
struct FileSystemId {
|
||||||
|
|||||||
@@ -226,26 +226,9 @@ Inode::Link(Inode* dir, const char* name)
|
|||||||
|
|
||||||
FileInfo fi = fInfo;
|
FileInfo fi = fInfo;
|
||||||
fi.fParent = dir->fInfo.fHandle;
|
fi.fParent = dir->fInfo.fHandle;
|
||||||
free(const_cast<char*>(fi.fName));
|
result = fi.CreateName(fInfo.fPath, name);
|
||||||
fi.fName = strdup(name);
|
if (result != B_OK)
|
||||||
if (fi.fName == NULL)
|
return result;
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
if (fInfo.fPath != NULL) {
|
|
||||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
|
||||||
strlen(fInfo.fPath)));
|
|
||||||
if (path == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
strcpy(path, fInfo.fPath);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, name);
|
|
||||||
fi.fPath = path;
|
|
||||||
} else {
|
|
||||||
fi.fPath = strdup(name);
|
|
||||||
if (fi.fPath == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId);
|
fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId);
|
||||||
|
|
||||||
@@ -315,7 +298,7 @@ Inode::Remove(const char* name, FileType type, ino_t* id)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
||||||
bool attribute)
|
bool attribute, ino_t* id)
|
||||||
{
|
{
|
||||||
if (from->fFileSystem != to->fFileSystem)
|
if (from->fFileSystem != to->fFileSystem)
|
||||||
return B_DONT_DO_THAT;
|
return B_DONT_DO_THAT;
|
||||||
@@ -342,8 +325,8 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
|||||||
|
|
||||||
ChangeInfo fromChange, toChange;
|
ChangeInfo fromChange, toChange;
|
||||||
uint64 fileID;
|
uint64 fileID;
|
||||||
status_t result = NFS4Inode::Rename(from, to, fromName, toName, &fromChange,
|
status_t result = NFS4Inode::RenameNode(from, to, fromName, toName,
|
||||||
&toChange, &fileID, attribute);
|
&fromChange, &toChange, &fileID, attribute);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -360,6 +343,9 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
|
|||||||
cache->Unlock();
|
cache->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id != NULL)
|
||||||
|
*id = FileIdToInoT(fileID);
|
||||||
|
|
||||||
cache = attribute ? to->fAttrCache : to->fCache;
|
cache = attribute ? to->fAttrCache : to->fCache;
|
||||||
if (cache->Lock() == B_OK) {
|
if (cache->Lock() == B_OK) {
|
||||||
if (toChange.fAtomic
|
if (toChange.fAtomic
|
||||||
@@ -828,25 +814,9 @@ Inode::ChildAdded(const char* name, uint64 fileID,
|
|||||||
fi.fFileId = fileID;
|
fi.fFileId = fileID;
|
||||||
fi.fHandle = fileHandle;
|
fi.fHandle = fileHandle;
|
||||||
fi.fParent = fInfo.fHandle;
|
fi.fParent = fInfo.fHandle;
|
||||||
fi.fName = strdup(name);
|
status_t result = fi.CreateName(fInfo.fPath, name);
|
||||||
if (fi.fName == NULL)
|
if (result != B_OK)
|
||||||
return B_NO_MEMORY;
|
return result;
|
||||||
|
|
||||||
if (fInfo.fPath != NULL) {
|
|
||||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
|
||||||
strlen(fInfo.fPath)));
|
|
||||||
if (path == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
strcpy(path, fInfo.fPath);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, name);
|
|
||||||
fi.fPath = path;
|
|
||||||
} else {
|
|
||||||
fi.fPath = strdup(name);
|
|
||||||
if (fi.fPath == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
|
return fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ public:
|
|||||||
|
|
||||||
status_t Link(Inode* dir, const char* name);
|
status_t Link(Inode* dir, const char* name);
|
||||||
status_t Remove(const char* name, FileType type,
|
status_t Remove(const char* name, FileType type,
|
||||||
ino_t* id);
|
ino_t* id = NULL);
|
||||||
static status_t Rename(Inode* from, Inode* to,
|
static status_t Rename(Inode* from, Inode* to,
|
||||||
const char* fromName, const char* toName,
|
const char* fromName, const char* toName,
|
||||||
bool attribute = false);
|
bool attribute = false, ino_t* id = NULL);
|
||||||
|
|
||||||
status_t Stat(struct stat* st,
|
status_t Stat(struct stat* st,
|
||||||
OpenAttrCookie* attr = NULL);
|
OpenAttrCookie* attr = NULL);
|
||||||
|
|||||||
@@ -38,17 +38,7 @@ Inode::CreateState(const char* name, int mode, int perms, OpenState* state,
|
|||||||
fi.fFileId = fileID;
|
fi.fFileId = fileID;
|
||||||
fi.fHandle = handle;
|
fi.fHandle = handle;
|
||||||
fi.fParent = fInfo.fHandle;
|
fi.fParent = fInfo.fHandle;
|
||||||
fi.fName = strdup(name);
|
fi.CreateName(fInfo.fPath, name);
|
||||||
|
|
||||||
if (fInfo.fPath != NULL) {
|
|
||||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
|
||||||
strlen(fInfo.fPath)));
|
|
||||||
strcpy(path, fInfo.fPath);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, name);
|
|
||||||
fi.fPath = path;
|
|
||||||
} else
|
|
||||||
fi.fPath = strdup(name);
|
|
||||||
|
|
||||||
fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
|
fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
|
||||||
|
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NFS4Inode::Rename(Inode* from, Inode* to, const char* fromName,
|
NFS4Inode::RenameNode(Inode* from, Inode* to, const char* fromName,
|
||||||
const char* toName, ChangeInfo* fromChange, ChangeInfo* toChange,
|
const char* toName, ChangeInfo* fromChange, ChangeInfo* toChange,
|
||||||
uint64* fileID, bool attribute)
|
uint64* fileID, bool attribute)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ protected:
|
|||||||
status_t Link(Inode* dir, const char* name,
|
status_t Link(Inode* dir, const char* name,
|
||||||
ChangeInfo* changeInfo);
|
ChangeInfo* changeInfo);
|
||||||
|
|
||||||
static status_t Rename(Inode* from, Inode* to, const char* fromName,
|
static status_t RenameNode(Inode* from, Inode* to, const char* fromName,
|
||||||
const char* toName, ChangeInfo* fromChange,
|
const char* toName, ChangeInfo* fromChange,
|
||||||
ChangeInfo* toChange, uint64* fileID,
|
ChangeInfo* toChange, uint64* fileID,
|
||||||
bool attribute = false);
|
bool attribute = false);
|
||||||
|
|||||||
@@ -429,7 +429,21 @@ nfs4_rename(fs_volume* volume, fs_vnode* fromDir, const char* fromName,
|
|||||||
{
|
{
|
||||||
Inode* fromInode = reinterpret_cast<Inode*>(fromDir->private_node);
|
Inode* fromInode = reinterpret_cast<Inode*>(fromDir->private_node);
|
||||||
Inode* toInode = reinterpret_cast<Inode*>(toDir->private_node);
|
Inode* toInode = reinterpret_cast<Inode*>(toDir->private_node);
|
||||||
return Inode::Rename(fromInode, toInode, fromName, toName);
|
|
||||||
|
ino_t id;
|
||||||
|
status_t result = Inode::Rename(fromInode, toInode, fromName, toName, false,
|
||||||
|
&id);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
Inode* child;
|
||||||
|
result = get_vnode(volume, id, reinterpret_cast<void**>(&child));
|
||||||
|
if (result == B_OK) {
|
||||||
|
child->fInfo.fParent = toInode->fInfo.fHandle;
|
||||||
|
child->fInfo.CreateName(toInode->fInfo.fPath, toName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user