2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "kernel_interface.h"
14 #include <fs_interface.h>
15 #include <KernelExport.h>
16 #include <io_requests.h>
18 #include <AutoDeleter.h>
20 #include "AttributeCookie.h"
21 #include "AttributeDirectoryCookie.h"
22 #include "DebugSupport.h"
23 #include "Directory.h"
24 #include "GlobalFactory.h"
26 #include "PackageFSRoot.h"
27 #include "StringConstants.h"
28 #include "StringPool.h"
33 static const uint32 kOptimalIOSize
= 64 * 1024;
36 // #pragma mark - helper functions
40 check_access(Node
* node
, int mode
)
42 // write access requested?
44 return B_READ_ONLY_DEVICE
;
46 return check_access_permissions(mode
, node
->Mode(), node
->GroupID(),
51 // #pragma mark - Volume
55 packagefs_mount(fs_volume
* fsVolume
, const char* device
, uint32 flags
,
56 const char* parameters
, ino_t
* _rootID
)
58 FUNCTION("fsVolume: %p, device: \"%s\", flags: %#" B_PRIx32
", parameters: "
59 "\"%s\"\n", fsVolume
, device
, flags
, parameters
);
61 // create a Volume object
62 Volume
* volume
= new(std::nothrow
) Volume(fsVolume
);
64 RETURN_ERROR(B_NO_MEMORY
);
65 ObjectDeleter
<Volume
> volumeDeleter(volume
);
67 // Initialize the fs_volume now already, so it is mostly usable in during
69 fsVolume
->private_volume
= volumeDeleter
.Detach();
70 fsVolume
->ops
= &gPackageFSVolumeOps
;
72 status_t error
= volume
->Mount(parameters
);
77 *_rootID
= volume
->RootDirectory()->ID();
84 packagefs_unmount(fs_volume
* fsVolume
)
86 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
88 FUNCTION("volume: %p\n", volume
);
98 packagefs_read_fs_info(fs_volume
* fsVolume
, struct fs_info
* info
)
100 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
102 FUNCTION("volume: %p, info: %p\n", volume
, info
);
104 info
->flags
= B_FS_IS_PERSISTENT
| B_FS_IS_READONLY
| B_FS_HAS_MIME
105 | B_FS_HAS_ATTR
| B_FS_HAS_QUERY
| B_FS_SUPPORTS_NODE_MONITORING
;
106 info
->block_size
= 4096;
107 info
->io_size
= kOptimalIOSize
;
108 info
->total_blocks
= info
->free_blocks
= 1;
109 strlcpy(info
->volume_name
, volume
->RootDirectory()->Name(),
110 sizeof(info
->volume_name
));
115 // #pragma mark - VNodes
119 packagefs_lookup(fs_volume
* fsVolume
, fs_vnode
* fsDir
, const char* entryName
,
122 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
123 Node
* dir
= (Node
*)fsDir
->private_node
;
125 FUNCTION("volume: %p, dir: %p (%" B_PRId64
"), entry: \"%s\"\n", volume
,
126 dir
, dir
->ID(), entryName
);
128 if (!S_ISDIR(dir
->Mode()))
129 return B_NOT_A_DIRECTORY
;
132 if (strcmp(entryName
, ".") == 0) {
135 return volume
->GetVNode(*_vnid
, node
);
139 if (strcmp(entryName
, "..") == 0) {
141 *_vnid
= dir
->Parent()->ID();
142 return volume
->GetVNode(*_vnid
, node
);
145 // resolve normal entries -- look up the node
146 NodeReadLocker
dirLocker(dir
);
147 String entryNameString
;
148 Node
* node
= dynamic_cast<Directory
*>(dir
)->FindChild(StringKey(entryName
));
150 return B_ENTRY_NOT_FOUND
;
151 BReference
<Node
> nodeReference(node
);
154 // get the vnode reference
156 RETURN_ERROR(volume
->GetVNode(*_vnid
, node
));
161 packagefs_get_vnode_name(fs_volume
* fsVolume
, fs_vnode
* fsNode
, char* buffer
,
164 Node
* node
= (Node
*)fsNode
->private_node
;
166 FUNCTION("volume: %p, node: %p (%" B_PRIdINO
"), %p, %zu\n",
167 fsVolume
->private_volume
, node
, node
->ID(), buffer
, bufferSize
);
169 if (strlcpy(buffer
, node
->Name(), bufferSize
) >= bufferSize
)
170 return B_BUFFER_OVERFLOW
;
177 packagefs_get_vnode(fs_volume
* fsVolume
, ino_t vnid
, fs_vnode
* fsNode
,
178 int* _type
, uint32
* _flags
, bool reenter
)
180 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
182 FUNCTION("volume: %p, vnid: %" B_PRId64
"\n", volume
, vnid
);
184 VolumeReadLocker
volumeLocker(volume
);
185 Node
* node
= volume
->FindNode(vnid
);
187 return B_ENTRY_NOT_FOUND
;
188 BReference
<Node
> nodeReference(node
);
189 volumeLocker
.Unlock();
191 NodeWriteLocker
nodeLocker(node
);
192 status_t error
= node
->VFSInit(volume
->ID());
197 fsNode
->private_node
= nodeReference
.Detach();
198 fsNode
->ops
= &gPackageFSVnodeOps
;
199 *_type
= node
->Mode() & S_IFMT
;
207 packagefs_put_vnode(fs_volume
* fsVolume
, fs_vnode
* fsNode
, bool reenter
)
209 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
210 Node
* node
= (Node
*)fsNode
->private_node
;
212 FUNCTION("volume: %p, node: %p\n", volume
, node
);
215 NodeWriteLocker
nodeLocker(node
);
219 node
->ReleaseReference();
225 // #pragma mark - Request I/O
229 packagefs_io(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* cookie
,
232 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
233 Node
* node
= (Node
*)fsNode
->private_node
;
235 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p, request: %p\n",
236 volume
, node
, node
->ID(), cookie
, request
);
239 if (io_request_is_write(request
))
240 RETURN_ERROR(B_READ_ONLY_DEVICE
);
242 status_t error
= node
->Read(request
);
243 notify_io_request(request
, error
);
248 // #pragma mark - Nodes
252 packagefs_ioctl(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* cookie
,
253 uint32 operation
, void* buffer
, size_t size
)
255 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
256 Node
* node
= (Node
*)fsNode
->private_node
;
258 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p, operation: %"
259 B_PRIu32
", buffer: %p, size: %zu\n", volume
, node
, node
->ID(), cookie
,
260 operation
, buffer
, size
);
263 return volume
->IOCtl(node
, operation
, buffer
, size
);
268 packagefs_read_symlink(fs_volume
* fsVolume
, fs_vnode
* fsNode
, char* buffer
,
271 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
272 Node
* node
= (Node
*)fsNode
->private_node
;
274 FUNCTION("volume: %p, node: %p (%" B_PRId64
")\n", volume
, node
,
278 NodeReadLocker
nodeLocker(node
);
280 if (!S_ISLNK(node
->Mode()))
283 return node
->ReadSymlink(buffer
, _bufferSize
);
288 packagefs_access(fs_volume
* fsVolume
, fs_vnode
* fsNode
, int mode
)
290 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
291 Node
* node
= (Node
*)fsNode
->private_node
;
293 FUNCTION("volume: %p, node: %p (%" B_PRId64
")\n", volume
, node
,
297 NodeReadLocker
nodeLocker(node
);
298 return check_access(node
, mode
);
303 packagefs_read_stat(fs_volume
* fsVolume
, fs_vnode
* fsNode
, struct stat
* st
)
305 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
306 Node
* node
= (Node
*)fsNode
->private_node
;
308 FUNCTION("volume: %p, node: %p (%" B_PRId64
")\n", volume
, node
,
312 NodeReadLocker
nodeLocker(node
);
314 st
->st_mode
= node
->Mode();
316 st
->st_uid
= node
->UserID();
317 st
->st_gid
= node
->GroupID();
318 st
->st_size
= node
->FileSize();
319 st
->st_blksize
= kOptimalIOSize
;
320 st
->st_mtim
= node
->ModifiedTime();
321 st
->st_atim
= st
->st_mtim
;
322 st
->st_ctim
= st
->st_mtim
;
323 // TODO: Perhaps manage a changed time (particularly for directories)?
324 st
->st_crtim
= st
->st_mtim
;
325 st
->st_blocks
= (st
->st_size
+ 511) / 512;
331 // #pragma mark - Files
337 FileCookie(int openMode
)
346 packagefs_open(fs_volume
* fsVolume
, fs_vnode
* fsNode
, int openMode
,
349 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
350 Node
* node
= (Node
*)fsNode
->private_node
;
352 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), openMode %#x\n",
353 volume
, node
, node
->ID(), openMode
);
356 NodeReadLocker
nodeLocker(node
);
358 // check the open mode and permissions
359 if (S_ISDIR(node
->Mode()) && (openMode
& O_RWMASK
) != O_RDONLY
)
360 return B_IS_A_DIRECTORY
;
362 if ((openMode
& O_RWMASK
) != O_RDONLY
)
363 return B_NOT_ALLOWED
;
365 status_t error
= check_access(node
, R_OK
);
369 // allocate the cookie
370 FileCookie
* cookie
= new(std::nothrow
) FileCookie(openMode
);
372 RETURN_ERROR(B_NO_MEMORY
);
381 packagefs_close(fs_volume
* fs
, fs_vnode
* _node
, void* cookie
)
388 packagefs_free_cookie(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
390 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
391 Node
* node
= (Node
*)fsNode
->private_node
;
392 FileCookie
* cookie
= (FileCookie
*)_cookie
;
394 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
406 packagefs_read(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
,
407 off_t offset
, void* buffer
, size_t* bufferSize
)
409 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
410 Node
* node
= (Node
*)fsNode
->private_node
;
411 FileCookie
* cookie
= (FileCookie
*)_cookie
;
413 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p, offset: %"
414 B_PRId64
", buffer: %p, size: %" B_PRIuSIZE
"\n", volume
, node
,
415 node
->ID(), cookie
, offset
, buffer
, *bufferSize
);
418 if ((cookie
->openMode
& O_RWMASK
) != O_RDONLY
)
421 return node
->Read(offset
, buffer
, bufferSize
);
425 // #pragma mark - Directories
428 struct DirectoryCookie
: DirectoryIterator
{
429 Directory
* directory
;
433 DirectoryCookie(Directory
* directory
)
435 directory(directory
),
445 directory
->RemoveDirectoryIterator(this);
451 directory
->RemoveDirectoryIterator(this);
458 Node
* Current(const char*& _name
) const
468 _name
= node
->Name();
477 node
= directory
->Parent();
484 node
= directory
->FirstChild();
488 node
= directory
->NextChild(node
);
493 directory
->RemoveDirectoryIterator(this);
501 directory
->AddDirectoryIterator(this);
511 packagefs_open_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void** _cookie
)
513 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
514 Node
* node
= (Node
*)fsNode
->private_node
;
516 FUNCTION("volume: %p, node: %p (%" B_PRId64
")\n", volume
, node
,
520 if (!S_ISDIR(node
->Mode()))
521 return B_NOT_A_DIRECTORY
;
523 Directory
* dir
= dynamic_cast<Directory
*>(node
);
525 status_t error
= check_access(dir
, R_OK
);
530 NodeWriteLocker
dirLocker(dir
);
531 DirectoryCookie
* cookie
= new(std::nothrow
) DirectoryCookie(dir
);
533 RETURN_ERROR(B_NO_MEMORY
);
541 packagefs_close_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* cookie
)
548 packagefs_free_dir_cookie(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
550 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
551 Node
* node
= (Node
*)fsNode
->private_node
;
552 DirectoryCookie
* cookie
= (DirectoryCookie
*)_cookie
;
554 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
559 NodeWriteLocker
dirLocker(node
);
567 packagefs_read_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
,
568 struct dirent
* buffer
, size_t bufferSize
, uint32
* _count
)
570 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
571 Node
* node
= (Node
*)fsNode
->private_node
;
572 DirectoryCookie
* cookie
= (DirectoryCookie
*)_cookie
;
574 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
579 NodeWriteLocker
dirLocker(cookie
->directory
);
581 uint32 maxCount
= *_count
;
584 dirent
* previousEntry
= NULL
;
587 while (Node
* child
= cookie
->Current(name
)) {
588 // don't read more entries than requested
589 if (count
>= maxCount
)
592 // align the buffer for subsequent entries
594 addr_t offset
= (addr_t
)buffer
% 8;
597 if (bufferSize
<= offset
)
600 previousEntry
->d_reclen
+= offset
;
601 buffer
= (dirent
*)((addr_t
)buffer
+ offset
);
602 bufferSize
-= offset
;
606 // fill in the entry name -- checks whether the entry fits into the
608 if (!set_dirent_name(buffer
, bufferSize
, name
)) {
610 RETURN_ERROR(B_BUFFER_OVERFLOW
);
614 // fill in the other data
615 buffer
->d_dev
= volume
->ID();
616 buffer
->d_ino
= child
->ID();
619 previousEntry
= buffer
;
620 bufferSize
-= buffer
->d_reclen
;
621 buffer
= (dirent
*)((addr_t
)buffer
+ buffer
->d_reclen
);
632 packagefs_rewind_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
634 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
635 Node
* node
= (Node
*)fsNode
->private_node
;
636 DirectoryCookie
* cookie
= (DirectoryCookie
*)_cookie
;
638 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
643 NodeWriteLocker
dirLocker(node
);
650 // #pragma mark - Attribute Directories
654 packagefs_open_attr_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void** _cookie
)
656 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
657 Node
* node
= (Node
*)fsNode
->private_node
;
659 FUNCTION("volume: %p, node: %p (%" B_PRId64
")\n", volume
, node
,
663 status_t error
= check_access(node
, R_OK
);
668 NodeReadLocker
nodeLocker(node
);
669 AttributeDirectoryCookie
* cookie
;
670 error
= node
->OpenAttributeDirectory(cookie
);
680 packagefs_close_attr_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
682 AttributeDirectoryCookie
* cookie
= (AttributeDirectoryCookie
*)_cookie
;
683 return cookie
->Close();
688 packagefs_free_attr_dir_cookie(fs_volume
* fsVolume
, fs_vnode
* fsNode
,
691 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
692 Node
* node
= (Node
*)fsNode
->private_node
;
693 AttributeDirectoryCookie
* cookie
= (AttributeDirectoryCookie
*)_cookie
;
695 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
707 packagefs_read_attr_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
,
708 struct dirent
* buffer
, size_t bufferSize
, uint32
* _count
)
710 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
711 Node
* node
= (Node
*)fsNode
->private_node
;
712 AttributeDirectoryCookie
* cookie
= (AttributeDirectoryCookie
*)_cookie
;
714 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
719 return cookie
->Read(volume
->ID(), node
->ID(), buffer
, bufferSize
, _count
);
724 packagefs_rewind_attr_dir(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
726 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
727 Node
* node
= (Node
*)fsNode
->private_node
;
728 AttributeDirectoryCookie
* cookie
= (AttributeDirectoryCookie
*)_cookie
;
730 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
735 return cookie
->Rewind();
739 // #pragma mark - Attribute Operations
743 packagefs_open_attr(fs_volume
* fsVolume
, fs_vnode
* fsNode
, const char* name
,
744 int openMode
, void** _cookie
)
746 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
747 Node
* node
= (Node
*)fsNode
->private_node
;
749 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), name: \"%s\", openMode "
750 "%#x\n", volume
, node
, node
->ID(), name
, openMode
);
753 NodeReadLocker
nodeLocker(node
);
755 // check the open mode and permissions
756 if ((openMode
& O_RWMASK
) != O_RDONLY
)
757 return B_NOT_ALLOWED
;
759 status_t error
= check_access(node
, R_OK
);
763 AttributeCookie
* cookie
;
764 error
= node
->OpenAttribute(StringKey(name
), openMode
, cookie
);
774 packagefs_close_attr(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
776 AttributeCookie
* cookie
= (AttributeCookie
*)_cookie
;
777 RETURN_ERROR(cookie
->Close());
782 packagefs_free_attr_cookie(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
)
784 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
785 Node
* node
= (Node
*)fsNode
->private_node
;
786 AttributeCookie
* cookie
= (AttributeCookie
*)_cookie
;
788 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
800 packagefs_read_attr(fs_volume
* fsVolume
, fs_vnode
* fsNode
, void* _cookie
,
801 off_t offset
, void* buffer
, size_t* bufferSize
)
803 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
804 Node
* node
= (Node
*)fsNode
->private_node
;
805 AttributeCookie
* cookie
= (AttributeCookie
*)_cookie
;
807 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
812 return cookie
->ReadAttribute(offset
, buffer
, bufferSize
);
817 packagefs_read_attr_stat(fs_volume
* fsVolume
, fs_vnode
* fsNode
,
818 void* _cookie
, struct stat
* st
)
820 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
821 Node
* node
= (Node
*)fsNode
->private_node
;
822 AttributeCookie
* cookie
= (AttributeCookie
*)_cookie
;
824 FUNCTION("volume: %p, node: %p (%" B_PRId64
"), cookie: %p\n", volume
, node
,
829 return cookie
->ReadAttributeStat(st
);
833 // #pragma mark - index directory & index operations
836 // NOTE: We don't do any locking in the index dir hooks, since once mounted
837 // the index directory is immutable.
841 packagefs_open_index_dir(fs_volume
* fsVolume
, void** _cookie
)
843 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
845 FUNCTION("volume: %p\n", volume
);
847 IndexDirIterator
* iterator
= new(std::nothrow
) IndexDirIterator(
848 volume
->GetIndexDirIterator());
849 if (iterator
== NULL
)
858 packagefs_close_index_dir(fs_volume
* fsVolume
, void* cookie
)
865 packagefs_free_index_dir_cookie(fs_volume
* fsVolume
, void* cookie
)
867 FUNCTION("volume: %p, cookie: %p\n", fsVolume
->private_volume
, cookie
);
869 delete (IndexDirIterator
*)cookie
;
875 packagefs_read_index_dir(fs_volume
* fsVolume
, void* cookie
,
876 struct dirent
* buffer
, size_t bufferSize
, uint32
* _num
)
878 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
880 FUNCTION("volume: %p, cookie: %p, buffer: %p, bufferSize: %zu, num: %"
881 B_PRIu32
"\n", volume
, cookie
, buffer
, bufferSize
, *_num
);
883 IndexDirIterator
* iterator
= (IndexDirIterator
*)cookie
;
888 IndexDirIterator previousIterator
= *iterator
;
890 // get the next index
891 Index
* index
= iterator
->Next();
898 if (!set_dirent_name(buffer
, bufferSize
, index
->Name())) {
899 *iterator
= previousIterator
;
900 return B_BUFFER_OVERFLOW
;
903 buffer
->d_dev
= volume
->ID();
912 packagefs_rewind_index_dir(fs_volume
* fsVolume
, void* cookie
)
914 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
916 FUNCTION("volume: %p, cookie: %p\n", volume
, cookie
);
918 IndexDirIterator
* iterator
= (IndexDirIterator
*)cookie
;
919 *iterator
= volume
->GetIndexDirIterator();
926 packagefs_create_index(fs_volume
* fsVolume
, const char* name
, uint32 type
,
929 return B_NOT_SUPPORTED
;
934 packagefs_remove_index(fs_volume
* fsVolume
, const char* name
)
936 return B_NOT_SUPPORTED
;
941 packagefs_read_index_stat(fs_volume
* fsVolume
, const char* name
,
944 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
946 FUNCTION("volume: %p, name: \"%s\", stat: %p\n", volume
, name
, stat
);
948 Index
* index
= volume
->FindIndex(StringKey(name
));
950 return B_ENTRY_NOT_FOUND
;
952 VolumeReadLocker
volumeReadLocker(volume
);
954 memset(stat
, 0, sizeof(*stat
));
955 // TODO: st_mtime, st_crtime, st_uid, st_gid are made available to
956 // userland, so we should make an attempt to fill in values that make
959 stat
->st_type
= index
->Type();
960 stat
->st_size
= index
->CountEntries();
966 // #pragma mark - query operations
970 packagefs_open_query(fs_volume
* fsVolume
, const char* queryString
, uint32 flags
,
971 port_id port
, uint32 token
, void** _cookie
)
973 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
975 FUNCTION("volume: %p, query: \"%s\", flags: %#" B_PRIx32
", port: %"
976 B_PRId32
", token: %" B_PRIu32
"\n", volume
, queryString
, flags
, port
,
979 VolumeWriteLocker
volumeWriteLocker(volume
);
982 status_t error
= Query::Create(volume
, queryString
, flags
, port
, token
,
993 packagefs_close_query(fs_volume
* fsVolume
, void* cookie
)
1001 packagefs_free_query_cookie(fs_volume
* fsVolume
, void* cookie
)
1003 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
1004 Query
* query
= (Query
*)cookie
;
1006 FUNCTION("volume: %p, query: %p\n", volume
, query
);
1008 VolumeWriteLocker
volumeWriteLocker(volume
);
1017 packagefs_read_query(fs_volume
* fsVolume
, void* cookie
, struct dirent
* buffer
,
1018 size_t bufferSize
, uint32
* _num
)
1020 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
1021 Query
* query
= (Query
*)cookie
;
1023 FUNCTION("volume: %p, query: %p\n", volume
, query
);
1025 VolumeWriteLocker
volumeWriteLocker(volume
);
1027 status_t error
= query
->GetNextEntry(buffer
, bufferSize
);
1030 else if (error
== B_ENTRY_NOT_FOUND
)
1040 packagefs_rewind_query(fs_volume
* fsVolume
, void* cookie
)
1042 Volume
* volume
= (Volume
*)fsVolume
->private_volume
;
1043 Query
* query
= (Query
*)cookie
;
1045 FUNCTION("volume: %p, query: %p\n", volume
, query
);
1047 VolumeWriteLocker
volumeWriteLocker(volume
);
1049 return query
->Rewind();
1053 // #pragma mark - Module Interface
1057 packagefs_std_ops(int32 op
, ...)
1063 PRINT("package_std_ops(): B_MODULE_INIT\n");
1065 status_t error
= StringPool::Init();
1066 if (error
!= B_OK
) {
1067 ERROR("Failed to init StringPool\n");
1072 if (!StringConstants::Init()) {
1073 ERROR("Failed to init string constants\n");
1074 StringPool::Cleanup();
1079 error
= GlobalFactory::CreateDefault();
1080 if (error
!= B_OK
) {
1081 ERROR("Failed to init GlobalFactory\n");
1082 StringConstants::Cleanup();
1083 StringPool::Cleanup();
1088 error
= PackageFSRoot::GlobalInit();
1089 if (error
!= B_OK
) {
1090 ERROR("Failed to init PackageFSRoot\n");
1091 GlobalFactory::DeleteDefault();
1092 StringConstants::Cleanup();
1093 StringPool::Cleanup();
1101 case B_MODULE_UNINIT
:
1103 PRINT("package_std_ops(): B_MODULE_UNINIT\n");
1104 PackageFSRoot::GlobalUninit();
1105 GlobalFactory::DeleteDefault();
1106 StringConstants::Cleanup();
1107 StringPool::Cleanup();
1118 static file_system_module_info sPackageFSModuleInfo
= {
1120 "file_systems/packagefs" B_CURRENT_FS_API_VERSION
,
1125 "packagefs", // short_name
1126 "Package File System", // pretty_name
1131 NULL
, // identify_partition,
1132 NULL
, // scan_partition,
1133 NULL
, // free_identify_partition_cookie,
1134 NULL
, // free_partition_content_cookie()
1140 fs_volume_ops gPackageFSVolumeOps
= {
1142 &packagefs_read_fs_info
,
1143 NULL
, // write_fs_info,
1146 &packagefs_get_vnode
,
1149 &packagefs_open_index_dir
,
1150 &packagefs_close_index_dir
,
1151 &packagefs_free_index_dir_cookie
,
1152 &packagefs_read_index_dir
,
1153 &packagefs_rewind_index_dir
,
1155 &packagefs_create_index
,
1156 &packagefs_remove_index
,
1157 &packagefs_read_index_stat
,
1160 &packagefs_open_query
,
1161 &packagefs_close_query
,
1162 &packagefs_free_query_cookie
,
1163 &packagefs_read_query
,
1164 &packagefs_rewind_query
,
1166 // TODO: FS layer operations
1170 fs_vnode_ops gPackageFSVnodeOps
= {
1173 &packagefs_get_vnode_name
,
1174 &packagefs_put_vnode
,
1175 &packagefs_put_vnode
, // remove_vnode -- same as put_vnode
1179 NULL
, // read_pages,
1180 NULL
, // write_pages,
1183 NULL
, // cancel_io()
1185 NULL
, // get_file_map,
1193 &packagefs_read_symlink
,
1194 NULL
, // create_symlink,
1201 &packagefs_read_stat
,
1202 NULL
, // write_stat,
1203 NULL
, // preallocate,
1209 &packagefs_free_cookie
,
1213 // directory operations
1214 NULL
, // create_dir,
1215 NULL
, // remove_dir,
1216 &packagefs_open_dir
,
1217 &packagefs_close_dir
,
1218 &packagefs_free_dir_cookie
,
1219 &packagefs_read_dir
,
1220 &packagefs_rewind_dir
,
1222 // attribute directory operations
1223 &packagefs_open_attr_dir
,
1224 &packagefs_close_attr_dir
,
1225 &packagefs_free_attr_dir_cookie
,
1226 &packagefs_read_attr_dir
,
1227 &packagefs_rewind_attr_dir
,
1229 // attribute operations
1230 NULL
, // create_attr,
1231 &packagefs_open_attr
,
1232 &packagefs_close_attr
,
1233 &packagefs_free_attr_cookie
,
1234 &packagefs_read_attr
,
1235 NULL
, // write_attr,
1237 &packagefs_read_attr_stat
,
1238 NULL
, // write_attr_stat,
1239 NULL
, // rename_attr,
1240 NULL
// remove_attr,
1242 // TODO: FS layer operations
1246 module_info
*modules
[] = {
1247 (module_info
*)&sPackageFSModuleInfo
,