nfs4: Fix file handle recovery
This commit is contained in:
@@ -184,7 +184,7 @@ status_t
|
|||||||
DirectoryCache::Revalidate()
|
DirectoryCache::Revalidate()
|
||||||
{
|
{
|
||||||
uint64 change;
|
uint64 change;
|
||||||
if (fInode->GetChangeInfo(&change, true) != B_OK) {
|
if (fInode->GetChangeInfo(&change, fAttrDir) != B_OK) {
|
||||||
Trash();
|
Trash();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -263,24 +263,34 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
|
|||||||
notify_entry_created(fInode->GetFileSystem()->DevId(),
|
notify_entry_created(fInode->GetFileSystem()->DevId(),
|
||||||
fInode->ID(), newCurrent->fName, newCurrent->fNode);
|
fInode->ID(), newCurrent->fName, newCurrent->fNode);
|
||||||
|
|
||||||
|
do {
|
||||||
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);
|
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 +
|
size_t pathLength = strlen(newCurrent->fName) + 2 +
|
||||||
strlen(fInode->fInfo.fPath);
|
strlen(fInode->fInfo.fPath);
|
||||||
char* path = reinterpret_cast<char*>(malloc(pathLength));
|
char* path = reinterpret_cast<char*>(pathLength);
|
||||||
if (path != NULL) {
|
if (path == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
strcpy(path, fInode->fInfo.fPath);
|
strcpy(path, fInode->fInfo.fPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, newCurrent->fName);
|
strcat(path, newCurrent->fName);
|
||||||
fi.fPath = path;
|
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));
|
Inode::FileIdToInoT(newCurrent->fNode), true);
|
||||||
}
|
} while (false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
oldSnapshot->fEntries.Remove(prev, oldCurrent);
|
oldSnapshot->fEntries.Remove(prev, oldCurrent);
|
||||||
|
|||||||
@@ -56,7 +56,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;
|
||||||
|
|||||||
@@ -58,10 +58,11 @@ FileSystem::~FileSystem()
|
|||||||
|
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
sGetPath(const char* root, const char* path)
|
GetPath(const char* root, const char* path)
|
||||||
{
|
{
|
||||||
int slash = 0;
|
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')
|
if (path[i] != root[i] || root[i] == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -69,6 +70,9 @@ sGetPath(const char* root, const char* path)
|
|||||||
slash = i;
|
slash = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path[i] == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return path + slash;
|
return path + slash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,12 +153,6 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath,
|
|||||||
const char* name;
|
const char* name;
|
||||||
if (fsPath != NULL && fsPath[0] == '/')
|
if (fsPath != NULL && fsPath[0] == '/')
|
||||||
fsPath++;
|
fsPath++;
|
||||||
name = strrchr(fsPath, '/');
|
|
||||||
if (name != NULL) {
|
|
||||||
name++;
|
|
||||||
fi.fName = strdup(name);
|
|
||||||
} else
|
|
||||||
fi.fName = strdup(fsPath);
|
|
||||||
|
|
||||||
fs->fServer = serv;
|
fs->fServer = serv;
|
||||||
fs->fDevId = id;
|
fs->fDevId = id;
|
||||||
@@ -162,18 +160,30 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath,
|
|||||||
|
|
||||||
fi.fHandle = fh;
|
fi.fHandle = fh;
|
||||||
fi.fParent = 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;
|
delete[] values;
|
||||||
|
|
||||||
if (fi.fName == NULL || fi.fPath == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
Inode* inode;
|
Inode* inode;
|
||||||
result = Inode::CreateInode(fs, fi, &inode);
|
result = Inode::CreateInode(fs, fi, &inode);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
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->fRoot = reinterpret_cast<RootInode*>(inode);
|
||||||
|
|
||||||
fs->NFSServer()->AddFileSystem(fs);
|
fs->NFSServer()->AddFileSystem(fs);
|
||||||
|
|||||||
@@ -230,16 +230,21 @@ Inode::Link(Inode* dir, const char* name)
|
|||||||
if (fi.fName == NULL)
|
if (fi.fName == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
if (fInfo.fPath != NULL) {
|
||||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
||||||
strlen(fInfo.fPath)));
|
strlen(fInfo.fPath)));
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
strcpy(path, dir->fInfo.fPath);
|
strcpy(path, fInfo.fPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, name);
|
strcat(path, name);
|
||||||
free(const_cast<char*>(fi.fPath));
|
|
||||||
fi.fPath = path;
|
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);
|
||||||
|
|
||||||
@@ -803,6 +808,7 @@ Inode::ChildAdded(const char* name, uint64 fileID,
|
|||||||
if (fi.fName == NULL)
|
if (fi.fName == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
if (fInfo.fPath != NULL) {
|
||||||
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
|
||||||
strlen(fInfo.fPath)));
|
strlen(fInfo.fPath)));
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
@@ -812,11 +818,23 @@ Inode::ChildAdded(const char* name, uint64 fileID,
|
|||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, name);
|
strcat(path, name);
|
||||||
fi.fPath = path;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Inode::Name() const
|
||||||
|
{
|
||||||
|
return fInfo.fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Inode::SetDelegation(Delegation* delegation)
|
Inode::SetDelegation(Delegation* delegation)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ class Inode : public NFS4Inode {
|
|||||||
public:
|
public:
|
||||||
static status_t CreateInode(FileSystem* fs, const FileInfo& fi,
|
static status_t CreateInode(FileSystem* fs, const FileInfo& fi,
|
||||||
Inode** inode);
|
Inode** inode);
|
||||||
~Inode();
|
virtual ~Inode();
|
||||||
|
|
||||||
inline ino_t ID() const;
|
inline ino_t ID() const;
|
||||||
inline mode_t Type() const;
|
inline mode_t Type() const;
|
||||||
inline const char* Name() const;
|
virtual const char* Name() const;
|
||||||
inline FileSystem* GetFileSystem() const;
|
inline FileSystem* GetFileSystem() const;
|
||||||
|
|
||||||
inline void SetOpenState(OpenState* state);
|
inline void SetOpenState(OpenState* state);
|
||||||
@@ -181,13 +181,6 @@ Inode::Type() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const char*
|
|
||||||
Inode::Name() const
|
|
||||||
{
|
|
||||||
return fInfo.fName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline FileSystem*
|
inline FileSystem*
|
||||||
Inode::GetFileSystem() const
|
Inode::GetFileSystem() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
inline ~InodeIdMap();
|
inline ~InodeIdMap();
|
||||||
|
|
||||||
inline status_t AddEntry(const FileInfo& fi,
|
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 RemoveEntry(ino_t id);
|
||||||
inline status_t GetFileInfo(FileInfo* fi, ino_t id);
|
inline status_t GetFileInfo(FileInfo* fi, ino_t id);
|
||||||
|
|
||||||
@@ -49,9 +49,10 @@ InodeIdMap::~InodeIdMap()
|
|||||||
|
|
||||||
|
|
||||||
inline status_t
|
inline status_t
|
||||||
InodeIdMap::AddEntry(const FileInfo& fi, ino_t id)
|
InodeIdMap::AddEntry(const FileInfo& fi, ino_t id, bool weak)
|
||||||
{
|
{
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
//if (weak)
|
||||||
fMap.Remove(id);
|
fMap.Remove(id);
|
||||||
return fMap.Insert(id, fi);
|
return fMap.Insert(id, fi);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
RootInode::RootInode()
|
RootInode::RootInode()
|
||||||
:
|
:
|
||||||
fInfoCacheExpire(0),
|
fInfoCacheExpire(0),
|
||||||
|
fName(NULL),
|
||||||
fIOSize(0)
|
fIOSize(0)
|
||||||
{
|
{
|
||||||
mutex_init(&fInfoCacheLock, NULL);
|
mutex_init(&fInfoCacheLock, NULL);
|
||||||
@@ -26,6 +27,7 @@ RootInode::RootInode()
|
|||||||
|
|
||||||
RootInode::~RootInode()
|
RootInode::~RootInode()
|
||||||
{
|
{
|
||||||
|
free(const_cast<char*>(fName));
|
||||||
mutex_destroy(&fInfoCacheLock);
|
mutex_destroy(&fInfoCacheLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ RootInode::_UpdateInfo(bool force)
|
|||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
fInfoCache.flags = 0;
|
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;
|
fInfoCacheExpire = time(NULL) + MetadataCache::kExpirationTime;
|
||||||
|
|
||||||
@@ -161,7 +163,6 @@ RootInode::ProbeMigration()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootInode::GetLocations(AttrValue** attrv)
|
RootInode::GetLocations(AttrValue** attrv)
|
||||||
{
|
{
|
||||||
@@ -198,3 +199,10 @@ RootInode::GetLocations(AttrValue** attrv)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
RootInode::Name() const
|
||||||
|
{
|
||||||
|
return fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ public:
|
|||||||
RootInode();
|
RootInode();
|
||||||
~RootInode();
|
~RootInode();
|
||||||
|
|
||||||
|
virtual const char* Name() const;
|
||||||
|
inline void SetName(const char* name);
|
||||||
|
|
||||||
status_t ReadInfo(struct fs_info* info);
|
status_t ReadInfo(struct fs_info* info);
|
||||||
inline void MakeInfoInvalid();
|
inline void MakeInfoInvalid();
|
||||||
|
|
||||||
@@ -32,6 +35,8 @@ private:
|
|||||||
mutex fInfoCacheLock;
|
mutex fInfoCacheLock;
|
||||||
time_t fInfoCacheExpire;
|
time_t fInfoCacheExpire;
|
||||||
|
|
||||||
|
const char* fName;
|
||||||
|
|
||||||
uint32 fIOSize;
|
uint32 fIOSize;
|
||||||
|
|
||||||
status_t _UpdateInfo(bool force = false);
|
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
|
#endif // ROOTINODE_H
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user