[haiku-commits] r39036 - haiku/trunk/src/add-ons/kernel/file_systems/ext2

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 20 Oct 2010 23:40:35 +0200 (CEST)

Author: korli
Date: 2010-10-20 23:40:35 +0200 (Wed, 20 Oct 2010)
New Revision: 39036
Changeset: http://dev.haiku-os.org/changeset/39036

Added:
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.h
Removed:
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/AttributeIterator.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/AttributeIterator.h
Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/Jamfile
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp
Log:
ext3 inodes whose size is at least 256 bytes can also contain attributes (like 
smalldata for bfs).
We now use the Attribute class from bfs (instead of AttributeIterator) to 
manage small data and block attributes, though it's still readonly.


Added: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.cpp              
                (rev 0)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.cpp      
2010-10-20 21:40:35 UTC (rev 39036)
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2010, Jérôme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2010, François Revol, <revol@xxxxxxx>.
+ * Copyright 2004-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
+
+//!    connection between pure inode and kernel_interface attributes
+
+
+#include "Attribute.h"
+#include "Utility.h"
+
+#include <stdio.h>
+
+
+//#define TRACE_EXT2
+#ifdef TRACE_EXT2
+#      define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
+#else
+#      define TRACE(x...) ;
+#endif
+
+
+Attribute::Attribute(Inode* inode)
+       :
+       fVolume(inode->GetVolume()),
+       fBlock(fVolume),
+       fInode(inode),
+       fBodyEntry(NULL),
+       fBlockEntry(NULL),
+       fName(NULL)
+{
+       
+}
+
+
+Attribute::Attribute(Inode* inode, attr_cookie* cookie)
+       :
+       fVolume(inode->GetVolume()),
+       fBlock(fVolume),
+       fInode(inode),
+       fBodyEntry(NULL),
+       fBlockEntry(NULL),
+       fName(NULL)
+{
+       Find(cookie->name);
+}
+
+
+Attribute::~Attribute()
+{
+       Put();
+}
+
+
+status_t
+Attribute::InitCheck()
+{
+       return (fBodyEntry != NULL || fBlockEntry != NULL) ? B_OK : B_NO_INIT;
+}
+
+
+status_t
+Attribute::CheckAccess(const char* name, int openMode)
+{
+       return fInode->CheckPermissions(open_mode_to_access(openMode)
+               | (openMode & O_TRUNC ? W_OK : 0));
+}
+
+
+status_t
+Attribute::Find(const char* name)
+{
+       return _Find(name, -1);
+}
+
+
+status_t
+Attribute::Find(int32 index)
+{
+       return _Find(NULL, index);
+}
+
+
+status_t
+Attribute::GetName(char* name, size_t* _nameLength)
+{
+       if (fBodyEntry == NULL && fBlockEntry == NULL)
+               return B_NO_INIT;
+       if (fBodyEntry != NULL)
+               return _PrefixedName(fBodyEntry, name, _nameLength);
+       else
+               return _PrefixedName(fBlockEntry, name, _nameLength);
+}
+
+
+void
+Attribute::Put()
+{
+       if (fBodyEntry != NULL) {
+               recursive_lock_unlock(&fInode->SmallDataLock());
+               fBlock.Unset();
+               fBodyEntry = NULL;
+       }
+
+       if (fBlockEntry != NULL) {
+               fBlock.Unset();
+               fBlockEntry = NULL;
+       }
+}
+
+
+status_t
+Attribute::Create(const char* name, type_code type, int openMode,
+       attr_cookie** _cookie)
+{
+       status_t status = CheckAccess(name, openMode);
+       if (status < B_OK)
+               return status;
+
+       attr_cookie* cookie = new(std::nothrow) attr_cookie;
+       if (cookie == NULL)
+               return B_NO_MEMORY;
+
+       fName = name;
+
+       // initialize the cookie
+       strlcpy(cookie->name, fName, B_ATTR_NAME_LENGTH);
+       cookie->type = type;
+       cookie->open_mode = openMode;
+       cookie->create = true;
+
+       if (Find(name) == B_OK) {
+               // attribute already exists
+               if ((openMode & O_TRUNC) != 0)
+                       _Truncate();
+       }
+       *_cookie = cookie;
+       return B_OK;
+}
+
+
+status_t
+Attribute::Open(const char* name, int openMode, attr_cookie** _cookie)
+{
+       TRACE("Open\n");
+       status_t status = CheckAccess(name, openMode);
+       if (status < B_OK)
+               return status;
+
+       status = Find(name);
+       if (status < B_OK)
+               return status;
+
+       attr_cookie* cookie = new(std::nothrow) attr_cookie;
+       if (cookie == NULL)
+               return B_NO_MEMORY;
+
+       // initialize the cookie
+       strlcpy(cookie->name, fName, B_ATTR_NAME_LENGTH);
+       cookie->open_mode = openMode;
+       cookie->create = false;
+
+       // Should we truncate the attribute?
+       if ((openMode & O_TRUNC) != 0)
+               _Truncate();
+
+       *_cookie = cookie;
+       return B_OK;
+}
+
+
+status_t
+Attribute::Stat(struct stat& stat)
+{
+       TRACE("Stat\n");
+       if (fBodyEntry == NULL && fBlockEntry == NULL)
+               return B_NO_INIT;
+
+       stat.st_type = B_RAW_TYPE;
+       
+       if (fBodyEntry != NULL)
+               stat.st_size = fBodyEntry->ValueSize();
+       else if (fBlockEntry != NULL)
+               stat.st_size = fBlockEntry->ValueSize();
+       
+       return B_OK;
+}
+
+
+status_t
+Attribute::Read(attr_cookie* cookie, off_t pos, uint8* buffer, size_t* _length)
+{
+       if (fBodyEntry == NULL && fBlockEntry == NULL)
+               return B_NO_INIT;
+
+       if (pos < 0LL)
+               return ERANGE;
+
+       size_t length = *_length;
+       const uint8* start = (uint8 *)fBlock.Block();
+       if (fBlockEntry != NULL) {
+               pos += fBlockEntry->ValueOffset();
+               if (((uint32)pos + length) > fVolume->BlockSize()
+                       || length > fBlockEntry->ValueSize())
+                       return ERANGE;
+       } else {
+               start += fVolume->InodeBlockIndex(fInode->ID()) * 
fVolume->InodeSize();
+               const uint8* end = start + fVolume->InodeSize();
+               start += EXT2_INODE_NORMAL_SIZE + 
fInode->Node().ExtraInodeSize()
+                       + sizeof(uint32);
+               pos += fBodyEntry->ValueOffset();
+               if ((pos + length) > (end - start) || length > 
fBodyEntry->ValueSize())
+                       return ERANGE;
+       }
+       memcpy(buffer, start + (uint32)pos, length);
+
+       *_length = length;
+       return B_OK;
+}
+
+
+status_t
+Attribute::Write(Transaction& transaction, attr_cookie* cookie, off_t pos,
+       const uint8* buffer, size_t* _length, bool* _created)
+{
+       if (!cookie->create && fBodyEntry == NULL && fBlockEntry == NULL)
+               return B_NO_INIT;
+
+       // TODO: Implement
+       return B_ERROR;
+}
+
+
+status_t
+Attribute::_Truncate()
+{
+       // TODO: Implement
+       return B_ERROR;
+}
+
+
+status_t
+Attribute::_Find(const char* name, int32 index)
+{
+       Put();
+
+       fName = name;
+
+       // try to find it in the small data region
+       if (fInode->HasExtraAttributes() 
+               && recursive_lock_lock(&fInode->SmallDataLock()) == B_OK) {
+               uint32 block;
+               fVolume->GetInodeBlock(fInode->ID(), block);
+               
+               if (block != 0) {
+                       fBlock.SetTo(block);
+                       const uint8* start = fBlock.Block() 
+                               + fVolume->InodeBlockIndex(fInode->ID()) * 
fVolume->InodeSize();
+                       const uint8* end = start + fVolume->InodeSize();
+                       int32 count = 0;
+                       if (_FindAttributeBody(start + EXT2_INODE_NORMAL_SIZE 
+                               + fInode->Node().ExtraInodeSize(), end, name, 
index, &count, 
+                               &fBodyEntry) == B_OK)
+                               return B_OK;
+                       index -= count;
+               }
+
+               recursive_lock_unlock(&fInode->SmallDataLock());
+               fBlock.Unset();
+       }
+
+       // then, search in the attribute directory
+       if (fInode->Node().ExtendedAttributesBlock() != 0) {
+               fBlock.SetTo(fInode->Node().ExtendedAttributesBlock());
+               if (_FindAttributeBlock(fBlock.Block(), 
+                       fBlock.Block() + fVolume->BlockSize(), name, index, 
NULL, 
+                       &fBlockEntry) == B_OK)
+                       return B_OK;
+               fBlock.Unset();
+       }
+
+       return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
+Attribute::_FindAttributeBody(const uint8* start, const uint8* end, 
+       const char* name, int32 index, int32 *count, ext2_xattr_entry** _entry)
+{
+       TRACE("_FindAttributeBody %p %p %s\n", start, end, name);
+       if (*((uint32*)start) != EXT2_XATTR_MAGIC)
+               return B_BAD_DATA;
+       return _FindAttribute(start + sizeof(uint32), end, name, index, count,
+               _entry);
+}
+
+
+status_t
+Attribute::_FindAttributeBlock(const uint8* start, const uint8* end, const 
char* name,
+       int32 index, int32 *count, ext2_xattr_entry** _entry)
+{
+       TRACE("_FindAttributeBlock %p %p %s\n", start, end, name);
+       ext2_xattr_header *header = (ext2_xattr_header*)start;
+       if (!header->IsValid())
+               return B_BAD_DATA;
+       
+       return _FindAttribute(start + sizeof(ext2_xattr_header), end, name, 
index, 
+               count, _entry);
+}
+
+
+status_t
+Attribute::_FindAttribute(const uint8* start, const uint8* end, const char* 
name,
+       int32 index, int32 *count, ext2_xattr_entry** _entry)
+{
+       TRACE("_FindAttribute %p %p %s\n", start, end, name);
+       char buffer[EXT2_XATTR_NAME_LENGTH];
+       
+       int32 i = 0;
+       while (start < end) {
+               ext2_xattr_entry* entry = (ext2_xattr_entry*)start;
+               if (!entry->IsValid())
+                       break;
+               
+               size_t length = EXT2_XATTR_NAME_LENGTH;
+               if ((name != NULL && _PrefixedName(entry, buffer, &length) == 
B_OK
+                               && strncmp(name, buffer, length) == 0) || index 
== i) {
+                       *_entry = entry;
+                       return B_OK;
+               }
+               start += entry->Length();
+               i++;
+       }
+
+       if (count != NULL)
+               *count = i;
+       return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
+Attribute::_PrefixedName(ext2_xattr_entry* entry, char* _name, size_t* 
_nameLength)
+{
+       const char *indexNames[] = { "0", "user" };
+       size_t l = 0;
+       
+       if (entry->NameIndex() < ((sizeof(indexNames) / sizeof(indexNames[0]))))
+               l = snprintf(_name, *_nameLength, "%s.%s.%.*s",
+                       "linux", indexNames[entry->NameIndex()], 
entry->NameLength(),
+                       entry->name);
+       else
+               l = snprintf(_name, *_nameLength, "%s.%d.%.*s",
+                       "linux", entry->NameIndex(), entry->NameLength(), 
entry->name);
+       if (l < 1 || l > *_nameLength - 1)
+               return ENOBUFS;
+       
+       *_nameLength = l + 1;
+       _name[l] = '\0';
+
+       return B_OK;
+}
+

Added: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.h                
                (rev 0)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Attribute.h        
2010-10-20 21:40:35 UTC (rev 39036)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010, Jérôme Duval, korli@xxxxxxxxxxxxxxxxx
+ * Copyright 2004-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * This file may be used under the terms of the MIT License.
+ */
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+
+#include "CachedBlock.h"
+#include "Inode.h"
+
+
+struct attr_cookie {
+       char    name[B_ATTR_NAME_LENGTH];
+       uint32  type;
+       int             open_mode;
+       bool    create;
+};
+
+
+class Attribute {
+public:
+                                                       Attribute(Inode* inode);
+                                                       Attribute(Inode* inode, 
attr_cookie* cookie);
+                                                       ~Attribute();
+
+                       status_t                InitCheck();
+                       status_t                CheckAccess(const char* name, 
int openMode);
+
+                       status_t                Find(const char* name);
+                       status_t                Find(int32 index);
+                       status_t                GetName(char* name, size_t* 
_nameLength);
+                       void                    Put();
+
+                       status_t                Create(const char* name, 
type_code type,
+                                                               int openMode, 
attr_cookie** _cookie);
+                       status_t                Open(const char* name, int 
openMode,
+                                                               attr_cookie** 
_cookie);
+
+                       status_t                Stat(struct stat& stat);
+
+                       status_t                Read(attr_cookie* cookie, off_t 
pos, uint8* buffer,
+                                                               size_t* 
_length);
+                       status_t                Write(Transaction& transaction, 
attr_cookie* cookie,
+                                                               off_t pos, 
const uint8* buffer, 
+                                                               size_t* 
_length, bool* _created);
+
+private:
+                       status_t                _Truncate();
+                       status_t                _Find(const char* name, int32 
index);
+                       status_t                _FindAttributeBody(const uint8* 
start, const uint8* end,
+                                                               const char* 
name, int32 index, int32 *count,
+                                                               
ext2_xattr_entry** entry);
+                       status_t                _FindAttributeBlock(const 
uint8* start, const uint8* end,
+                                                               const char* 
name, int32 index, int32 *count,
+                                                               
ext2_xattr_entry** entry);
+                       status_t                _FindAttribute(const uint8* 
start, const uint8* end,
+                                                               const char* 
name, int32 index, int32 *count,
+                                                               
ext2_xattr_entry** entry);
+                       status_t                _PrefixedName(ext2_xattr_entry* 
entry, char* _name,
+                                                               size_t* 
_nameLength);
+
+                       ::Volume*               fVolume;
+                       CachedBlock             fBlock;
+                       Inode*                  fInode;
+                       ext2_xattr_entry* fBodyEntry;
+                       ext2_xattr_entry* fBlockEntry;
+                       const char*             fName;
+};
+
+#endif // ATTRIBUTE_H

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp  2010-10-20 
21:36:23 UTC (rev 39035)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.cpp  2010-10-20 
21:40:35 UTC (rev 39036)
@@ -32,9 +32,11 @@
        fCache(NULL),
        fMap(NULL),
        fCached(false),
+       fHasExtraAttributes(false),
        fAttributesBlock(NULL)
 {
        rw_lock_init(&fLock, "ext2 inode");
+       recursive_lock_init(&fSmallDataLock, "ext2 inode small data");
 
        TRACE("Inode::Inode(): ext2_inode: %lu, disk inode: %lu\n",
                sizeof(ext2_inode), fVolume->InodeSize());
@@ -70,6 +72,7 @@
        fInitStatus(B_NO_INIT)
 {
        rw_lock_init(&fLock, "ext2 inode");
+       recursive_lock_init(&fSmallDataLock, "ext2 inode small data");
 
        TRACE("Inode::Inode(): ext2_inode: %lu, disk inode: %lu\n",
                sizeof(ext2_inode), fVolume->InodeSize());
@@ -476,7 +479,7 @@
        size_t length = *_length;
 
        if (!fAttributesBlock) {
-               uint32 block = 
B_LENDIAN_TO_HOST_INT32(Node().file_access_control);
+               uint32 block = Node().ExtendedAttributesBlock();
 
                if (block == 0)
                        return B_ENTRY_NOT_FOUND;

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h    2010-10-20 
21:36:23 UTC (rev 39035)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Inode.h    2010-10-20 
21:40:35 UTC (rev 39036)
@@ -37,6 +37,8 @@
                        status_t        UpdateNodeFromDisk();
                        status_t        WriteBack(Transaction& transaction);
 
+                       recursive_lock& SmallDataLock() { return 
fSmallDataLock; }
+
                        bool            IsDirectory() const
                                                        { return 
S_ISDIR(Mode()); }
                        bool            IsFile() const
@@ -148,6 +150,8 @@
                                // information is always the same size (except 
in ext4)
                        ext2_xattr_header* fAttributesBlock;
                        status_t        fInitStatus;
+
+                       mutable recursive_lock fSmallDataLock;
 };
 
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/Jamfile    2010-10-20 
21:36:23 UTC (rev 39035)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/Jamfile    2010-10-20 
21:40:35 UTC (rev 39036)
@@ -15,7 +15,7 @@
        Volume.cpp
        DataStream.cpp
        Inode.cpp
-       AttributeIterator.cpp
+       Attribute.cpp
        DirectoryIterator.cpp
        HTree.cpp
        HTreeEntryIterator.cpp

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h     2010-10-20 
21:36:23 UTC (rev 39035)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/ext2.h     2010-10-20 
21:40:35 UTC (rev 39036)
@@ -349,6 +349,9 @@
                return B_LENDIAN_TO_HOST_INT32(size);
        }
 
+       uint32 ExtendedAttributesBlock() const
+       {       return B_LENDIAN_TO_HOST_INT32(file_access_control);}
+
        uint16 ExtraInodeSize() const
                { return B_LENDIAN_TO_HOST_INT16(extra_inode_size); }
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp       
2010-10-20 21:36:23 UTC (rev 39035)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp       
2010-10-20 21:40:35 UTC (rev 39036)
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2010, Jérôme Duval, korli@xxxxxxxxxxxxxxxxx
  * Copyright 2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * This file may be used under the terms of the MIT License.
  */
@@ -15,7 +16,7 @@
 #include <NodeMonitor.h>
 #include <util/AutoLock.h>
 
-#include "AttributeIterator.h"
+#include "Attribute.h"
 #include "CachedBlock.h"
 #include "DirectoryIterator.h"
 #include "ext2.h"
@@ -1416,11 +1417,11 @@
        if (!inode->IsFile())
                return EINVAL;
 
-       AttributeIterator* iterator = new(std::nothrow) 
AttributeIterator(inode);
-       if (iterator == NULL)
+       int32 *index = new(std::nothrow) int32;
+       if (index == NULL)
                return B_NO_MEMORY;
-
-       *_cookie = iterator;
+       *index = 0;
+       *(int32**)_cookie = index;
        return B_OK;
 }
 
@@ -1436,7 +1437,7 @@
 ext2_free_attr_dir_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
 {
        TRACE("%s()\n", __FUNCTION__);
-       delete (AttributeIterator *)_cookie;
+       delete (int32 *)_cookie;
        return B_OK;
 }
 
@@ -1447,17 +1448,22 @@
                                uint32* _num)
 {
        Inode* inode = (Inode*)_node->private_node;
-       AttributeIterator *iterator = (AttributeIterator *)_cookie;
+       int32 index = *(int32 *)_cookie;
+       Attribute attribute(inode);
        TRACE("%s()\n", __FUNCTION__);
 
        size_t length = bufferSize;
-       status_t status = iterator->GetNext(dirent->d_name, &length);
+       status_t status = attribute.Find(index);
        if (status == B_ENTRY_NOT_FOUND) {
                *_num = 0;
                return B_OK;
        } else if (status != B_OK)
                return status;
 
+       status = attribute.GetName(dirent->d_name, &length);
+       if (status != B_OK)
+               return B_OK;
+
        Volume* volume = (Volume*)_volume->private_volume;
 
        dirent->d_dev = volume->ID();
@@ -1465,6 +1471,7 @@
        dirent->d_reclen = sizeof(struct dirent) + length;
 
        *_num = 1;
+       *(int32*)_cookie = index + 1;
        return B_OK;
 }
 
@@ -1472,9 +1479,9 @@
 static status_t
 ext2_rewind_attr_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie)
 {
-       AttributeIterator *iterator = (AttributeIterator *)_cookie;
+       *(int32*)_cookie = 0;
        TRACE("%s()\n", __FUNCTION__);
-       return iterator->Rewind();
+       return B_OK;
 }
 
 
@@ -1492,31 +1499,15 @@
        int openMode, void** _cookie)
 {
        TRACE("%s()\n", __FUNCTION__);
-       if ((openMode & O_RWMASK) != O_RDONLY)
-               return EROFS;
-
-       Inode* inode = (Inode*)_node->private_node;
+       
        Volume* volume = (Volume*)_volume->private_volume;
+       Inode* inode = (Inode*)_node->private_node;
+       Attribute attribute(inode);
 
        if (!(volume->SuperBlock().CompatibleFeatures() & 
EXT2_FEATURE_EXT_ATTR))
                return ENOSYS;
 
-       // on directories too ?
-       if (!inode->IsFile())
-               return EINVAL;
-
-       ext2_xattr_entry *entry = new ext2_xattr_entry;
-
-       AttributeIterator i(inode);
-       status_t status = i.Find(name, entry);
-       if (status == B_OK) {
-               //entry->Dump();
-               *_cookie = entry;
-               return B_OK;
-       }
-       
-       delete entry;
-       return status;
+       return attribute.Open(name, openMode, (attr_cookie**)_cookie);
 }
 
 
@@ -1532,31 +1523,23 @@
 ext2_free_attr_cookie(fs_volume* _volume, fs_vnode* _node,
        void* cookie)
 {
-       ext2_xattr_entry *entry = (ext2_xattr_entry *)cookie;
-
-       delete entry;
+       delete (attr_cookie*)cookie;
        return B_OK;
 }
 
 
 static status_t
-ext2_read_attr(fs_volume* _volume, fs_vnode* _node, void* cookie,
-       off_t pos, void* buffer, size_t* length)
+ext2_read_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie,
+       off_t pos, void* buffer, size_t* _length)
 {
        TRACE("%s()\n", __FUNCTION__);
 
+       attr_cookie* cookie = (attr_cookie*)_cookie;
        Inode* inode = (Inode*)_node->private_node;
-       //Volume* volume = (Volume*)_volume->private_volume;
-       ext2_xattr_entry *entry = (ext2_xattr_entry *)cookie;
 
-       if (!entry->IsValid())
-               return EINVAL;
+       Attribute attribute(inode, cookie);
 
-       if (pos < 0 || (pos + *length) > entry->ValueSize())
-               return ERANGE;
-
-       return inode->AttributeBlockReadAt(entry->ValueOffset() + pos,
-               (uint8 *)buffer, length);
+       return attribute.Read(cookie, pos, (uint8*)buffer, _length);
 }
 
 
@@ -1571,15 +1554,14 @@
 
 static status_t
 ext2_read_attr_stat(fs_volume* _volume, fs_vnode* _node,
-       void* cookie, struct stat* stat)
+       void* _cookie, struct stat* stat)
 {
-       ext2_xattr_entry *entry = (ext2_xattr_entry *)cookie;
+       attr_cookie* cookie = (attr_cookie*)_cookie;
+       Inode* inode = (Inode*)_node->private_node;
 
-       stat->st_type = B_RAW_TYPE;
-       stat->st_size = entry->ValueSize();
-       TRACE("%s: st_size %d\n", __FUNCTION__, stat->st_size);
+       Attribute attribute(inode, cookie);
 
-       return B_OK;
+       return attribute.Stat(*stat);
 }
 
 


Other related posts:

  • » [haiku-commits] r39036 - haiku/trunk/src/add-ons/kernel/file_systems/ext2 - korli