The Pedigree Project  0.1
LoDisk.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "LoDisk.h"
21 #include "modules/Module.h"
22 #include "modules/system/vfs/VFS.h"
23 #include "pedigree/kernel/LockGuard.h"
24 #include "pedigree/kernel/Log.h"
25 #include "pedigree/kernel/Service.h"
26 #include "pedigree/kernel/ServiceFeatures.h"
27 #include "pedigree/kernel/ServiceManager.h"
28 #include "pedigree/kernel/utilities/assert.h"
29 
30 FileDisk::FileDisk(String file, AccessType mode)
31  : m_pFile(0), m_Mode(mode), m_Cache(), m_MemRegion("FileDisk"),
32  m_ReqMutex(false), m_nAlignPoints(0)
33 {
34  m_pFile = VFS::instance().find(file);
35  if (!m_pFile)
36  WARNING("FileDisk: '" << file << "' doesn't exist...");
37  else
38  {
39  m_pFile->increaseRefCount(false);
40 
41  // Chat to the partition service and let it pick up that we're around
42  // now
43  ServiceFeatures *pFeatures =
44  ServiceManager::instance().enumerateOperations(String("partition"));
45  Service *pService =
46  ServiceManager::instance().getService(String("partition"));
47  NOTICE("Asking if the partition provider supports touch");
48  if (pFeatures->provides(ServiceFeatures::touch))
49  {
50  NOTICE("It does, attempting to inform the partitioner of our "
51  "presence...");
52  if (pService)
53  {
54  if (pService->serve(
56  reinterpret_cast<void *>(static_cast<Disk *>(this)),
57  sizeof(*static_cast<Disk *>(this))))
58  {
59  NOTICE("Successful.");
60  }
61  else
62  ERROR("Failed.");
63  }
64  else
65  ERROR("FileDisk: Couldn't tell the partition service about the "
66  "new disk presence");
67  }
68  else
69  ERROR(
70  "FileDisk: Partition service doesn't appear to support touch");
71  }
72 }
73 
74 FileDisk::~FileDisk()
75 {
76  m_pFile->decreaseRefCount(false);
77 }
78 
79 bool FileDisk::initialise()
80 {
81  return (m_pFile != 0);
82 }
83 
84 uintptr_t FileDisk::read(uint64_t location)
85 {
86  LockGuard<Mutex> guard(m_ReqMutex);
87 
88  if (location % 512)
89  FATAL("Read with location % 512.");
90 
91  if (!m_pFile)
92  return 0;
93 
94  // Look through the align points.
95  uint64_t alignPoint = 0;
96  for (size_t i = 0; i < m_nAlignPoints; i++)
97  if (m_AlignPoints[i] <= location && m_AlignPoints[i] > alignPoint)
98  alignPoint = m_AlignPoints[i];
99  alignPoint %= 4096;
100 
101  // Determine which page the read is in
102  uint64_t readPage = ((location - alignPoint) & ~0xFFFUL) + alignPoint;
103  uint64_t pageOffset = (location - alignPoint) % 4096;
104 
105  uintptr_t buffer = m_Cache.lookup(readPage);
106 
107  if (buffer)
108  return buffer + pageOffset;
109 
110  buffer = m_Cache.insert(readPage);
111 
112  // Read the data from the file itself
113  m_pFile->read(readPage, 4096, buffer);
114 
115  m_Cache.markNoLongerEditing(readPage);
116 
117  return buffer + pageOffset;
118 }
119 
120 void FileDisk::write(uint64_t location)
121 {
122  LockGuard<Mutex> guard(m_ReqMutex);
123  if (!m_pFile)
124  return;
125 
127 }
128 
129 void FileDisk::align(uint64_t location)
130 {
131  assert(m_nAlignPoints < 8);
132  m_AlignPoints[m_nAlignPoints++] = location;
133 }
134 
135 static bool init()
136 {
137  return true;
138 }
139 
140 static void destroy()
141 {
142 }
143 
144 MODULE_INFO("lodisk", &init, &destroy, "vfs");
File * find(const String &path, File *pStartNode=0)
Definition: VFS.cc:243
virtual uintptr_t read(uint64_t location)
Definition: LoDisk.cc:84
virtual void write(uint64_t location)
Definition: LoDisk.cc:120
Definition: String.h:49
virtual bool provides(Type service)
static VFS & instance()
Definition: VFS.cc:56
#define WARNING(text)
Definition: Log.h:78
#define NOTICE(text)
Definition: Log.h:74
#define assert(x)
Definition: assert.h:37
Service * getService(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
#define ERROR(text)
Definition: Log.h:82
virtual void align(uint64_t location)
Sets the page boundary alignment after a specific location on the disk.
Definition: LoDisk.cc:129
#define FATAL(text)
Definition: Log.h:89
ServiceFeatures * enumerateOperations(const String &serviceName)