1 /* 2 * Copyright 2001 - 2017, Axel Dörfler, axeld @pinc - software.de. 3 * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "Volume.h" 9 10 #include "Inode.h" 11 12 13 Volume::Volume(fs_volume *volume) 14 : fFSVolume(volume) 15 { 16 fFlags = 0; 17 mutex_init(&fLock, "xfs volume"); 18 TRACE("Volume::Volume() : Initialising volume"); 19 } 20 21 22 Volume::~Volume() 23 { 24 mutex_destroy(&fLock); 25 TRACE("Volume::Destructor : Removing Volume"); 26 } 27 28 29 bool 30 Volume::IsValidSuperBlock() const 31 { 32 return fSuperBlock.IsValid(); 33 } 34 35 36 status_t 37 Volume::Identify(int fd, XfsSuperBlock *superBlock) 38 { 39 40 TRACE("Volume::Identify() : Identifying Volume in progress"); 41 42 if (read_pos(fd, 0, superBlock, sizeof(XfsSuperBlock)) 43 != sizeof(XfsSuperBlock)) 44 return B_IO_ERROR; 45 46 superBlock->SwapEndian(); 47 48 if (!superBlock->IsValid()) { 49 ERROR("Volume::Identify(): Invalid Superblock!\n"); 50 return B_BAD_VALUE; 51 } 52 return B_OK; 53 } 54 55 56 status_t 57 Volume::Mount(const char *deviceName, uint32 flags) 58 { 59 TRACE("Volume::Mount() : Mounting in progress"); 60 61 flags |= B_MOUNT_READ_ONLY; 62 63 if ((flags & B_MOUNT_READ_ONLY) != 0) { 64 TRACE("Volume::Mount(): Read only\n"); 65 } else { 66 TRACE("Volume::Mount(): Read write\n"); 67 } 68 69 DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0 70 ? O_RDONLY 71 : O_RDWR); 72 fDevice = opener.Device(); 73 if (fDevice < B_OK) { 74 ERROR("Volume::Mount(): couldn't open device\n"); 75 return fDevice; 76 } 77 78 if (opener.IsReadOnly()) 79 fFlags |= VOLUME_READ_ONLY; 80 81 // read the superblock 82 status_t status = Identify(fDevice, &fSuperBlock); 83 if (status != B_OK) { 84 ERROR("Volume::Mount(): Invalid super block!\n"); 85 return B_BAD_VALUE; 86 } 87 88 TRACE("Volume::Mount(): Valid SuperBlock.\n"); 89 90 // check if the device size is large enough to hold the file system 91 off_t diskSize; 92 if (opener.GetSize(&diskSize) != B_OK) { 93 ERROR("Volume:Mount() Unable to get diskSize"); 94 return B_ERROR; 95 } 96 97 opener.Keep(); 98 99 //publish the root inode 100 Inode* rootInode = new(std::nothrow) Inode(this, Root()); 101 if (rootInode == NULL) 102 return B_NO_MEMORY; 103 104 status = rootInode->Init(); 105 if (status != B_OK) 106 return status; 107 108 status = publish_vnode(FSVolume(), Root(), 109 (void*)rootInode, &gxfsVnodeOps, rootInode->Mode(), 0); 110 if (status != B_OK) 111 return B_BAD_VALUE; 112 113 return B_OK; 114 } 115 116 117 status_t 118 Volume::Unmount() 119 { 120 TRACE("Volume::Unmount(): Unmounting"); 121 122 TRACE("Volume::Unmount(): Closing device"); 123 close(fDevice); 124 125 return B_OK; 126 } 127