[haiku-commits] r37595 - haiku/trunk/src/tests/system/kernel/file_corruption/fs

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 19 Jul 2010 15:58:03 +0200 (CEST)

Author: bonefish
Date: 2010-07-19 15:58:03 +0200 (Mon, 19 Jul 2010)
New Revision: 37595
Changeset: http://dev.haiku-os.org/changeset/37595

Modified:
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.h
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp
Log:
Implemented hooks write_fs_info(), sync(), set_flags(), fsync(), access().


Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp     
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.cpp     
2010-07-19 13:58:03 UTC (rev 37595)
@@ -237,6 +237,13 @@
 }
 
 
+status_t
+File::Sync()
+{
+       return file_cache_sync(fFileCache);
+}
+
+
 void
 File::RevertNodeData(const checksumfs_node& nodeData)
 {

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h       
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/File.h       
2010-07-19 13:58:03 UTC (rev 37595)
@@ -29,6 +29,7 @@
                                                                        size_t& 
_bytesRead);
        virtual status_t                        Write(off_t pos, const void* 
buffer,
                                                                        size_t 
size, size_t& _bytesWritten);
+       virtual status_t                        Sync();
 
        virtual void                            RevertNodeData(const 
checksumfs_node& nodeData);
 

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp     
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.cpp     
2010-07-19 13:58:03 UTC (rev 37595)
@@ -105,6 +105,13 @@
 }
 
 
+status_t
+Node::Sync()
+{
+       return B_OK;
+}
+
+
 void
 Node::SetParentDirectory(uint32 blockIndex)
 {

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h       
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Node.h       
2010-07-19 13:58:03 UTC (rev 37595)
@@ -43,6 +43,7 @@
                                                                        size_t& 
_bytesRead);
        virtual status_t                        Write(off_t pos, const void* 
buffer,
                                                                        size_t 
size, size_t& _bytesWritten);
+       virtual status_t                        Sync();
 
        inline  const checksumfs_node& NodeData() const { return fNode; }
        inline  Volume*                         GetVolume() const       { 
return fVolume; }

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.cpp       
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.cpp       
2010-07-19 13:58:03 UTC (rev 37595)
@@ -52,3 +52,10 @@
 {
        freeBlocks = count;
 }
+
+
+void
+SuperBlock::SetName(const char* name)
+{
+       strlcpy(this->name, name, kCheckSumFSNameLength);
+}

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.h 
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/SuperBlock.h 
2010-07-19 13:58:03 UTC (rev 37595)
@@ -25,6 +25,7 @@
                        void                            Initialize(Volume* 
volume);
 
                        void                            SetFreeBlocks(uint64 
count);
+                       void                            SetName(const char* 
name);
 };
 
 

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.cpp   
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.cpp   
2010-07-19 13:58:03 UTC (rev 37595)
@@ -17,6 +17,9 @@
 
 #include <fs_cache.h>
 
+#include <AutoDeleter.h>
+#include <util/AutoLock.h>
+
 #include "Block.h"
 #include "BlockAllocator.h"
 #include "checksumfs.h"
@@ -40,6 +43,7 @@
        fBlockAllocator(NULL),
        fRootDirectory(NULL)
 {
+       mutex_init(&fLock, "checksumfs volume");
        mutex_init(&fTransactionLock, "checksumfs transaction");
 }
 
@@ -58,6 +62,7 @@
        free(fName);
 
        mutex_destroy(&fTransactionLock);
+       mutex_destroy(&fLock);
 }
 
 
@@ -217,6 +222,8 @@
 void
 Volume::GetInfo(fs_info& info)
 {
+       MutexLocker locker(fLock);
+
        info.flags = fFlags;
        info.block_size = B_PAGE_SIZE;
        info.io_size = B_PAGE_SIZE * 16;        // random value
@@ -225,7 +232,6 @@
        info.total_nodes = 1;   // phew, who cares?
        info.free_nodes = info.free_blocks;
        strlcpy(info.volume_name, fName, sizeof(info.volume_name));
-               // TODO: We need locking once we are able to change the name!
 }
 
 
@@ -428,6 +434,53 @@
 
 
 status_t
+Volume::SetName(const char* name)
+{
+       if (name == NULL || strlen(name) > kCheckSumFSNameLength)
+               return B_BAD_VALUE;
+
+       // clone the name
+       char* newName = strdup(name);
+       if (newName == NULL)
+               return B_NO_MEMORY;
+       MemoryDeleter newNameDeleter(newName);
+
+       // start a transaction
+       Transaction transaction(this);
+       status_t error = transaction.Start();
+       if (error != B_OK)
+               return error;
+
+       // we lock the volume now, to keep the locking order (transaction -> 
volume)
+       MutexLocker locker(fLock);
+
+       // update the super block
+       Block block;
+       if (!block.GetWritable(this, kCheckSumFSSuperBlockOffset / B_PAGE_SIZE,
+                       transaction)) {
+               return B_ERROR;
+       }
+
+       SuperBlock* superBlock = (SuperBlock*)block.Data();
+       superBlock->SetName(newName);
+
+       block.Put();
+
+       // commit the transaction
+       error = transaction.Commit();
+       if (error != B_OK)
+               return error;
+
+       // Everything went fine. We can replace the name. Since we still have 
the
+       // volume lock, there's no race condition.
+       free(fName);
+       fName = (char*)newNameDeleter.Detach();
+
+       return B_OK;
+}
+
+
+status_t
 Volume::_Init(uint64 totalBlocks)
 {
        fTotalBlocks = totalBlocks;

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.h     
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.h     
2010-07-19 13:58:03 UTC (rev 37595)
@@ -54,6 +54,8 @@
                                                                        
SymLink*& _symLink);
                        status_t                        DeleteNode(Node* node);
 
+                       status_t                        SetName(const char* 
name);
+
        inline  void                            TransactionStarted();
        inline  void                            TransactionFinished();
 
@@ -80,6 +82,7 @@
                        char*                           fName;
                        BlockAllocator*         fBlockAllocator;
                        Directory*                      fRootDirectory;
+                       mutex                           fLock;
                        mutex                           fTransactionLock;
 };
 

Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp       
2010-07-19 13:48:16 UTC (rev 37594)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp       
2010-07-19 13:58:03 UTC (rev 37595)
@@ -36,6 +36,107 @@
 static const char* const kCheckSumFSShortName  = "checksumfs";
 
 
+// #pragma mark -
+
+
+struct FileCookie {
+       int     openMode;
+
+       FileCookie(int openMode)
+               :
+               openMode(openMode)
+       {
+       }
+};
+
+
+struct DirCookie {
+       DirCookie(Directory* directory)
+               :
+               fDirectory(directory)
+       {
+               Rewind();
+       }
+
+       Directory* GetDirectory() const
+       {
+               return fDirectory;
+       }
+
+       status_t ReadNextEntry(struct dirent* buffer, size_t size,
+               uint32& _countRead)
+       {
+               const char* name;
+               size_t nameLength;
+               uint64 blockIndex;
+
+               int nextIterationState = OTHERS;
+               switch (fIterationState) {
+                       case DOT:
+                               name = ".";
+                               nameLength = 1;
+                               blockIndex = fDirectory->BlockIndex();
+                               nextIterationState = DOT_DOT;
+                               break;
+                       case DOT_DOT:
+                               name = "..";
+                               nameLength = 2;
+                               blockIndex = fDirectory->ParentDirectory();
+                               break;
+                       default:
+                       {
+                               status_t error = 
fDirectory->LookupNextEntry(fEntryName,
+                                       fEntryName, nameLength, blockIndex);
+                               if (error != B_OK) {
+                                       if (error != B_ENTRY_NOT_FOUND)
+                                               return error;
+
+                                       _countRead = 0;
+                                       return B_OK;
+                               }
+
+                               name = fEntryName;
+                               break;
+                       }
+               }
+
+               size_t entrySize = sizeof(dirent) + nameLength;
+               if (entrySize > size)
+                       return B_BUFFER_OVERFLOW;
+
+               buffer->d_dev = fDirectory->GetVolume()->ID();
+               buffer->d_ino = blockIndex;
+               buffer->d_reclen = entrySize;
+               strcpy(buffer->d_name, name);
+
+               fIterationState = nextIterationState;
+
+               _countRead = 1;
+               return B_OK;
+       }
+
+       void Rewind()
+       {
+               fIterationState = DOT;
+               fEntryName[0] = '\0';
+       }
+
+private:
+       enum {
+               DOT,
+               DOT_DOT,
+               OTHERS
+       };
+
+       Directory*      fDirectory;
+       int                     fIterationState;
+       char            fEntryName[kCheckSumFSNameLength + 1];
+};
+
+
+// #pragma mark -
+
+
 static void
 set_timespec(timespec& time, uint64 nanos)
 {
@@ -356,6 +457,31 @@
 
 
 static status_t
+checksumfs_write_fs_info(fs_volume* fsVolume, const struct fs_info* info,
+       uint32 mask)
+{
+       Volume* volume = (Volume*)fsVolume->private_volume;
+
+       if ((mask & FS_WRITE_FSINFO_NAME) != 0) {
+               status_t error = volume->SetName(info->volume_name);
+               if (error != B_OK)
+                       return error;
+       }
+
+       return B_OK;
+}
+
+
+static status_t
+checksumfs_sync(fs_volume* fsVolume)
+{
+       Volume* volume = (Volume*)fsVolume->private_volume;
+
+       return block_cache_sync(volume->BlockCache());
+}
+
+
+static status_t
 checksumfs_get_vnode(fs_volume* fsVolume, ino_t id, fs_vnode* vnode,
        int* _type, uint32* _flags, bool reenter)
 {
@@ -508,6 +634,31 @@
 
 
 static status_t
+checksumfs_set_flags(fs_volume* fsVolume, fs_vnode* vnode, void* _cookie,
+       int flags)
+{
+       FileCookie* cookie = (FileCookie*)_cookie;
+
+       cookie->openMode = (cookie->openMode & ~O_APPEND) | (flags & O_APPEND);
+
+       // TODO: Also support O_NOCACHE!
+
+       return B_OK;
+}
+
+
+static status_t
+checksumfs_fsync(fs_volume* fsVolume, fs_vnode* vnode)
+{
+       Node* node = (Node*)vnode->private_node;
+
+       NodeReadLocker nodeLocker(node);
+
+       return node->Sync();
+}
+
+
+static status_t
 checksumfs_read_symlink(fs_volume* fsVolume, fs_vnode* vnode, char* buffer,
        size_t* _bufferSize)
 {
@@ -750,6 +901,17 @@
 
 
 static status_t
+checksumfs_access(fs_volume* fsVolume, fs_vnode* vnode, int mode)
+{
+       Node* node = (Node*)vnode->private_node;
+
+       NodeReadLocker nodeLocker(node);
+
+       return check_access(node, mode);
+}
+
+
+static status_t
 checksumfs_read_stat(fs_volume* fsVolume, fs_vnode* vnode, struct stat* st)
 {
        Node* node = (Node*)vnode->private_node;
@@ -872,17 +1034,6 @@
 // #pragma mark - file operations
 
 
-struct FileCookie {
-       int     openMode;
-
-       FileCookie(int openMode)
-               :
-               openMode(openMode)
-       {
-       }
-};
-
-
 /*!    Opens the node according to the given open mode (if the permissions 
allow
        that) and creates a file cookie.
        The caller must either pass a \a transaction, which is already started 
and
@@ -1187,90 +1338,6 @@
 // #pragma mark - directory operations
 
 
-struct DirCookie {
-       DirCookie(Directory* directory)
-               :
-               fDirectory(directory)
-       {
-               Rewind();
-       }
-
-       Directory* GetDirectory() const
-       {
-               return fDirectory;
-       }
-
-       status_t ReadNextEntry(struct dirent* buffer, size_t size,
-               uint32& _countRead)
-       {
-               const char* name;
-               size_t nameLength;
-               uint64 blockIndex;
-
-               int nextIterationState = OTHERS;
-               switch (fIterationState) {
-                       case DOT:
-                               name = ".";
-                               nameLength = 1;
-                               blockIndex = fDirectory->BlockIndex();
-                               nextIterationState = DOT_DOT;
-                               break;
-                       case DOT_DOT:
-                               name = "..";
-                               nameLength = 2;
-                               blockIndex = fDirectory->ParentDirectory();
-                               break;
-                       default:
-                       {
-                               status_t error = 
fDirectory->LookupNextEntry(fEntryName,
-                                       fEntryName, nameLength, blockIndex);
-                               if (error != B_OK) {
-                                       if (error != B_ENTRY_NOT_FOUND)
-                                               return error;
-
-                                       _countRead = 0;
-                                       return B_OK;
-                               }
-
-                               name = fEntryName;
-                               break;
-                       }
-               }
-
-               size_t entrySize = sizeof(dirent) + nameLength;
-               if (entrySize > size)
-                       return B_BUFFER_OVERFLOW;
-
-               buffer->d_dev = fDirectory->GetVolume()->ID();
-               buffer->d_ino = blockIndex;
-               buffer->d_reclen = entrySize;
-               strcpy(buffer->d_name, name);
-
-               fIterationState = nextIterationState;
-
-               _countRead = 1;
-               return B_OK;
-       }
-
-       void Rewind()
-       {
-               fIterationState = DOT;
-               fEntryName[0] = '\0';
-       }
-
-private:
-       enum {
-               DOT,
-               DOT_DOT,
-               OTHERS
-       };
-
-       Directory*      fDirectory;
-       int                     fIterationState;
-       char            fEntryName[kCheckSumFSNameLength + 1];
-};
-
-
 status_t
 checksumfs_create_dir(fs_volume* fsVolume, fs_vnode* parent, const char* name,
        int perms)
@@ -1469,8 +1536,8 @@
        checksumfs_unmount,
 
        checksumfs_read_fs_info,
-       NULL,   // write_fs_info
-       NULL,   // sync
+       checksumfs_write_fs_info,
+       checksumfs_sync,
 
        checksumfs_get_vnode,
 
@@ -1521,10 +1588,10 @@
 
        /* common operations */
        NULL,   // checksumfs_ioctl,
-       NULL,   // checksumfs_set_flags,
-       NULL,   // checksumfs_select,
-       NULL,   // checksumfs_deselect,
-       NULL,   // checksumfs_fsync,
+       checksumfs_set_flags,
+       NULL,   // select
+       NULL,   // deselect
+       checksumfs_fsync,
 
        checksumfs_read_symlink,
        checksumfs_create_symlink,
@@ -1533,7 +1600,7 @@
        checksumfs_unlink,
        checksumfs_rename,
 
-       NULL,   // checksumfs_access,
+       checksumfs_access,
        checksumfs_read_stat,
        checksumfs_write_stat,
 


Other related posts:

  • » [haiku-commits] r37595 - haiku/trunk/src/tests/system/kernel/file_corruption/fs - ingo_weinhold