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