NodeMonitor: Added B_WATCH_CHILDREN flag.

* Added a directory argument for notify_{stat/attribute}_changed().
* This allows to watch only a directory, and get the notifications for
  all of its files, not just add/remove entry notifications.
This commit is contained in:
Axel Dörfler
2016-03-28 14:31:27 +02:00
parent 55f28f1396
commit 6f7fc2204b
31 changed files with 367 additions and 307 deletions
+4 -4
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _FS_INTERFACE_H #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, extern status_t notify_entry_moved(dev_t device, ino_t fromDirectory,
const char* fromName, ino_t toDirectory, const char* fromName, ino_t toDirectory,
const char* toName, ino_t node); 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); uint32 statFields);
extern status_t notify_attribute_changed(dev_t device, ino_t node, extern status_t notify_attribute_changed(dev_t device, ino_t directory,
const char* attribute, int32 cause); ino_t node, const char* attribute, int32 cause);
extern status_t notify_query_entry_created(port_id port, int32 token, extern status_t notify_query_entry_created(port_id port, int32 token,
dev_t device, ino_t directory, const char* name, dev_t device, ino_t directory, const char* name,
+2 -1
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _FS_INFO_H #ifndef _FS_INFO_H
@@ -20,6 +20,7 @@
#define B_FS_HAS_SELF_HEALING_LINKS 0x00080000 #define B_FS_HAS_SELF_HEALING_LINKS 0x00080000
#define B_FS_HAS_ALIASES 0x00100000 #define B_FS_HAS_ALIASES 0x00100000
#define B_FS_SUPPORTS_NODE_MONITORING 0x00200000 #define B_FS_SUPPORTS_NODE_MONITORING 0x00200000
#define B_FS_SUPPORTS_MONITOR_CHILDREN 0x00400000
typedef struct fs_info { typedef struct fs_info {
dev_t dev; /* volume dev_t */ dev_t dev; /* volume dev_t */
+3 -2
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _NODE_MONITOR_H #ifndef _NODE_MONITOR_H
@@ -23,7 +23,8 @@ enum {
B_WATCH_ALL = 0x000f, B_WATCH_ALL = 0x000f,
B_WATCH_MOUNT = 0x0010, B_WATCH_MOUNT = 0x0010,
B_WATCH_INTERIM_STAT = 0x0020 B_WATCH_INTERIM_STAT = 0x0020,
B_WATCH_CHILDREN = 0x0040
}; };
@@ -895,6 +895,7 @@
#define B_FS_HAS_SELF_HEALING_LINKS FSSH_B_FS_HAS_SELF_HEALING_LINKS #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_HAS_ALIASES FSSH_B_FS_HAS_ALIASES
#define B_FS_SUPPORTS_NODE_MONITORING FSSH_B_FS_SUPPORTS_NODE_MONITORING #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 #define fs_info fssh_fs_info
+1
View File
@@ -21,6 +21,7 @@
#define FSSH_B_FS_HAS_SELF_HEALING_LINKS 0x00080000 #define FSSH_B_FS_HAS_SELF_HEALING_LINKS 0x00080000
#define FSSH_B_FS_HAS_ALIASES 0x00100000 #define FSSH_B_FS_HAS_ALIASES 0x00100000
#define FSSH_B_FS_SUPPORTS_NODE_MONITORING 0x00200000 #define FSSH_B_FS_SUPPORTS_NODE_MONITORING 0x00200000
#define FSSH_B_FS_SUPPORTS_MONITOR_CHILDREN 0x00400000
typedef struct fssh_fs_info { typedef struct fssh_fs_info {
fssh_dev_t dev; /* volume dev_t */ fssh_dev_t dev; /* volume dev_t */
+4 -3
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _FSSH_FS_INTERFACE_H #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 toDirectory, const char *toName,
fssh_vnode_id node); fssh_vnode_id node);
extern fssh_status_t fssh_notify_stat_changed(fssh_mount_id device, 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, 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, extern fssh_status_t fssh_notify_query_entry_created(fssh_port_id port,
int32_t token, fssh_mount_id device, int32_t token, fssh_mount_id device,
+4 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2010, Axel Dörfler, [email protected]. * Copyright 2001-2016, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License. * This file may be used under the terms of the MIT License.
*/ */
#ifndef INODE_H #ifndef INODE_H
@@ -95,6 +95,9 @@ public:
const block_run& BlockRun() const const block_run& BlockRun() const
{ return fNode.inode_num; } { return fNode.inode_num; }
block_run& Parent() { return fNode.parent; } 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; } block_run& Attributes() { return fNode.attributes; }
Volume* GetVolume() const { return fVolume; } Volume* GetVolume() const { return fVolume; }
@@ -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. * 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. // File system flags.
info->flags = B_FS_IS_PERSISTENT | B_FS_HAS_ATTR | B_FS_HAS_MIME info->flags = B_FS_IS_PERSISTENT | B_FS_HAS_ATTR | B_FS_HAS_MIME
| (volume->IndicesNode() != NULL ? B_FS_HAS_QUERY : 0) | (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; info->io_size = BFS_IO_SIZE;
// whatever is appropriate here? // 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) if (status == B_OK)
status = transaction.Done(); status = transaction.Done();
if (status == B_OK) if (status == B_OK)
notify_stat_changed(volume->ID(), inode->ID(), mask); notify_stat_changed(volume->ID(), inode->ParentID(), inode->ID(), mask);
return status; 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() if (!inode->IsDeleted() && cookie->last_size != inode->Size()
&& system_time() > cookie->last_notification && system_time() > cookie->last_notification
+ INODE_NOTIFICATION_INTERVAL) { + 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); B_STAT_MODIFICATION_TIME | B_STAT_SIZE | B_STAT_INTERIM_UPDATE);
cookie->last_size = inode->Size(); cookie->last_size = inode->Size();
cookie->last_notification = system_time(); cookie->last_notification = system_time();
@@ -1483,7 +1484,7 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
} }
if (changedSize || changedTime) { 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) (changedTime ? B_STAT_MODIFICATION_TIME : 0)
| (changedSize ? B_STAT_SIZE : 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) { if (status == B_OK) {
status = transaction.Done(); status = transaction.Done();
if (status == B_OK) { 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); 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) if (status == B_OK)
status = transaction.Done(); status = transaction.Done();
if (status == B_OK) { if (status == B_OK) {
notify_attribute_changed(volume->ID(), inode->ID(), name, notify_attribute_changed(volume->ID(), inode->ParentID(), inode->ID(),
B_ATTR_REMOVED); name, B_ATTR_REMOVED);
} }
return status; return status;
@@ -466,7 +466,7 @@ btrfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
Inode* inode = (Inode*)_node->private_node; Inode* inode = (Inode*)_node->private_node;
if (inode->Size() != cookie->last_size) 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; delete cookie;
return B_OK; return B_OK;
@@ -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. * 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) if (status != B_OK)
return status; return status;
notify_attribute_changed(volume->ID(), inode->ID(), name, notify_attribute_changed(volume->ID(), -1, inode->ID(), name,
B_ATTR_CREATED); B_ATTR_CREATED);
} else if ((openMode & O_EXCL) == 0) { } else if ((openMode & O_EXCL) == 0) {
if (attribute->IsProtectedNamespace()) 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); status_t status = attribute->WriteAt(offset, (uint8*)buffer, _length);
if (status == B_OK) { if (status == B_OK) {
notify_attribute_changed(volume->ID(), inode->ID(), attribute->Name(), notify_attribute_changed(volume->ID(), -1, inode->ID(),
B_ATTR_CHANGED); attribute->Name(), B_ATTR_CHANGED);
} }
return status; 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); status_t status = inode->RemoveAttribute(name, true);
if (status == B_OK) { if (status == B_OK) {
notify_attribute_changed(volume->ID(), inode->ID(), name, notify_attribute_changed(volume->ID(), -1, inode->ID(), name,
B_ATTR_REMOVED); B_ATTR_REMOVED);
} }
@@ -514,7 +514,7 @@ exfat_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
Inode* inode = (Inode*)_node->private_node; Inode* inode = (Inode*)_node->private_node;
if (inode->Size() != cookie->last_size) 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; delete cookie;
return B_OK; return B_OK;
@@ -710,7 +710,7 @@ ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
if (status == B_OK) if (status == B_OK)
status = transaction.Done(); status = transaction.Done();
if (status == B_OK) if (status == B_OK)
notify_stat_changed(volume->ID(), inode->ID(), mask); notify_stat_changed(volume->ID(), -1, inode->ID(), mask);
return status; 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() if (cookie->last_size != inode->Size()
&& system_time() > cookie->last_notification && system_time() > cookie->last_notification
+ INODE_NOTIFICATION_INTERVAL) { + 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); B_STAT_MODIFICATION_TIME | B_STAT_SIZE | B_STAT_INTERIM_UPDATE);
cookie->last_size = inode->Size(); cookie->last_size = inode->Size();
cookie->last_notification = system_time(); 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; Inode* inode = (Inode*)_node->private_node;
if (inode->Size() != cookie->last_size) 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) if ((cookie->open_mode & O_NOCACHE) != 0)
inode->EnableFileCache(); inode->EnableFileCache();
+2 -2
View File
@@ -116,7 +116,7 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
diri_free(&diri); diri_free(&diri);
// TODO: figure out which stats have actually changed // 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_GID | B_STAT_SIZE | B_STAT_ACCESS_TIME
| B_STAT_MODIFICATION_TIME | B_STAT_CREATION_TIME | B_STAT_MODIFICATION_TIME | B_STAT_CREATION_TIME
| B_STAT_CHANGE_TIME); | B_STAT_CHANGE_TIME);
@@ -1025,7 +1025,7 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
// update MIME information // update MIME information
if(!(file->mode & FAT_SUBDIR)) { if(!(file->mode & FAT_SUBDIR)) {
set_mime_type(file, newname); 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); B_ATTR_CHANGED);
} }
@@ -752,7 +752,7 @@ static int googlefs_create_gen(fs_volume *_volume, fs_node *dir, const char *nam
n->attrs_indirect = iattrs; n->attrs_indirect = iattrs;
notify_entry_created(ns->nsid, dir->vnid, name, n->vnid); notify_entry_created(ns->nsid, dir->vnid, name, n->vnid);
/* dosfs doesn't do that one but I believe it should */ /* 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 */ /* give node to caller if it wants it */
if (node) if (node)
*node = n; *node = n;
@@ -1367,7 +1367,7 @@ int googlefs_open_query(fs_volume *_volume, const char *query, ulong flags,
n->attrs[0].value = &n->attrs[1].value; n->attrs[0].value = &n->attrs[1].value;
n->attrs[0].size = sizeof(int32); n->attrs[0].size = sizeof(int32);
n->attrs[0].name = "GOOGLE:order"; 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) if (err)
goto err_gn; goto err_gn;
} }
@@ -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].value = result->name;
n->attrs[i].size = strlen(result->name)+1; n->attrs[i].size = strlen(result->name)+1;
n->attrs[i].name = "META:title"; 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++; i++;
n->attrs[i].type = 'CSTR'; n->attrs[i].type = 'CSTR';
n->attrs[i].value = result->url; n->attrs[i].value = result->url;
n->attrs[i].size = strlen(result->url)+1; n->attrs[i].size = strlen(result->url)+1;
n->attrs[i].name = "META:url"; 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++; i++;
n->attrs[i].type = 'CSTR'; n->attrs[i].type = 'CSTR';
n->attrs[i].value = request->query_string; n->attrs[i].value = request->query_string;
n->attrs[i].size = strlen(request->query_string)+1; n->attrs[i].size = strlen(request->query_string)+1;
n->attrs[i].name = "META:keyw"; 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++; i++;
n->attrs[i].type = 'LONG'; n->attrs[i].type = 'LONG';
n->attrs[i].value = &result->id; n->attrs[i].value = &result->id;
n->attrs[i].size = sizeof(int32); n->attrs[i].size = sizeof(int32);
n->attrs[i].name = "GOOGLE:order"; 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++; i++;
if (result->snipset[0]) { if (result->snipset[0]) {
n->attrs[i].type = 'CSTR'; n->attrs[i].type = 'CSTR';
n->attrs[i].value = result->snipset; n->attrs[i].value = result->snipset;
n->attrs[i].size = strlen(result->snipset)+1; n->attrs[i].size = strlen(result->snipset)+1;
n->attrs[i].name = "GOOGLE:excerpt"; 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++; i++;
} }
if (result->cache_url[0]) { 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].value = result->cache_url;
n->attrs[i].size = strlen(result->cache_url)+1; n->attrs[i].size = strlen(result->cache_url)+1;
n->attrs[i].name = "GOOGLE:cache_url"; 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++; i++;
} }
if (result->similar_url[0]) { 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].value = result->similar_url;
n->attrs[i].size = strlen(result->similar_url)+1; n->attrs[i].size = strlen(result->similar_url)+1;
n->attrs[i].name = "GOOGLE:similar_url"; 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++; i++;
} }
UNLOCK(&n->l); UNLOCK(&n->l);
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -853,7 +853,7 @@ AttributeFile::RemoveAttribute(const char *name, AttributeEntry **_entry)
else else
delete entry; delete entry;
notify_attribute_changed(fVolumeID, fFileInode, name, B_ATTR_REMOVED); notify_attribute_changed(fVolumeID, -1, fFileInode, name, B_ATTR_REMOVED);
return B_OK; return B_OK;
} }
@@ -876,7 +876,7 @@ AttributeFile::AddAttribute(AttributeEntry *entry)
fEntries = newEntries; fEntries = newEntries;
fEntries[fFile->entry_count++] = entry; fEntries[fFile->entry_count++] = entry;
notify_attribute_changed(fVolumeID, fFileInode, entry->Name(), notify_attribute_changed(fVolumeID, -1, fFileInode, entry->Name(),
B_ATTR_CREATED); B_ATTR_CREATED);
return B_OK; return B_OK;
@@ -1068,7 +1068,7 @@ AttributeEntry::Write(off_t position, const void *buffer, size_t *length)
} }
memcpy(fData + position, buffer, *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); fEntry->name, B_ATTR_CHANGED);
return B_OK; return B_OK;
} }
@@ -1752,6 +1752,7 @@ overlay_read_fs_info(fs_volume *volume, struct fs_info *info)
if (result != B_OK) if (result != B_OK)
return result; return result;
info->flags &= B_FS_SUPPORTS_MONITOR_CHILDREN;
info->flags |= B_FS_HAS_MIME | B_FS_HAS_ATTR /*| B_FS_HAS_QUERY*/; info->flags |= B_FS_HAS_MIME | B_FS_HAS_ATTR /*| B_FS_HAS_QUERY*/;
return B_OK; return B_OK;
} }
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -74,8 +74,8 @@ struct overlay_dirent {
void dispose_attribute(fs_volume *volume, ino_t fileInode) void dispose_attribute(fs_volume *volume, ino_t fileInode)
{ {
notify_attribute_changed(volume->id, fileInode, name, notify_attribute_changed(volume->id, -1, fileInode,
B_ATTR_REMOVED); name, B_ATTR_REMOVED);
free(name); free(name);
free(this); free(this);
} }
@@ -547,7 +547,7 @@ OverlayInode::WriteStat(const struct stat *stat, uint32 statMask)
if (!fIsModified) if (!fIsModified)
SetModified(); SetModified();
notify_stat_changed(SuperVolume()->id, fInodeNumber, statMask); notify_stat_changed(SuperVolume()->id, -1, fInodeNumber, statMask);
return B_OK; return B_OK;
} }
@@ -843,10 +843,10 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
fStat.st_mtime = time(NULL); fStat.st_mtime = time(NULL);
if (fIsAttribute) { if (fIsAttribute) {
notify_attribute_changed(SuperVolume()->id, fInodeNumber, notify_attribute_changed(SuperVolume()->id, -1,
fName, B_ATTR_CHANGED); fInodeNumber, fName, B_ATTR_CHANGED);
} else { } else {
notify_stat_changed(SuperVolume()->id, fInodeNumber, notify_stat_changed(SuperVolume()->id, -1, fInodeNumber,
B_STAT_MODIFICATION_TIME); B_STAT_MODIFICATION_TIME);
} }
return B_OK; return B_OK;
@@ -903,10 +903,10 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
fStat.st_mtime = time(NULL); fStat.st_mtime = time(NULL);
if (fIsAttribute) { if (fIsAttribute) {
notify_attribute_changed(SuperVolume()->id, fInodeNumber, fName, notify_attribute_changed(SuperVolume()->id, -1, fInodeNumber, fName,
B_ATTR_CHANGED); B_ATTR_CHANGED);
} else { } else {
notify_stat_changed(SuperVolume()->id, fInodeNumber, notify_stat_changed(SuperVolume()->id, -1, fInodeNumber,
B_STAT_MODIFICATION_TIME | (sizeChanged ? B_STAT_SIZE : 0)); B_STAT_MODIFICATION_TIME | (sizeChanged ? B_STAT_SIZE : 0));
} }
@@ -1503,8 +1503,8 @@ OverlayInode::_CreateCommon(const char *name, int type, int perms,
*_node = node; *_node = node;
if (attribute) { if (attribute) {
notify_attribute_changed(SuperVolume()->id, fInodeNumber, entry->name, notify_attribute_changed(SuperVolume()->id, -1, fInodeNumber,
B_ATTR_CREATED); entry->name, B_ATTR_CREATED);
} else { } else {
notify_entry_created(SuperVolume()->id, fInodeNumber, entry->name, notify_entry_created(SuperVolume()->id, fInodeNumber, entry->name,
entry->inode_number); entry->inode_number);
@@ -2164,9 +2164,9 @@ overlay_rename_attr(fs_volume *volume, fs_vnode *vnode,
node->SetSuperVnode(toNode->SuperVnode()); node->SetSuperVnode(toNode->SuperVnode());
node->SetInodeNumber(toNode->InodeNumber()); node->SetInodeNumber(toNode->InodeNumber());
notify_attribute_changed(volume->id, fromNode->InodeNumber(), fromName, notify_attribute_changed(volume->id, -1, fromNode->InodeNumber(), fromName,
B_ATTR_REMOVED); B_ATTR_REMOVED);
notify_attribute_changed(volume->id, toNode->InodeNumber(), toName, notify_attribute_changed(volume->id, -1, toNode->InodeNumber(), toName,
B_ATTR_CREATED); B_ATTR_CREATED);
free(oldName); free(oldName);
@@ -2183,7 +2183,7 @@ overlay_remove_attr(fs_volume *volume, fs_vnode *vnode, const char *name)
if (result != B_OK) if (result != B_OK)
return result; return result;
notify_attribute_changed(volume->id, node->InodeNumber(), name, notify_attribute_changed(volume->id, -1, node->InodeNumber(), name,
B_ATTR_REMOVED); B_ATTR_REMOVED);
return result; return result;
} }
@@ -1694,7 +1694,7 @@ fs_wstat(fs_volume *_volume, fs_vnode *_node, const struct stat *st, uint32 mask
XDRInPacketDestroy(&reply); XDRInPacketDestroy(&reply);
XDROutPacketDestroy(&call); XDROutPacketDestroy(&call);
return notify_stat_changed(_volume->id, node->vnid, mask); return notify_stat_changed(_volume->id, -1, node->vnid, mask);
} }
static status_t static status_t
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -304,7 +304,7 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
if (!found) { if (!found) {
if (fAttrDir) { if (fAttrDir) {
notify_attribute_changed(fInode->GetFileSystem()->DevId(), notify_attribute_changed(fInode->GetFileSystem()->DevId(),
fInode->ID(), newCurrent->fName, B_ATTR_CREATED); -1, fInode->ID(), newCurrent->fName, B_ATTR_CREATED);
} else { } else {
notify_entry_created(fInode->GetFileSystem()->DevId(), notify_entry_created(fInode->GetFileSystem()->DevId(),
fInode->ID(), newCurrent->fName, newCurrent->fNode); fInode->ID(), newCurrent->fName, newCurrent->fNode);
@@ -321,7 +321,7 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
while (oldCurrent != NULL) { while (oldCurrent != NULL) {
if (fAttrDir) { if (fAttrDir) {
notify_attribute_changed(fInode->GetFileSystem()->DevId(), notify_attribute_changed(fInode->GetFileSystem()->DevId(),
fInode->ID(), oldCurrent->fName, B_ATTR_REMOVED); -1, fInode->ID(), oldCurrent->fName, B_ATTR_REMOVED);
} else { } else {
notify_entry_removed(fInode->GetFileSystem()->DevId(), fInode->ID(), notify_entry_removed(fInode->GetFileSystem()->DevId(), fInode->ID(),
oldCurrent->fName, oldCurrent->fNode); oldCurrent->fName, oldCurrent->fNode);
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -293,7 +293,7 @@ Inode::Remove(const char* name, FileType type, ino_t* id)
*id = FileIdToInoT(fileID); *id = FileIdToInoT(fileID);
if (type == NF4NAMEDATTR) { if (type == NF4NAMEDATTR) {
notify_attribute_changed(fFileSystem->DevId(), ID(), name, notify_attribute_changed(fFileSystem->DevId(), -1, ID(), name,
B_ATTR_REMOVED); B_ATTR_REMOVED);
} else { } else {
notify_entry_removed(fFileSystem->DevId(), ID(), name, 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) { if (attribute) {
notify_attribute_changed(from->fFileSystem->DevId(), from->ID(), notify_attribute_changed(from->fFileSystem->DevId(), -1, from->ID(),
fromName, B_ATTR_REMOVED); 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); B_ATTR_CREATED);
} else { } else {
notify_entry_moved(from->fFileSystem->DevId(), from->ID(), fromName, notify_entry_moved(from->fFileSystem->DevId(), from->ID(), fromName,
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -79,7 +79,7 @@ MetadataCache::GrowFile(size_t newSize)
fStatCache.st_size = max_c((off_t)newSize, fStatCache.st_size); fStatCache.st_size = max_c((off_t)newSize, fStatCache.st_size);
if (oldSize != 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); B_STAT_SIZE);
} }
} }
@@ -181,6 +181,7 @@ MetadataCache::NotifyChanges(const struct stat* oldStat,
sizeof(struct timespec) == 0)) sizeof(struct timespec) == 0))
flags |= B_STAT_MODIFICATION_TIME; flags |= B_STAT_MODIFICATION_TIME;
notify_stat_changed(fInode->GetFileSystem()->DevId(), fInode->ID(), flags); notify_stat_changed(fInode->GetFileSystem()->DevId(), -1, fInode->ID(),
flags);
} }
@@ -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)) if (ntfs_attr_truncate(na, pos + size))
size = na->data_size - pos; size = na->data_size - pos;
else 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) { while (size) {
@@ -642,7 +642,7 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if(strncmp(attr_name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 ) if(strncmp(attr_name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 )
goto exit; goto exit;
real_name = attr_name + strlen(kHaikuAttrPrefix); real_name = attr_name + strlen(kHaikuAttrPrefix);
notify_attribute_changed(ns->id, MREF(ni->mft_no), notify_attribute_changed(ns->id, -1, MREF(ni->mft_no),
real_name, B_ATTR_CHANGED); real_name, B_ATTR_CHANGED);
free(attr_name); free(attr_name);
} }
@@ -712,7 +712,8 @@ fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name)
ni->flags |= FILE_ATTR_ARCHIVE; ni->flags |= FILE_ATTR_ARCHIVE;
NInoFileNameSetDirty(ni); NInoFileNameSetDirty(ni);
} }
notify_attribute_changed(ns->id, MREF(ni->mft_no), name, B_ATTR_REMOVED); notify_attribute_changed(ns->id, -1, MREF(ni->mft_no), name,
B_ATTR_REMOVED);
exit: exit:
if (uname != NULL) if (uname != NULL)
free(uname); free(uname);
@@ -905,7 +905,7 @@ fs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st, uint32 mask)
ntfs_mark_free_space_outdated(ns); 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_data_change_time = timespec2ntfs(st->st_mtim);
ni->last_mft_change_time = timespec2ntfs(st->st_ctim); 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: exit:
@@ -1316,7 +1316,7 @@ fs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t offset,
if (ntfs_attr_truncate(na, offset + size)) if (ntfs_attr_truncate(na, offset + size))
size = na->data_size - offset; size = na->data_size - offset;
else else
notify_stat_changed(ns->id, node->vnid, B_STAT_SIZE); notify_stat_changed(ns->id, -1, node->vnid, B_STAT_SIZE);
} }
while (size) { while (size) {
@@ -1753,7 +1753,7 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name,
set_mime(file, NULL); set_mime(file, NULL);
else else
set_mime(file, newname); 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); B_ATTR_CHANGED);
} }
@@ -680,7 +680,9 @@ void
Volume::PackageLinkNodeChanged(Node* node, uint32 statFields, Volume::PackageLinkNodeChanged(Node* node, uint32 statFields,
const OldNodeAttributes& oldAttributes) 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); _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. // The new package node has become the one representing the node.
// Send stat changed notification for directories and entry // Send stat changed notification for directories and entry
// removed + created notifications for files and symlinks. // 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! // 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 // Send stat changed notification for directories and entry
// removed + created notifications for files and symlinks. // removed + created notifications for files and symlinks.
if (S_ISDIR(packageNode->Mode())) { 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! // TODO: Actually the attributes might change, too!
} else { } else {
notify_entry_removed(ID(), directory->ID(), node->Name(), notify_entry_removed(ID(), directory->ID(), node->Name(),
@@ -4,7 +4,8 @@ local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel
file_systems userlandfs ] ; file_systems userlandfs ] ;
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ; local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
UsePrivateHeaders kernel shared ; UsePrivateHeaders shared ;
UsePrivateKernelHeaders ;
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ; SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
@@ -70,7 +70,7 @@ notify_if_stat_changed(Volume *volume, Node *node)
{ {
if (volume && node && node->IsModified()) { if (volume && node && node->IsModified()) {
uint32 statFields = node->MarkUnmodified(); 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 // debugging
int32 fIteratorID; int32 fIteratorID;
int32 fGetNextCounter; int32 fGetNextCounter;
static vint32 fNextIteratorID; static int32 fNextIteratorID;
}; };
vint32 DirectoryCookie::fNextIteratorID = 0; int32 DirectoryCookie::fNextIteratorID = 0;
// ramfs_create_dir // ramfs_create_dir
@@ -1531,7 +1531,7 @@ ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
attribute->SetType(type); attribute->SetType(type);
notify_attribute_changed(volume->GetID(), node->GetID(), name, notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CREATED); B_ATTR_CREATED);
// else truncate if requested // else truncate if requested
@@ -1540,7 +1540,7 @@ ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
if (error != B_OK) if (error != B_OK)
return error; return error;
notify_attribute_changed(volume->GetID(), node->GetID(), name, notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CHANGED); B_ATTR_CHANGED);
} }
NodeMTimeUpdater mTimeUpdater(node); NodeMTimeUpdater mTimeUpdater(node);
@@ -1598,8 +1598,8 @@ ramfs_open_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
error = attribute->SetSize(0); error = attribute->SetSize(0);
if (error == B_OK) { if (error == B_OK) {
notify_attribute_changed(volume->GetID(), node->GetID(), name, notify_attribute_changed(volume->GetID(), -1, node->GetID(),
B_ATTR_CHANGED); name, B_ATTR_CHANGED);
} }
} }
NodeMTimeUpdater mTimeUpdater(node); NodeMTimeUpdater mTimeUpdater(node);
@@ -1718,7 +1718,7 @@ ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie,
// notify listeners // notify listeners
if (error == B_OK) { if (error == B_OK) {
notify_attribute_changed(volume->GetID(), node->GetID(), name, notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CHANGED); B_ATTR_CHANGED);
} }
} else } else
@@ -1797,7 +1797,7 @@ ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name)
// notify listeners // notify listeners
if (error == B_OK) { if (error == B_OK) {
notify_attribute_changed(volume->GetID(), node->GetID(), name, notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_REMOVED); B_ATTR_REMOVED);
} }
} else } else
@@ -211,8 +211,8 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request)
PRINT(("notify_stat_changed(%" B_PRId32 ", %" B_PRId64 ", " PRINT(("notify_stat_changed(%" B_PRId32 ", %" B_PRId64 ", "
"0x%" B_PRIx32 ")\n", request->device, request->node, "0x%" B_PRIx32 ")\n", request->device, request->node,
request->details)); request->details));
result = notify_stat_changed(request->device, request->node, result = notify_stat_changed(request->device,
request->details); request->directory, request->node, request->details);
break; break;
case B_ATTR_CHANGED: case B_ATTR_CHANGED:
@@ -220,7 +220,8 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request)
"\"%s\", 0x%" B_PRIx32 ")\n", request->device, "\"%s\", 0x%" B_PRIx32 ")\n", request->device,
request->node, name, (int32)request->details)); request->node, name, (int32)request->details));
result = notify_attribute_changed(request->device, result = notify_attribute_changed(request->device,
request->node, name, (int32)request->details); request->directory, request->node, name,
(int32)request->details);
break; break;
default: default:
@@ -96,23 +96,24 @@ notify_entry_moved(dev_t device, ino_t fromDirectory,
// notify_stat_changed // notify_stat_changed
status_t 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, return UserlandFS::KernelEmu::notify_listener(B_STAT_CHANGED, statFields,
device, 0, 0, node, NULL, NULL); device, 0, directory, node, NULL, NULL);
} }
// notify_attribute_changed // notify_attribute_changed
status_t status_t
notify_attribute_changed(dev_t device, ino_t node, const char *attribute, notify_attribute_changed(dev_t device, ino_t directory, ino_t node,
int32 cause) const char *attribute, int32 cause)
{ {
if (!attribute) if (!attribute)
return B_BAD_VALUE; return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_listener(B_ATTR_CHANGED, cause, return UserlandFS::KernelEmu::notify_listener(B_ATTR_CHANGED, cause,
device, 0, 0, node, NULL, attribute); device, 0, directory, node, NULL, attribute);
} }
+16 -7
View File
@@ -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. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * 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 static int32
scan_mode(void) scan_mode(void)
{ {
@@ -378,7 +387,7 @@ devfs_insert_in_dir(struct devfs_vnode* dir, struct devfs_vnode* vnode,
if (notify) { if (notify) {
notify_entry_created(sDeviceFileSystem->id, dir->id, vnode->name, notify_entry_created(sDeviceFileSystem->id, dir->id, vnode->name,
vnode->id); vnode->id);
notify_stat_changed(sDeviceFileSystem->id, dir->id, notify_stat_changed(sDeviceFileSystem->id, get_parent_id(dir), dir->id,
B_STAT_MODIFICATION_TIME); B_STAT_MODIFICATION_TIME);
} }
return B_OK; return B_OK;
@@ -407,8 +416,8 @@ devfs_remove_from_dir(struct devfs_vnode* dir, struct devfs_vnode* removeNode,
if (notify) { if (notify) {
notify_entry_removed(sDeviceFileSystem->id, dir->id, vnode->name, notify_entry_removed(sDeviceFileSystem->id, dir->id, vnode->name,
vnode->id); vnode->id);
notify_stat_changed(sDeviceFileSystem->id, dir->id, notify_stat_changed(sDeviceFileSystem->id, get_parent_id(dir),
B_STAT_MODIFICATION_TIME); dir->id, B_STAT_MODIFICATION_TIME);
} }
return B_OK; 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) if (statMask & B_STAT_CREATION_TIME)
vnode->creation_time = stat->st_crtim; 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; 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, notify_entry_moved(sDeviceFileSystem->id, device->parent->id, oldName,
device->parent->id, newName, node->id); device->parent->id, newName, node->id);
notify_stat_changed(sDeviceFileSystem->id, device->parent->id, notify_stat_changed(sDeviceFileSystem->id, get_parent_id(device->parent),
B_STAT_MODIFICATION_TIME); device->parent->id, B_STAT_MODIFICATION_TIME);
return B_OK; return B_OK;
} }
+41 -22
View File
@@ -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 2005-2008, Ingo Weinhold, bonefish@users.sf.net.
* Copyright 2010, Clemens Zeidler, haiku@clemens-zeidler.de. * 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, status_t NotifyEntryMoved(dev_t device, ino_t fromDirectory,
const char *fromName, ino_t toDirectory, const char *toName, const char *fromName, ino_t toDirectory, const char *toName,
ino_t node); ino_t node);
status_t NotifyStatChanged(dev_t device, ino_t node, uint32 statFields); status_t NotifyStatChanged(dev_t device, ino_t directory, ino_t node,
status_t NotifyAttributeChanged(dev_t device, ino_t node, uint32 statFields);
const char *attribute, int32 cause); 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 NotifyUnmount(dev_t device);
status_t NotifyMount(dev_t device, dev_t parentDevice, status_t NotifyMount(dev_t device, dev_t parentDevice,
ino_t parentDirectory); 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 // iterate through the listeners until we find one with matching flags
MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator(); MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator();
while (monitor_listener *listener = iterator.Next()) { while (monitor_listener *listener = iterator.Next()) {
if (listener->flags & flags) { if ((listener->flags & flags) == flags) {
interested_monitor_listener_list &list interested_monitor_listener_list &list
= interestedListeners[interestedListenerCount++]; = interestedListeners[interestedListenerCount++];
list.iterator = iterator; 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 // iterate through the listeners until we find one with matching flags
MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator(); MonitorListenerList::Iterator iterator = monitor->listeners.GetIterator();
while (monitor_listener *listener = iterator.Next()) { while (monitor_listener *listener = iterator.Next()) {
if (listener->flags & flags) { if ((listener->flags & flags) == flags) {
interested_monitor_listener_list &list interested_monitor_listener_list &list
= interestedListeners[interestedListenerCount++]; = interestedListeners[interestedListenerCount++];
list.iterator = iterator; list.iterator = iterator;
@@ -730,21 +731,29 @@ NodeMonitorService::NotifyEntryMoved(dev_t device, ino_t fromDirectory,
inline status_t inline status_t
NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node, NodeMonitorService::NotifyStatChanged(dev_t device, ino_t directory, ino_t node,
uint32 statFields) uint32 statFields)
{ {
RecursiveLocker locker(fRecursiveLock); 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]; interested_monitor_listener_list interestedListeners[3];
int32 interestedListenerCount = 0; int32 interestedListenerCount = 0;
uint32 watchFlag = (statFields & B_STAT_INTERIM_UPDATE) != 0
? B_WATCH_INTERIM_STAT : B_WATCH_STAT;
// ... for the volume // ... for the volume
_GetInterestedVolumeListeners(device, B_WATCH_STAT, _GetInterestedVolumeListeners(device, watchFlag, interestedListeners,
interestedListeners, interestedListenerCount); interestedListenerCount);
// ... for the node, depending on whether its an interim update or not // ... for the directory
_GetInterestedMonitorListeners(device, node, if (directory >= 0) {
(statFields & B_STAT_INTERIM_UPDATE) != 0 _GetInterestedMonitorListeners(device, directory,
? B_WATCH_INTERIM_STAT : B_WATCH_STAT, B_WATCH_CHILDREN | watchFlag,
interestedListeners, interestedListenerCount);
}
// ... and for the node
_GetInterestedMonitorListeners(device, node, watchFlag,
interestedListeners, interestedListenerCount); interestedListeners, interestedListenerCount);
if (interestedListenerCount == 0) if (interestedListenerCount == 0)
@@ -775,8 +784,8 @@ NodeMonitorService::NotifyStatChanged(dev_t device, ino_t node,
- another error code otherwise. - another error code otherwise.
*/ */
status_t status_t
NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node, NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t directory,
const char *attribute, int32 cause) ino_t node, const char *attribute, int32 cause)
{ {
if (!attribute) if (!attribute)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -789,6 +798,12 @@ NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node,
// ... for the volume // ... for the volume
_GetInterestedVolumeListeners(device, B_WATCH_ATTR, _GetInterestedVolumeListeners(device, B_WATCH_ATTR,
interestedListeners, interestedListenerCount); interestedListeners, interestedListenerCount);
// ... for the directory
if (directory >= 0) {
_GetInterestedMonitorListeners(device, directory,
B_WATCH_CHILDREN | B_WATCH_ATTR,
interestedListeners, interestedListenerCount);
}
// ... for the node // ... for the node
_GetInterestedMonitorListeners(device, node, B_WATCH_ATTR, _GetInterestedMonitorListeners(device, node, B_WATCH_ATTR,
interestedListeners, interestedListenerCount); interestedListeners, interestedListenerCount);
@@ -802,6 +817,8 @@ NodeMonitorService::NotifyAttributeChanged(dev_t device, ino_t node,
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR); message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR);
message.AddInt32("opcode", B_ATTR_CHANGED); message.AddInt32("opcode", B_ATTR_CHANGED);
message.AddInt32("device", device); message.AddInt32("device", device);
if (directory >= 0)
message.AddInt64("directory", directory);
message.AddInt64("node", node); message.AddInt64("node", node);
message.AddString("attr", attribute); message.AddString("attr", attribute);
message.AddInt32("cause", cause); // Haiku only message.AddInt32("cause", cause); // Haiku only
@@ -1155,9 +1172,11 @@ notify_entry_moved(dev_t device, ino_t fromDirectory,
- another error code otherwise. - another error code otherwise.
*/ */
status_t 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. - another error code otherwise.
*/ */
status_t status_t
notify_attribute_changed(dev_t device, ino_t node, const char *attribute, notify_attribute_changed(dev_t device, ino_t directory, ino_t node,
int32 cause) const char *attribute, int32 cause)
{ {
return sNodeMonitorService.NotifyAttributeChanged(device, node, attribute, return sNodeMonitorService.NotifyAttributeChanged(device, directory, node,
cause); attribute, cause);
} }
+15 -4
View File
@@ -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. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * 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* static struct rootfs_vnode*
rootfs_create_vnode(struct rootfs* fs, struct rootfs_vnode* parent, rootfs_create_vnode(struct rootfs* fs, struct rootfs_vnode* parent,
const char* name, int type) const char* name, int type)
@@ -264,7 +273,8 @@ rootfs_insert_in_dir(struct rootfs* fs, struct rootfs_vnode* dir,
vnode->parent = dir; vnode->parent = dir;
dir->modification_time = current_timespec(); 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; return B_OK;
} }
@@ -289,7 +299,8 @@ rootfs_remove_from_dir(struct rootfs* fs, struct rootfs_vnode* dir,
vnode->dir_next = NULL; vnode->dir_next = NULL;
dir->modification_time = current_timespec(); 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; return B_OK;
} }
} }
@@ -1057,7 +1068,7 @@ rootfs_write_stat(fs_volume* _volume, fs_vnode* _vnode, const struct stat* stat,
locker.Unlock(); 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; return B_OK;
} }
+4 -4
View File
@@ -33,16 +33,16 @@ fssh_notify_entry_moved(fssh_mount_id device, fssh_vnode_id fromDirectory,
fssh_status_t fssh_status_t
fssh_notify_stat_changed(fssh_mount_id device, fssh_vnode_id node, fssh_notify_stat_changed(fssh_mount_id device, fssh_vnode_id dir,
uint32_t statFields) fssh_vnode_id node, uint32_t statFields)
{ {
return FSSH_B_OK; return FSSH_B_OK;
} }
fssh_status_t fssh_status_t
fssh_notify_attribute_changed(fssh_mount_id device, fssh_vnode_id node, fssh_notify_attribute_changed(fssh_mount_id device, fssh_vnode_id dir,
const char *attribute, int32_t cause) fssh_vnode_id node, const char *attribute, int32_t cause)
{ {
return FSSH_B_OK; return FSSH_B_OK;
} }