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() 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);
+20 -2
View File
@@ -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)
{ {
+2 -9
View File
@@ -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