nfs4: Fix file handle recovery
This commit is contained in:
@@ -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);
|
||||
|
||||
do {
|
||||
FileInfo fi;
|
||||
fi.fFileId = newCurrent->fNode;
|
||||
fi.fParent = fInode->fInfo.fHandle;
|
||||
fi.fName = strdup(newCurrent->fName);
|
||||
if (fi.fName != NULL) {
|
||||
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<char*>(malloc(pathLength));
|
||||
if (path != NULL) {
|
||||
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,
|
||||
Inode::FileIdToInoT(newCurrent->fNode));
|
||||
}
|
||||
}
|
||||
Inode::FileIdToInoT(newCurrent->fNode), true);
|
||||
} while (false);
|
||||
}
|
||||
} else
|
||||
oldSnapshot->fEntries.Remove(prev, oldCurrent);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<RootInode*>(inode)->SetName(name);
|
||||
} else
|
||||
reinterpret_cast<RootInode*>(inode)->SetName(fsPath);
|
||||
|
||||
fs->fRoot = reinterpret_cast<RootInode*>(inode);
|
||||
|
||||
fs->NFSServer()->AddFileSystem(fs);
|
||||
|
||||
@@ -230,16 +230,21 @@ Inode::Link(Inode* dir, const char* name)
|
||||
if (fi.fName == NULL)
|
||||
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, dir->fInfo.fPath);
|
||||
strcpy(path, fInfo.fPath);
|
||||
strcat(path, "/");
|
||||
strcat(path, name);
|
||||
free(const_cast<char*>(fi.fPath));
|
||||
fi.fPath = path;
|
||||
} else {
|
||||
fi.fPath = strdup(name);
|
||||
if (fi.fPath == NULL)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId);
|
||||
|
||||
@@ -803,6 +808,7 @@ Inode::ChildAdded(const char* name, uint64 fileID,
|
||||
if (fi.fName == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (fInfo.fPath != NULL) {
|
||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
||||
strlen(fInfo.fPath)));
|
||||
if (path == NULL)
|
||||
@@ -812,11 +818,23 @@ Inode::ChildAdded(const char* name, uint64 fileID,
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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,9 +49,10 @@ 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);
|
||||
//if (weak)
|
||||
fMap.Remove(id);
|
||||
return fMap.Insert(id, fi);
|
||||
}
|
||||
|
||||
@@ -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<char*>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<char*>(fName));
|
||||
fName = strdup(name);
|
||||
}
|
||||
|
||||
|
||||
#endif // ROOTINODE_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user