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

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 12 Jul 2010 18:15:47 +0200 (CEST)

Author: bonefish
Date: 2010-07-12 18:15:47 +0200 (Mon, 12 Jul 2010)
New Revision: 37481
Changeset: http://dev.haiku-os.org/changeset/37481

Added:
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.cpp
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.h
Modified:
   haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile
   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:
Added symlink support.


Modified: haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile      
2010-07-12 16:11:56 UTC (rev 37480)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Jamfile      
2010-07-12 16:15:47 UTC (rev 37481)
@@ -22,6 +22,7 @@
        Directory.cpp
        Node.cpp
        SuperBlock.cpp
+       SymLink.cpp
        Transaction.cpp
        Volume.cpp
 ;

Added: haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.cpp          
                (rev 0)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.cpp  
2010-07-12 16:15:47 UTC (rev 37481)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "SymLink.h"
+
+#include <string.h>
+
+#include "Block.h"
+#include "DebugSupport.h"
+
+
+static const size_t kSymLinkDataOffset = sizeof(checksumfs_node);
+static const size_t kMaxSymLinkSize            = B_PAGE_SIZE - 
kSymLinkDataOffset;
+
+
+SymLink::SymLink(Volume* volume, uint64 blockIndex,
+       const checksumfs_node& nodeData)
+       :
+       Node(volume, blockIndex, nodeData)
+{
+}
+
+
+SymLink::SymLink(Volume* volume, uint64 blockIndex, mode_t mode)
+       :
+       Node(volume, blockIndex, mode)
+{
+}
+
+
+SymLink::~SymLink()
+{
+}
+
+
+status_t
+SymLink::Read(char* buffer, size_t toRead, size_t& _bytesRead)
+{
+       uint64 size = Size();
+       if (size > kMaxSymLinkSize)
+               RETURN_ERROR(B_BAD_DATA);
+
+       if (toRead > size)
+               toRead = size;
+
+       if (toRead == 0) {
+               _bytesRead = 0;
+               return B_OK;
+       }
+
+       // get the block
+       Block block;
+       if (!block.GetReadable(GetVolume(), BlockIndex()))
+               RETURN_ERROR(B_ERROR);
+
+       const char* data = (char*)block.Data() + kSymLinkDataOffset;
+       memcpy(buffer, data, toRead);
+
+       _bytesRead = toRead;
+       return B_OK;
+}
+
+
+status_t
+SymLink::Write(const char* buffer, size_t toWrite, Transaction& transaction)
+{
+       uint64 size = Size();
+       if (size > kMaxSymLinkSize)
+               RETURN_ERROR(B_BAD_DATA);
+
+       if (toWrite > kMaxSymLinkSize)
+               RETURN_ERROR(B_NAME_TOO_LONG);
+
+       if (toWrite == 0) {
+               SetSize(0);
+               return B_OK;
+       }
+
+       Block block;
+       if (!block.GetWritable(GetVolume(), BlockIndex(), transaction))
+               return B_ERROR;
+
+       char* data = (char*)block.Data() + kSymLinkDataOffset;
+       memcpy(data, buffer, toWrite);
+       SetSize(toWrite);
+
+       return B_OK;
+}

Added: haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.h
===================================================================
--- haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.h            
                (rev 0)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/SymLink.h    
2010-07-12 16:15:47 UTC (rev 37481)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef SYM_LINK_H
+#define SYM_LINK_H
+
+
+#include "Node.h"
+
+
+class SymLink : public Node {
+public:
+                                                               SymLink(Volume* 
volume, uint64 blockIndex,
+                                                                       const 
checksumfs_node& nodeData);
+                                                               SymLink(Volume* 
volume, uint64 blockIndex,
+                                                                       mode_t 
mode);
+       virtual                                         ~SymLink();
+
+                       status_t                        Read(char* buffer, 
size_t toRead,
+                                                                       size_t& 
_bytesRead);
+                       status_t                        Write(const char* 
buffer, size_t toWrite,
+                                                                       
Transaction& transaction);
+};
+
+
+#endif // SYM_LINK_H

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-12 16:11:56 UTC (rev 37480)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.cpp   
2010-07-12 16:15:47 UTC (rev 37481)
@@ -24,6 +24,7 @@
 #include "DebugSupport.h"
 #include "Directory.h"
 #include "SuperBlock.h"
+#include "SymLink.h"
 
 
 Volume::Volume(uint32 flags)
@@ -276,6 +277,9 @@
                case S_IFDIR:
                        node = new(std::nothrow) Directory(this, blockIndex, 
*nodeData);
                        break;
+               case S_IFLNK:
+                       node = new(std::nothrow) SymLink(this, blockIndex, 
*nodeData);
+                       break;
                default:
                        node = new(std::nothrow) Node(this, blockIndex, 
*nodeData);
                        break;
@@ -322,6 +326,35 @@
 
 
 status_t
+Volume::CreateSymLink(mode_t mode, Transaction& transaction, SymLink*& 
_symLink)
+{
+       // allocate a free block
+       AllocatedBlock allocatedBlock(fBlockAllocator, transaction);
+       status_t error = allocatedBlock.Allocate();
+       if (error != B_OK)
+               return error;
+
+       // create the symlink
+       SymLink* symLink = new(std::nothrow) SymLink(this, 
allocatedBlock.Index(),
+               (mode & ~(mode_t)S_IFMT) | S_IFLNK);
+       if (symLink == NULL)
+               return B_NO_MEMORY;
+
+       // attach the directory to the transaction
+       error = transaction.AddNode(symLink, TRANSACTION_DELETE_NODE);
+       if (error != B_OK) {
+               delete symLink;
+               return error;
+       }
+
+       allocatedBlock.Detach();
+       _symLink = symLink;
+
+       return B_OK;
+}
+
+
+status_t
 Volume::DeleteNode(Node* node)
 {
        Transaction transaction(this);

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-12 16:11:56 UTC (rev 37480)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/Volume.h     
2010-07-12 16:15:47 UTC (rev 37481)
@@ -16,6 +16,7 @@
 class BlockAllocator;
 class Directory;
 class Node;
+class SymLink;
 class Transaction;
 
 
@@ -44,6 +45,9 @@
                        status_t                        CreateDirectory(mode_t 
mode,
                                                                        
Transaction& transaction,
                                                                        
Directory*& _directory);
+                       status_t                        CreateSymLink(mode_t 
mode,
+                                                                       
Transaction& transaction,
+                                                                       
SymLink*& _symLink);
                        status_t                        DeleteNode(Node* node);
 
        inline  void                            TransactionStarted();

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-12 16:11:56 UTC (rev 37480)
+++ haiku/trunk/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp       
2010-07-12 16:15:47 UTC (rev 37481)
@@ -23,6 +23,7 @@
 #include "DebugSupport.h"
 #include "Directory.h"
 #include "SuperBlock.h"
+#include "SymLink.h"
 #include "Transaction.h"
 #include "Volume.h"
 
@@ -428,6 +429,83 @@
 
 
 static status_t
+checksumfs_read_symlink(fs_volume* fsVolume, fs_vnode* vnode, char* buffer,
+       size_t* _bufferSize)
+{
+       SymLink* symLink = dynamic_cast<SymLink*>((Node*)vnode->private_node);
+       if (symLink == NULL)
+               RETURN_ERROR(B_BAD_VALUE);
+
+       status_t error = check_access(symLink, R_OK);
+       if (error != B_OK)
+               return error;
+
+       return symLink->Read(buffer, *_bufferSize, *_bufferSize);
+}
+
+
+static status_t
+checksumfs_create_symlink(fs_volume* fsVolume, fs_vnode* parent,
+       const char* name, const char* path, int mode)
+{
+       Volume* volume = (Volume*)fsVolume->private_volume;
+       Directory* directory
+               = dynamic_cast<Directory*>((Node*)parent->private_node);
+       if (directory == NULL)
+               return B_NOT_A_DIRECTORY;
+
+       if (volume->IsReadOnly())
+               return B_READ_ONLY_DEVICE;
+
+       status_t error = check_access(directory, W_OK);
+       if (error != B_OK)
+               return error;
+
+       // start a transaction
+       Transaction transaction(volume);
+       error = transaction.Start();
+       if (error != B_OK)
+               return error;
+
+       // attach the directory to the transaction (write locks it, too)
+       error = transaction.AddNode(directory);
+       if (error != B_OK)
+               return error;
+
+       // create a symlink node
+       SymLink* newSymLink;
+       error = volume->CreateSymLink(mode, transaction, newSymLink);
+       if (error != B_OK)
+               return error;
+
+       // write it
+       error = newSymLink->Write(path, strlen(path), transaction);
+       if (error != B_OK)
+               return error;
+
+       // insert the new symlink
+       error = directory->InsertEntry(name, newSymLink->BlockIndex(), 
transaction);
+       if (error != B_OK)
+               return error;
+
+       // update stat data
+       newSymLink->SetHardLinks(1);
+
+       directory->Touched(NODE_MODIFIED);
+
+       // commit the transaction
+       return transaction.Commit();
+}
+
+
+static status_t
+checksumfs_unlink(fs_volume* fsVolume, fs_vnode* dir, const char* name)
+{
+       return remove_entry(fsVolume, dir, name, false);
+}
+
+
+static status_t
 checksumfs_read_stat(fs_volume* fsVolume, fs_vnode* vnode, struct stat* st)
 {
        Node* node = (Node*)vnode->private_node;
@@ -869,11 +947,11 @@
        NULL,   // checksumfs_deselect,
        NULL,   // checksumfs_fsync,
 
-       NULL,   // checksumfs_read_symlink,
-       NULL,   // checksumfs_create_symlink,
+       checksumfs_read_symlink,
+       checksumfs_create_symlink,
 
        NULL,   // checksumfs_link,
-       NULL,   // checksumfs_unlink,
+       checksumfs_unlink,
        NULL,   // checksumfs_rename,
 
        NULL,   // checksumfs_access,


Other related posts:

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