Changeset 854
- Timestamp:
- 08/21/08 21:46:43 (3 years ago)
- Files:
-
- 1 modified
-
Whitix/trunk/fs/devfs/devfs.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/trunk/fs/devfs/devfs.c
r705 r854 33 33 #include <init.h> 34 34 #include <error.h> 35 #include <fs/kfs.h> 35 36 #include <print.h> 36 37 … … 38 39 #include "../devices/storage/ata/ata.h" 39 40 40 /* Local prototypes */41 int DevFsDirSize(struct DevFsDir* dir);42 43 41 /* Root directory of the device filesystem. */ 44 struct DevFsDir* rootDir;45 struct DevFsEntry rootEntry;42 struct KeFsDir* rootDir; 43 struct KeFsEntry rootEntry; 46 44 47 45 struct SuperBlockOps devFsSbOps; … … 127 125 int DevFsReadVNode(struct VNode* vNode) 128 126 { 129 struct DevFsEntry* entry=(struct DevFsEntry*)(vNode->id); 127 struct KeFsEntry* entry=(struct KeFsEntry*)(vNode->id); 128 struct DevFsDevice* device; 130 129 struct StorageDevice* sDevice; 131 132 vNode->extraInfo=entry; 130 133 131 vNode->vNodeOps=&devFsVOps; 134 135 132 vNode->mode=VFS_ATTR_READ | VFS_ATTR_WRITE; 136 133 … … 138 135 { 139 136 vNode->mode |= VFS_ATTR_FILE; 140 vNode->devId.major=entry->device.devId.major; 141 vNode->devId.minor=entry->device.devId.minor; 137 device=(struct DevFsDevice*)entry->file; 138 vNode->devId.major=device->devId.major; 139 vNode->devId.minor=device->devId.minor; 142 140 if (entry->type & DEVICE_BLOCK) 143 141 { … … 152 150 vNode->mode |= VFS_ATTR_CHAR; 153 151 /* Just redirect to the usual char devices */ 154 vNode->fileOps= entry->device.ops;152 vNode->fileOps=device->ops; 155 153 vNode->size=0; 156 154 } … … 159 157 vNode->fileOps=&devFsFileOps; 160 158 vNode->mode|=VFS_ATTR_DIR; 161 vNode->size=DevFsDirSize(&entry->dir); 162 } 163 164 return 0; 165 } 166 167 int DevFsFreeVNode(struct VNode* vNode) 168 { 169 /* This function is so that extraInfo (which contains the DevFsEntry and could be 170 malloc'ed) is not freed by the virtual filesystem layer. */ 171 return 0; 172 } 173 174 int DevFsLookup(struct VNode** retVal,struct VNode* dir,char* name,int nameLength) 175 { 176 struct DevFsDir* dDir; 177 struct DevFsEntry* entry; 178 179 entry=(struct DevFsEntry*)(dir->extraInfo); 180 dDir=&entry->dir; 181 182 /* Handle '..'. '..' on the root directory will already have been handled by the VFS. */ 183 if (nameLength == 2 && name[0] == '.' && name[1] == '.') 184 { 185 dDir=dDir->parent; 186 entry=(struct DevFsEntry*)(((DWORD)dDir)-offsetof(struct DevFsEntry, dir)); 187 goto found; 188 } 189 190 ListForEachEntry(entry,&(dDir->entries),next) 191 if (!strnicmp(entry->name,name,nameLength)) 192 goto found; 193 194 /* Cycled through the whole directory with no luck */ 195 return -ENOENT; 196 197 found: 198 *retVal=VNodeGet(dir->superBlock,(DWORD)entry); 199 return 0; 200 } 201 202 struct DevFsDir* DevDirLookup(char* name,int nameLength,struct DevFsDir* dir) 203 { 204 struct DevFsEntry* entry; 205 206 /* Look it up */ 207 ListForEachEntry(entry,&(dir->entries),next) 208 { 209 if ((entry->type & VFS_ATTR_DIR) && !strnicmp(entry->name, name, nameLength)) 210 return &entry->dir; 211 } 212 213 return NULL; 159 vNode->size=KeFsDirSize(&entry->dir); 160 } 161 162 return 0; 214 163 } 215 164 216 165 int DevAddDevice(char* name, WORD major, WORD minor, int type, void* ops) 217 166 { 218 struct DevFsEntry* entry; 167 struct KeFsDir* dir=rootDir; 168 struct KeFsEntry* entry; 219 169 struct DevFsDevice* device; 220 struct DevFsDir* dir=rootDir;221 char* endName;222 DWORD offset;223 170 224 171 /* Sanity checks */ … … 228 175 if (!major) 229 176 return -EINVAL; 230 231 /* Get to the directory first. */ 232 while ((endName=strchr(name,'/'))) 233 { 234 offset=(DWORD)(endName-name); 235 dir=DevDirLookup(name, offset,dir); 236 if (!dir) 237 return -ENOENT; 238 239 name+=offset+1; 240 } 241 242 // printf("DevAddDevice(%s)\n", name); 243 244 /* Check if the name exists already */ 245 ListForEachEntry(entry,&(dir->entries),next) 246 if (!strnicmp(entry->name,name,strlen(name))) 247 return -EEXIST; 248 249 /* Allocate the DevFsEntry, and the name with it */ 250 entry=(struct DevFsEntry*)malloc(sizeof(struct DevFsEntry)+strlen(name)+1); 177 178 entry=KeFsAddEntry(dir, name); 179 251 180 if (!entry) 252 return -ENOMEM; 253 254 /* Always a device */ 255 entry->type=type | VFS_ATTR_FILE | VFS_ATTR_READ | VFS_ATTR_WRITE; 256 strcpy(entry->name,name); 257 258 device=(struct DevFsDevice*)(&entry->device); 181 return -EFAULT; 182 183 device=(struct DevFsDevice*)malloc(sizeof(struct DevFsDevice)); 259 184 260 185 device->ops=ops; 261 186 device->devId.major=major; 262 187 device->devId.minor=minor; 263 ListAddTail(&entry->next,&dir->entries); 188 entry->file=device; 189 190 entry->type |= type; 264 191 265 192 return 0; … … 274 201 { 275 202 /* Any storage devices will be found in the Storage directory. */ 276 struct DevFsDir* dir; 277 struct DevFsEntry* entry; 278 279 dir=DevDirLookup("Storage", strlen("Storage"), rootDir); 203 struct KeFsDir* dir; 204 struct KeFsEntry* entry; 205 struct DevFsDevice* device; 206 207 dir=KeFsDirLookup("Storage", strlen("Storage"), rootDir); 280 208 281 209 if (!dir) 282 210 return NULL; 283 211 284 ListForEachEntry(entry,& (dir->entries), next)212 ListForEachEntry(entry,&dir->entries, next) 285 213 { 286 214 if (entry->type & VFS_ATTR_FILE) 287 215 { 288 if (entry->device.devId.major == major && entry->device.devId.minor == minor && (entry->type & DEVICE_BLOCK)) 289 return (struct StorageDevice*)(entry->device.ops); 216 device=(struct DevFsDevice*)(entry->file); 217 if (device->devId.major == major && device->devId.minor == minor && (entry->type & DEVICE_BLOCK)) 218 return (struct StorageDevice*)(device->ops); 290 219 } 291 220 } … … 330 259 else 331 260 /* Decode root filesystem here */ 332 rootDev=DevFindRootDev(rootDevMajor, rootDevMinor);261 rootDev=DevFindRootDev(rootDevMajor, rootDevMinor); 333 262 334 263 if (!rootDev) … … 347 276 { 348 277 char* endName; 349 DWORD offset; 350 struct DevFsDir* dir=rootDir, *newDir; 351 struct DevFsEntry* entry; 278 DWORD offset; 279 struct KeFsDir* dir=rootDir; 352 280 353 281 /* Get to the directory */ … … 355 283 { 356 284 offset=(DWORD)(endName-name); 357 dir= DevDirLookup(name, strlen(name),dir);285 dir=KeFsDirLookup(name, strlen(name),dir); 358 286 if (!dir) 359 287 return -ENOENT; 360 288 } 361 289 362 /* Check it doesn't exist already. */ 363 ListForEachEntry(entry,&(dir->entries),next) 364 if (!strnicmp(entry->name,name,strlen(name))) 365 return -EEXIST; 366 367 /* Add entry. */ 368 entry=(struct DevFsEntry*)malloc(sizeof(struct DevFsEntry)+strlen(name)+1); 369 entry->type=VFS_ATTR_DIR | VFS_ATTR_READ; 370 strcpy(entry->name, name); 371 372 newDir=&entry->dir; 373 INIT_LIST_HEAD(&newDir->entries); 374 newDir->parent=dir; 375 376 ListAddTail(&entry->next,&dir->entries); 290 KeFsAddDir(dir, name); 291 377 292 return 0; 378 293 } … … 384 299 } 385 300 386 int DevFsPermission(struct VNode* node,int access) 387 { 388 KePrint("DevFsPermission\n"); 389 return 0; 390 } 391 392 int DevFsReadDir(struct File* file,void* dirEntries) 393 { 394 struct DevFsEntry* entry; 395 struct DevFsEntry* entryDir=(struct DevFsEntry*)(file->vNode->extraInfo); 396 struct DevFsDir* dir=&entryDir->dir; 397 int ret; 398 399 ListForEachEntry(entry, &(dir->entries), next) 400 { 401 ret=FillDir(dirEntries,entry->name,strlen(entry->name),(DWORD)entry); 402 if (ret < 0) 403 return ret; 404 405 file->position++; 406 } 407 301 int DevFsReadDir(struct File* file, void* dirEntries) 302 { 303 return KeFsReadDir(file, FillDir, dirEntries); 304 } 305 306 int DevFsLookup(struct VNode** retVal,struct VNode* dir,char* name,int nameLength) 307 { 308 struct KeFsEntry* entry; 309 310 entry=KeFsLookup(dir, name, nameLength); 311 312 *retVal=VNodeGet(dir->superBlock, (DWORD)entry); 313 408 314 return 0; 409 315 } … … 412 318 { 413 319 .readVNode = DevFsReadVNode, 414 .freeVNode = DevFsFreeVNode,415 320 }; 416 321 … … 418 323 { 419 324 .lookup=DevFsLookup, 420 .permission=DevFsPermission,421 325 }; 422 326 … … 426 330 .readDir=DevFsReadDir, 427 331 }; 428 429 int DevFsDirSize(struct DevFsDir* dir)430 {431 struct DevFsEntry* entry;432 int i=0;433 434 ListForEachEntry(entry, &(dir->entries), next)435 i++;436 437 return i;438 }439 332 440 333 struct VfsSuperBlock* DevFsReadSuper(struct StorageDevice* dev,int flags,char* data) … … 452 345 retVal->sbOps=&devFsSbOps; 453 346 retVal->mount=VNodeGet(retVal,(DWORD)&rootEntry); 347 454 348 retVal->mount->mode=VFS_ATTR_DIR | VFS_ATTR_READ; 455 retVal->mount->size= DevFsDirSize(rootDir);349 retVal->mount->size=KeFsDirSize(rootDir); 456 350 retVal->mount->vNodeOps=&devFsVOps; 457 351 retVal->mount->fileOps=&devFsFileOps; 458 retVal->mount->extraInfo=(void*)&rootEntry;459 352 460 353 return retVal; … … 469 362 int DevFsInit() 470 363 { 471 /* Set up the data structure here, and DevFsReadSuper doesn't do too much (at the moment) */472 364 VfsRegisterFileSystem(&devFileSystem); 473 365 474 366 /* Set up the root directory here, as devices will be added before ReadSuper is called. */ 475 rootEntry.type=VFS_ATTR_DIR | VFS_ATTR_READ | VFS_ATTR_WRITE; 476 rootEntry.name[0]='\0'; 477 rootEntry.dir.parent=NULL; /* Parent is handled by VFS for the root directory. */ 478 INIT_LIST_HEAD(&rootEntry.dir.entries); 367 KeFsInitRoot(&rootEntry); 479 368 rootDir=&rootEntry.dir; 480 369
