From c0c445f1f45fbdb79d65763f84d53f7eea98077c Mon Sep 17 00:00:00 2001 From: threedeyes <3dEyes@gmail.com> Date: Mon, 22 Oct 2012 10:13:02 +0000 Subject: [PATCH 1/6] NTFS:Critical fixes for renaming and creating nodes. The adaptation of some functions to the new version of the libntfs3g. --- .../kernel/file_systems/ntfs/fs_func.c | 505 +++++++++--------- 1 file changed, 247 insertions(+), 258 deletions(-) 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 28c27c62ec..fd8c6e423c 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -113,6 +113,176 @@ get_node_type(ntfs_inode* ni, int* _type) } +static u64 +ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) +{ + nspace *ns = (nspace*)_vol->private_volume; + + u64 ino = (u64)-1; + u64 inum; + ntfs_inode *dir_ni; + + /* Open target directory. */ + dir_ni = ntfs_inode_open(ns->ntvol, parent); + if (dir_ni) { + /* Lookup file */ + inum = ntfs_inode_lookup_by_mbsname(dir_ni, name); + /* never return inodes 0 and 1 */ + if (MREF(inum) <= 1) { + inum = (u64)-1; + errno = ENOENT; + } + if (ntfs_inode_close(dir_ni) + || (inum == (u64)-1)) + ino = (u64)-1; + else + ino = MREF(inum); + } + return (ino); +} + + +static int +ntfs_remove(fs_volume *_vol, ino_t parent, const char *name) +{ + nspace *ns = (nspace*)_vol->private_volume; + + ntfschar *uname = NULL; + ntfs_inode *dir_ni = NULL, *ni = NULL; + int res = B_OK, uname_len; + u64 iref; + + /* Open parent directory. */ + dir_ni = ntfs_inode_open(ns->ntvol, parent); + if (!dir_ni) { + res = EINVAL; + goto exit; + } + /* Generate unicode filename. */ + uname_len = ntfs_mbstoucs(name, &uname); + if (uname_len < 0) { + res = EINVAL; + goto exit; + } + /* Open object for delete. */ + iref = ntfs_inode_lookup_by_mbsname(dir_ni, name); + if (iref == (u64)-1) { + res = EINVAL; + goto exit; + } + /* deny unlinking metadata files */ + if (MREF(iref) < FILE_first_user) { + res = EINVAL; + goto exit; + } + + ni = ntfs_inode_open(ns->ntvol, MREF(iref)); + if (!ni) { + res = EINVAL; + goto exit; + } + + if (ntfs_delete(ns->ntvol, (char*)NULL, ni, dir_ni, uname, uname_len)) + res = EINVAL; + /* ntfs_delete() always closes ni and dir_ni */ + ni = dir_ni = NULL; +exit: + if (ni) + ntfs_inode_close(ni); + if (dir_ni) + ntfs_inode_close(dir_ni); + + free(uname); + return res; +} + + +static status_t +do_unlink(fs_volume *_vol, vnode *dir, const char *name, bool isdir) +{ + nspace *ns = (nspace*)_vol->private_volume; + ino_t vnid; + vnode *node = NULL; + ntfs_inode *ni = NULL; + ntfs_inode *bi = NULL; + ntfschar *uname = NULL; + int unameLength; + + status_t result = B_NO_ERROR; + + unameLength = ntfs_mbstoucs(name, &uname); + if (unameLength < 0) { + result = EINVAL; + goto exit1; + } + + bi = ntfs_inode_open(ns->ntvol, dir->vnid); + if (bi == NULL) { + result = ENOENT; + goto exit1; + } + + vnid = MREF(ntfs_inode_lookup_by_name(bi, uname, unameLength)); + + if ( vnid == (u64)-1 || vnid == FILE_root) { + result = EINVAL; + goto exit1; + } + + result = get_vnode(_vol, vnid, (void**)&node); + + if (result != B_NO_ERROR || node==NULL) { + result = ENOENT; + goto exit1; + } + + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if (ni == NULL) { + result = ENOENT; + goto exit2; + } + + if (isdir) { + if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { + result = ENOTDIR; + goto exit2; + } + if (ntfs_check_empty_dir(ni)<0) { + result = ENOTEMPTY; + goto exit2; + } + } else if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { + result = EISDIR; + goto exit2; + } + + // TODO: the file must not be deleted here, only unlinked! + if (ntfs_delete(ns->ntvol, (char*)NULL, ni, bi, uname, unameLength)) + result = errno; + + ni = bi = NULL; + + node->parent_vnid = dir->vnid; + + notify_entry_removed(ns->id, dir->vnid, name, vnid); + + remove_vnode(_vol, vnid); + + result = 0; +exit2: + put_vnode(_vol, vnid); +exit1: + free(uname); + + if (ni) + ntfs_inode_close(ni); + if (bi) + ntfs_inode_close(bi); + + return result; +} + + void fs_ntfs_update_times(fs_volume *vol, ntfs_inode *ni, ntfs_time_update_flags mask) @@ -964,8 +1134,6 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, le32 securid = const_cpu_to_le32(0); ni = ntfs_create(bi, securid, uname, unameLength, S_IFREG); if (ni) { - NInoSetDirty(ni); - *_vnid = MREF(ni->mft_no); newNode = (vnode*)ntfs_calloc(sizeof(vnode)); @@ -983,13 +1151,16 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, newNode->parent_vnid = MREF(bi->mft_no); set_mime(newNode, name); + ni->flags |= FILE_ATTR_ARCHIVE; + ntfs_inode_update_mbsname(bi, name, ni->mft_no); + NInoSetDirty(ni); + result = B_NO_ERROR; result = publish_vnode(_vol, *_vnid, (void*)newNode, &gNTFSVnodeOps, S_IFREG, 0); - ntfs_mark_free_space_outdated(ns); - fs_ntfs_update_times(_vol, bi, NTFS_UPDATE_MCTIME); - + ntfs_mark_free_space_outdated(ns); + fs_ntfs_update_times(_vol, bi, NTFS_UPDATE_MCTIME); notify_entry_created(ns->id, MREF(bi->mft_no), name, *_vnid); } else result = errno; @@ -1470,8 +1641,6 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) ni = ntfs_create(bi, securid, uname, unameLength, S_IFDIR); if (ni) { ino_t vnid = MREF(ni->mft_no); - - NInoSetDirty(ni); newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode == NULL) { @@ -1487,6 +1656,10 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) newNode->vnid = vnid; newNode->parent_vnid = MREF(bi->mft_no); set_mime(newNode, ".***"); + + ni->flags |= FILE_ATTR_ARCHIVE; + ntfs_inode_update_mbsname(bi, name, ni->mft_no); + NInoSetDirty(ni); result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, S_IFDIR, 0); @@ -1513,30 +1686,24 @@ exit: status_t -fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname, +fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, fs_vnode *_ndir, const char *newname) { nspace *ns = (nspace*)_vol->private_volume; vnode *odir = (vnode*)_odir->private_node; vnode *ndir = (vnode*)_ndir->private_node; + vnode *file = NULL; + + ino_t parent = odir->vnid; + ino_t newparent = ndir->vnid; - vnode *onode = NULL; - vnode *nnode = NULL; + ino_t ino, xino; - ino_t ovnid, nvnid; - - ntfs_inode *oi = NULL; - ntfs_inode *ndi = NULL; - ntfs_inode *odi = NULL; - - ntfschar *unewname = NULL; - ntfschar *uoldname = NULL; - int unewnameLength; - int uoldnameLength; + ntfs_inode *ni = NULL; + ntfs_inode *dir_ni = NULL; status_t result = B_NO_ERROR; - char path[MAX_PATH]; if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); @@ -1545,156 +1712,70 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname, LOCK_VOL(ns); - TRACE("fs_rename - oldname:%s newname:%s\n", oldname, newname); - - // convert names from utf8 to unicode string - unewnameLength = ntfs_mbstoucs(newname, &unewname); - if (unewnameLength < 0) { + TRACE("NTFS:fs_rename - oldname:%s newname:%s\n", name, newname); + + ino = ntfs_inode_lookup(_vol, parent, name); + if (ino == (u64)-1) { result = EINVAL; - goto exit; + goto exit; } + + /* Check whether target is present */ + xino = ntfs_inode_lookup(_vol, newparent, newname); + + if (xino == (u64)-1) { + ntfschar *uname = NULL; + int uname_len; - uoldnameLength = ntfs_mbstoucs(oldname, &uoldname); - if (uoldnameLength < 0) { + result = get_vnode(_vol, ino, (void**)&file); + if (result != B_NO_ERROR) + goto exit; + + + ni = ntfs_inode_open(ns->ntvol, ino); + if (!ni) { + result = EINVAL; + goto exit; + } + + uname_len = ntfs_mbstoucs(newname, &uname); + if (uname_len < 0) { + result = EINVAL; + goto exit; + } + + dir_ni = ntfs_inode_open(ns->ntvol, newparent); + if (!dir_ni) { + result = EINVAL; + goto exit; + } + + if (ntfs_link(ni, dir_ni, uname, uname_len)) { + result = EINVAL; + goto exit; + } + + ntfs_inode_update_mbsname(dir_ni, newname, ni->mft_no); + + ni->flags |= FILE_ATTR_ARCHIVE; + + fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_CTIME); + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + + ntfs_inode_close(dir_ni); + ntfs_inode_close(ni); + + free(uname); + + ntfs_remove(_vol, parent, name); + + file->parent_vnid = newparent; + put_vnode(_vol, file->vnid); + + notify_entry_moved(ns->id, parent, name, newparent, newname, ino); + } else result = EINVAL; - goto exit; - } - - // open source directory inode - odi = ntfs_inode_open(ns->ntvol, odir->vnid); - if (odi == NULL) { - result = ENOENT; - goto exit; - } - - ovnid = MREF(ntfs_inode_lookup_by_name(odi, uoldname, uoldnameLength)); - if (ovnid == (u64) -1) { - result = EINVAL; - goto exit; - } - - result = get_vnode(_vol, ovnid, (void**)&onode); - if (result != B_NO_ERROR) - goto exit; - - - if (odir != ndir) { - // moving - ndi = ntfs_inode_open(ns->ntvol, ndir->vnid); - if (ndi != NULL) { - nvnid = MREF(ntfs_inode_lookup_by_name(ndi, unewname, - unewnameLength)); - if (nvnid != (u64) -1) - get_vnode(_vol, nvnid, (void**)&nnode); - } - - if (nnode != NULL) { - result = EINVAL; - put_vnode(_vol, nnode->vnid); - goto exit; - } - - oi = ntfs_inode_open(ns->ntvol, onode->vnid); - if (oi == NULL) { - result = EINVAL; - goto exit; - } - - if (ntfs_link(oi, ndi, unewname, unewnameLength)) { - ntfs_inode_close(oi); - result = EINVAL; - goto exit; - } - - if (oi->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(onode, ".***"); - else - set_mime(onode, newname); - - ntfs_inode_close(oi); - - oi = ntfs_inode_open(ns->ntvol, onode->vnid); - if (oi == NULL) { - result = EINVAL; - goto exit; - } - - onode->parent_vnid = MREF(ndi->mft_no); - - notify_entry_moved(ns->id, MREF(odi->mft_no), oldname, MREF(ndi->mft_no), - newname, onode->vnid); - - if (utils_inode_get_name(oi, path, MAX_PATH) == 0) { - result = EINVAL; - goto exit; - } - - ntfs_delete(ns->ntvol, path, oi, odi, uoldname, uoldnameLength); - oi = odi = NULL; - /* ntfs_delete() always closes ni and dir_ni */ - - put_vnode(_vol, onode->vnid); - } else { - // renaming - - nvnid = MREF(ntfs_inode_lookup_by_name(odi, unewname, unewnameLength)); - if (nvnid != (u64)-1) - get_vnode(_vol, nvnid, (void**)&nnode); - - if (nnode != NULL) { - result = EINVAL; - put_vnode(_vol, nnode->vnid); - goto exit; - } - - oi = ntfs_inode_open(ns->ntvol, onode->vnid); - if (oi == NULL) { - result = EINVAL; - goto exit; - } - - if (ntfs_link(oi, odi, unewname, unewnameLength)) { - ntfs_inode_close(oi); - result = EINVAL; - goto exit; - } - - if (oi->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(onode, ".***"); - else - set_mime(onode, newname); - - ntfs_inode_close(oi); - - oi = ntfs_inode_open(ns->ntvol, onode->vnid); - if (oi == NULL) { - result = EINVAL; - goto exit; - } - - notify_entry_moved(ns->id, MREF(odi->mft_no), oldname, - MREF(odi->mft_no), newname, onode->vnid); - put_vnode(_vol, onode->vnid); - - if (utils_inode_get_name(oi, path, MAX_PATH) == 0) { - result = EINVAL; - goto exit; - } - - ntfs_delete(ns->ntvol, path, oi, odi, uoldname, uoldnameLength); - oi = odi = NULL; - /* ntfs_delete() always closes ni and dir_ni */ - } - exit: - free(unewname); - free(uoldname); - - if (odi) - ntfs_inode_close(odi); - if (ndi) - ntfs_inode_close(ndi); - TRACE("fs_rename - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); @@ -1703,97 +1784,6 @@ exit: } -static status_t -do_unlink(fs_volume *_vol, vnode *dir, const char *name, bool isdir) -{ - nspace *ns = (nspace*)_vol->private_volume; - ino_t vnid; - vnode *node = NULL; - ntfs_inode *ni = NULL; - ntfs_inode *bi = NULL; - ntfschar *uname = NULL; - int unameLength; - char path[MAX_PATH]; - - status_t result = B_NO_ERROR; - - unameLength = ntfs_mbstoucs(name, &uname); - if (unameLength < 0) { - result = EINVAL; - goto exit1; - } - - bi = ntfs_inode_open(ns->ntvol, dir->vnid); - if (bi == NULL) { - result = ENOENT; - goto exit1; - } - - vnid = MREF(ntfs_inode_lookup_by_name(bi, uname, unameLength)); - - if ( vnid == (u64)-1 || vnid == FILE_root) { - result = EINVAL; - goto exit1; - } - - result = get_vnode(_vol, vnid, (void**)&node); - - if (result != B_NO_ERROR || node==NULL) { - result = ENOENT; - goto exit1; - } - - ni = ntfs_inode_open(ns->ntvol, node->vnid); - if (ni == NULL) { - result = ENOENT; - goto exit2; - } - - if (isdir) { - if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { - result = ENOTDIR; - goto exit2; - } - if (ntfs_check_empty_dir(ni)<0) { - result = ENOTEMPTY; - goto exit2; - } - } else if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { - result = EISDIR; - goto exit2; - } - - if (utils_inode_get_name(ni, path, MAX_PATH) == 0) { - result = EINVAL; - goto exit2; - } - - // TODO: the file must not be deleted here, only unlinked! - if (ntfs_delete(ns->ntvol, path, ni, bi, uname, unameLength)) - result = errno; - - ni = bi = NULL; - - node->parent_vnid = dir->vnid; - - notify_entry_removed(ns->id, dir->vnid, name, vnid); - - result = remove_vnode(_vol, vnid); - -exit2: - put_vnode(_vol, vnid); -exit1: - free(uname); - - if (ni) - ntfs_inode_close(ni); - if (bi) - ntfs_inode_close(bi); - - return result; -} - - status_t fs_rmdir(fs_volume *_vol, fs_vnode *_dir, const char *name) { @@ -1872,4 +1862,3 @@ exit: return result; } - From 184ecaf4c509dd651770aafe3dd2b2c27aad0990 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Mon, 22 Oct 2012 20:18:21 -0400 Subject: [PATCH 2/6] Draw rounded inner corners for return key in Keymap. Draw the return key with rounded inner corners instead of square, this builds on top of the changes made in hrev44709. The secret to rounding the corners was to draw both the edge and background of the individual sections before drawing the button's background on top minus the clipped out bottom left section. +alpha4 (optionally, purely cosmetic but shouldn't hurt) --- src/preferences/keymap/KeyboardLayoutView.cpp | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index bbe8506c47..574e1b0672 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -622,7 +622,8 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key, + (key->frame.Width() - key->second_row) * fFactor - fGap - 2); topLeft.bottom = bottomLeft.top; - topLeft.right = bottomLeft.right; + topLeft.right = bottomLeft.right + 1; + // add one to make the borders meet topRight.bottom = topLeft.bottom; topRight.left = topLeft.right; @@ -630,28 +631,48 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key, bottomRight.top = bottomLeft.top; bottomRight.left = bottomLeft.right; + // draw top left corner be_control_look->DrawButtonFrame(view, topLeft, updateRect, - 4.0f, 0.0f, 0.0f, 0.0f, base, background, + 4.0f, 0.0f, 4.0f, 0.0f, base, background, pressed ? BControlLook::B_ACTIVATED : 0, BControlLook::B_LEFT_BORDER | BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER); + be_control_look->DrawButtonBackground(view, topLeft, updateRect, + 4.0f, 0.0f, 4.0f, 0.0f, base, + pressed ? BControlLook::B_ACTIVATED : 0, + BControlLook::B_LEFT_BORDER | BControlLook::B_TOP_BORDER + | BControlLook::B_BOTTOM_BORDER); + + // draw top right corner be_control_look->DrawButtonFrame(view, topRight, updateRect, 0.0f, 4.0f, 0.0f, 0.0f, base, background, pressed ? BControlLook::B_ACTIVATED : 0, BControlLook::B_TOP_BORDER | BControlLook::B_RIGHT_BORDER); + be_control_look->DrawButtonBackground(view, topRight, updateRect, + 0.0f, 4.0f, 0.0f, 0.0f, base, + pressed ? BControlLook::B_ACTIVATED : 0, + BControlLook::B_TOP_BORDER | BControlLook::B_RIGHT_BORDER); + + // draw bottom right corner be_control_look->DrawButtonFrame(view, bottomRight, updateRect, - 0.0f, 0.0f, 0.0f, 4.0f, base, background, + 0.0f, 0.0f, 4.0f, 4.0f, base, background, + pressed ? BControlLook::B_ACTIVATED : 0, + BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER + | BControlLook::B_BOTTOM_BORDER); + be_control_look->DrawButtonBackground(view, bottomRight, updateRect, + 0.0f, 0.0f, 4.0f, 4.0f, base, pressed ? BControlLook::B_ACTIVATED : 0, BControlLook::B_LEFT_BORDER | BControlLook::B_RIGHT_BORDER | BControlLook::B_BOTTOM_BORDER); - // Clip out the bottom left corner + // clip out the bottom left corner bottomLeft.right += 1; bottomLeft.top -= 2; BRegion region(rect); region.Exclude(bottomLeft); view->ConstrainClippingRegion(®ion); + // draw the button background BRect bgRect = rect.InsetByCopy(2, 2); be_control_look->DrawButtonBackground(view, bgRect, updateRect, 4.0f, 4.0f, 0.0f, 4.0f, base, @@ -660,9 +681,11 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key, rect.left = bottomLeft.right; _GetAbbreviatedKeyLabelIfNeeded(view, rect, key, text, sizeof(text)); + // draw the button label be_control_look->DrawLabel(view, text, rect, updateRect, base, 0, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE)); + // reset the clipping region view->ConstrainClippingRegion(NULL); } } From 3a0a7215a9b83a81ee80c83537fb68becff4a546 Mon Sep 17 00:00:00 2001 From: threedeyes <3dEyes@gmail.com> Date: Tue, 23 Oct 2012 04:31:34 +0000 Subject: [PATCH 3/6] Added support for fake attributes. If necessary, you can disable support for extended attributes in the settings file. --- src/add-ons/kernel/file_systems/ntfs/Jamfile | 1 + .../kernel/file_systems/ntfs/attributes.c | 35 -- .../kernel/file_systems/ntfs/attributes.h | 3 - .../file_systems/ntfs/fake_attributes.c | 337 ++++++++++++++++++ .../file_systems/ntfs/fake_attributes.h | 39 ++ .../kernel/file_systems/ntfs/fs_func.c | 73 ++-- src/add-ons/kernel/file_systems/ntfs/ntfs.h | 1 + .../kernel/file_systems/ntfs/settings/ntfs | 1 + 8 files changed, 432 insertions(+), 58 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/ntfs/fake_attributes.c create mode 100644 src/add-ons/kernel/file_systems/ntfs/fake_attributes.h diff --git a/src/add-ons/kernel/file_systems/ntfs/Jamfile b/src/add-ons/kernel/file_systems/ntfs/Jamfile index afffa6e31c..1b61b11623 100644 --- a/src/add-ons/kernel/file_systems/ntfs/Jamfile +++ b/src/add-ons/kernel/file_systems/ntfs/Jamfile @@ -9,6 +9,7 @@ UsePrivateHeaders kernel ; KernelAddon ntfs : attributes.c + fake_attributes.c mime_table.c utils.c ntfsdir.c diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.c b/src/add-ons/kernel/file_systems/ntfs/attributes.c index c6fe2a56c8..bef6dcd11c 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.c @@ -25,41 +25,6 @@ //TODO: notify*() - -int32 kBeOSTypeCookie = 0x1234; - - -status_t -set_mime(vnode *node, const char *filename) -{ - struct ext_mime *p; - int32 namelen, ext_len; - - TRACE("set_mime - for [%s]\n", filename); - - node->mime = NULL; - - namelen = strlen(filename); - - for (p = mimes; p->extension; p++) { - ext_len = strlen(p->extension); - - if (namelen <= ext_len) - continue; - - if (filename[namelen-ext_len-1] != '.') - continue; - - if (!strcasecmp(filename + namelen - ext_len, p->extension)) - break; - } - - node->mime = p->mime; - - return B_NO_ERROR; -} - - status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) { diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.h b/src/add-ons/kernel/file_systems/ntfs/attributes.h index a485bd539a..a7d924ef81 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.h @@ -14,9 +14,6 @@ #include "ntfs.h" - -status_t set_mime(vnode *node, const char *filename); - status_t fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, uint32 type, int openMode, void** _cookie); status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie); diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c new file mode 100644 index 0000000000..517add5d57 --- /dev/null +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c @@ -0,0 +1,337 @@ +/* + Copyright 1999-2001, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ +/* fake_attributes.c + * handles mime type information for ntfs + * gets/sets mime information in vnode + */ + +#define MIME_STRING_TYPE 'MIMS' + +#include +#include + +#include +#include +#include +#include + +#include "ntfs.h" +#include "fake_attributes.h" +#include "mime_table.h" + +int32 kBeOSTypeCookie = 0x1234; + +status_t set_mime(vnode *node, const char *filename) +{ + struct ext_mime *p; + int32 namelen, ext_len; + node->mime = NULL; + namelen = strlen(filename); + + for (p=mimes; p->extension; p++) { + ext_len = strlen(p->extension); + + if (namelen <= ext_len) + continue; + + if (filename[namelen-ext_len-1] != '.') + continue; + + if (!strcasecmp(filename + namelen - ext_len, p->extension)) + break; + } + node->mime = p->mime; + return B_NO_ERROR; +} + + +status_t +fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + TRACE("fake_open_attrdir - ENTER\n"); + + LOCK_VOL(ns); + + if ((*_cookie = malloc(sizeof(uint32))) == NULL) { + result = ENOMEM; + goto exit; + } + + *(int32 *)(*_cookie) = 0; + +exit: + + TRACE("fs_open_attrdir - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + +status_t +fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + TRACE("fake_close_attrdir - ENTER\n"); + + LOCK_VOL(ns); + + *(int32 *)_cookie = 1; + + TRACE("fake_close_attrdir - EXIT\n"); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + +status_t +fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_free_attrib_dir_cookie - ENTER\n"); + + if (_cookie == NULL) { + TRACE("fake_free_attrib_dir_cookie - error:called with null cookie\n"); + result = EINVAL; + goto exit; + } + + *(int32 *)_cookie = 0x87654321; + free(_cookie); + +exit: + + TRACE("fake_free_attrib_dir_cookie - EXIT, result is %s\n", + strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + +status_t +fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_rewind_attrcookie - ENTER\n"); + + if (_cookie == NULL) { + TRACE("fake_rewind_attrcookie - error: fs_rewind_attrcookie" + "called with null cookie\n"); + result = EINVAL; + goto exit; + } + + *(uint32 *)_cookie = 0; + +exit: + + TRACE("fake_rewind_attrcookie - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +status_t +fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, + struct dirent *entry, size_t bufsize, uint32 *num) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + + int32 *cookie = (int32 *)_cookie; + + LOCK_VOL(ns); + + TRACE("fake_read_attrdir - ENTER\n"); + + *num = 0; + + if ((*cookie == 0) && (node->mime)) { + *num = 1; + + entry->d_ino = node->vnid; + entry->d_dev = ns->id; + entry->d_reclen = 10; + strcpy(entry->d_name, "BEOS:TYPE"); + } + + *cookie = 1; + + TRACE("fake_read_attrdir - EXIT\n"); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + +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\n"); + + if (strcmp(name, "BEOS:TYPE")) { + result = ENOENT; + goto exit; + } + + if (node->mime == NULL) { + result = ENOENT; + goto exit; + } + + *_cookie = &kBeOSTypeCookie; + +exit: + + TRACE("fake_open_attrib - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +status_t +fake_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie) +{ + return B_NO_ERROR; +} + + +status_t +fake_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie) +{ + return B_NO_ERROR; +} + + +status_t +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; + 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) { + result = ENOENT; + goto exit; + } + + stat->st_type = MIME_STRING_TYPE; + stat->st_size = strlen(node->mime) + 1; + +exit: + + TRACE("fake_read_attrib_stat - EXIT, result is %s\n", + strerror(result)); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + + +status_t +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; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_read_attr - ENTER\n"); + + if (_cookie != &kBeOSTypeCookie) { + result = ENOENT; + goto exit; + } + + if (node->mime == NULL) { + result = ENOENT; + goto exit; + } + + if ((pos < 0) || (pos > strlen(node->mime))) { + result = EINVAL; + goto exit; + } + + strncpy(buffer, node->mime + pos, *_length - 1); + ((char *)buffer)[*_length - 1] = 0; + *_length = strlen(buffer) + 1; + +exit: + + TRACE("fake_read_attr - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +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; +} diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h new file mode 100644 index 0000000000..c12749418a --- /dev/null +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h @@ -0,0 +1,39 @@ +/* + Copyright 1999-2001, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ +/* fake_attributes.h + * handles mime type information for ntfs + * gets/sets mime information in vnode + */ + +#ifndef NTFS_FAKE_ATTR_H_ +#define NTFS_FAKE_ATTR_H_ + +#include + +status_t set_mime(vnode *node, const char *filename); + +status_t fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, + void **_cookie); +status_t fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, + void *_cookie); +status_t fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, + void *_cookie); +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_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); +status_t fake_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, + void *cookie); +status_t fake_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *cookie, + struct stat *stat); +status_t fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, + off_t pos,void *buffer, size_t *_length); +status_t fake_write_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, + off_t pos, const void *buffer, size_t *_length); + +#endif //NTFS_FAKE_ATTR_H_ 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 fd8c6e423c..3427e4b314 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -38,6 +38,7 @@ #include #include "attributes.h" +#include "fake_attributes.h" #include "lock.h" #include "ntfs.h" #include "volume_util.h" @@ -404,6 +405,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, .state = NF_FreeClustersOutdate | NF_FreeMFTOutdate, .show_sys_files = false, .ro = false, + .fake_attrib = false, .flags = 0 }; @@ -419,6 +421,8 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, "false"), "false") != 0; 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; unload_driver_settings(handle); if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0 @@ -427,6 +431,21 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, ns->flags |= B_FS_IS_READONLY; } + if (ns->fake_attrib) { + gNTFSVnodeOps.open_attr_dir = fake_open_attrib_dir; + gNTFSVnodeOps.close_attr_dir = fake_close_attrib_dir; + 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.open_attr = fake_open_attrib; + gNTFSVnodeOps.close_attr = fake_close_attrib; + gNTFSVnodeOps.free_attr_cookie = fake_free_attrib_cookie; + gNTFSVnodeOps.read_attr = fake_read_attrib; + gNTFSVnodeOps.read_attr_stat = fake_read_attrib_stat; + gNTFSVnodeOps.write_attr = fake_write_attrib; + } + ns->ntvol = utils_mount_volume(device, mountFlags | MS_RECOVER); if (ns->ntvol != NULL) result = B_NO_ERROR; @@ -701,18 +720,19 @@ fs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type, newNode->vnid = vnid; newNode->parent_vnid = ntfs_mft_get_parent_ref(ni); - - if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(newNode, ".***"); - else { - name = (char*)malloc(MAX_PATH); - if (name != NULL) { - if (utils_inode_get_name(ni, name, MAX_PATH) == 1) - set_mime(newNode, name); - free(name); + + if (ns->fake_attrib) { + if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) + set_mime(newNode, ".***"); + else { + name = (char*)malloc(MAX_PATH); + if (name != NULL) { + if (utils_inode_get_name(ni, name, MAX_PATH) == 1) + set_mime(newNode, name); + free(name); + } } } - _node->private_node = newNode; } else result = ENOMEM; @@ -1149,7 +1169,9 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, newNode->vnid = *_vnid; newNode->parent_vnid = MREF(bi->mft_no); - set_mime(newNode, name); + + if (ns->fake_attrib) + set_mime(newNode, name); ni->flags |= FILE_ATTR_ARCHIVE; ntfs_inode_update_mbsname(bi, name, ni->mft_no); @@ -1511,7 +1533,7 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, int unameLength; int utargetLength; status_t result = B_NO_ERROR; - int fmode; + int fmode = FS_FILE_MODE; le32 securid = 0; LOCK_VOL(ns); @@ -1557,12 +1579,13 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, symnode->vnid = MREF(sym->mft_no); symnode->parent_vnid = MREF(bi->mft_no); - if (sym->mrec->flags & MFT_RECORD_IS_DIRECTORY) { - set_mime(symnode, ".***"); - fmode = FS_DIR_MODE; - } else { - set_mime(symnode, name); - fmode = FS_FILE_MODE; + if (ns->fake_attrib) { + if (sym->mrec->flags & MFT_RECORD_IS_DIRECTORY) { + set_mime(symnode, ".***"); + fmode = FS_DIR_MODE; + } else { + set_mime(symnode, name); + } } result = publish_vnode(_vol, MREF(sym->mft_no), symnode, &gNTFSVnodeOps, @@ -1655,7 +1678,9 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) newNode->vnid = vnid; newNode->parent_vnid = MREF(bi->mft_no); - set_mime(newNode, ".***"); + + if (ns->fake_attrib) + set_mime(newNode, ".***"); ni->flags |= FILE_ATTR_ARCHIVE; ntfs_inode_update_mbsname(bi, name, ni->mft_no); @@ -1761,6 +1786,13 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_CTIME); fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + + if (ns->fake_attrib) { + if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) + set_mime(file, ".***"); + else + set_mime(file, newname); + } ntfs_inode_close(dir_ni); ntfs_inode_close(ni); @@ -1769,7 +1801,8 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, ntfs_remove(_vol, parent, name); - file->parent_vnid = newparent; + file->parent_vnid = newparent; + put_vnode(_vol, file->vnid); notify_entry_moved(ns->id, parent, name, newparent, newname, ino); diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfs.h b/src/add-ons/kernel/file_systems/ntfs/ntfs.h index df87c89a9b..e26147d1e7 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfs.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfs.h @@ -119,6 +119,7 @@ typedef struct nspace { long free_mft; BOOL ro; BOOL show_sys_files; + BOOL fake_attrib; BOOL silent; BOOL force; BOOL debug; diff --git a/src/add-ons/kernel/file_systems/ntfs/settings/ntfs b/src/add-ons/kernel/file_systems/ntfs/settings/ntfs index 3a8e574252..d3f182acf0 100644 --- a/src/add-ons/kernel/file_systems/ntfs/settings/ntfs +++ b/src/add-ons/kernel/file_systems/ntfs/settings/ntfs @@ -6,3 +6,4 @@ hide_sys_files true read_only false no_atime true +fake_attributes true From ee3c8867434cd7d42c5efa26e591ab87eb484358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 23 Oct 2012 21:46:36 +0200 Subject: [PATCH 4/6] UDF: use mirror metadata file when needed * style fixes * try the mirror metadata file in case read fails on the main file --- src/add-ons/kernel/file_systems/udf/Icb.cpp | 32 ++++++++++++------- src/add-ons/kernel/file_systems/udf/Icb.h | 3 +- .../file_systems/udf/MetadataPartition.cpp | 20 ++++++++++-- .../file_systems/udf/MetadataPartition.h | 1 + 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/add-ons/kernel/file_systems/udf/Icb.cpp b/src/add-ons/kernel/file_systems/udf/Icb.cpp index faf1f9c5f2..61a91357af 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.cpp +++ b/src/add-ons/kernel/file_systems/udf/Icb.cpp @@ -183,7 +183,7 @@ void Icb::GetAccessTime(struct timespec ×pec) const { timestamp ts; - if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) + if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY) ts = _ExtendedEntry()->access_date_and_time(); else ts = _FileEntry()->access_date_and_time(); @@ -200,7 +200,7 @@ void Icb::GetModificationTime(struct timespec ×pec) const { timestamp ts; - if ((_Tag().id() == TAGID_EXTENDED_FILE_ENTRY)) + if (_Tag().id() == TAGID_EXTENDED_FILE_ENTRY) ts = _ExtendedEntry()->modification_date_and_time(); else ts = _FileEntry()->modification_date_and_time(); @@ -214,7 +214,7 @@ Icb::GetModificationTime(struct timespec ×pec) const status_t -Icb::FindBlock(uint32 logicalBlock, off_t &block) +Icb::FindBlock(uint32 logicalBlock, off_t &block, bool &recorded) { off_t pos = logicalBlock << fVolume->BlockShift(); if (uint64(pos) >= Length()) { @@ -227,9 +227,11 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) status_t status = B_OK; long_address extent; bool isEmpty = false; + recorded = false; switch (_IcbTag().descriptor_flags()) { - case ICB_DESCRIPTOR_TYPE_SHORT: { + case ICB_DESCRIPTOR_TYPE_SHORT: + { TRACE(("Icb::FindBlock: descriptor type -> short\n")); AllocationDescriptorList list(this, ShortDescriptorAccessor(fPartition)); @@ -241,7 +243,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_LONG: { + case ICB_DESCRIPTOR_TYPE_LONG: + { TRACE(("Icb::FindBlock: descriptor type -> long\n")); AllocationDescriptorList list(this); status = list.FindExtent(pos, &extent, &isEmpty); @@ -252,7 +255,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_EXTENDED: { + case ICB_DESCRIPTOR_TYPE_EXTENDED: + { TRACE(("Icb::FindBlock: descriptor type -> extended\n")); // AllocationDescriptorList list(this, ExtendedDescriptorAccessor(0)); // RETURN(_Read(list, pos, buffer, length, block)); @@ -260,7 +264,8 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) break; } - case ICB_DESCRIPTOR_TYPE_EMBEDDED: { + case ICB_DESCRIPTOR_TYPE_EMBEDDED: + { TRACE(("Icb::FindBlock: descriptor type: embedded\n")); RETURN(B_ERROR); break; @@ -275,6 +280,7 @@ Icb::FindBlock(uint32 logicalBlock, off_t &block) if (status == B_OK) { block = extent.block(); + recorded = extent.type() == EXTENT_TYPE_RECORDED; TRACE(("Icb::FindBlock: block %lld\n", block)); } return status; @@ -301,7 +307,8 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) return file_cache_read(fFileCache, NULL, pos, buffer, length); switch (_IcbTag().descriptor_flags()) { - case ICB_DESCRIPTOR_TYPE_SHORT: { + case ICB_DESCRIPTOR_TYPE_SHORT: + { TRACE(("Icb::Read: descriptor type -> short\n")); AllocationDescriptorList list(this, ShortDescriptorAccessor(fPartition)); @@ -309,14 +316,16 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) break; } - case ICB_DESCRIPTOR_TYPE_LONG: { + case ICB_DESCRIPTOR_TYPE_LONG: + { TRACE(("Icb::Read: descriptor type -> long\n")); AllocationDescriptorList list(this); RETURN(_Read(list, pos, buffer, length, block)); break; } - case ICB_DESCRIPTOR_TYPE_EXTENDED: { + case ICB_DESCRIPTOR_TYPE_EXTENDED: + { TRACE(("Icb::Read: descriptor type -> extended\n")); // AllocationDescriptorList list(this, ExtendedDescriptorAccessor(0)); // RETURN(_Read(list, pos, buffer, length, block)); @@ -324,7 +333,8 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) break; } - case ICB_DESCRIPTOR_TYPE_EMBEDDED: { + case ICB_DESCRIPTOR_TYPE_EMBEDDED: + { TRACE(("Icb::Read: descriptor type: embedded\n")); RETURN(B_ERROR); break; diff --git a/src/add-ons/kernel/file_systems/udf/Icb.h b/src/add-ons/kernel/file_systems/udf/Icb.h index fd3893a40e..ab61ae71b0 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.h +++ b/src/add-ons/kernel/file_systems/udf/Icb.h @@ -105,7 +105,8 @@ public: uint32 AllocationDescriptorsSize() { return _AbstractEntry()->AllocationDescriptorsLength(); } - status_t FindBlock(uint32 logicalBlock, off_t &block); + status_t FindBlock(uint32 logicalBlock, off_t &block, + bool &recorded); status_t Read(off_t pos, void *buffer, size_t *length, uint32 *block = NULL); diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp index 2c58a2c2a6..619a6b809c 100644 --- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp +++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.cpp @@ -31,8 +31,16 @@ MetadataPartition::MetadataPartition(Volume *volume, fMetadataIcb = new(nothrow) Icb(volume, address); if (fMetadataIcb == NULL || fMetadataIcb->InitCheck() != B_OK) fInitStatus = B_NO_MEMORY; + else + fInitStatus = B_OK; - fInitStatus = B_OK; + address.set_to(metadataMirrorFileLocation, fPartition); + + fMetadataMirrorIcb = new(nothrow) Icb(volume, address); + if (fMetadataMirrorIcb == NULL + || fMetadataMirrorIcb->InitCheck() != B_OK) { + fInitStatus = B_NO_MEMORY; + } } /*! \brief Destroys the MetadataPartition object. @@ -48,9 +56,17 @@ status_t MetadataPartition::MapBlock(uint32 logicalBlock, off_t &physicalBlock) { off_t block = 0; - status_t status = fMetadataIcb->FindBlock(logicalBlock, block); + bool isRecorded; + status_t status = fMetadataIcb->FindBlock(logicalBlock, block, isRecorded); if (status != B_OK) return status; + if (!isRecorded) { + status = fMetadataMirrorIcb->FindBlock(logicalBlock, block, isRecorded); + if (status != B_OK) + return status; + if (!isRecorded) + return B_BAD_DATA; + } return fParentPartition.MapBlock(block, physicalBlock); } diff --git a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h index 0c97bf6d1c..030ca0db12 100644 --- a/src/add-ons/kernel/file_systems/udf/MetadataPartition.h +++ b/src/add-ons/kernel/file_systems/udf/MetadataPartition.h @@ -44,6 +44,7 @@ private: bool fMetadataIsDuplicated; status_t fInitStatus; Icb *fMetadataIcb; + Icb *fMetadataMirrorIcb; }; #endif // _UDF_METADATA_PARTITION_H From 97d1235cef30c0445af4986d84671b33acb41ee9 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 23 Oct 2012 20:35:09 -0400 Subject: [PATCH 5/6] Fill in the return key rect with the background color. This eliminates artifacts that are seen when the key is drawn while being dragged. --- src/preferences/keymap/KeyboardLayoutView.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index 574e1b0672..467e6a303b 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -672,6 +672,10 @@ KeyboardLayoutView::_DrawKey(BView* view, BRect updateRect, const Key* key, region.Exclude(bottomLeft); view->ConstrainClippingRegion(®ion); + // Fill in the rect with the background color + SetHighColor(background); + FillRect(rect); + // draw the button background BRect bgRect = rect.InsetByCopy(2, 2); be_control_look->DrawButtonBackground(view, bgRect, updateRect, From 26fbc34f1b8ec7508e5809c7cbae9df27eb879ad Mon Sep 17 00:00:00 2001 From: czeidler Date: Thu, 25 Oct 2012 18:54:45 +1300 Subject: [PATCH 6/6] Max size constraints can be NULL. --- src/libs/alm/Area.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/alm/Area.cpp b/src/libs/alm/Area.cpp index 3d0a79488f..cd80cd2c83 100644 --- a/src/libs/alm/Area.cpp +++ b/src/libs/alm/Area.cpp @@ -613,8 +613,10 @@ void Area::_UpdateMaxSizeConstraint(BSize max) { if (!fLayoutItem->IsVisible()) { - fMaxContentHeight->SetRightSide(B_SIZE_UNLIMITED); - fMaxContentWidth->SetRightSide(B_SIZE_UNLIMITED); + if (fMaxContentHeight != NULL) + fMaxContentHeight->SetRightSide(B_SIZE_UNLIMITED); + if (fMaxContentWidth != NULL) + fMaxContentWidth->SetRightSide(B_SIZE_UNLIMITED); return; }