From 157d82668176fd86c627a4655565d7602ed3eb40 Mon Sep 17 00:00:00 2001 From: threedeyes <3dEyes@gmail.com> Date: Wed, 31 Oct 2012 00:00:06 +0000 Subject: [PATCH] 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. --- .../file_systems/ntfs/fake_attributes.c | 110 ++++++++++-------- .../file_systems/ntfs/fake_attributes.h | 2 + .../kernel/file_systems/ntfs/fs_func.c | 39 +++++-- .../kernel/file_systems/ntfs/mime_table.c | 42 +++++-- 4 files changed, 125 insertions(+), 68 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c index a2fd0964ec..be029521f6 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c @@ -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; } diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h index c12749418a..f121f0fdb6 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index a50c6f6b2a..40bc4dd69b 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -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); diff --git a/src/add-ons/kernel/file_systems/ntfs/mime_table.c b/src/add-ons/kernel/file_systems/ntfs/mime_table.c index 5a92158088..649dbf6e4f 100644 --- a/src/add-ons/kernel/file_systems/ntfs/mime_table.c +++ b/src/add-ons/kernel/file_systems/ntfs/mime_table.c @@ -3,14 +3,14 @@ This file may be used under the terms of the Be Sample Code License. */ +#include + 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 } };