BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / bindfs / Volume.cpp
blobe811459d3466554da1dbb94fff69f57050c8b92a
1 /*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
7 #include "Volume.h"
9 #include <dirent.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <sys/stat.h>
15 #include <new>
17 #include <driver_settings.h>
18 #include <KernelExport.h>
19 #include <vfs.h>
21 #include <AutoDeleter.h>
23 #include "DebugSupport.h"
24 #include "kernel_interface.h"
25 #include "Node.h"
26 #include "Utils.h"
29 // #pragma mark - Volume
32 Volume::Volume(fs_volume* fsVolume)
34 fFSVolume(fsVolume),
35 fSourceFSVolume(NULL),
36 fSourceVnode(NULL),
37 fRootNode(NULL)
42 Volume::~Volume()
44 if (fSourceVnode != NULL)
45 vfs_put_vnode(fSourceVnode);
49 status_t
50 Volume::Mount(const char* parameterString)
52 const char* source = NULL;
53 void* parameterHandle = parse_driver_settings_string(parameterString);
54 CObjectDeleter<void, status_t> parameterDeleter(parameterHandle,
55 delete_driver_settings);
56 if (parameterHandle != NULL)
57 source = get_driver_parameter(parameterHandle, "source", NULL, NULL);
58 if (source == NULL || source[0] == '\0') {
59 ERROR("need source folder ('source' parameter)!\n");
60 RETURN_ERROR(B_BAD_VALUE);
63 status_t error = vfs_get_vnode_from_path(source, true, &fSourceVnode);
64 if (error != B_OK)
65 RETURN_ERROR(error);
66 if (fSourceVnode == NULL)
67 RETURN_ERROR(B_ENTRY_NOT_FOUND);
68 fs_vnode* sourceFSNode = vfs_fsnode_for_vnode(fSourceVnode);
69 fSourceFSVolume = volume_for_vnode(sourceFSNode);
71 struct stat st;
72 if ((stat(source, &st)) != 0)
73 RETURN_ERROR(B_ERROR);
75 strlcpy(fName, "bindfs:", sizeof(fName));
76 strlcpy(fName, source, sizeof(fName));
78 // create the root node
79 fRootNode = new(std::nothrow) Node(st.st_ino, st.st_mode);
80 if (fRootNode == NULL)
81 RETURN_ERROR(B_NO_MEMORY);
83 _InitVnodeOpsFrom(sourceFSNode);
85 // publish the root node
86 error = publish_vnode(fFSVolume, fRootNode->ID(), fRootNode, &fVnodeOps,
87 fRootNode->Mode() & S_IFMT, 0);
88 if (error != B_OK) {
89 delete fRootNode;
90 fRootNode = NULL;
91 return error;
94 return B_OK;
98 void
99 Volume::Unmount()
104 status_t
105 Volume::_InitVnodeOpsFrom(fs_vnode* sourceNode)
107 // vnode ops
108 int opsCount = sizeof(fVnodeOps) / sizeof(void*);
109 for (int i = 0; i < opsCount; ++i) {
110 if (((void**)sourceNode->ops)[i] == NULL)
111 ((void**)&fVnodeOps)[i] = NULL;
112 else
113 ((void**)&fVnodeOps)[i] = ((void**)&gBindFSVnodeOps)[i];
116 return B_OK;