diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index 2aa195d357..96b69fab04 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2014, Haiku Inc. All Rights Reserved. + * Copyright 2004-2016, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FS_INTERFACE_H @@ -358,10 +358,10 @@ extern status_t notify_entry_removed(dev_t device, ino_t directory, extern status_t notify_entry_moved(dev_t device, ino_t fromDirectory, const char* fromName, ino_t toDirectory, const char* toName, ino_t node); -extern status_t notify_stat_changed(dev_t device, ino_t node, +extern status_t notify_stat_changed(dev_t device, ino_t directory, ino_t node, uint32 statFields); -extern status_t notify_attribute_changed(dev_t device, ino_t node, - const char* attribute, int32 cause); +extern status_t notify_attribute_changed(dev_t device, ino_t directory, + ino_t node, const char* attribute, int32 cause); extern status_t notify_query_entry_created(port_id port, int32 token, dev_t device, ino_t directory, const char* name, diff --git a/headers/os/kernel/fs_info.h b/headers/os/kernel/fs_info.h index 13935ca66e..546dd45a64 100644 --- a/headers/os/kernel/fs_info.h +++ b/headers/os/kernel/fs_info.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003, Haiku Inc. All Rights Reserved. + * Copyright 2002-2016, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FS_INFO_H @@ -20,6 +20,7 @@ #define B_FS_HAS_SELF_HEALING_LINKS 0x00080000 #define B_FS_HAS_ALIASES 0x00100000 #define B_FS_SUPPORTS_NODE_MONITORING 0x00200000 +#define B_FS_SUPPORTS_MONITOR_CHILDREN 0x00400000 typedef struct fs_info { dev_t dev; /* volume dev_t */ diff --git a/headers/os/storage/NodeMonitor.h b/headers/os/storage/NodeMonitor.h index abd3832c6f..45ddfa6b68 100644 --- a/headers/os/storage/NodeMonitor.h +++ b/headers/os/storage/NodeMonitor.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Haiku Inc. All rights reserved. + * Copyright 2003-2016 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _NODE_MONITOR_H @@ -23,7 +23,8 @@ enum { B_WATCH_ALL = 0x000f, B_WATCH_MOUNT = 0x0010, - B_WATCH_INTERIM_STAT = 0x0020 + B_WATCH_INTERIM_STAT = 0x0020, + B_WATCH_CHILDREN = 0x0040 }; diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h index 1651b2a041..b7dbcfa3fb 100644 --- a/headers/private/fs_shell/fssh_api_wrapper.h +++ b/headers/private/fs_shell/fssh_api_wrapper.h @@ -895,6 +895,7 @@ #define B_FS_HAS_SELF_HEALING_LINKS FSSH_B_FS_HAS_SELF_HEALING_LINKS #define B_FS_HAS_ALIASES FSSH_B_FS_HAS_ALIASES #define B_FS_SUPPORTS_NODE_MONITORING FSSH_B_FS_SUPPORTS_NODE_MONITORING +#define B_FS_SUPPORTS_MONITOR_CHILDREN FSSH_B_FS_SUPPORTS_MONITOR_CHILDREN #define fs_info fssh_fs_info diff --git a/headers/private/fs_shell/fssh_fs_info.h b/headers/private/fs_shell/fssh_fs_info.h index 66a6b522db..2c79770b5f 100644 --- a/headers/private/fs_shell/fssh_fs_info.h +++ b/headers/private/fs_shell/fssh_fs_info.h @@ -21,6 +21,7 @@ #define FSSH_B_FS_HAS_SELF_HEALING_LINKS 0x00080000 #define FSSH_B_FS_HAS_ALIASES 0x00100000 #define FSSH_B_FS_SUPPORTS_NODE_MONITORING 0x00200000 +#define FSSH_B_FS_SUPPORTS_MONITOR_CHILDREN 0x00400000 typedef struct fssh_fs_info { fssh_dev_t dev; /* volume dev_t */ diff --git a/headers/private/fs_shell/fssh_fs_interface.h b/headers/private/fs_shell/fssh_fs_interface.h index 48dfce0545..7d2d6fcc58 100644 --- a/headers/private/fs_shell/fssh_fs_interface.h +++ b/headers/private/fs_shell/fssh_fs_interface.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2008, Haiku Inc. All Rights Reserved. + * Copyright 2004-2016, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FSSH_FS_INTERFACE_H @@ -395,9 +395,10 @@ extern fssh_status_t fssh_notify_entry_moved(fssh_mount_id device, fssh_vnode_id toDirectory, const char *toName, fssh_vnode_id node); extern fssh_status_t fssh_notify_stat_changed(fssh_mount_id device, - fssh_vnode_id node, uint32_t statFields); + fssh_vnode_id dir, fssh_vnode_id node, uint32_t statFields); extern fssh_status_t fssh_notify_attribute_changed(fssh_mount_id device, - fssh_vnode_id node, const char *attribute, int32_t cause); + fssh_vnode_id dir, fssh_vnode_id node, const char *attribute, + int32_t cause); extern fssh_status_t fssh_notify_query_entry_created(fssh_port_id port, int32_t token, fssh_mount_id device, diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index c3f1b9c23a..1a51804174 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2016, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ #ifndef INODE_H @@ -95,6 +95,9 @@ public: const block_run& BlockRun() const { return fNode.inode_num; } block_run& Parent() { return fNode.parent; } + const block_run& Parent() const { return fNode.parent; } + ino_t ParentID() const + { return fVolume->ToVnode(Parent()); } block_run& Attributes() { return fNode.attributes; } Volume* GetVolume() const { return fVolume; } diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index fe2478aa6a..dac0c51967 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2014, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2016, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ @@ -208,7 +208,8 @@ bfs_read_fs_stat(fs_volume* _volume, struct fs_info* info) // File system flags. info->flags = B_FS_IS_PERSISTENT | B_FS_HAS_ATTR | B_FS_HAS_MIME | (volume->IndicesNode() != NULL ? B_FS_HAS_QUERY : 0) - | (volume->IsReadOnly() ? B_FS_IS_READONLY : 0); + | (volume->IsReadOnly() ? B_FS_IS_READONLY : 0) + | B_FS_SUPPORTS_MONITOR_CHILDREN; info->io_size = BFS_IO_SIZE; // whatever is appropriate here? @@ -923,7 +924,7 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, if (status == B_OK) status = transaction.Done(); if (status == B_OK) - notify_stat_changed(volume->ID(), inode->ID(), mask); + notify_stat_changed(volume->ID(), inode->ParentID(), inode->ID(), mask); return status; } @@ -1397,7 +1398,7 @@ bfs_write(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos, if (!inode->IsDeleted() && cookie->last_size != inode->Size() && system_time() > cookie->last_notification + INODE_NOTIFICATION_INTERVAL) { - notify_stat_changed(volume->ID(), inode->ID(), + notify_stat_changed(volume->ID(), inode->ParentID(), inode->ID(), B_STAT_MODIFICATION_TIME | B_STAT_SIZE | B_STAT_INTERIM_UPDATE); cookie->last_size = inode->Size(); cookie->last_notification = system_time(); @@ -1483,7 +1484,7 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) } if (changedSize || changedTime) { - notify_stat_changed(volume->ID(), inode->ID(), + notify_stat_changed(volume->ID(), inode->ParentID(), inode->ID(), (changedTime ? B_STAT_MODIFICATION_TIME : 0) | (changedSize ? B_STAT_SIZE : 0)); } @@ -1890,9 +1891,11 @@ bfs_write_attr(fs_volume* _volume, fs_vnode* _file, void* _cookie, if (status == B_OK) { status = transaction.Done(); if (status == B_OK) { - notify_attribute_changed(volume->ID(), inode->ID(), cookie->name, + notify_attribute_changed(volume->ID(), inode->ParentID(), + inode->ID(), cookie->name, created ? B_ATTR_CREATED : B_ATTR_CHANGED); - notify_stat_changed(volume->ID(), inode->ID(), B_STAT_CHANGE_TIME); + notify_stat_changed(volume->ID(), inode->ParentID(), inode->ID(), + B_STAT_CHANGE_TIME); } } @@ -1956,8 +1959,8 @@ bfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char* name) if (status == B_OK) status = transaction.Done(); if (status == B_OK) { - notify_attribute_changed(volume->ID(), inode->ID(), name, - B_ATTR_REMOVED); + notify_attribute_changed(volume->ID(), inode->ParentID(), inode->ID(), + name, B_ATTR_REMOVED); } return status; diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp index 1de0f486d8..3ab3765ea0 100644 --- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp @@ -353,7 +353,7 @@ btrfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name, status = DirectoryIterator(directory).Lookup(name, strlen(name), _vnodeID); if (status != B_OK) return status; - + return get_vnode(volume->FSVolume(), *_vnodeID, NULL); } @@ -373,7 +373,7 @@ static status_t btrfs_read_stat(fs_volume* _volume, fs_vnode* _node, struct stat* stat) { Inode* inode = (Inode*)_node->private_node; - + stat->st_dev = inode->GetVolume()->ID(); stat->st_ino = inode->ID(); stat->st_nlink = 1; @@ -466,7 +466,7 @@ btrfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) Inode* inode = (Inode*)_node->private_node; if (inode->Size() != cookie->last_size) - notify_stat_changed(volume->ID(), inode->ID(), B_STAT_SIZE); + notify_stat_changed(volume->ID(), -1, inode->ID(), B_STAT_SIZE); delete cookie; return B_OK; diff --git a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp index d31d9672f5..2bfad463e9 100644 --- a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2013, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2007-2016, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -2067,7 +2067,7 @@ cdda_create_attr(fs_volume* _volume, fs_vnode* _node, const char* name, if (status != B_OK) return status; - notify_attribute_changed(volume->ID(), inode->ID(), name, + notify_attribute_changed(volume->ID(), -1, inode->ID(), name, B_ATTR_CREATED); } else if ((openMode & O_EXCL) == 0) { if (attribute->IsProtectedNamespace()) @@ -2157,8 +2157,8 @@ cdda_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie, status_t status = attribute->WriteAt(offset, (uint8*)buffer, _length); if (status == B_OK) { - notify_attribute_changed(volume->ID(), inode->ID(), attribute->Name(), - B_ATTR_CHANGED); + notify_attribute_changed(volume->ID(), -1, inode->ID(), + attribute->Name(), B_ATTR_CHANGED); } return status; } @@ -2203,7 +2203,7 @@ cdda_remove_attr(fs_volume* _volume, fs_vnode* _node, const char* name) status_t status = inode->RemoveAttribute(name, true); if (status == B_OK) { - notify_attribute_changed(volume->ID(), inode->ID(), name, + notify_attribute_changed(volume->ID(), -1, inode->ID(), name, B_ATTR_REMOVED); } diff --git a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp index 627a38bf22..517f1a2c04 100644 --- a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp @@ -421,7 +421,7 @@ static status_t exfat_read_stat(fs_volume* _volume, fs_vnode* _node, struct stat* stat) { Inode* inode = (Inode*)_node->private_node; - + stat->st_dev = inode->GetVolume()->ID(); stat->st_ino = inode->ID(); stat->st_nlink = 1; @@ -514,7 +514,7 @@ exfat_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) Inode* inode = (Inode*)_node->private_node; if (inode->Size() != cookie->last_size) - notify_stat_changed(volume->ID(), inode->ID(), B_STAT_SIZE); + notify_stat_changed(volume->ID(), -1, inode->ID(), B_STAT_SIZE); delete cookie; return B_OK; diff --git a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp index 9bdb045aab..7c16d2b434 100644 --- a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp @@ -710,7 +710,7 @@ ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, if (status == B_OK) status = transaction.Done(); if (status == B_OK) - notify_stat_changed(volume->ID(), inode->ID(), mask); + notify_stat_changed(volume->ID(), -1, inode->ID(), mask); return status; } @@ -1219,7 +1219,7 @@ ext2_write(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos, if (cookie->last_size != inode->Size() && system_time() > cookie->last_notification + INODE_NOTIFICATION_INTERVAL) { - notify_stat_changed(volume->ID(), inode->ID(), + notify_stat_changed(volume->ID(), -1, inode->ID(), B_STAT_MODIFICATION_TIME | B_STAT_SIZE | B_STAT_INTERIM_UPDATE); cookie->last_size = inode->Size(); cookie->last_notification = system_time(); @@ -1247,7 +1247,7 @@ ext2_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) Inode* inode = (Inode*)_node->private_node; if (inode->Size() != cookie->last_size) - notify_stat_changed(volume->ID(), inode->ID(), B_STAT_SIZE); + notify_stat_changed(volume->ID(), -1, inode->ID(), B_STAT_SIZE); if ((cookie->open_mode & O_NOCACHE) != 0) inode->EnableFileCache(); @@ -1449,7 +1449,7 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, status = iterator->Next(); if (status != B_OK && status != B_ENTRY_NOT_FOUND) return status; - + dirent->d_dev = volume->ID(); dirent->d_ino = id; dirent->d_reclen = sizeof(struct dirent) + length; diff --git a/src/add-ons/kernel/file_systems/fat/file.c b/src/add-ons/kernel/file_systems/fat/file.c index 77a8d2c4fa..86ab67a48d 100644 --- a/src/add-ons/kernel/file_systems/fat/file.c +++ b/src/add-ons/kernel/file_systems/fat/file.c @@ -116,7 +116,7 @@ status_t write_vnode_entry(nspace *vol, vnode *node) diri_free(&diri); // TODO: figure out which stats have actually changed - notify_stat_changed(vol->id, node->vnid, B_STAT_MODE | B_STAT_UID + notify_stat_changed(vol->id, -1, node->vnid, B_STAT_MODE | B_STAT_UID | B_STAT_GID | B_STAT_SIZE | B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME | B_STAT_CREATION_TIME | B_STAT_CHANGE_TIME); @@ -1025,7 +1025,7 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname, // update MIME information if(!(file->mode & FAT_SUBDIR)) { set_mime_type(file, newname); - notify_attribute_changed(vol->id, file->vnid, "BEOS:TYPE", + notify_attribute_changed(vol->id, -1, file->vnid, "BEOS:TYPE", B_ATTR_CHANGED); } diff --git a/src/add-ons/kernel/file_systems/googlefs/googlefs.c b/src/add-ons/kernel/file_systems/googlefs/googlefs.c index f8756bb45a..2322e51442 100644 --- a/src/add-ons/kernel/file_systems/googlefs/googlefs.c +++ b/src/add-ons/kernel/file_systems/googlefs/googlefs.c @@ -95,14 +95,14 @@ static int googlefs_publish_static_entries(fs_volume *_volume) if (err) return err; n->is_perm = 1; - + err = googlefs_create_gen(_volume, dir, "README", 0, 0444, NULL, &n, text_attrs, false, true); if (err) return err; n->is_perm = 1; n->data = readmestr; n->data_size = strlen(n->data);// + 1; - + err = googlefs_create_gen(_volume, dir, "Author", 0, 0444, NULL, &n, mailto_me_bookmark_attrs, false, true); if (err) return err; @@ -126,9 +126,9 @@ int googlefs_mount(fs_volume *_vol, const char *devname, uint32 flags, /* only allow a single mount */ if (atomic_add(&refcount, 1)) return EALREADY; - + err = load_settings(); - + err = google_request_init(); if (err) goto err_http; @@ -150,7 +150,7 @@ int googlefs_mount(fs_volume *_vol, const char *devname, uint32 flags, new_lock(&(ns->l), "googlefs main lock"); ns->nodes = NULL; - + /* create root dir */ err = B_NO_MEMORY; root = malloc(sizeof(fs_node)); @@ -164,7 +164,7 @@ int googlefs_mount(fs_volume *_vol, const char *devname, uint32 flags, root->attrs_indirect = root_folder_attrs; new_lock(&(root->l), "googlefs root dir"); TRACE((PFS "mount: root->l @ %p\n", &root->l)); - + _vol->private_volume = ns; _vol->ops = &sGoogleFSVolumeOps; *vnid = ns->rootid; @@ -199,10 +199,10 @@ status_t googlefs_unmount(fs_volume *_volume) ns->nodes = node->nlnext; /* better cache that before we free node */ googlefs_free_vnode(_volume, node); } - + // Unlike in BeOS, we need to put the reference to our root node ourselves put_vnode(_volume, ns->rootid); - + free_lock(&ns->l); vnidpool_free(ns->vnids); free(ns); @@ -338,7 +338,7 @@ int googlefs_walk(fs_volume *_volume, fs_vnode *_base, const char *file, ino_t * } else err = EINVAL; } else if (base) { /* child of dir */ - n = (fs_node *)SLL_FIND(base->children, next, + n = (fs_node *)SLL_FIND(base->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)file); if (n) { *vnid = n->vnid; @@ -397,7 +397,7 @@ int googlefs_closedir(fs_volume *_volume, fs_vnode *_node, fs_dir_cookie *cookie err = LOCK(&node->l); if (err) return err; - + SLL_REMOVE(node->opened, next, cookie); UNLOCK(&node->l); @@ -532,7 +532,7 @@ int googlefs_open(fs_volume *_volume, fs_vnode *_node, int omode, fs_file_cookie TRACE((PFS"open(%ld, %Ld, 0x%x)\n", ns->nsid, node->vnid, omode)); if (!node || !cookie) return EINVAL; - + // err = LOCK(&ns->l); // if (err) // return err; @@ -589,7 +589,7 @@ int googlefs_close(fs_volume *_volume, fs_vnode *_node, fs_file_cookie *cookie) if (err) return err; SLL_REMOVE(node->opened, next, cookie); - + all_ok: err_n_l: UNLOCK(&node->l); @@ -680,7 +680,7 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam fs_node *n; int i; TRACE((PFS"create_gen(%ld, %Ld, '%s', 0x%08lx, %c, %c)\n", ns->nsid, dir->vnid, name, omode, mkdir?'t':'f', uniq?'t':'f')); - + if (strlen(name) > GOOGLEFS_NAME_LEN-1) return ENAMETOOLONG; err = LOCK(&dir->l); @@ -689,7 +689,7 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam err = ENOTDIR; if (!S_ISDIR(dir->st.st_mode)) goto err_l; - n = (fs_node *)SLL_FIND(dir->children, next, + n = (fs_node *)SLL_FIND(dir->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)name); err = EEXIST; if (n && (omode & O_EXCL) && !uniq) /* already existing entry in there! */ @@ -703,13 +703,13 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam strncpy(newname, name, 56); newname[56] = '\0'; sprintf(newname+strlen(newname), " %05d", i); - n = (fs_node *)SLL_FIND(dir->children, next, + n = (fs_node *)SLL_FIND(dir->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)newname); } if (n && (uniq || mkdir)) /* still there! */ goto err_l; name = newname; - + if (n) { /* already exists, so return it */ if (node) *node = n; @@ -730,9 +730,9 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam strcpy(n->name, name); //n->is_perm = 1; fill_default_stat(&n->st, ns->nsid, n->vnid, (perms & ~S_IFMT) | (mkdir?S_IFDIR:S_IFREG)); - + new_lock(&(n->l), mkdir?"googlefs dir":"googlefs file"); - + err = LOCK(&ns->l); if (err) goto err_nl; @@ -752,14 +752,14 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam n->attrs_indirect = iattrs; notify_entry_created(ns->nsid, dir->vnid, name, n->vnid); /* dosfs doesn't do that one but I believe it should */ - notify_stat_changed(B_STAT_CHANGED, ns->nsid, -1); + notify_stat_changed(B_STAT_CHANGED, -1, ns->nsid, -1); /* give node to caller if it wants it */ if (node) *node = n; if (vnid) *vnid = n->vnid; goto done; - + err_insnl: SLL_REMOVE(ns->nodes, nlnext, n); err_lns: @@ -784,7 +784,7 @@ int googlefs_create(fs_volume *_volume, fs_vnode *_dir, const char *name, int om TRACE((PFS"create(%ld, %Ld, '%s', 0x%08lx)\n", ns->nsid, dir->vnid, name, omode)); /* don't let ppl mess our fs up */ return ENOSYS; - + err = googlefs_create_gen(_volume, dir, name, omode, perms, vnid, &n, NULL, false, false); if (err) return err; @@ -804,7 +804,7 @@ static int googlefs_unlink_gen(fs_volume *_volume, fs_node *dir, const char *nam return err; err = ENOENT; /* no need to check for S_ISDIR */ - n = (fs_node *)SLL_FIND(dir->children, next, + n = (fs_node *)SLL_FIND(dir->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)name); if (n) { if (n->children) @@ -887,7 +887,7 @@ static int googlefs_mkdir_gen(fs_volume *_volume, fs_vnode *_dir, const char *na fs_node *n; int i; TRACE((PFS"mkdir_gen(%ld, %Ld, '%s', 0x%08lx, %c)\n", ns->nsid, dir->vnid, name, perms, uniq?'t':'f')); - + if (strlen(name) > GOOGLEFS_NAME_LEN-1) return ENAMETOOLONG; err = LOCK(&dir->l); @@ -896,24 +896,24 @@ static int googlefs_mkdir_gen(fs_volume *_volume, fs_vnode *_dir, const char *na err = ENOTDIR; if (!S_ISDIR(dir->st.st_mode)) goto err_l; - n = (fs_node *)SLL_FIND(dir->children, next, + n = (fs_node *)SLL_FIND(dir->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)name); err = EEXIST; if (n && !uniq) /* already existing entry in there! */ goto err_l; - + strncpy(newname, name, GOOGLEFS_NAME_LEN); newname[GOOGLEFS_NAME_LEN-1] = '\0'; for (i = 1; n && i < 5000; i++) { /* uniquify the name */ //sprintf("%"#(GOOGLEFS_NAME_LEN-8)"s %05d", name, i); sprintf("%56s %05d", name, i); - n = (fs_node *)SLL_FIND(dir->children, next, + n = (fs_node *)SLL_FIND(dir->children, next, (sll_compare_func)compare_fs_node_by_name, (void *)newname); } if (n) /* still there! */ goto err_l; name = newname; - + err = ENOMEM; n = malloc(sizeof(fs_node)); if (!n) @@ -952,7 +952,7 @@ static int googlefs_mkdir_gen(fs_volume *_volume, fs_vnode *_dir, const char *na if (node) *node = n; goto done; - + err_insnl: SLL_REMOVE(ns->nodes, nlnext, n); err_lns: @@ -1066,7 +1066,7 @@ int googlefs_read_attrdir(fs_volume *_volume, fs_vnode *_node, fs_attr_dir_cooki for (i = 0; !ae && i < 10 && node->attrs[i].name; i++) if (i + count_indirect == cookie->dir_current) ae = &node->attrs[i]; - + if (ae) { TRACE((PFS "read_attrdir: giving %s\n", ae->name)); buf->d_dev = ns->nsid; @@ -1079,12 +1079,12 @@ int googlefs_read_attrdir(fs_volume *_volume, fs_vnode *_node, fs_attr_dir_cooki *num = 1; } else *num = 0; - + UNLOCK(&node->l); return B_OK; } -/* Haiku and BeOs differ in the way the handle attributes at the vfs layer. +/* Haiku and BeOs differ in the way the handle attributes at the vfs layer. BeOS uses atomic calls on the vnode, Haiku retains the open/close/read/write semantics for attributes (loosing atomicity). Here we don't care much though, open is used for both to factorize attribute lookup. <- TODO @@ -1135,7 +1135,7 @@ int googlefs_open_attr_h(fs_volume *_volume, fs_vnode *_node, const char *name, err = SLL_INSERT(node->opened, next, fc); if (err) goto err_linsert; - + *cookie = fc; err = B_OK; goto all_ok; @@ -1165,7 +1165,7 @@ int googlefs_close_attr_h(fs_volume *_volume, fs_vnode *_node, fs_file_cookie *c if (err) return err; SLL_REMOVE(node->opened, next, cookie); - + all_ok: err_n_l: UNLOCK(&node->l); @@ -1218,7 +1218,7 @@ int googlefs_read_attr(fs_volume *_volume, fs_vnode *_node, fs_file_cookie *cook return EINVAL; err = LOCK(&node->l); - + if (ae && pos < ae->size) { memcpy(buf, (char *)ae->value + pos, MIN(*len, ae->size-pos)); *len = MIN(*len, ae->size-pos); @@ -1227,7 +1227,7 @@ int googlefs_read_attr(fs_volume *_volume, fs_vnode *_node, fs_file_cookie *cook *len = 0; err = ENOENT; } - + UNLOCK(&node->l); return err; } @@ -1270,7 +1270,7 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, return EINVAL; // filter out queries that aren't for us, we don't want to trigger google searches when apps check for mails, ... :) - + err = B_NO_MEMORY; c = malloc(sizeof(fs_query_cookie)); if (!c) @@ -1300,7 +1300,7 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, goto err_qs; } } - + if (!accepted) { free(qstring); /* return an empty cookie */ @@ -1310,7 +1310,7 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, TRACE((PFS"open_query: QUERY: '%s'\n", qstring)); /* reuse query if it's not too old */ LOCK(&ns->l); - qn = SLL_FIND(ns->queries, qnext, + qn = SLL_FIND(ns->queries, qnext, (sll_compare_func)compare_fs_node_by_recent_query_string, (void *)qstring); UNLOCK(&ns->l); reused = (qn != NULL); @@ -1349,14 +1349,14 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, err = google_request_open(qstring, _volume, qn, &qn->request); if (err) goto err_gn; - + TRACE((PFS"open_query: request_open done\n")); #ifndef NO_SEARCH err = google_request_process(qn->request); if (err) goto err_gro; TRACE((PFS"open_query: request_process done\n")); - + #else /* fake entries */ for (i = 0; i < 10; i++) { @@ -1367,11 +1367,11 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags, n->attrs[0].value = &n->attrs[1].value; n->attrs[0].size = sizeof(int32); n->attrs[0].name = "GOOGLE:order"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[0].name, B_ATTR_CHANGED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[0].name, B_ATTR_CHANGED); if (err) goto err_gn; } -#endif /*NO_SEARCH*/ +#endif /*NO_SEARCH*/ // //err = google_request_close(q->request); @@ -1509,7 +1509,7 @@ int googlefs_push_result_to_query(struct google_request *request, struct google_ return EINVAL; // filter out queries that aren't for us, we don't want to trigger google searches when apps check for mails, ... :) - + /* stripped name for folder */ strncpy(ename, result->name, GOOGLEFS_NAME_LEN); ename[GOOGLEFS_NAME_LEN-1] = '\0'; @@ -1517,7 +1517,7 @@ int googlefs_push_result_to_query(struct google_request *request, struct google_ p = ename; while ((p = strchr(p, '/'))) *p++ = '_'; - + err = googlefs_create_gen(_volume, qn, ename, 0, 0644, NULL, &n, bookmark_attrs, false, true); if (err) return err; @@ -1528,32 +1528,32 @@ int googlefs_push_result_to_query(struct google_request *request, struct google_ n->attrs[i].value = result->name; n->attrs[i].size = strlen(result->name)+1; n->attrs[i].name = "META:title"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; n->attrs[i].type = 'CSTR'; n->attrs[i].value = result->url; n->attrs[i].size = strlen(result->url)+1; n->attrs[i].name = "META:url"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; n->attrs[i].type = 'CSTR'; n->attrs[i].value = request->query_string; n->attrs[i].size = strlen(request->query_string)+1; n->attrs[i].name = "META:keyw"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; n->attrs[i].type = 'LONG'; n->attrs[i].value = &result->id; n->attrs[i].size = sizeof(int32); n->attrs[i].name = "GOOGLE:order"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; if (result->snipset[0]) { n->attrs[i].type = 'CSTR'; n->attrs[i].value = result->snipset; n->attrs[i].size = strlen(result->snipset)+1; n->attrs[i].name = "GOOGLE:excerpt"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; } if (result->cache_url[0]) { @@ -1561,7 +1561,7 @@ int googlefs_push_result_to_query(struct google_request *request, struct google_ n->attrs[i].value = result->cache_url; n->attrs[i].size = strlen(result->cache_url)+1; n->attrs[i].name = "GOOGLE:cache_url"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; } if (result->similar_url[0]) { @@ -1569,7 +1569,7 @@ int googlefs_push_result_to_query(struct google_request *request, struct google_ n->attrs[i].value = result->similar_url; n->attrs[i].size = strlen(result->similar_url)+1; n->attrs[i].name = "GOOGLE:similar_url"; - notify_attribute_changed(ns->nsid, n->vnid, n->attrs[i].name, B_ATTR_CREATED); + notify_attribute_changed(ns->nsid, -1, n->vnid, n->attrs[i].name, B_ATTR_CREATED); i++; } UNLOCK(&n->l); diff --git a/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp b/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp index 201c5583ae..d12fd46143 100644 --- a/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp +++ b/src/add-ons/kernel/file_systems/layers/attribute_overlay/attribute_overlay.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010, Haiku Inc. All rights reserved. + * Copyright 2009-2016, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -853,7 +853,7 @@ AttributeFile::RemoveAttribute(const char *name, AttributeEntry **_entry) else delete entry; - notify_attribute_changed(fVolumeID, fFileInode, name, B_ATTR_REMOVED); + notify_attribute_changed(fVolumeID, -1, fFileInode, name, B_ATTR_REMOVED); return B_OK; } @@ -876,7 +876,7 @@ AttributeFile::AddAttribute(AttributeEntry *entry) fEntries = newEntries; fEntries[fFile->entry_count++] = entry; - notify_attribute_changed(fVolumeID, fFileInode, entry->Name(), + notify_attribute_changed(fVolumeID, -1, fFileInode, entry->Name(), B_ATTR_CREATED); return B_OK; @@ -1068,7 +1068,7 @@ AttributeEntry::Write(off_t position, const void *buffer, size_t *length) } memcpy(fData + position, buffer, *length); - notify_attribute_changed(fParent->VolumeID(), fParent->FileInode(), + notify_attribute_changed(fParent->VolumeID(), -1, fParent->FileInode(), fEntry->name, B_ATTR_CHANGED); return B_OK; } @@ -1752,6 +1752,7 @@ overlay_read_fs_info(fs_volume *volume, struct fs_info *info) if (result != B_OK) return result; + info->flags &= B_FS_SUPPORTS_MONITOR_CHILDREN; info->flags |= B_FS_HAS_MIME | B_FS_HAS_ATTR /*| B_FS_HAS_QUERY*/; return B_OK; } diff --git a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp index e49074ae12..93078a8c51 100644 --- a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp +++ b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009, Haiku Inc. All rights reserved. + * Copyright 2009-2016, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -74,8 +74,8 @@ struct overlay_dirent { void dispose_attribute(fs_volume *volume, ino_t fileInode) { - notify_attribute_changed(volume->id, fileInode, name, - B_ATTR_REMOVED); + notify_attribute_changed(volume->id, -1, fileInode, + name, B_ATTR_REMOVED); free(name); free(this); } @@ -547,7 +547,7 @@ OverlayInode::WriteStat(const struct stat *stat, uint32 statMask) if (!fIsModified) SetModified(); - notify_stat_changed(SuperVolume()->id, fInodeNumber, statMask); + notify_stat_changed(SuperVolume()->id, -1, fInodeNumber, statMask); return B_OK; } @@ -843,10 +843,10 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer, fStat.st_mtime = time(NULL); if (fIsAttribute) { - notify_attribute_changed(SuperVolume()->id, fInodeNumber, - fName, B_ATTR_CHANGED); + notify_attribute_changed(SuperVolume()->id, -1, + fInodeNumber, fName, B_ATTR_CHANGED); } else { - notify_stat_changed(SuperVolume()->id, fInodeNumber, + notify_stat_changed(SuperVolume()->id, -1, fInodeNumber, B_STAT_MODIFICATION_TIME); } return B_OK; @@ -903,10 +903,10 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer, fStat.st_mtime = time(NULL); if (fIsAttribute) { - notify_attribute_changed(SuperVolume()->id, fInodeNumber, fName, + notify_attribute_changed(SuperVolume()->id, -1, fInodeNumber, fName, B_ATTR_CHANGED); } else { - notify_stat_changed(SuperVolume()->id, fInodeNumber, + notify_stat_changed(SuperVolume()->id, -1, fInodeNumber, B_STAT_MODIFICATION_TIME | (sizeChanged ? B_STAT_SIZE : 0)); } @@ -1219,7 +1219,7 @@ OverlayInode::_PopulateStat() { if (fHasStat) return B_OK; - + fHasStat = true; if (fIsAttribute) { if (fName == NULL || fSuperVnode.ops->open_attr == NULL @@ -1503,8 +1503,8 @@ OverlayInode::_CreateCommon(const char *name, int type, int perms, *_node = node; if (attribute) { - notify_attribute_changed(SuperVolume()->id, fInodeNumber, entry->name, - B_ATTR_CREATED); + notify_attribute_changed(SuperVolume()->id, -1, fInodeNumber, + entry->name, B_ATTR_CREATED); } else { notify_entry_created(SuperVolume()->id, fInodeNumber, entry->name, entry->inode_number); @@ -2164,9 +2164,9 @@ overlay_rename_attr(fs_volume *volume, fs_vnode *vnode, node->SetSuperVnode(toNode->SuperVnode()); node->SetInodeNumber(toNode->InodeNumber()); - notify_attribute_changed(volume->id, fromNode->InodeNumber(), fromName, + notify_attribute_changed(volume->id, -1, fromNode->InodeNumber(), fromName, B_ATTR_REMOVED); - notify_attribute_changed(volume->id, toNode->InodeNumber(), toName, + notify_attribute_changed(volume->id, -1, toNode->InodeNumber(), toName, B_ATTR_CREATED); free(oldName); @@ -2183,7 +2183,7 @@ overlay_remove_attr(fs_volume *volume, fs_vnode *vnode, const char *name) if (result != B_OK) return result; - notify_attribute_changed(volume->id, node->InodeNumber(), name, + notify_attribute_changed(volume->id, -1, node->InodeNumber(), name, B_ATTR_REMOVED); return result; } diff --git a/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c b/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c index eab631ca2d..62ef40d6e5 100644 --- a/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c +++ b/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c @@ -1694,7 +1694,7 @@ fs_wstat(fs_volume *_volume, fs_vnode *_node, const struct stat *st, uint32 mask XDRInPacketDestroy(&reply); XDROutPacketDestroy(&call); - return notify_stat_changed(_volume->id, node->vnid, mask); + return notify_stat_changed(_volume->id, -1, node->vnid, mask); } static status_t diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index 168f54ccdf..5e9558b05a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012 Haiku, Inc. All rights reserved. + * Copyright 2012-2016 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -304,7 +304,7 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot, if (!found) { if (fAttrDir) { notify_attribute_changed(fInode->GetFileSystem()->DevId(), - fInode->ID(), newCurrent->fName, B_ATTR_CREATED); + -1, fInode->ID(), newCurrent->fName, B_ATTR_CREATED); } else { notify_entry_created(fInode->GetFileSystem()->DevId(), fInode->ID(), newCurrent->fName, newCurrent->fNode); @@ -321,7 +321,7 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot, while (oldCurrent != NULL) { if (fAttrDir) { notify_attribute_changed(fInode->GetFileSystem()->DevId(), - fInode->ID(), oldCurrent->fName, B_ATTR_REMOVED); + -1, fInode->ID(), oldCurrent->fName, B_ATTR_REMOVED); } else { notify_entry_removed(fInode->GetFileSystem()->DevId(), fInode->ID(), oldCurrent->fName, oldCurrent->fNode); diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index cb13665156..9e186fc02b 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012 Haiku, Inc. All rights reserved. + * Copyright 2012-2016 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -293,7 +293,7 @@ Inode::Remove(const char* name, FileType type, ino_t* id) *id = FileIdToInoT(fileID); if (type == NF4NAMEDATTR) { - notify_attribute_changed(fFileSystem->DevId(), ID(), name, + notify_attribute_changed(fFileSystem->DevId(), -1, ID(), name, B_ATTR_REMOVED); } else { notify_entry_removed(fFileSystem->DevId(), ID(), name, @@ -382,9 +382,9 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName, } if (attribute) { - notify_attribute_changed(from->fFileSystem->DevId(), from->ID(), + notify_attribute_changed(from->fFileSystem->DevId(), -1, from->ID(), fromName, B_ATTR_REMOVED); - notify_attribute_changed(to->fFileSystem->DevId(), to->ID(), toName, + notify_attribute_changed(to->fFileSystem->DevId(), -1, to->ID(), toName, B_ATTR_CREATED); } else { notify_entry_moved(from->fFileSystem->DevId(), from->ID(), fromName, @@ -898,7 +898,7 @@ Inode::SetDelegation(Delegation* delegation) fMetaCache.InvalidateStat(); struct stat st; Stat(&st); - fMetaCache.LockValid(); + fMetaCache.LockValid(); fDelegation = delegation; fOpenState->AcquireReference(); diff --git a/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp b/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp index 4801e8e575..cd4f479d97 100644 --- a/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012 Haiku, Inc. All rights reserved. + * Copyright 2012-2016 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -79,7 +79,7 @@ MetadataCache::GrowFile(size_t newSize) fStatCache.st_size = max_c((off_t)newSize, fStatCache.st_size); if (oldSize != fStatCache.st_size) { - notify_stat_changed(fInode->GetFileSystem()->DevId(), fInode->ID(), + notify_stat_changed(fInode->GetFileSystem()->DevId(), -1, fInode->ID(), B_STAT_SIZE); } } @@ -181,6 +181,7 @@ MetadataCache::NotifyChanges(const struct stat* oldStat, sizeof(struct timespec) == 0)) flags |= B_STAT_MODIFICATION_TIME; - notify_stat_changed(fInode->GetFileSystem()->DevId(), fInode->ID(), flags); + notify_stat_changed(fInode->GetFileSystem()->DevId(), -1, fInode->ID(), + flags); } diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.c b/src/add-ons/kernel/file_systems/ntfs/attributes.c index 0e10eba511..9e58572587 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.c @@ -63,18 +63,18 @@ fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) ni = NULL; ctx = NULL; *_cookie = cookie; - + exit: if (ctx != NULL) ntfs_attr_put_search_ctx(ctx); if (ni != NULL) ntfs_inode_close(ni); - + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); - + UNLOCK_VOL(ns); - + return result; } @@ -130,7 +130,7 @@ fs_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); - + return result; } @@ -160,18 +160,18 @@ fs_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, // it's the actual file body if (attr->name_length == 0) continue; - + name = ntfs_attr_name_get((const ntfschar *)(((char *)attr) + attr->name_offset), attr->name_length); - + if(strncmp(name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 ) { TRACE("found AT_DATA '%s' - Skip\n", name); continue; } TRACE("found AT_DATA '%s' - Found\n", name); - + real_name = name + strlen(kHaikuAttrPrefix); - + bufsize = MIN(bufsize, sizeof(struct dirent) + strlen(real_name) + 1); entry->d_ino = node->vnid; entry->d_dev = ns->id; @@ -197,7 +197,7 @@ exit: strerror(result), *num); UNLOCK_VOL(ns); - + if (result) *num = 0; else @@ -218,9 +218,9 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, int ulen; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; - status_t result = B_NO_ERROR; + status_t result = B_NO_ERROR; - if (ns->flags & B_FS_IS_READONLY) { + if (ns->flags & B_FS_IS_READONLY) { return B_READ_ONLY_DEVICE; } @@ -250,7 +250,7 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, char ntfs_attr_name[MAX_PATH] = {0}; strcat(ntfs_attr_name, kHaikuAttrPrefix); strcat(ntfs_attr_name,name); - + uname = ntfs_calloc(MAX_PATH); ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); if (ulen < 0) { @@ -261,7 +261,7 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, na = ntfs_attr_open(ni, AT_DATA, uname, ulen); if (na != NULL) { - if (ntfs_attr_truncate(na, 0)) { + if (ntfs_attr_truncate(na, 0)) { result = errno; goto exit; } @@ -278,7 +278,7 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, TRACE("%s - ntfs_attr_open: %s\n", __FUNCTION__, strerror(result)); goto exit; - } + } } if(ntfs_attr_pwrite(na, 0, sizeof(uint32), &type) < 0 ) { result = errno; @@ -356,7 +356,7 @@ fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, char ntfs_attr_name[MAX_PATH] = {0}; strcat(ntfs_attr_name, kHaikuAttrPrefix); strcat(ntfs_attr_name, name); - + uname = ntfs_calloc(MAX_PATH); ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); if (ulen < 0) { @@ -367,7 +367,7 @@ fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, na = ntfs_attr_open(ni, AT_DATA, uname, ulen); if (na != NULL) { if (openMode & O_TRUNC) { - if (ns->flags & B_FS_IS_READONLY) { + if (ns->flags & B_FS_IS_READONLY) { result = B_READ_ONLY_DEVICE; goto exit; } else { @@ -445,7 +445,7 @@ fs_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) } -status_t +status_t fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct stat *stat) { @@ -453,8 +453,8 @@ fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; ntfs_inode *ni = NULL; - ntfs_attr *na = NULL; - status_t result = B_NO_ERROR; + ntfs_attr *na = NULL; + status_t result = B_NO_ERROR; LOCK_VOL(ns); @@ -466,7 +466,7 @@ fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); if (na == NULL) { result = errno; - goto exit; + goto exit; } stat->st_type = cookie->type; @@ -476,15 +476,15 @@ exit: if (na != NULL) ntfs_attr_close(na); if (ni != NULL) - ntfs_inode_close(ni); + ntfs_inode_close(ni); UNLOCK_VOL(ns); - + return B_NO_ERROR; } -status_t +status_t fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, void *buffer, size_t *len) { @@ -505,7 +505,7 @@ fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, LOCK_VOL(ns); TRACE("%s - ENTER vnid: %d\n", __FUNCTION__, node->vnid); - + ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { result = errno; @@ -514,9 +514,9 @@ fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); if (na == NULL) { result = errno; - goto exit; - } - + goto exit; + } + pos += sizeof(uint32); // it is a named stream @@ -551,11 +551,11 @@ exit: ntfs_attr_close(na); if (ni != NULL) ntfs_inode_close(ni); - + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); - + return result; } @@ -576,8 +576,8 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, status_t result = B_NO_ERROR; TRACE("%s - ENTER vnode: %d\n", __FUNCTION__, node->vnid); - - if (ns->flags & B_FS_IS_READONLY) { + + if (ns->flags & B_FS_IS_READONLY) { return B_READ_ONLY_DEVICE; } @@ -596,8 +596,8 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); if (na == NULL) { result = errno; - goto exit; - } + goto exit; + } pos += sizeof(uint32); @@ -611,7 +611,7 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, if (ntfs_attr_truncate(na, pos + size)) size = na->data_size - pos; else - notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE); + notify_stat_changed(ns->id, -1, MREF(ni->mft_no), B_STAT_SIZE); } while (size) { @@ -636,28 +636,28 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, result = EINVAL; goto exit; } - + if (ntfs_ucstombs(na->name, na->name_len, &attr_name, 0) >= 0) { if (attr_name != NULL) { if(strncmp(attr_name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 ) goto exit; - real_name = attr_name + strlen(kHaikuAttrPrefix); - notify_attribute_changed(ns->id, MREF(ni->mft_no), + real_name = attr_name + strlen(kHaikuAttrPrefix); + notify_attribute_changed(ns->id, -1, MREF(ni->mft_no), real_name, B_ATTR_CHANGED); free(attr_name); } } - -exit: + +exit: if (na != NULL) ntfs_attr_close(na); if (ni != NULL) ntfs_inode_close(ni); - + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); - + return result; } @@ -670,18 +670,18 @@ fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name) char ntfs_attr_name[MAX_PATH]={0}; ntfschar *uname = NULL; int ulen; - ntfs_inode *ni = NULL; + ntfs_inode *ni = NULL; status_t result = B_NO_ERROR; TRACE("%s - ENTER - name: [%s]\n", __FUNCTION__, name); - + if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); - + if (node == NULL) { result = EINVAL; goto exit; @@ -691,18 +691,18 @@ fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name) if (ni == NULL) { result = errno; goto exit; - } - + } + strcat(ntfs_attr_name, kHaikuAttrPrefix); strcat(ntfs_attr_name, name); - + uname = ntfs_calloc(MAX_PATH); ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); if (ulen < 0) { result = EILSEQ; goto exit; - } - + } + if (ntfs_attr_remove(ni, AT_DATA, uname, ulen)) { result = ENOENT; goto exit; @@ -712,17 +712,18 @@ fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name) ni->flags |= FILE_ATTR_ARCHIVE; NInoFileNameSetDirty(ni); } - notify_attribute_changed(ns->id, MREF(ni->mft_no), name, B_ATTR_REMOVED); -exit: + notify_attribute_changed(ns->id, -1, MREF(ni->mft_no), name, + B_ATTR_REMOVED); +exit: if (uname != NULL) free(uname); if (ni != NULL) ntfs_inode_close(ni); - + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); - + return result; } 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 051cea64c9..3b892687a5 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -116,7 +116,7 @@ get_node_type(ntfs_inode* ni, int* _type) } -static u64 +static u64 ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) { nspace *ns = (nspace*)_vol->private_volume; @@ -124,7 +124,7 @@ ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) int uname_len; u64 ino = (u64)-1; u64 inum; - ntfs_inode *dir_ni; + ntfs_inode *dir_ni; /* Open target directory. */ dir_ni = ntfs_inode_open(ns->ntvol, parent); @@ -133,7 +133,7 @@ ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) if (uname_len < 0) { errno = EINVAL; return (ino); - } + } /* Lookup file */ inum = ntfs_inode_lookup_by_name(dir_ni, uname, uname_len); /* never return inodes 0 and 1 */ @@ -152,11 +152,11 @@ ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) } -static int +static int ntfs_remove(fs_volume *_vol, ino_t parent, const char *name) { nspace *ns = (nspace*)_vol->private_volume; - + ntfschar *uname = NULL; ntfs_inode *ni = NULL; ntfs_inode *dir_ni = NULL; @@ -193,17 +193,17 @@ ntfs_remove(fs_volume *_vol, ino_t parent, const char *name) result = EINVAL; goto exit; } - + if (ntfs_delete(ns->ntvol, (char*)NULL, ni, dir_ni, uname, uname_len)) result = EINVAL; /* ntfs_delete() always closes ni and dir_ni */ - ni = dir_ni = NULL; + ni = dir_ni = NULL; exit: if (ni != NULL) ntfs_inode_close(ni); if (dir_ni != NULL) ntfs_inode_close(dir_ni); - + free(uname); return result; } @@ -268,7 +268,7 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie) if (ntVolume->vol_name && ntVolume->vol_name[0] != '\0') strcpy(cookie->label, ntVolume->vol_name); ntfs_umount(ntVolume, true); - } + } } *_cookie = cookie; @@ -313,14 +313,14 @@ fs_get_supported_operations(partition_data* partition, uint32 mask) status_t fs_initialize(int fd, partition_id partitionID, const char* name, const char* parameterString, off_t partitionSize, disk_job_id job) -{ +{ char devpath[MAX_PATH]; status_t result = B_OK; TRACE("fs_initialize - [%s] - [%s]\n",name, parameterString); - + update_disk_device_job_progress(job, 0); - + if (ioctl(fd, B_GET_PATH_FOR_DEVICE, devpath) != 0) { result = mkntfs_main(devpath, name); if (result != 0) @@ -414,7 +414,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, 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; + gNTFSVnodeOps.remove_attr = fs_remove_attrib; } ns->ntvol = utils_mount_volume(device, mountFlags | NTFS_MNT_RECOVER); @@ -521,7 +521,7 @@ fs_rfsstat(fs_volume *_vol, struct fs_info *fss) size = (double)((10 * diskSize + divisor - 1) / divisor); snprintf(fss->volume_name, sizeof(fss->volume_name), "%g %cB NTFS Volume", - size / 10, unit); + size / 10, unit); } else fss->volume_name[i + 1] = 0; @@ -598,7 +598,7 @@ fs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid) if (newNode!=NULL) newNode->parent_vnid = baseNode->vnid; - + *_vnid = vnid; } @@ -686,7 +686,7 @@ 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 (ns->fake_attrib) { if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) set_mime(newNode, NULL); @@ -905,7 +905,7 @@ fs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st, uint32 mask) ntfs_mark_free_space_outdated(ns); - notify_stat_changed(ns->id, MREF(ni->mft_no), mask); + notify_stat_changed(ns->id, -1, MREF(ni->mft_no), mask); } } @@ -916,7 +916,7 @@ fs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st, uint32 mask) ni->last_data_change_time = timespec2ntfs(st->st_mtim); ni->last_mft_change_time = timespec2ntfs(st->st_ctim); - notify_stat_changed(ns->id, MREF(ni->mft_no), mask); + notify_stat_changed(ns->id, -1, MREF(ni->mft_no), mask); } exit: @@ -1057,9 +1057,9 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, status_t result = B_NO_ERROR; int unameLength; - if (ns->flags & B_FS_IS_READONLY) { + if (ns->flags & B_FS_IS_READONLY) { return B_READ_ONLY_DEVICE; - } + } LOCK_VOL(ns); @@ -1111,7 +1111,7 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, if (na != NULL) { if (ntfs_attr_truncate(na, 0)) result = errno; - ntfs_attr_close(na); + ntfs_attr_close(na); } else result = errno; } @@ -1121,7 +1121,7 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, ni = ntfs_create(dir_ni, securid, uname, unameLength, S_IFREG); if (ni != NULL) { ino_t vnid = MREF(ni->mft_no); - + newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode == NULL) { result = ENOMEM; @@ -1130,17 +1130,17 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, newNode->vnid = vnid; newNode->parent_vnid = dir->vnid; - + ni->flags |= FILE_ATTR_ARCHIVE; NInoSetDirty(ni); result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, S_IFREG, 0); - + if (ntfs_inode_close_in_dir(ni, dir_ni)) { result = EINVAL; goto exit; - } + } *_vnid = vnid; @@ -1151,8 +1151,8 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, set_mime(newNode, name); } - ntfs_mark_free_space_outdated(ns); - fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + 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; @@ -1163,7 +1163,7 @@ exit: *_cookie = cookie; else free(cookie); - + if (dir_ni != NULL) ntfs_inode_close(dir_ni); @@ -1316,7 +1316,7 @@ fs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t offset, if (ntfs_attr_truncate(na, offset + size)) size = na->data_size - offset; else - notify_stat_changed(ns->id, node->vnid, B_STAT_SIZE); + notify_stat_changed(ns->id, -1, node->vnid, B_STAT_SIZE); } while (size) { @@ -1504,10 +1504,10 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, int utargetLength; status_t result = B_NO_ERROR; le32 securid = const_cpu_to_le32(0); - - if (ns->flags & B_FS_IS_READONLY) { + + if (ns->flags & B_FS_IS_READONLY) { return B_READ_ONLY_DEVICE; - } + } LOCK_VOL(ns); @@ -1517,10 +1517,10 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, result = EINVAL; goto exit; } - + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); if (dir_ni == NULL) { - result = ENOENT; + result = ENOENT; goto exit; } @@ -1548,7 +1548,7 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, newNode->vnid = vnid; newNode->parent_vnid = MREF(dir_ni->mft_no); - + ni->flags |= FILE_ATTR_ARCHIVE; NInoSetDirty(ni); @@ -1556,15 +1556,15 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, S_IFREG, 0); put_vnode(_vol, vnid); - + if (ntfs_inode_close_in_dir(ni, dir_ni)) { result = EINVAL; goto exit; } - 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); + 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); } else result = errno; @@ -1630,16 +1630,16 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) ni = ntfs_create(dir_ni, securid, uname, unameLength, S_IFDIR); if (ni != NULL) { ino_t vnid = MREF(ni->mft_no); - + newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode == NULL) { result = ENOMEM; goto exit; } - + newNode->vnid = vnid; newNode->parent_vnid = MREF(dir_ni->mft_no); - + ni->flags |= FILE_ATTR_ARCHIVE; NInoSetDirty(ni); @@ -1700,51 +1700,51 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, LOCK_VOL(ns); - TRACE("NTFS:fs_rename - oldname:%s newname:%s\n", name, newname); - + TRACE("NTFS:fs_rename - oldname:%s newname:%s\n", name, newname); + inode = ntfs_inode_lookup(_vol, parent_vnid, name); if (inode == (u64)-1) { result = EINVAL; - goto exit; + goto exit; } - + /* Check whether target is present */ target_inode = ntfs_inode_lookup(_vol, newparent_vnid, newname); - + if (target_inode == (u64)-1) { ntfschar *uname = NULL; int uname_len; result = get_vnode(_vol, inode, (void**)&file); if (result != B_NO_ERROR) - goto exit; + goto exit; + - ni = ntfs_inode_open(ns->ntvol, inode); 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_vnid); if (!dir_ni) { result = EINVAL; goto exit; - } - + } + if (ntfs_link(ni, dir_ni, uname, uname_len)) { result = EINVAL; goto exit; } ni->flags |= FILE_ATTR_ARCHIVE; - + fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_CTIME); fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); @@ -1753,13 +1753,13 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, set_mime(file, NULL); else set_mime(file, newname); - notify_attribute_changed(ns->id, file->vnid, "BEOS:TYPE", + notify_attribute_changed(ns->id, -1, file->vnid, "BEOS:TYPE", B_ATTR_CHANGED); } - ntfs_inode_close(dir_ni); + ntfs_inode_close(dir_ni); ntfs_inode_close(ni); - + free(uname); ntfs_remove(_vol, parent_vnid, name); @@ -1767,10 +1767,10 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, file->parent_vnid = newparent_vnid; put_vnode(_vol, file->vnid); - + notify_entry_moved(ns->id, parent_vnid, name, newparent_vnid, newname, inode); - } else + } else result = EINVAL; exit: TRACE("fs_rename - EXIT, result is %s\n", strerror(result)); @@ -1814,13 +1814,13 @@ fs_rmdir(fs_volume *_vol, fs_vnode *_dir, const char *name) ino = ntfs_inode_lookup(_vol, dir->vnid, name); if (ino == (u64)-1) { result = EINVAL; - goto exit; - } + goto exit; + } result = get_vnode(_vol, ino, (void**)&file); if (result != B_NO_ERROR) - goto exit; - + goto exit; + ni = ntfs_inode_open(ns->ntvol, file->vnid); if (ni != NULL) { if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { @@ -1836,31 +1836,31 @@ fs_rmdir(fs_volume *_vol, fs_vnode *_dir, const char *name) result = EINVAL; goto exit; } - - + + result = ntfs_remove(_vol, dir->vnid, name); if(result != B_NO_ERROR) { goto exit; } - + notify_entry_removed(ns->id, dir->vnid, name, file->vnid); - + remove_vnode(_vol, file->vnid); - - put_vnode(_vol, ino); + + put_vnode(_vol, ino); dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); if (dir_ni != NULL) { fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); ntfs_inode_close(dir_ni); } - + ntfs_mark_free_space_outdated(ns); exit: if (ni != NULL) ntfs_inode_close(ni); - + TRACE("fs_rmdir - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); @@ -1901,13 +1901,13 @@ fs_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name) inode = ntfs_inode_lookup(_vol, dir->vnid, name); if (inode == (u64)-1) { result = EINVAL; - goto exit; - } + goto exit; + } result = get_vnode(_vol, inode, (void**)&file); if (result != B_NO_ERROR) - goto exit; - + goto exit; + result = ntfs_remove(_vol, dir->vnid, name); if(result != B_NO_ERROR) { goto exit; @@ -1917,7 +1917,7 @@ fs_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name) remove_vnode(_vol, file->vnid); - put_vnode(_vol, inode); + put_vnode(_vol, inode); dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); if (dir_ni != NULL) { @@ -1926,7 +1926,7 @@ fs_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name) } ntfs_mark_free_space_outdated(ns); - + exit: TRACE("fs_unlink - EXIT, result is %s\n", strerror(result)); diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp index 7007d007ef..b8949b450f 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -680,7 +680,9 @@ void Volume::PackageLinkNodeChanged(Node* node, uint32 statFields, const OldNodeAttributes& oldAttributes) { - notify_stat_changed(ID(), node->ID(), statFields); + Directory* parent = node->Parent(); + notify_stat_changed(ID(), parent != NULL ? parent->ID() : -1, node->ID(), + statFields); _NotifyNodeChanged(node, statFields, oldAttributes); } @@ -1261,7 +1263,8 @@ Volume::_AddPackageNode(Directory* directory, PackageNode* packageNode, // The new package node has become the one representing the node. // Send stat changed notification for directories and entry // removed + created notifications for files and symlinks. - notify_stat_changed(ID(), node->ID(), kAllStatFields); + notify_stat_changed(ID(), directory->ID(), node->ID(), + kAllStatFields); // TODO: Actually the attributes might change, too! } } @@ -1356,7 +1359,8 @@ Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode, // Send stat changed notification for directories and entry // removed + created notifications for files and symlinks. if (S_ISDIR(packageNode->Mode())) { - notify_stat_changed(ID(), node->ID(), kAllStatFields); + notify_stat_changed(ID(), directory->ID(), node->ID(), + kAllStatFields); // TODO: Actually the attributes might change, too! } else { notify_entry_removed(ID(), directory->ID(), node->Name(), diff --git a/src/add-ons/kernel/file_systems/ramfs/Jamfile b/src/add-ons/kernel/file_systems/ramfs/Jamfile index 33bc97b911..5cf9133c31 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Jamfile +++ b/src/add-ons/kernel/file_systems/ramfs/Jamfile @@ -4,7 +4,8 @@ local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems userlandfs ] ; local userlandFSIncludes = [ PrivateHeaders userlandfs ] ; -UsePrivateHeaders kernel shared ; +UsePrivateHeaders shared ; +UsePrivateKernelHeaders ; SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ; diff --git a/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp index 2bf4e8178c..64427a095e 100644 --- a/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp @@ -70,7 +70,7 @@ notify_if_stat_changed(Volume *volume, Node *node) { if (volume && node && node->IsModified()) { uint32 statFields = node->MarkUnmodified(); - notify_stat_changed(volume->GetID(), node->GetID(), statFields); + notify_stat_changed(volume->GetID(), -1, node->GetID(), statFields); } } @@ -1093,11 +1093,11 @@ private: // debugging int32 fIteratorID; int32 fGetNextCounter; - static vint32 fNextIteratorID; + static int32 fNextIteratorID; }; -vint32 DirectoryCookie::fNextIteratorID = 0; +int32 DirectoryCookie::fNextIteratorID = 0; // ramfs_create_dir @@ -1531,7 +1531,7 @@ ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name, attribute->SetType(type); - notify_attribute_changed(volume->GetID(), node->GetID(), name, + notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, B_ATTR_CREATED); // else truncate if requested @@ -1540,7 +1540,7 @@ ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name, if (error != B_OK) return error; - notify_attribute_changed(volume->GetID(), node->GetID(), name, + notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, B_ATTR_CHANGED); } NodeMTimeUpdater mTimeUpdater(node); @@ -1598,8 +1598,8 @@ ramfs_open_attr(fs_volume* _volume, fs_vnode* _node, const char *name, error = attribute->SetSize(0); if (error == B_OK) { - notify_attribute_changed(volume->GetID(), node->GetID(), name, - B_ATTR_CHANGED); + notify_attribute_changed(volume->GetID(), -1, node->GetID(), + name, B_ATTR_CHANGED); } } NodeMTimeUpdater mTimeUpdater(node); @@ -1718,7 +1718,7 @@ ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie, // notify listeners if (error == B_OK) { - notify_attribute_changed(volume->GetID(), node->GetID(), name, + notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, B_ATTR_CHANGED); } } else @@ -1797,7 +1797,7 @@ ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name) // notify listeners if (error == B_OK) { - notify_attribute_changed(volume->GetID(), node->GetID(), name, + notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, B_ATTR_REMOVED); } } else diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp index d038f24066..6bfc4fb225 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp @@ -211,8 +211,8 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request) PRINT(("notify_stat_changed(%" B_PRId32 ", %" B_PRId64 ", " "0x%" B_PRIx32 ")\n", request->device, request->node, request->details)); - result = notify_stat_changed(request->device, request->node, - request->details); + result = notify_stat_changed(request->device, + request->directory, request->node, request->details); break; case B_ATTR_CHANGED: @@ -220,7 +220,8 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request) "\"%s\", 0x%" B_PRIx32 ")\n", request->device, request->node, name, (int32)request->details)); result = notify_attribute_changed(request->device, - request->node, name, (int32)request->details); + request->directory, request->node, name, + (int32)request->details); break; default: diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp index 48b37243f1..62e8c46aed 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp @@ -96,23 +96,24 @@ notify_entry_moved(dev_t device, ino_t fromDirectory, // notify_stat_changed status_t -notify_stat_changed(dev_t device, ino_t node, uint32 statFields) +notify_stat_changed(dev_t device, ino_t directory, ino_t node, + uint32 statFields) { return UserlandFS::KernelEmu::notify_listener(B_STAT_CHANGED, statFields, - device, 0, 0, node, NULL, NULL); + device, 0, directory, node, NULL, NULL); } // notify_attribute_changed status_t -notify_attribute_changed(dev_t device, ino_t node, const char *attribute, - int32 cause) +notify_attribute_changed(dev_t device, ino_t directory, ino_t node, + const char *attribute, int32 cause) { if (!attribute) return B_BAD_VALUE; return UserlandFS::KernelEmu::notify_listener(B_ATTR_CHANGED, cause, - device, 0, 0, node, NULL, attribute); + device, 0, directory, node, NULL, attribute); } diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index af6c7f7a89..c0139f3fe3 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2016, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -196,6 +196,15 @@ current_timespec() } +static ino_t +get_parent_id(struct devfs_vnode* vnode) +{ + if (vnode->parent != NULL) + return vnode->parent->id; + return -1; +} + + static int32 scan_mode(void) { @@ -378,7 +387,7 @@ devfs_insert_in_dir(struct devfs_vnode* dir, struct devfs_vnode* vnode, if (notify) { notify_entry_created(sDeviceFileSystem->id, dir->id, vnode->name, vnode->id); - notify_stat_changed(sDeviceFileSystem->id, dir->id, + notify_stat_changed(sDeviceFileSystem->id, get_parent_id(dir), dir->id, B_STAT_MODIFICATION_TIME); } return B_OK; @@ -407,8 +416,8 @@ devfs_remove_from_dir(struct devfs_vnode* dir, struct devfs_vnode* removeNode, if (notify) { notify_entry_removed(sDeviceFileSystem->id, dir->id, vnode->name, vnode->id); - notify_stat_changed(sDeviceFileSystem->id, dir->id, - B_STAT_MODIFICATION_TIME); + notify_stat_changed(sDeviceFileSystem->id, get_parent_id(dir), + dir->id, B_STAT_MODIFICATION_TIME); } return B_OK; } @@ -1833,7 +1842,7 @@ devfs_write_stat(fs_volume* _volume, fs_vnode* _vnode, const struct stat* stat, if (statMask & B_STAT_CREATION_TIME) vnode->creation_time = stat->st_crtim; - notify_stat_changed(fs->id, vnode->id, statMask); + notify_stat_changed(fs->id, get_parent_id(vnode), vnode->id, statMask); return B_OK; } @@ -2081,8 +2090,8 @@ devfs_rename_partition(const char* devicePath, const char* oldName, notify_entry_moved(sDeviceFileSystem->id, device->parent->id, oldName, device->parent->id, newName, node->id); - notify_stat_changed(sDeviceFileSystem->id, device->parent->id, - B_STAT_MODIFICATION_TIME); + notify_stat_changed(sDeviceFileSystem->id, get_parent_id(device->parent), + device->parent->id, B_STAT_MODIFICATION_TIME); return B_OK; } diff --git a/src/system/kernel/fs/node_monitor.cpp b/src/system/kernel/fs/node_monitor.cpp index 95f16411b8..a953e755c6 100644 --- a/src/system/kernel/fs/node_monitor.cpp +++ b/src/system/kernel/fs/node_monitor.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2016, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2005-2008, Ingo Weinhold, bonefish@users.sf.net. * Copyright 2010, Clemens Zeidler, haiku@clemens-zeidler.de. * @@ -97,9 +97,10 @@ class NodeMonitorService : public NotificationService { status_t NotifyEntryMoved(dev_t device, ino_t fromDirectory, const char *fromName, ino_t toDirectory, const char *toName, ino_t node); - status_t NotifyStatChanged(dev_t device, ino_t node, uint32 statFields); - status_t NotifyAttributeChanged(dev_t device, ino_t node, - const char *attribute, int32 cause); + status_t NotifyStatChanged(dev_t device, ino_t directory, ino_t node, + uint32 statFields); + status_t NotifyAttributeChanged(dev_t device, ino_t directory, + ino_t node, const char *attribute, int32 cause); status_t NotifyUnmount(dev_t device); status_t NotifyMount(dev_t device, dev_t parentDevice, ino_t parentDirectory); @@ -547,7 +548,7 @@ NodeMonitorService::_GetInterestedMonitorListeners(dev_t device, ino_t node, // iterate through the listeners until we find one with matching flags MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator(); while (monitor_listener *listener = iterator.Next()) { - if (listener->flags & flags) { + if ((listener->flags & flags) == flags) { interested_monitor_listener_list &list = interestedListeners[interestedListenerCount++]; list.iterator = iterator; @@ -571,7 +572,7 @@ NodeMonitorService::_GetInterestedVolumeListeners(dev_t device, uint32 flags, // iterate through the listeners until we find one with matching flags MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator(); while (monitor_listener *listener = iterator.Next()) { - if (listener->flags & flags) { + if ((listener->flags & flags) == flags) { interested_monitor_listener_list &list = interestedListeners[interestedListenerCount++]; list.iterator = iterator; @@ -730,21 +731,29 @@ NodeMonitorService::NotifyEntryMoved(dev_t device, ino_t fromDirectory, inline status_t -NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node, +NodeMonitorService::NotifyStatChanged(dev_t device, ino_t directory, ino_t node, uint32 statFields) { RecursiveLocker locker(fRecursiveLock); - // get the lists of all interested listeners + // get the lists of all interested listeners depending on whether its an + // interim update or not interested_monitor_listener_list interestedListeners[3]; int32 interestedListenerCount = 0; + uint32 watchFlag = (statFields & B_STAT_INTERIM_UPDATE) != 0 + ? B_WATCH_INTERIM_STAT : B_WATCH_STAT; + // ... for the volume - _GetInterestedVolumeListeners(device, B_WATCH_STAT, - interestedListeners, interestedListenerCount); - // ... for the node, depending on whether its an interim update or not - _GetInterestedMonitorListeners(device, node, - (statFields & B_STAT_INTERIM_UPDATE) != 0 - ? B_WATCH_INTERIM_STAT : B_WATCH_STAT, + _GetInterestedVolumeListeners(device, watchFlag, interestedListeners, + interestedListenerCount); + // ... for the directory + if (directory >= 0) { + _GetInterestedMonitorListeners(device, directory, + B_WATCH_CHILDREN | watchFlag, + interestedListeners, interestedListenerCount); + } + // ... and for the node + _GetInterestedMonitorListeners(device, node, watchFlag, interestedListeners, interestedListenerCount); if (interestedListenerCount == 0) @@ -775,8 +784,8 @@ NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node, - another error code otherwise. */ status_t -NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node, - const char *attribute, int32 cause) +NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t directory, + ino_t node, const char *attribute, int32 cause) { if (!attribute) return B_BAD_VALUE; @@ -789,6 +798,12 @@ NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node, // ... for the volume _GetInterestedVolumeListeners(device, B_WATCH_ATTR, interestedListeners, interestedListenerCount); + // ... for the directory + if (directory >= 0) { + _GetInterestedMonitorListeners(device, directory, + B_WATCH_CHILDREN | B_WATCH_ATTR, + interestedListeners, interestedListenerCount); + } // ... for the node _GetInterestedMonitorListeners(device, node, B_WATCH_ATTR, interestedListeners, interestedListenerCount); @@ -802,6 +817,8 @@ NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node, message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR); message.AddInt32("opcode", B_ATTR_CHANGED); message.AddInt32("device", device); + if (directory >= 0) + message.AddInt64("directory", directory); message.AddInt64("node", node); message.AddString("attr", attribute); message.AddInt32("cause", cause); // Haiku only @@ -1155,9 +1172,11 @@ notify_entry_moved(dev_t device, ino_t fromDirectory, - another error code otherwise. */ status_t -notify_stat_changed(dev_t device, ino_t node, uint32 statFields) +notify_stat_changed(dev_t device, ino_t directory, ino_t node, + uint32 statFields) { - return sNodeMonitorService.NotifyStatChanged(device, node, statFields); + return sNodeMonitorService.NotifyStatChanged(device, directory, node, + statFields); } @@ -1172,11 +1191,11 @@ notify_stat_changed(dev_t device, ino_t node, uint32 statFields) - another error code otherwise. */ status_t -notify_attribute_changed(dev_t device, ino_t node, const char *attribute, - int32 cause) +notify_attribute_changed(dev_t device, ino_t directory, ino_t node, + const char *attribute, int32 cause) { - return sNodeMonitorService.NotifyAttributeChanged(device, node, attribute, - cause); + return sNodeMonitorService.NotifyAttributeChanged(device, directory, node, + attribute, cause); } diff --git a/src/system/kernel/fs/rootfs.cpp b/src/system/kernel/fs/rootfs.cpp index 2dbd5b1112..21214fa3f8 100644 --- a/src/system/kernel/fs/rootfs.cpp +++ b/src/system/kernel/fs/rootfs.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2016, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -149,6 +149,15 @@ current_timespec() } +static ino_t +get_parent_id(struct rootfs_vnode* vnode) +{ + if (vnode->parent != NULL) + return vnode->parent->id; + return -1; +} + + static struct rootfs_vnode* rootfs_create_vnode(struct rootfs* fs, struct rootfs_vnode* parent, const char* name, int type) @@ -264,7 +273,8 @@ rootfs_insert_in_dir(struct rootfs* fs, struct rootfs_vnode* dir, vnode->parent = dir; dir->modification_time = current_timespec(); - notify_stat_changed(fs->id, dir->id, B_STAT_MODIFICATION_TIME); + notify_stat_changed(fs->id, get_parent_id(dir), dir->id, + B_STAT_MODIFICATION_TIME); return B_OK; } @@ -289,7 +299,8 @@ rootfs_remove_from_dir(struct rootfs* fs, struct rootfs_vnode* dir, vnode->dir_next = NULL; dir->modification_time = current_timespec(); - notify_stat_changed(fs->id, dir->id, B_STAT_MODIFICATION_TIME); + notify_stat_changed(fs->id, get_parent_id(dir), dir->id, + B_STAT_MODIFICATION_TIME); return B_OK; } } @@ -1057,7 +1068,7 @@ rootfs_write_stat(fs_volume* _volume, fs_vnode* _vnode, const struct stat* stat, locker.Unlock(); - notify_stat_changed(fs->id, vnode->id, statMask); + notify_stat_changed(fs->id, get_parent_id(vnode), vnode->id, statMask); return B_OK; } diff --git a/src/tools/fs_shell/node_monitor.cpp b/src/tools/fs_shell/node_monitor.cpp index daa604da6b..f15aa9ec37 100644 --- a/src/tools/fs_shell/node_monitor.cpp +++ b/src/tools/fs_shell/node_monitor.cpp @@ -33,16 +33,16 @@ fssh_notify_entry_moved(fssh_mount_id device, fssh_vnode_id fromDirectory, fssh_status_t -fssh_notify_stat_changed(fssh_mount_id device, fssh_vnode_id node, - uint32_t statFields) +fssh_notify_stat_changed(fssh_mount_id device, fssh_vnode_id dir, + fssh_vnode_id node, uint32_t statFields) { return FSSH_B_OK; } fssh_status_t -fssh_notify_attribute_changed(fssh_mount_id device, fssh_vnode_id node, - const char *attribute, int32_t cause) +fssh_notify_attribute_changed(fssh_mount_id device, fssh_vnode_id dir, + fssh_vnode_id node, const char *attribute, int32_t cause) { return FSSH_B_OK; }