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 // The name may be empty, in that case, userspace will generate one. 34 return fSuperBlock.fs_volname; 35 } 36 37 38 bool 39 Volume::IsValidSuperBlock() 40 { 41 return fSuperBlock.IsValid(); 42 } 43 44 45 Volume::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 55 Volume::~Volume() 56 { 57 mutex_destroy(&fLock); 58 TRACE("Volume::Destructor : Removing Volume\n"); 59 } 60 61 62 status_t 63 Volume::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 79 status_t 80 Volume::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 122 status_t 123 Volume::Unmount() 124 { 125 TRACE("Unmounting the volume"); 126 127 TRACE("Closing device"); 128 close(fDevice); 129 130 return B_OK; 131 } 132