NTFS: fake-attributes improvements

* Fake-atributes enabled by default (Real attributes require optimization. Too slow with big and fragmented volumes.)
* Upadted mime-table for file extension to mime-type mapping.
* Fix for fake-attributes mode switching.
This commit is contained in:
threedeyes 2012-10-31 00:00:06 +00:00
parent 4107ac9cda
commit 157d826681
4 changed files with 125 additions and 68 deletions

View File

@ -21,14 +21,27 @@
#include "fake_attributes.h"
#include "mime_table.h"
int32 kBeOSTypeCookie = 0x1234;
int32 kOpenTypeCookie = 0;
int32 kCloseTypeCookie = 1;
int32 kSetTypeCookie = 0x1234;
int32 kFreeTypeCookie = 0x87654321;
char *kFailBackMime = {"application/octet-stream"};
char *kDirectoryMime = {"application/x-vnd.Be-directory"};
status_t set_mime(vnode *node, const char *filename)
{
struct ext_mime *p;
int32 namelen, ext_len;
int32 namelen;
int32 ext_len;
node->mime = kFailBackMime;
if (filename == NULL)
{
node->mime = kDirectoryMime;
return B_NO_ERROR;
}
namelen = strlen(filename);
for (p=mimes; p->extension; p++) {
@ -64,7 +77,7 @@ fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
goto exit;
}
*(int32 *)(*_cookie) = 0;
*(int32 *)(*_cookie) = kOpenTypeCookie;
exit:
@ -75,6 +88,7 @@ exit:
return result;
}
status_t
fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
@ -84,7 +98,7 @@ fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
LOCK_VOL(ns);
*(int32 *)_cookie = 1;
*(int32 *)_cookie = kCloseTypeCookie;
TRACE("fake_close_attrdir - EXIT\n");
@ -93,6 +107,7 @@ fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
return B_NO_ERROR;
}
status_t
fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
@ -110,7 +125,7 @@ fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
goto exit;
}
*(int32 *)_cookie = 0x87654321;
*(int32 *)_cookie = kFreeTypeCookie;
free(_cookie);
exit:
@ -123,6 +138,7 @@ exit:
return result;
}
status_t
fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
@ -141,7 +157,7 @@ fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
goto exit;
}
*(uint32 *)_cookie = 0;
*(uint32 *)_cookie = kOpenTypeCookie;
exit:
@ -168,16 +184,16 @@ fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
*num = 0;
if ((*cookie == 0) && (node->mime)) {
if ((*cookie == kOpenTypeCookie) && (node->mime)) {
*num = 1;
entry->d_ino = node->vnid;
entry->d_dev = ns->id;
entry->d_reclen = sizeof(struct dirent)+10;
entry->d_reclen = sizeof(struct dirent) + 10;
strcpy(entry->d_name, "BEOS:TYPE");
}
*cookie = 1;
*cookie = kCloseTypeCookie;
TRACE("fake_read_attrdir - EXIT\n");
@ -186,30 +202,46 @@ fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
return B_NO_ERROR;
}
status_t
fake_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name,
uint32 type, int openMode, void** _cookie)
{
nspace *ns = (nspace *)_vol->private_volume;
int result = B_NO_ERROR;
LOCK_VOL(ns);
TRACE("fake_create_attrib - ENTER (name = [%s])\n",name);
if (strcmp(name, "BEOS:TYPE") != 0)
goto exit;
*_cookie = &kSetTypeCookie;
exit:
TRACE("fake_create_attrib - EXIT, result is %s\n", strerror(result));
UNLOCK_VOL(ns);
return result;
}
status_t
fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
int openMode, void **_cookie)
{
nspace *ns = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
int result = B_NO_ERROR;
LOCK_VOL(ns);
TRACE("fake_open_attrib - ENTER (name = [%s])\n",name);
if (strcmp(name, "BEOS:TYPE") != 0) {
result = ENOENT;
if (strcmp(name, "BEOS:TYPE") != 0)
goto exit;
}
if (node->mime == NULL) {
TRACE("fake_open_attrib - MIME = NULL\n");
result = ENOENT;
goto exit;
}
*_cookie = &kBeOSTypeCookie;
*_cookie = &kSetTypeCookie;
exit:
@ -240,25 +272,23 @@ fake_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct stat *stat)
{
nspace *ns = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
vnode *node = (vnode *)_node->private_node;
int result = B_NO_ERROR;
LOCK_VOL(ns);
TRACE("fake_read_attr_stat - ENTER\n");
if (_cookie != &kBeOSTypeCookie) {
result = ENOENT;
goto exit;
}
if (node->mime == NULL) {
if (_cookie != &kSetTypeCookie) {
result = ENOENT;
goto exit;
}
stat->st_type = MIME_STRING_TYPE;
stat->st_size = strlen(node->mime) + 1;
if (node->mime == NULL)
stat->st_size = 0;
else
stat->st_size = strlen(node->mime) + 1;
exit:
@ -276,7 +306,7 @@ fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,
off_t pos,void *buffer, size_t *_length)
{
nspace *ns = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
vnode *node = (vnode *)_node->private_node;
int result = B_NO_ERROR;
@ -284,7 +314,7 @@ fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,
TRACE("fake_read_attr - ENTER\n");
if (_cookie != &kBeOSTypeCookie) {
if (_cookie != &kSetTypeCookie) {
result = ENOENT;
goto exit;
}
@ -317,23 +347,5 @@ status_t
fake_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
const void *buffer, size_t *_length)
{
nspace *ns = (nspace *)_vol->private_volume;
int result = B_NO_ERROR;
LOCK_VOL(ns);
TRACE("fake_write_attr - ENTER\n");
*_length = 0;
if (_cookie != &kBeOSTypeCookie) {
result = ENOSYS;
}
TRACE("fake_write_attrib - EXIT, result is %s\n", strerror(result));
UNLOCK_VOL(ns);
return result;
return B_NO_ERROR;
}

View File

@ -24,6 +24,8 @@ status_t fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node,
void *_cookie);
status_t fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
struct dirent *buf, size_t bufsize, uint32 *num);
status_t fake_create_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
uint32 type, int openMode, void** _cookie);
status_t fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
int openMode, void **_cookie);
status_t fake_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie);

View File

@ -346,7 +346,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args,
ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true",
"true"), "true") == 0;
ns->fake_attrib = strcasecmp(get_driver_parameter(handle, "fake_attributes",
"false", "false"), "false") != 0;
"true", "true"), "true") == 0;
unload_driver_settings(handle);
if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0
@ -361,7 +361,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args,
gNTFSVnodeOps.free_attr_dir_cookie = fake_free_attrib_dir_cookie;
gNTFSVnodeOps.read_attr_dir = fake_read_attrib_dir;
gNTFSVnodeOps.rewind_attr_dir = fake_rewind_attrib_dir;
gNTFSVnodeOps.create_attr = NULL;
gNTFSVnodeOps.create_attr = fake_create_attrib;
gNTFSVnodeOps.open_attr = fake_open_attrib;
gNTFSVnodeOps.close_attr = fake_close_attrib;
gNTFSVnodeOps.free_attr_cookie = fake_free_attrib_cookie;
@ -369,6 +369,20 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args,
gNTFSVnodeOps.read_attr_stat = fake_read_attrib_stat;
gNTFSVnodeOps.write_attr = fake_write_attrib;
gNTFSVnodeOps.remove_attr = NULL;
} else {
gNTFSVnodeOps.open_attr_dir = fs_open_attrib_dir;
gNTFSVnodeOps.close_attr_dir = fs_close_attrib_dir;
gNTFSVnodeOps.free_attr_dir_cookie = fs_free_attrib_dir_cookie;
gNTFSVnodeOps.read_attr_dir = fs_read_attrib_dir;
gNTFSVnodeOps.rewind_attr_dir = fs_rewind_attrib_dir;
gNTFSVnodeOps.create_attr = fs_create_attrib;
gNTFSVnodeOps.open_attr = fs_open_attrib;
gNTFSVnodeOps.close_attr = fs_close_attrib;
gNTFSVnodeOps.free_attr_cookie = fs_free_attrib_cookie;
gNTFSVnodeOps.read_attr = fs_read_attrib;
gNTFSVnodeOps.read_attr_stat = fs_read_attrib_stat;
gNTFSVnodeOps.write_attr = fs_write_attrib;
gNTFSVnodeOps.remove_attr = fs_remove_attrib;
}
ns->ntvol = utils_mount_volume(device, mountFlags | MS_RECOVER);
@ -1088,7 +1102,7 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
}
newNode->vnid = vnid;
newNode->parent_vnid = MREF(dir_ni->mft_no);
newNode->parent_vnid = dir->vnid;
ni->flags |= FILE_ATTR_ARCHIVE;
NInoSetDirty(ni);
@ -1102,10 +1116,17 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
}
*_vnid = vnid;
ntfs_mark_free_space_outdated(ns);
fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME);
notify_entry_created(ns->id, MREF(dir_ni->mft_no), name, *_vnid);
if (ns->fake_attrib) {
if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
set_mime(newNode, NULL);
else
set_mime(newNode, name);
}
ntfs_mark_free_space_outdated(ns);
fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME);
notify_entry_created(ns->id, dir->vnid, name, vnid);
} else
result = errno;
}
@ -1703,13 +1724,13 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name,
if (ns->fake_attrib) {
if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
set_mime(file, ".***");
set_mime(file, NULL);
else
set_mime(file, newname);
notify_attribute_changed(ns->id, file->vnid, "BEOS:TYPE",
B_ATTR_CHANGED);
}
ntfs_inode_close(dir_ni);
ntfs_inode_close(ni);

View File

@ -3,14 +3,14 @@
This file may be used under the terms of the Be Sample Code License.
*/
#include <sys/types.h>
struct ext_mime {
char *extension;
char *mime;
};
struct ext_mime mimes[] = {
{ "***", "application/x-vnd.Be-directory"},
{ "gz", "application/x-gzip" },
{ "hqx", "application/x-binhex40" },
{ "lha", "application/x-lharc" },
@ -24,8 +24,13 @@ struct ext_mime mimes[] = {
{ "z", "application/x-compress" },
{ "zip", "application/zip" },
{ "zoo", "application/x-zoo" },
{ "rar", "application/x-rar-compressed" },
{ "rar", "application/x-rar" },
{ "pkg", "application/x-scode-UPkg" },
{ "7z", "application/x-7z-compressed" },
{ "bz2", "application/x-bzip2" },
{ "xz", "application/x-xz" },
{ "jar", "application/x-jar" },
{ "aif", "audio/x-aiff" },
{ "aiff", "audio/x-aiff" },
@ -37,13 +42,20 @@ struct ext_mime mimes[] = {
{ "wav", "audio/x-wav" },
{ "mp3", "audio/x-mpeg" },
{ "ogg", "audio/x-vorbis" },
{ "flac", "audio/x-flac" },
{ "wma", "audio/x-ms-wma" },
{ "avi", "video/x-msvideo" },
{ "mov", "video/quicktime" },
{ "qt", "video/quicktime" },
{ "mpg", "video/mpeg" },
{ "mpeg", "video/mpeg" },
{ "flv", "video/x-flv" },
{ "mp4", "video/mp4" },
{ "mkv", "video/x-matroska" },
{ "asf", "application/x-asf" },
{ "rm", "video/vnd.rn-realvideo" },
{ "wmv", "video/x-ms-wmv" },
{ "bmp", "image/x-bmp" },
{ "fax", "image/g3fax" },
@ -61,11 +73,21 @@ struct ext_mime mimes[] = {
{ "tif", "image/tiff" },
{ "tiff", "image/tiff" },
{ "xbm", "image/x-xbitmap" },
{ "djvu", "image/x-djvu" },
{ "djvu", "image/x-djvu" },
{ "svg", "image/svg+xml" },
{ "ico", "image/vnd.microsoft.icon" },
{ "doc", "application/msword" },
{ "xls", "application/vnd.ms-excel" },
{ "xls", "application/vnd.ms-excel" },
{ "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
{ "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
{ "ppt", "application/vnd.ms-powerpoint" },
{ "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
{ "chm", "application/x-chm" },
{ "txt", "text/plain" },
{ "xml", "text/plain" },
{ "doc", "text/plain" },
{ "htm", "text/html" },
{ "html", "text/html" },
{ "rtf", "text/rtf" },
@ -74,15 +96,15 @@ struct ext_mime mimes[] = {
{ "c++", "text/x-source-code" },
{ "h", "text/x-source-code" },
{ "hh", "text/x-source-code" },
{ "hpp", "text/x-source-code" },
{ "cxx", "text/x-source-code" },
{ "cpp", "text/x-source-code" },
{ "S", "text/x-source-code" },
{ "java", "text/x-source-code" },
{ "exe", "application/x-vnd.Be-elfexecutable" },
{ "dll", "application/x-vnd.Be.ELF-object" },
{ "ini", "text/plain" },
{ "inf", "text/plain" },
{ "ttf", "application/x-truetype" },
{ 0, 0 }
{ NULL, NULL }
};