diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index 52be9fddff..370a3378a5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -184,7 +184,7 @@ status_t DirectoryCache::Revalidate() { uint64 change; - if (fInode->GetChangeInfo(&change, true) != B_OK) { + if (fInode->GetChangeInfo(&change, fAttrDir) != B_OK) { Trash(); return B_ERROR; } @@ -263,24 +263,34 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot, notify_entry_created(fInode->GetFileSystem()->DevId(), fInode->ID(), newCurrent->fName, newCurrent->fNode); - FileInfo fi; - fi.fFileId = newCurrent->fNode; - fi.fParent = fInode->fInfo.fHandle; - fi.fName = strdup(newCurrent->fName); - if (fi.fName != NULL) { - size_t pathLength = strlen(newCurrent->fName) + 2 + - strlen(fInode->fInfo.fPath); - char* path = reinterpret_cast(malloc(pathLength)); - if (path != NULL) { + do { + FileInfo fi; + fi.fFileId = newCurrent->fNode; + fi.fParent = fInode->fInfo.fHandle; + fi.fName = strdup(newCurrent->fName); + if (fi.fName == NULL) + break; + + if (fInode->fInfo.fPath != NULL) { + size_t pathLength = strlen(newCurrent->fName) + 2 + + strlen(fInode->fInfo.fPath); + char* path = reinterpret_cast(pathLength); + if (path == NULL) + break; + strcpy(path, fInode->fInfo.fPath); strcat(path, "/"); strcat(path, newCurrent->fName); fi.fPath = path; - - fInode->GetFileSystem()->InoIdMap()->AddEntry(fi, - Inode::FileIdToInoT(newCurrent->fNode)); + } else { + fi.fPath = strdup(newCurrent->fName); + if (fi.fPath == NULL) + break; } - } + + fInode->GetFileSystem()->InoIdMap()->AddEntry(fi, + Inode::FileIdToInoT(newCurrent->fNode), true); + } while (false); } } else oldSnapshot->fEntries.Remove(prev, oldCurrent); diff --git a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp index e81242e526..9ff0e49211 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp @@ -56,7 +56,7 @@ FileInfo::UpdateFileHandles(FileSystem* fs) uint32 lookupCount = 0; status_t result; - +dprintf("%s %s\n", fs->Path(), fPath); result = ParsePath(req, lookupCount, fs->Path()); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index 4c8963aa9e..ec5d992987 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -58,10 +58,11 @@ FileSystem::~FileSystem() static const char* -sGetPath(const char* root, const char* path) +GetPath(const char* root, const char* path) { int slash = 0; - for (int i = 0; path[i] != '\0'; i++) { + int i; + for (i = 0; path[i] != '\0'; i++) { if (path[i] != root[i] || root[i] == '\0') break; @@ -69,6 +70,9 @@ sGetPath(const char* root, const char* path) slash = i; } + if (path[i] == '\0') + return NULL; + return path + slash; } @@ -149,12 +153,6 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, const char* name; if (fsPath != NULL && fsPath[0] == '/') fsPath++; - name = strrchr(fsPath, '/'); - if (name != NULL) { - name++; - fi.fName = strdup(name); - } else - fi.fName = strdup(fsPath); fs->fServer = serv; fs->fDevId = id; @@ -162,18 +160,30 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, fi.fHandle = fh; fi.fParent = fh; - fi.fPath = strdup(sGetPath(fs->fPath, fsPath)); + fi.fPath = strdup(GetPath(fs->fPath, fsPath)); + + if (fi.fPath != NULL) { + name = strrchr(fi.fPath, '/'); + if (name != NULL) { + name++; + fi.fName = strdup(name); + } + } delete[] values; - if (fi.fName == NULL || fi.fPath == NULL) - return B_NO_MEMORY; - Inode* inode; result = Inode::CreateInode(fs, fi, &inode); if (result != B_OK) return result; + name = strrchr(fsPath, '/'); + if (name != NULL) { + name++; + reinterpret_cast(inode)->SetName(name); + } else + reinterpret_cast(inode)->SetName(fsPath); + fs->fRoot = reinterpret_cast(inode); fs->NFSServer()->AddFileSystem(fs); diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index c8cfd2c808..a98ca4c67b 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -230,16 +230,21 @@ Inode::Link(Inode* dir, const char* name) if (fi.fName == NULL) return B_NO_MEMORY; - char* path = reinterpret_cast(malloc(strlen(name) + 2 + - strlen(fInfo.fPath))); - if (path == NULL) - return B_NO_MEMORY; + if (fInfo.fPath != NULL) { + char* path = reinterpret_cast(malloc(strlen(name) + 2 + + strlen(fInfo.fPath))); + if (path == NULL) + return B_NO_MEMORY; - strcpy(path, dir->fInfo.fPath); - strcat(path, "/"); - strcat(path, name); - free(const_cast(fi.fPath)); - fi.fPath = path; + 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); @@ -803,20 +808,33 @@ Inode::ChildAdded(const char* name, uint64 fileID, if (fi.fName == NULL) return B_NO_MEMORY; - char* path = reinterpret_cast(malloc(strlen(name) + 2 + - strlen(fInfo.fPath))); - if (path == NULL) - return B_NO_MEMORY; + if (fInfo.fPath != NULL) { + char* path = reinterpret_cast(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; + 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)); } +const char* +Inode::Name() const +{ + return fInfo.fName; +} + + void Inode::SetDelegation(Delegation* delegation) { diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index d4d16acdae..7497fa5fd2 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -20,11 +20,11 @@ class Inode : public NFS4Inode { public: static status_t CreateInode(FileSystem* fs, const FileInfo& fi, Inode** inode); - ~Inode(); + virtual ~Inode(); inline ino_t ID() const; inline mode_t Type() const; - inline const char* Name() const; + virtual const char* Name() const; inline FileSystem* GetFileSystem() const; inline void SetOpenState(OpenState* state); @@ -181,13 +181,6 @@ Inode::Type() const } -inline const char* -Inode::Name() const -{ - return fInfo.fName; -} - - inline FileSystem* Inode::GetFileSystem() const { diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h b/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h index 2a29e07942..ae85c32594 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h +++ b/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h @@ -23,7 +23,7 @@ public: inline ~InodeIdMap(); inline status_t AddEntry(const FileInfo& fi, - ino_t id); + ino_t id, bool weak = false); inline status_t RemoveEntry(ino_t id); inline status_t GetFileInfo(FileInfo* fi, ino_t id); @@ -49,10 +49,11 @@ InodeIdMap::~InodeIdMap() inline status_t -InodeIdMap::AddEntry(const FileInfo& fi, ino_t id) +InodeIdMap::AddEntry(const FileInfo& fi, ino_t id, bool weak) { MutexLocker _(fLock); - fMap.Remove(id); + //if (weak) + fMap.Remove(id); return fMap.Insert(id, fi); } diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp index 0275f67f01..4ca51e2021 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp @@ -18,6 +18,7 @@ RootInode::RootInode() : fInfoCacheExpire(0), + fName(NULL), fIOSize(0) { mutex_init(&fInfoCacheLock, NULL); @@ -26,6 +27,7 @@ RootInode::RootInode() RootInode::~RootInode() { + free(const_cast(fName)); mutex_destroy(&fInfoCacheLock); } @@ -125,7 +127,7 @@ RootInode::_UpdateInfo(bool force) } while (true); fInfoCache.flags = 0; - strncpy(fInfoCache.volume_name, fInfo.fName, B_FILE_NAME_LENGTH); + strncpy(fInfoCache.volume_name, fName, B_FILE_NAME_LENGTH); fInfoCacheExpire = time(NULL) + MetadataCache::kExpirationTime; @@ -161,7 +163,6 @@ RootInode::ProbeMigration() } - status_t RootInode::GetLocations(AttrValue** attrv) { @@ -198,3 +199,10 @@ RootInode::GetLocations(AttrValue** attrv) return B_OK; } + +const char* +RootInode::Name() const +{ + return fName; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.h b/src/add-ons/kernel/file_systems/nfs4/RootInode.h index 864d49ddba..4810b7829d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.h +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.h @@ -19,6 +19,9 @@ public: RootInode(); ~RootInode(); + virtual const char* Name() const; + inline void SetName(const char* name); + status_t ReadInfo(struct fs_info* info); inline void MakeInfoInvalid(); @@ -32,6 +35,8 @@ private: mutex fInfoCacheLock; time_t fInfoCacheExpire; + const char* fName; + uint32 fIOSize; status_t _UpdateInfo(bool force = false); @@ -55,5 +60,13 @@ RootInode::IOSize() } +inline void +RootInode::SetName(const char* name) +{ + free(const_cast(fName)); + fName = strdup(name); +} + + #endif // ROOTINODE_H