hrev54452 adds 1 changeset to branch 'master'
old head: 4c2a60b03d5f572b75979eaf09bcd890fe736c8e
new head: f16979003a9740ca3fa54ebe0b64aa627b6f69f1
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=f16979003a97+%5E4c2a60b03d5f
----------------------------------------------------------------------------
f16979003a97: btrfs: partially implemented btrfs_write_stat
Change-Id: Ib17ef1467a320af6edc3739555ebfb3f46bcc98b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/1640
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ brjhaiku <brjhaiku@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54452
Commit: f16979003a9740ca3fa54ebe0b64aa627b6f69f1
URL: https://git.haiku-os.org/haiku/commit/?id=f16979003a97
Author: brjhaiku <brjhaiku@xxxxxxxxx>
Date: Wed Jul 10 22:48:19 2019 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Wed Jul 22 01:37:08 2020 UTC
----------------------------------------------------------------------------
2 files changed, 95 insertions(+), 1 deletion(-)
src/add-ons/kernel/file_systems/btrfs/Inode.h | 1 +
.../file_systems/btrfs/kernel_interface.cpp | 95 +++++++++++++++++++-
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h
b/src/add-ons/kernel/file_systems/btrfs/Inode.h
index a970304516..cdfebbadd0 100644
--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
@@ -46,6 +46,7 @@ public:
{ return
S_ISLNK(Mode()); }
status_t CheckPermissions(int accessMode) const;
+ btrfs_inode& Node() { return fNode; }
mode_t Mode() const { return fNode.Mode(); }
off_t Size() const { return fNode.Size(); }
uid_t UserID() const { return fNode.UserID();
}
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 bbe0c32b6d..b87118b7e8 100644
--- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
@@ -399,6 +399,99 @@ btrfs_read_stat(fs_volume* _volume, fs_vnode* _node,
struct stat* stat)
}
+static status_t
+btrfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat,
+ uint32 mask)
+{
+ FUNCTION();
+
+ Volume* volume = (Volume*)_volume->private_volume;
+ Inode* inode = (Inode*)_node->private_node;
+
+ if (volume->IsReadOnly())
+ return B_READ_ONLY_DEVICE;
+
+ btrfs_inode& node = inode->Node();
+ bool updateTime = false;
+ uid_t uid = geteuid();
+
+ bool isOwnerOrRoot = uid == 0 || uid == (uid_t)node.UserID();
+ bool hasWriteAccess = inode->CheckPermissions(W_OK) == B_OK;
+
+ Transaction transaction(volume);
+
+ if ((mask & B_STAT_SIZE) != 0 && inode->Size() != stat->st_size) {
+ if (inode->IsDirectory())
+ return B_IS_A_DIRECTORY;
+ if (!inode->IsFile())
+ return B_BAD_VALUE;
+ if (!hasWriteAccess)
+ RETURN_ERROR(B_NOT_ALLOWED);
+
+ //TODO: implement file shrinking/growing
+ return B_NOT_SUPPORTED;
+ }
+
+ if ((mask & B_STAT_UID) != 0) {
+ if (uid != 0)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ node.uid = B_HOST_TO_LENDIAN_INT32(stat->st_uid);
+ updateTime = true;
+ }
+
+ if ((mask & B_STAT_GID) != 0) {
+ if (!isOwnerOrRoot)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ node.gid = B_HOST_TO_LENDIAN_INT32(stat->st_gid);
+ updateTime = true;
+ }
+
+ if ((mask & B_STAT_MODE) != 0) {
+ if (!isOwnerOrRoot)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ PRINT(("original mode = %ld, stat->st_mode = %d\n", node.Mode(),
+ stat->st_mode));
+ node.mode = B_HOST_TO_LENDIAN_INT32((node.Mode() & ~S_IUMSK)
+ | (stat->st_mode & S_IUMSK));
+ updateTime = true;
+ }
+
+ if ((mask & B_STAT_CREATION_TIME) != 0) {
+ if (!isOwnerOrRoot && !hasWriteAccess)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ btrfs_inode::SetTime(node.change_time, stat->st_crtim);
+ }
+
+ if ((mask & B_STAT_MODIFICATION_TIME) != 0) {
+ if (!isOwnerOrRoot && !hasWriteAccess)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ btrfs_inode::SetTime(node.change_time, stat->st_mtim);
+ }
+
+ if ((mask & B_STAT_CHANGE_TIME) != 0 || updateTime) {
+ if (!isOwnerOrRoot && !hasWriteAccess)
+ RETURN_ERROR(B_NOT_ALLOWED);
+ if ((mask & B_STAT_CHANGE_TIME) == 0) {
+ uint64_t microseconds = real_time_clock_usecs();
+ struct timespec t;
+ t.tv_sec = microseconds / 1000000;
+ t.tv_usecs = microseconds % 1000000;
+ btrfs_inode::SetTime(node.change_time, t);
+ } else
+ btrfs_inode::SetTime(node.change_time, stat->st_ctim);
+ }
+
+ status_t status = transaction.Done();
+ if (status == B_OK) {
+ ino_t pid;
+ inode->FindParent(&pid);
+ notify_stat_changed(volume->ID(), pid, inode->ID(), mask);
+ }
+
+ return status;
+}
+
+
static status_t
btrfs_open(fs_volume* /*_volume*/, fs_vnode* _node, int openMode,
void** _cookie)
@@ -1044,7 +1137,7 @@ fs_vnode_ops gBtrfsVnodeOps = {
&btrfs_access,
&btrfs_read_stat,
- NULL, // fs_write_stat,
+ &btrfs_write_stat,
NULL, // fs_preallocate
/* file operations */