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 20bool 21ufs2_super_block::IsValid() 22{ 23 if (fs_magic != FS_UFS2_MAGIC) 24 return false; 25 26 return true; 27} 28 29 30const char* 31Volume::Name() const 32{ 33 // The name may be empty, in that case, userspace will generate one. 34 return fSuperBlock.fs_volname; 35} 36 37 38bool 39Volume::IsValidSuperBlock() 40{ 41 return fSuperBlock.IsValid(); 42} 43 44 45Volume::Volume(fs_volume *volume) 46 : fFSVolume(volume), 47 fRootNode(NULL) 48{ 49 fFlags = 0; 50 mutex_init(&fLock, "ufs2 volume"); 51 TRACE("Volume::Volume() : Initialising volume\n"); 52} 53 54 55Volume::~Volume() 56{ 57 mutex_destroy(&fLock); 58 TRACE("Volume::Destructor : Removing Volume\n"); 59} 60 61 62status_t 63Volume::Identify(int fd, ufs2_super_block *superBlock) 64{ 65 if (read_pos(fd, SBLOCK_UFS2, superBlock, 66 sizeof(ufs2_super_block)) != sizeof(ufs2_super_block)) 67 return B_IO_ERROR; 68 69 70 if (!superBlock->IsValid()) { 71 ERROR("Invalid superblock! Identify failed!!\n"); 72 return B_BAD_VALUE; 73 } 74 75 return B_OK; 76} 77 78 79status_t 80Volume::Mount(const char *deviceName, uint32 flags) 81{ 82 TRACE("Mounting volume... Please wait.\n"); 83 flags |= B_MOUNT_READ_ONLY; 84 if ((flags & B_MOUNT_READ_ONLY) != 0) 85 { 86 TRACE("Volume is read only\n"); 87 } 88 else 89 { 90 TRACE("Volume is read write\n"); 91 } 92 93 DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0 94 ? O_RDONLY:O_RDWR); 95 fDevice = opener.Device(); 96 if (fDevice < B_OK) { 97 ERROR("Could not open device\n"); 98 return fDevice; 99 } 100 101 if (opener.IsReadOnly()) 102 fFlags |= VOLUME_READ_ONLY; 103 104 status_t status = Identify(fDevice, &fSuperBlock); 105 if (status != B_OK) { 106 ERROR("Invalid super block\n"); 107 return status; 108 } 109 110 TRACE("Valid super block\n"); 111 112 fRootNode = new(std::nothrow) Inode(this, UFS2_ROOT); 113 status = publish_vnode(this->FSVolume(), UFS2_ROOT, (void*)fRootNode, 114 &gufs2VnodeOps, fRootNode->Mode(), 0); 115 116 opener.Keep(); 117 return B_OK; 118 119} 120 121 122status_t 123Volume::Unmount() 124{ 125 TRACE("Unmounting the volume"); 126 127 TRACE("Closing device"); 128 close(fDevice); 129 130 return B_OK; 131} 132