From <suhelmehta@xxxxxxxxxxx>:
suhelmehta@xxxxxxxxxxx has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/2344 ;)
Change subject: Making of ufs file system
......................................................................
Making of ufs file system
kernel_interface.cpp and system_dependencies file created.
---
M src/add-ons/kernel/file_systems/Jamfile
A src/add-ons/kernel/file_systems/ufs2/Jamfile
A src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
A src/add-ons/kernel/file_systems/ufs2/system_dependencies.h
M src/tests/add-ons/kernel/file_systems/Jamfile
A src/tests/add-ons/kernel/file_systems/ufs2/Jamfile
A src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
7 files changed, 712 insertions(+), 0 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/44/2344/1
diff --git a/src/add-ons/kernel/file_systems/Jamfile
b/src/add-ons/kernel/file_systems/Jamfile
index 7ac800a..22053c6 100644
--- a/src/add-ons/kernel/file_systems/Jamfile
+++ b/src/add-ons/kernel/file_systems/Jamfile
@@ -20,5 +20,6 @@
SubInclude HAIKU_TOP src add-ons kernel file_systems udf ;
SubInclude HAIKU_TOP src add-ons kernel file_systems userlandfs ;
SubInclude HAIKU_TOP src add-ons kernel file_systems xfs ;
+SubInclude HAIKU_TOP src add-ons kernel file_systems ufs2 ;
SubInclude HAIKU_TOP src add-ons kernel file_systems layers ;
diff --git a/src/add-ons/kernel/file_systems/ufs2/Jamfile
b/src/add-ons/kernel/file_systems/ufs2/Jamfile
new file mode 100644
index 0000000..83b3568
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/ufs2/Jamfile
@@ -0,0 +1,37 @@
+SubDir HAIKU_TOP src add-ons kernel file_systems ufs2 ;
+
+# set some additional defines
+{
+ local defines =
+ UFS2_DEBUGGER_COMMANDS
+ ;
+
+ defines = [ FDefines $(defines) ] ;
+ SubDirCcFlags $(defines) ;
+ SubDirC++Flags $(defines) ;
+}
+
+UsePrivateHeaders [ FDirName kernel util ] ;
+UsePrivateHeaders shared storage file_systems ;
+UsePrivateKernelHeaders ;
+
+DEFINES += DEBUG_APP="\\\"ufs2\\\"" ;
+
+UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
+
+local ufs2Sources =
+ kernel_cpp.cpp
+ kernel_interface.cpp
+ ;
+KernelAddon ufs2 :
+ $(ufs2Sources)
+ :
+ libuuid_kernel.a
+;
+
+SEARCH on [ FGristFiles $(ufs2Sources) ]
+ = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems ufs2 ] ;
+
+SEARCH on [ FGristFiles kernel_cpp.cpp ]
+ = [ FDirName $(HAIKU_TOP src system kernel util ] ;
+
diff --git a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
new file mode 100644
index 0000000..25e4531
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp
@@ -0,0 +1,556 @@
+#include "system_dependencies.h"
+
+#ifdef TRACE_ufs2
+#define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
+#else
+#define TRACE(x...) ;
+#endif
+
+
+struct identify_cookie
+{
+ /* super_block_struct super_block;
+ * No structure yet implemented.
+ */
+ int cookie;
+};
+
+
+//! ufs2_io() callback hook
+static status_t
+iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
+ size_t size, struct file_io_vec
*vecs, size_t *_count)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+//! ufs2_io() callback hook
+static status_t
+iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
+ bool partialTransfer, size_t
bytesTransferred)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark - Scanning
+static float
+ufs2_identify_partition(int fd, partition_data *partition, void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_scan_partition(int fd, partition_data *partition, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static void
+ufs2_free_identify_partition_cookie(partition_data *partition, void *_cookie)
+{
+ dprintf("Unsupported in ufs2 currently.\n");
+ return;
+}
+
+
+// #pragma mark -
+static status_t
+ufs2_mount(fs_volume *_volume, const char *device, uint32 flags,
+ const char *args, ino_t *_rootID)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_unmount(fs_volume *_volume)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_fs_info(fs_volume *_volume, struct fs_info *info)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark -
+
+static status_t
+ufs2_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
+ uint32 *_flags, bool reenter)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_put_vnode(fs_volume *_volume, fs_vnode *_node, bool reenter)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static bool
+ufs2_can_page(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
+ off_t pos, const iovec *vecs, size_t count, size_t
*_numBytes)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
+ io_request *request)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
+ size_t size, struct file_io_vec *vecs, size_t
*_count)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark -
+
+static status_t
+ufs2_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
+ ino_t *_vnodeID)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
+ void *buffer, size_t bufferLength)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
+ void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
+ void *buffer, size_t *_length)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_close(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_free_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+static status_t
+ufs2_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
+ size_t *_bufferSize)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+status_t
+ufs2_unlink(fs_volume *_volume, fs_vnode *_directory, const char *name)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark - Directory functions
+
+static status_t
+ufs2_create_dir(fs_volume *_volume, fs_vnode *_directory, const char *name,
+ int mode)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_remove_dir(fs_volume *_volume, fs_vnode *_directory, const char *name)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
+ struct dirent *dirent, size_t bufferSize, uint32 *_num)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_rewind_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_close_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/,
+ void * /*_cookie*/)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_free_dir_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_open_attr_dir(fs_volume *_volume, fs_vnode *_node, void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_close_attr_dir(fs_volume *_volume, fs_vnode *_node, void *cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_free_attr_dir_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_attr_dir(fs_volume *_volume, fs_vnode *_node,
+ void *_cookie, struct dirent *dirent, size_t
bufferSize, uint32 *_num)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_rewind_attr_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+/* attribute operations */
+static status_t
+ufs2_create_attr(fs_volume *_volume, fs_vnode *_node,
+ const char *name, uint32 type, int openMode,
void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
+ int openMode, void **_cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_close_attr(fs_volume *_volume, fs_vnode *_node,
+ void *cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_free_attr_cookie(fs_volume *_volume, fs_vnode *_node,
+ void *cookie)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
+ off_t pos, void *buffer, size_t *_length)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
+ off_t pos, const void *buffer, size_t *length)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
+ void *_cookie, struct stat *stat)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
+ void *cookie, const struct stat *stat,
int statMask)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
+ const char *fromName, fs_vnode *toVnode, const
char *toName)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_remove_attr(fs_volume *_volume, fs_vnode *vnode,
+ const char *name)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static uint32
+ufs2_get_supported_operations(partition_data *partition, uint32 mask)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_initialize(int fd, partition_id partitionID, const char *name,
+ const char *parameterString, off_t partitionSize,
disk_job_id job)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+static status_t
+ufs2_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
+ uint32 blockSize, disk_job_id job)
+{
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark -
+
+static status_t
+ufs2_std_ops(int32 op, ...)
+{
+ switch (op)
+ {
+ case B_MODULE_INIT:
+#ifdef ufs2_DEBUGGER_COMMANDS
+ // Perform nothing at the moment
+ // add_debugger_commands();
+#endif
+ return B_OK;
+ case B_MODULE_UNINIT:
+#ifdef ufs2_DEBUGGER_COMMANDS
+ // Perform nothing at the moment
+ // remove_debugger_commands();
+#endif
+ return B_OK;
+
+ default:
+ return B_ERROR;
+ }
+}
+
+fs_volume_ops gufs2VolumeOps = {
+ &ufs2_unmount,
+ &ufs2_read_fs_info,
+ NULL, // write_fs_info()
+ NULL, // fs_sync,
+ &ufs2_get_vnode,
+};
+
+fs_vnode_ops gufs2VnodeOps = {
+ /* vnode operations */
+ &ufs2_lookup,
+ NULL, // ufs2_get_vnode_name - optional, and we can't do better than the
+ // fallback implementation, so leave as NULL.
+ &ufs2_put_vnode,
+ NULL, // ufs2_remove_vnode,
+
+ /* VM file access */
+ &ufs2_can_page,
+ &ufs2_read_pages,
+ NULL, // ufs2_write_pages,
+
+ &ufs2_io, // io()
+ NULL, // cancel_io()
+
+ &ufs2_get_file_map,
+
+ &ufs2_ioctl,
+ NULL,
+ NULL, // fs_select
+ NULL, // fs_deselect
+ NULL, // fs_fsync,
+
+ &ufs2_read_link,
+ NULL, // fs_create_symlink,
+
+ NULL, // fs_link,
+ &ufs2_unlink,
+ NULL, // fs_rename,
+
+ &ufs2_access,
+ &ufs2_read_stat,
+ NULL, // fs_write_stat,
+ NULL, // fs_preallocate
+
+ /* file operations */
+ NULL, // fs_create,
+ &ufs2_open,
+ &ufs2_close,
+ &ufs2_free_cookie,
+ &ufs2_read,
+ NULL, // fs_write,
+
+ /* directory operations */
+ &ufs2_create_dir,
+ &ufs2_remove_dir,
+ &ufs2_open_dir,
+ &ufs2_close_dir,
+ &ufs2_free_dir_cookie,
+ &ufs2_read_dir,
+ &ufs2_rewind_dir,
+
+ /* attribute directory operations */
+ &ufs2_open_attr_dir,
+ &ufs2_close_attr_dir,
+ &ufs2_free_attr_dir_cookie,
+ &ufs2_read_attr_dir,
+ &ufs2_rewind_attr_dir,
+
+ /* attribute operations */
+ &ufs2_create_attr,
+ &ufs2_open_attr,
+ &ufs2_close_attr,
+ &ufs2_free_attr_cookie,
+ &ufs2_read_attr,
+ &ufs2_write_attr,
+ &ufs2_read_attr_stat,
+ &ufs2_write_attr_stat,
+ &ufs2_rename_attr,
+ &ufs2_remove_attr,
+};
+
+
+static file_system_module_info sufs2FileSystem = {
+ {
+ "file_systems/ufs2" B_CURRENT_FS_API_VERSION,
+ 0,
+ ufs2_std_ops,
+ },
+
+ "ufs2", // short_name
+ "ufs2 File System", // pretty_name
+
+ // DDM flags
+ 0| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
+ // | B_DISK_SYSTEM_SUPPORTS_WRITING
+ ,
+
+ // scanning
+ ufs2_identify_partition,
+ ufs2_scan_partition,
+ ufs2_free_identify_partition_cookie,
+ NULL, // free_partition_content_cookie()
+
+ &ufs2_mount,
+
+ /* capability querying operations */
+ &ufs2_get_supported_operations,
+
+ NULL, // validate_resize
+ NULL, // validate_move
+ NULL, // validate_set_content_name
+ NULL, // validate_set_content_parameters
+ NULL, // validate_initialize,
+
+ /* shadow partition modification */
+ NULL, // shadow_changed
+
+ /* writing */
+ NULL, // defragment
+ NULL, // repair
+ NULL, // resize
+ NULL, // move
+ NULL, // set_content_name
+ NULL, // set_content_parameters
+ ufs2_initialize,
+ ufs2_uninitialize};
+
+module_info *modules[] = {
+ (module_info *)&sufs2FileSystem,
+ NULL,
+};
diff --git a/src/add-ons/kernel/file_systems/ufs2/system_dependencies.h
b/src/add-ons/kernel/file_systems/ufs2/system_dependencies.h
new file mode 100644
index 0000000..dfbb4e5
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/ufs2/system_dependencies.h
@@ -0,0 +1,50 @@
+
+#ifndef _SYSTE_DEPENDENCIES_H
+#define _SYSTEM_DEPENDENCIES_H
+
+#ifdef FS_SHELL
+// This needs to be included before the fs_shell wrapper
+
+#include "fssh_api_wrapper.h"
+#include "fssh_auto_deleter.h"
+//#include <new>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef unsigned char uuid_t[16];
+
+void uuid_generate(uuid_t out);
+#ifdef __cplusplus
+}
+#endif
+
+
+#else // !FS_SHELL
+
+#include <AutoDeleter.h>
+#include <util/AutoLock.h>
+#include <util/DoublyLinkedList.h>
+#include <util/SinglyLinkedList.h>
+#include <util/Stack.h>
+
+#include <ByteOrder.h>
+#include <uuid.h>
+
+#include <tracing.h>
+#include <driver_settings.h>
+#include <fs_attr.h>
+#include <fs_cache.h>
+#include <fs_index.h>
+#include <fs_info.h>
+#include <fs_interface.h>
+#include <fs_query.h>
+#include <fs_volume.h>
+#include <Drivers.h>
+#include <KernelExport.h>
+#include <NodeMonitor.h>
+#include <SupportDefs.h>
+#include <TypeConstants.h>
+#endif // !FS_SHELL
+
+#endif // _SYSTEM_DEPENDENCIES
diff --git a/src/tests/add-ons/kernel/file_systems/Jamfile
b/src/tests/add-ons/kernel/file_systems/Jamfile
index ff5e501..02abb22 100644
--- a/src/tests/add-ons/kernel/file_systems/Jamfile
+++ b/src/tests/add-ons/kernel/file_systems/Jamfile
@@ -11,3 +11,4 @@
HaikuSubInclude udf ;
HaikuSubInclude userlandfs ;
HaikuSubInclude xfs ;
+HaikuSubInclude ufs2 ;
diff --git a/src/tests/add-ons/kernel/file_systems/ufs2/Jamfile
b/src/tests/add-ons/kernel/file_systems/ufs2/Jamfile
new file mode 100644
index 0000000..faec536
--- /dev/null
+++ b/src/tests/add-ons/kernel/file_systems/ufs2/Jamfile
@@ -0,0 +1,3 @@
+SubDir HAIKU_TOP src tests add-ons kernel file_systems ufs2 ;
+
+SubInclude HAIKU_TOP src tests add-ons kernel file_systems ufs2 ufs2_shell ;
diff --git a/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
new file mode 100644
index 0000000..fe7873b
--- /dev/null
+++ b/src/tests/add-ons/kernel/file_systems/ufs2/ufs2_shell/Jamfile
@@ -0,0 +1,64 @@
+SubDir HAIKU_TOP src tests add-ons kernel file_systems ufs2 ufs2_shell ;
+
+SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems ufs2
] ;
+
+# prevent inclusion of HaikuBuildCompatibility.h
+DEFINES += HAIKU_BUILD_COMPATIBILITY_H ;
+
+# set some additional defines
+{
+ local defines =
+ FS_SHELL
+ ;
+
+ defines = [ FDefines $(defines) ] ;
+
+ local c++flags = ;
+
+ SubDirCcFlags $(defines) -Wno-multichar ;
+ SubDirC++Flags $(defines) $(c++flags) -Wno-multichar -fno-rtti ;
+}
+
+# platform specific libraries
+local fsShellCommandLibs ;
+if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
+ fsShellCommandLibs = $(HOST_NETWORK_LIBS) ;
+}
+
+UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
+
+if ! $(HOST_PLATFORM_HAIKU_COMPATIBLE) {
+ UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
+ UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
+}
+
+UsePrivateHeaders shared storage ;
+UsePrivateHeaders fs_shell ;
+UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
+UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
+
+local ufs2Source =
+ kernel_interface.cpp
+;
+
+BuildPlatformMergeObject <build>ufs2.o : $(ufs2Source) ;
+
+BuildPlatformMain <build>ufs2_shell
+ :
+ :
+ <build>ufs2.o
+ <build>fs_shell.a $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
+ $(HOST_LIBROOT) $(fsShellCommandLibs)
+;
+
+BuildPlatformMain <build>ufs2_fuse
+ :
+ :
+ <build>ufs2.o
+ <build>fuse_module.a
+ $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
+ $(HOST_STATIC_LIBROOT) $(fsShellCommandLibs) fuse
+;
+
+SEARCH on [ FGristFiles QueryParserUtils.cpp ]
+ += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
--
To view, visit https://review.haiku-os.org/c/haiku/+/2344
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I770ad6b906ca41d4d84d374cea209e22149fd727
Gerrit-Change-Number: 2344
Gerrit-PatchSet: 1
Gerrit-Owner: suhelmehta@xxxxxxxxxxx
Gerrit-MessageType: newchange