nfs4: Fix several problems with emulated attributes

This commit is contained in:
Pawel Dziepak
2012-08-17 01:14:30 +02:00
parent e8c12d9410
commit da950cb2ef
5 changed files with 39 additions and 11 deletions
@@ -12,6 +12,7 @@
#include <ctype.h>
#include <string.h>
#include <AutoDeleter.h>
#include <fs_cache.h>
#include <NodeMonitor.h>
@@ -267,10 +268,16 @@ Inode::Link(Inode* dir, const char* name)
status_t
Inode::Remove(const char* name, FileType type)
{
MemoryDeleter nameDeleter;
if (type == NF4NAMEDATTR) {
status_t result = LoadAttrDirHandle();
if (result != B_OK)
return result;
name = AttrToFileName(name);
if (name == NULL)
return B_NO_MEMORY;
nameDeleter.SetTo(const_cast<char*>(name));
}
ChangeInfo changeInfo;
@@ -311,6 +318,8 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
if (from->fFileSystem != to->fFileSystem)
return B_DONT_DO_THAT;
MemoryDeleter fromNameDeleter;
MemoryDeleter toNameDeleter;
if (attribute) {
status_t result = from->LoadAttrDirHandle();
if (result != B_OK)
@@ -319,6 +328,14 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName,
result = to->LoadAttrDirHandle();
if (result != B_OK)
return result;
fromName = from->AttrToFileName(fromName);
toName = to->AttrToFileName(toName);
fromNameDeleter.SetTo(const_cast<char*>(fromName));
toNameDeleter.SetTo(const_cast<char*>(toName));
if (fromName == NULL || toName == NULL)
return B_NO_MEMORY;
}
ChangeInfo fromChange, toChange;
@@ -132,6 +132,8 @@ protected:
status_t GetStat(struct stat* st,
OpenAttrCookie* attr = NULL);
char* AttrToFileName(const char* path);
static inline status_t CheckLockType(short ltype, uint32 mode);
private:
@@ -85,11 +85,11 @@ Inode::LoadAttrDirHandle()
return B_UNSUPPORTED;
char* attrDir
= reinterpret_cast<char*>(malloc(strlen(fInfo.fName) + 32));
= reinterpret_cast<char*>(malloc(strlen(Name()) + 32));
if (attrDir == NULL)
return B_NO_MEMORY;
strcpy(attrDir, ".");
strcat(attrDir, fInfo.fName);
strcat(attrDir, Name());
strcat(attrDir, "-haiku-attrs");
result = NFS4Inode::LookUp(attrDir, NULL, NULL, &handle, true);
@@ -40,12 +40,15 @@ Inode::CreateState(const char* name, int mode, int perms, OpenState* state,
fi.fParent = fInfo.fHandle;
fi.fName = strdup(name);
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
strlen(fInfo.fPath)));
strcpy(path, fInfo.fPath);
strcat(path, "/");
strcat(path, name);
fi.fPath = path;
if (fInfo.fPath != NULL) {
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
strlen(fInfo.fPath)));
strcpy(path, fInfo.fPath);
strcat(path, "/");
strcat(path, name);
fi.fPath = path;
} else
fi.fPath = strdup(name);
fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID));
@@ -193,8 +196,8 @@ Inode::Close(OpenFileCookie* cookie)
}
static char*
AttrToFileName(const char* path)
char*
Inode::AttrToFileName(const char* path)
{
char* name = strdup(path);
if (name == NULL)
@@ -126,7 +126,13 @@ RootInode::_UpdateInfo(bool force)
break;
} while (true);
fInfoCache.flags = 0;
fInfoCache.flags = B_FS_IS_PERSISTENT | B_FS_IS_SHARED
| B_FS_SUPPORTS_NODE_MONITORING;
if (fFileSystem->NamedAttrs()
|| fFileSystem->GetConfiguration().fEmulateNamedAttrs)
fInfoCache.flags |= B_FS_HAS_MIME | B_FS_HAS_ATTR;
strncpy(fInfoCache.volume_name, fName, B_FILE_NAME_LENGTH);
fInfoCacheExpire = time(NULL) + MetadataCache::kExpirationTime;