[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