[haiku-commits] haiku: hrev54452 - src/add-ons/kernel/file_systems/btrfs

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 21 Jul 2020 21:37:11 -0400 (EDT)

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 */


Other related posts:

  • » [haiku-commits] haiku: hrev54452 - src/add-ons/kernel/file_systems/btrfs - waddlesplash