xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
1 /*
2  * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "Directory.h"
8 
9 #include "DebugSupport.h"
10 #include "UnpackingAttributeCookie.h"
11 #include "UnpackingAttributeDirectoryCookie.h"
12 #include "Utils.h"
13 
14 
15 Directory::Directory(ino_t id)
16 	:
17 	Node(id)
18 {
19 	rw_lock_init(&fLock, "packagefs directory");
20 }
21 
22 
23 Directory::~Directory()
24 {
25 	Node* child = fChildTable.Clear(true);
26 	while (child != NULL) {
27 		Node* next = child->NameHashTableNext();
28 		child->_SetParent(NULL);
29 		child->ReleaseReference();
30 		child = next;
31 	}
32 
33 	rw_lock_destroy(&fLock);
34 }
35 
36 
37 status_t
38 Directory::Init(const String& name)
39 {
40 	status_t error = Node::Init(name);
41 	if (error != B_OK)
42 		return error;
43 
44 	return fChildTable.Init();
45 }
46 
47 
48 mode_t
49 Directory::Mode() const
50 {
51 	return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
52 }
53 
54 
55 off_t
56 Directory::FileSize() const
57 {
58 	return 0;
59 }
60 
61 
62 status_t
63 Directory::Read(off_t offset, void* buffer, size_t* bufferSize)
64 {
65 	return B_IS_A_DIRECTORY;
66 }
67 
68 
69 status_t
70 Directory::Read(io_request* request)
71 {
72 	return B_IS_A_DIRECTORY;
73 }
74 
75 
76 status_t
77 Directory::ReadSymlink(void* buffer, size_t* bufferSize)
78 {
79 	return B_IS_A_DIRECTORY;
80 }
81 
82 
83 void
84 Directory::AddChild(Node* node)
85 {
86 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
87 	ASSERT(node->fParent == NULL);
88 
89 	fChildTable.Insert(node);
90 	fChildList.Add(node);
91 	node->_SetParent(this);
92 	node->AcquireReference();
93 }
94 
95 
96 void
97 Directory::RemoveChild(Node* node)
98 {
99 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
100 	ASSERT(node->fParent == this);
101 
102 	Node* nextNode = fChildList.GetNext(node);
103 
104 	fChildTable.Remove(node);
105 	fChildList.Remove(node);
106 	node->_SetParent(NULL);
107 	node->ReleaseReference();
108 
109 	// adjust directory iterators pointing to the removed child
110 	for (DirectoryIteratorList::Iterator it = fIterators.GetIterator();
111 			DirectoryIterator* iterator = it.Next();) {
112 		if (iterator->node == node)
113 			iterator->node = nextNode;
114 	}
115 }
116 
117 
118 Node*
119 Directory::FindChild(const StringKey& name)
120 {
121 	return fChildTable.Lookup(name);
122 }
123 
124 
125 void
126 Directory::AddDirectoryIterator(DirectoryIterator* iterator)
127 {
128 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
129 	fIterators.Add(iterator);
130 }
131 
132 
133 void
134 Directory::RemoveDirectoryIterator(DirectoryIterator* iterator)
135 {
136 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
137 	fIterators.Remove(iterator);
138 }
139