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