xref: /haiku/src/add-ons/kernel/file_systems/ufs2/Volume.cpp (revision 3af8011358bd4c624a0979336d48dabb466171ed)
1 /*
2  * Copyright 2020 Suhel Mehta, mehtasuhel@gmail.com
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 #include "Volume.h"
6 
7 #include "DeviceOpener.h"
8 #include "Inode.h"
9 
10 
11 #define TRACE_UFS2
12 #ifdef TRACE_UFS2
13 #define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x);
14 #else
15 #define TRACE(x...) ;
16 #endif
17 #define ERROR(x...) dprintf("\33[34mufs2:\33[0m " x)
18 
19 
20 bool
21 ufs2_super_block::IsValid()
22 {
23 	if (fs_magic != FS_UFS2_MAGIC)
24 		return false;
25 
26 	return true;
27 }
28 
29 
30 const char*
31 Volume::Name() const
32 {
33 	if (fSuperBlock.fs_volname[0])
34 		return fSuperBlock.fs_volname;
35 
36 	return fName;
37 }
38 
39 
40 bool
41 Volume::IsValidSuperBlock()
42 {
43 	return fSuperBlock.IsValid();
44 }
45 
46 
47 Volume::Volume(fs_volume *volume)
48 	: fFSVolume(volume),
49 	fRootNode(NULL)
50 {
51 	fFlags = 0;
52 	mutex_init(&fLock, "ufs2 volume");
53 	TRACE("Volume::Volume() : Initialising volume\n");
54 }
55 
56 
57 Volume::~Volume()
58 {
59 	mutex_destroy(&fLock);
60 	TRACE("Volume::Destructor : Removing Volume\n");
61 }
62 
63 
64 status_t
65 Volume::Identify(int fd, ufs2_super_block *superBlock)
66 {
67 	if (read_pos(fd, SBLOCK_UFS2, superBlock,
68 		sizeof(ufs2_super_block)) != sizeof(ufs2_super_block))
69 		return B_IO_ERROR;
70 
71 
72 	if (!superBlock->IsValid()) {
73 		ERROR("Invalid superblock! Identify failed!!\n");
74 		return B_BAD_VALUE;
75 	}
76 
77 	return B_OK;
78 }
79 
80 
81 status_t
82 Volume::Mount(const char *deviceName, uint32 flags)
83 {
84 	TRACE("Mounting volume... Please wait.\n");
85 	flags |= B_MOUNT_READ_ONLY;
86 	if ((flags & B_MOUNT_READ_ONLY) != 0)
87 	{
88 		TRACE("Volume is read only\n");
89 	}
90 	else
91 	{
92 		TRACE("Volume is read write\n");
93 	}
94 
95 	DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
96 									? O_RDONLY:O_RDWR);
97 	fDevice = opener.Device();
98 	if (fDevice < B_OK) {
99 		ERROR("Could not open device\n");
100 		return fDevice;
101 	}
102 
103 	if (opener.IsReadOnly())
104 		fFlags |= VOLUME_READ_ONLY;
105 
106 	status_t status = Identify(fDevice, &fSuperBlock);
107 	if (status != B_OK) {
108 		ERROR("Invalid super block\n");
109 		return status;
110 	}
111 
112 	TRACE("Valid super block\n");
113 
114 	fRootNode = new(std::nothrow) Inode(this, UFS2_ROOT);
115 	status = publish_vnode(this->FSVolume(), UFS2_ROOT, (void*)fRootNode,
116 			&gufs2VnodeOps, fRootNode->Mode(), 0);
117 
118 	opener.Keep();
119 	return B_OK;
120 
121 }
122 
123 
124 status_t
125 Volume::Unmount()
126 {
127 	TRACE("Unmounting the volume");
128 
129 	TRACE("Closing device");
130 	close(fDevice);
131 
132 	return B_OK;
133 }
134