nfs4: Fix file handle recovery

This commit is contained in:
Pawel Dziepak
2012-08-16 21:11:56 +02:00
parent 060a4636e4
commit e8c12d9410
8 changed files with 111 additions and 58 deletions
@@ -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);
+20 -2
View File
@@ -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)
{
+2 -9
View File
@@ -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