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 "system_dependencies.h"
9 #include "Directory.h"
10 #include "Inode.h"
11 #include "ShortAttribute.h"
12 #include "Symlink.h"
13 #include "Volume.h"
14
15 #include <file_systems/fs_ops_support.h>
16
17
18 #define XFS_IO_SIZE 65536
19
20 struct identify_cookie {
21 /* super_block_struct super_block;
22 * No structure yet implemented.
23 */
24 int cookie;
25 };
26
27 // #pragma mark - Scanning
28
29
30 static float
xfs_identify_partition(int fd,partition_data * partition,void ** _cookie)31 xfs_identify_partition(int fd, partition_data *partition, void **_cookie)
32 {
33 return B_NOT_SUPPORTED;
34 }
35
36
37 static status_t
xfs_scan_partition(int fd,partition_data * partition,void * _cookie)38 xfs_scan_partition(int fd, partition_data *partition, void *_cookie)
39 {
40 return B_NOT_SUPPORTED;
41 }
42
43
44 static void
xfs_free_identify_partition_cookie(partition_data * partition,void * _cookie)45 xfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
46 {
47 dprintf("Unsupported in XFS currently.\n");
48 return;
49 }
50
51
52 // #pragma mark -
53
54
55 static status_t
xfs_mount(fs_volume * _volume,const char * device,uint32 flags,const char * args,ino_t * _rootID)56 xfs_mount(fs_volume *_volume, const char *device, uint32 flags,
57 const char *args, ino_t *_rootID)
58 {
59 TRACE("xfs_mount(): Trying to mount\n");
60
61 Volume *volume = new (std::nothrow) Volume(_volume);
62 if (volume == NULL)
63 return B_NO_MEMORY;
64
65 _volume->private_volume = volume;
66 _volume->ops = &gxfsVolumeOps;
67
68 status_t status = volume->Mount(device, flags);
69 if (status != B_OK) {
70 ERROR("Failed mounting the volume. Error: %s\n", strerror(status));
71 delete volume;
72 _volume->private_volume = NULL;
73 return status;
74 }
75
76 *_rootID = volume->Root();
77 return B_OK;
78 }
79
80
81 static status_t
xfs_unmount(fs_volume * _volume)82 xfs_unmount(fs_volume *_volume)
83 {
84 Volume* volume = (Volume*) _volume->private_volume;
85
86 status_t status = volume->Unmount();
87 delete volume;
88 TRACE("xfs_unmount(): Deleted volume");
89 return status;
90 }
91
92
93 static status_t
xfs_read_fs_info(fs_volume * _volume,struct fs_info * info)94 xfs_read_fs_info(fs_volume *_volume, struct fs_info *info)
95 {
96 TRACE("XFS_READ_FS_INFO:\n");
97 Volume* volume = (Volume*)_volume->private_volume;
98
99 info->flags = B_FS_IS_READONLY
100 | B_FS_HAS_ATTR | B_FS_IS_PERSISTENT;
101
102 info->io_size = XFS_IO_SIZE;
103 info->block_size = volume->SuperBlock().BlockSize();
104 info->total_blocks = volume->SuperBlock().TotalBlocks();
105 info->free_blocks = volume->SuperBlock().FreeBlocks();
106
107 // Volume name
108 strlcpy(info->volume_name, volume->Name(), sizeof(info->volume_name));
109
110 // Filesystem name
111 if(volume->IsVersion5())
112 strlcpy(info->fsh_name, "xfs V5", sizeof(info->fsh_name));
113 else
114 strlcpy(info->fsh_name, "xfs V4", sizeof(info->fsh_name));
115
116 return B_OK;
117 }
118
119
120 // #pragma mark -
121
122
123 static status_t
xfs_get_vnode(fs_volume * _volume,ino_t id,fs_vnode * _node,int * _type,uint32 * _flags,bool reenter)124 xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
125 uint32 *_flags, bool reenter)
126 {
127 TRACE("XFS_GET_VNODE:\n");
128 Volume* volume = (Volume*)_volume->private_volume;
129
130 Inode* inode = new(std::nothrow) Inode(volume, id);
131 if (inode == NULL)
132 return B_NO_MEMORY;
133
134 status_t status = inode->Init();
135 if (status != B_OK) {
136 delete inode;
137 ERROR("get_vnode: InitCheck() failed. Error: %s\n", strerror(status));
138 return B_NO_INIT;
139 }
140
141 _node->private_node = inode;
142 _node->ops = &gxfsVnodeOps;
143 *_type = inode->Mode();
144 *_flags = 0;
145 TRACE("(%ld)\n", inode->ID());
146 return B_OK;
147 }
148
149
150 static status_t
xfs_put_vnode(fs_volume * _volume,fs_vnode * _node,bool reenter)151 xfs_put_vnode(fs_volume *_volume, fs_vnode *_node, bool reenter)
152 {
153 TRACE("XFS_PUT_VNODE:\n");
154 delete (Inode*)_node->private_node;
155 return B_OK;
156 }
157
158
159 static bool
xfs_can_page(fs_volume * _volume,fs_vnode * _node,void * _cookie)160 xfs_can_page(fs_volume *_volume, fs_vnode *_node, void *_cookie)
161 {
162 return B_NOT_SUPPORTED;
163 }
164
165
166 static status_t
xfs_read_pages(fs_volume * _volume,fs_vnode * _node,void * _cookie,off_t pos,const iovec * vecs,size_t count,size_t * _numBytes)167 xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
168 off_t pos, const iovec *vecs, size_t count, size_t *_numBytes)
169 {
170 return B_NOT_SUPPORTED;
171 }
172
173
174 static status_t
xfs_io(fs_volume * _volume,fs_vnode * _node,void * _cookie,io_request * request)175 xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
176 io_request *request)
177 {
178 return B_NOT_SUPPORTED;
179 }
180
181
182 static status_t
xfs_get_file_map(fs_volume * _volume,fs_vnode * _node,off_t offset,size_t size,struct file_io_vec * vecs,size_t * _count)183 xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
184 size_t size, struct file_io_vec *vecs, size_t *_count)
185 {
186 return B_NOT_SUPPORTED;
187 }
188
189
190 // #pragma mark -
191
192
193 static status_t
xfs_lookup(fs_volume * _volume,fs_vnode * _directory,const char * name,ino_t * _vnodeID)194 xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
195 ino_t *_vnodeID)
196 {
197 TRACE("XFS_LOOKUP: %p (%s)\n", name, name);
198 Volume* volume = (Volume*)_volume->private_volume;
199 Inode* directory = (Inode*)_directory->private_node;
200
201 if (!directory->IsDirectory())
202 return B_NOT_A_DIRECTORY;
203
204 status_t status = directory->CheckPermissions(X_OK);
205 if (status < B_OK)
206 return status;
207
208 DirectoryIterator* iterator = DirectoryIterator::Init(directory);
209 if (iterator == NULL)
210 return B_BAD_VALUE;
211
212 status = iterator->Lookup(name, strlen(name), (xfs_ino_t*)_vnodeID);
213 if (status != B_OK) {
214 delete iterator;
215 return status;
216 }
217
218 TRACE("XFS_LOOKUP: ID: (%ld)\n", *_vnodeID);
219 status = get_vnode(volume->FSVolume(), *_vnodeID, NULL);
220 TRACE("get_vnode status: (%d)\n", status);
221 return status;
222 }
223
224
225 static status_t
xfs_ioctl(fs_volume * _volume,fs_vnode * _node,void * _cookie,uint32 cmd,void * buffer,size_t bufferLength)226 xfs_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
227 void *buffer, size_t bufferLength)
228 {
229 return B_NOT_SUPPORTED;
230 }
231
232
233 static status_t
xfs_read_stat(fs_volume * _volume,fs_vnode * _node,struct stat * stat)234 xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
235 {
236 Inode* inode = (Inode*)_node->private_node;
237 TRACE("XFS_READ_STAT: id: (%ld)\n", inode->ID());
238 stat->st_dev = inode->GetVolume()->ID();
239 stat->st_ino = inode->ID();
240 stat->st_nlink = 1;
241 stat->st_blksize = XFS_IO_SIZE;
242
243 stat->st_uid = inode->UserId();
244 stat->st_gid = inode->GroupId();
245 stat->st_mode = inode->Mode();
246 stat->st_type = 0; // TODO
247
248 stat->st_size = inode->Size();
249 stat->st_blocks = inode->BlockCount();
250
251 inode->GetAccessTime(stat->st_atim);
252 inode->GetModificationTime(stat->st_mtim);
253 inode->GetChangeTime(stat->st_ctim);
254
255 // Only version 3 Inodes has creation time
256 if(inode->Version() == 3)
257 inode->GetCreationTime(stat->st_crtim);
258 else
259 inode->GetChangeTime(stat->st_crtim);
260
261 return B_OK;
262 }
263
264
265 static status_t
xfs_open(fs_volume *,fs_vnode * _node,int openMode,void ** _cookie)266 xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
267 void **_cookie)
268 {
269 TRACE("XFS_OPEN:\n");
270 Inode* inode = (Inode*)_node->private_node;
271
272 // opening a directory read-only is allowed, although you can't read
273 // any data from it.
274 if (inode->IsDirectory() && (openMode & O_RWMASK) != 0)
275 return B_IS_A_DIRECTORY;
276
277 status_t status = inode->CheckPermissions(open_mode_to_access(openMode)
278 | (openMode & O_TRUNC ? W_OK : 0));
279 if (status != B_OK)
280 return status;
281
282 // Prepare the cookie
283 file_cookie* cookie = new(std::nothrow) file_cookie;
284 if (cookie == NULL)
285 return B_NO_MEMORY;
286 ObjectDeleter<file_cookie> cookieDeleter(cookie);
287
288 cookie->open_mode = openMode & XFS_OPEN_MODE_USER_MASK;
289 cookie->last_size = inode->Size();
290 cookie->last_notification = system_time();
291
292 cookieDeleter.Detach();
293 *_cookie = cookie;
294
295 return B_OK;
296 }
297
298
299 static status_t
xfs_read(fs_volume * _volume,fs_vnode * _node,void * _cookie,off_t pos,void * buffer,size_t * _length)300 xfs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
301 void *buffer, size_t *_length)
302 {
303 TRACE("Inode::ReadAt: pos:(%ld), *length:(%ld)\n", pos, *_length);
304 Inode* inode = (Inode*)_node->private_node;
305
306 if (!inode->IsFile()) {
307 *_length = 0;
308 return inode->IsDirectory() ? B_IS_A_DIRECTORY : B_BAD_VALUE;
309 }
310
311 return inode->ReadAt(pos, (uint8*)buffer, _length);
312 }
313
314
315 static status_t
xfs_close(fs_volume * _volume,fs_vnode * _node,void * _cookie)316 xfs_close(fs_volume *_volume, fs_vnode *_node, void *_cookie)
317 {
318 return B_OK;
319 }
320
321
322 static status_t
xfs_free_cookie(fs_volume * _volume,fs_vnode * _node,void * _cookie)323 xfs_free_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
324 {
325 TRACE("XFS_FREE_COOKIE:\n");
326 file_cookie* cookie = (file_cookie*)_cookie;
327 Volume* volume = (Volume*)_volume->private_volume;
328 Inode* inode = (Inode*)_node->private_node;
329
330 if (inode->Size() != cookie->last_size)
331 notify_stat_changed(volume->ID(), -1, inode->ID(), B_STAT_SIZE);
332
333 delete cookie;
334 return B_OK;
335 }
336
337
338 static status_t
xfs_access(fs_volume * _volume,fs_vnode * _node,int accessMode)339 xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
340 {
341 Inode* inode = (Inode*)_node->private_node;
342 return inode->CheckPermissions(accessMode);
343 }
344
345
346 static status_t
xfs_read_link(fs_volume * _volume,fs_vnode * _node,char * buffer,size_t * _bufferSize)347 xfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
348 size_t *_bufferSize)
349 {
350 TRACE("XFS_READ_SYMLINK\n");
351
352 Inode* inode = (Inode*)_node->private_node;
353
354 if (!inode->IsSymLink())
355 return B_BAD_VALUE;
356
357 Symlink symlink(inode);
358
359 status_t result = symlink.ReadLink(0, buffer, _bufferSize);
360
361 return result;
362 }
363
364
365 status_t
xfs_unlink(fs_volume * _volume,fs_vnode * _directory,const char * name)366 xfs_unlink(fs_volume *_volume, fs_vnode *_directory, const char *name)
367 {
368 return B_NOT_SUPPORTED;
369 }
370
371
372 // #pragma mark - Directory functions
373
374
375 static status_t
xfs_create_dir(fs_volume * _volume,fs_vnode * _directory,const char * name,int mode)376 xfs_create_dir(fs_volume *_volume, fs_vnode *_directory, const char *name,
377 int mode)
378 {
379 return B_NOT_SUPPORTED;
380 }
381
382
383 static status_t
xfs_remove_dir(fs_volume * _volume,fs_vnode * _directory,const char * name)384 xfs_remove_dir(fs_volume *_volume, fs_vnode *_directory, const char *name)
385 {
386 return B_NOT_SUPPORTED;
387 }
388
389
390 static status_t
xfs_open_dir(fs_volume *,fs_vnode * _node,void ** _cookie)391 xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
392 {
393 Inode* inode = (Inode*)_node->private_node;
394 TRACE("XFS_OPEN_DIR: (%ld)\n", inode->ID());
395
396 status_t status = inode->CheckPermissions(R_OK);
397 if (status < B_OK)
398 return status;
399
400 if (!inode->IsDirectory())
401 return B_NOT_A_DIRECTORY;
402
403 DirectoryIterator* iterator = DirectoryIterator::Init(inode);
404 if (iterator == NULL)
405 return B_BAD_VALUE;
406
407 *_cookie = iterator;
408 return status;
409 }
410
411
412 static status_t
xfs_read_dir(fs_volume * _volume,fs_vnode * _node,void * _cookie,struct dirent * buffer,size_t bufferSize,uint32 * _num)413 xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
414 struct dirent *buffer, size_t bufferSize, uint32 *_num)
415 {
416 TRACE("XFS_READ_DIR\n");
417 DirectoryIterator* iterator = (DirectoryIterator*)_cookie;
418 Volume* volume = (Volume*)_volume->private_volume;
419
420 uint32 maxCount = *_num;
421 uint32 count = 0;
422
423 while (count < maxCount && (bufferSize > sizeof(struct dirent))) {
424 size_t length = bufferSize - sizeof(struct dirent);
425 xfs_ino_t ino;
426
427 status_t status = iterator->GetNext(buffer->d_name, &length, &ino);
428 if (status == B_ENTRY_NOT_FOUND)
429 break;
430 if (status == B_BUFFER_OVERFLOW) {
431 if (count == 0)
432 return status;
433 break;
434 }
435 if (status != B_OK)
436 return status;
437
438 buffer->d_dev = volume->ID();
439 buffer->d_ino = ino;
440
441 buffer = next_dirent(buffer, length, bufferSize);
442 count++;
443 }
444
445 *_num = count;
446 TRACE("Count: (%d)\n", count);
447 return B_OK;
448 }
449
450
451 static status_t
xfs_rewind_dir(fs_volume *,fs_vnode *,void * _cookie)452 xfs_rewind_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/, void *_cookie)
453 {
454 return B_NOT_SUPPORTED;
455 }
456
457
458 static status_t
xfs_close_dir(fs_volume *,fs_vnode *,void *)459 xfs_close_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/,
460 void * /*_cookie*/)
461 {
462 return B_OK;
463 }
464
465
466 static status_t
xfs_free_dir_cookie(fs_volume * _volume,fs_vnode * _node,void * _cookie)467 xfs_free_dir_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
468 {
469 delete (DirectoryIterator*)_cookie;
470 return B_OK;
471 }
472
473
474 static status_t
xfs_open_attr_dir(fs_volume * _volume,fs_vnode * _node,void ** _cookie)475 xfs_open_attr_dir(fs_volume *_volume, fs_vnode *_node, void **_cookie)
476 {
477 Inode* inode = (Inode*)_node->private_node;
478 TRACE("%s()\n", __FUNCTION__);
479
480 Attribute* iterator = Attribute::Init(inode);
481 if (iterator == NULL)
482 return B_BAD_VALUE;
483
484 *_cookie = iterator;
485 return B_OK;
486 }
487
488
489 static status_t
xfs_close_attr_dir(fs_volume * _volume,fs_vnode * _node,void * cookie)490 xfs_close_attr_dir(fs_volume *_volume, fs_vnode *_node, void *cookie)
491 {
492 TRACE("%s()\n", __FUNCTION__);
493 return B_OK;
494 }
495
496
497 static status_t
xfs_free_attr_dir_cookie(fs_volume * _volume,fs_vnode * _node,void * _cookie)498 xfs_free_attr_dir_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
499 {
500 delete (Attribute*)_cookie;
501 return B_OK;
502 }
503
504
505 static status_t
xfs_read_attr_dir(fs_volume * _volume,fs_vnode * _node,void * _cookie,struct dirent * dirent,size_t bufferSize,uint32 * _num)506 xfs_read_attr_dir(fs_volume *_volume, fs_vnode *_node,
507 void *_cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
508 {
509 TRACE("%s()\n", __FUNCTION__);
510 Attribute* iterator = (Attribute*)_cookie;
511
512 size_t length = bufferSize;
513 status_t status = iterator->GetNext(dirent->d_name, &length);
514 if (status == B_ENTRY_NOT_FOUND) {
515 *_num = 0;
516 return B_OK;
517 }
518
519 if (status != B_OK)
520 return status;
521
522 Volume* volume = (Volume*)_volume->private_volume;
523 Inode* inode = (Inode*)_node->private_node;
524 dirent->d_dev = volume->ID();
525 dirent->d_ino = inode->ID();
526 dirent->d_reclen = offsetof(struct dirent, d_name) + length + 1;
527 *_num = 1;
528
529 return B_OK;
530 }
531
532
533 static status_t
xfs_rewind_attr_dir(fs_volume * _volume,fs_vnode * _node,void * _cookie)534 xfs_rewind_attr_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie)
535 {
536 return B_NOT_SUPPORTED;
537 }
538
539
540 /* attribute operations */
541 static status_t
xfs_create_attr(fs_volume * _volume,fs_vnode * _node,const char * name,uint32 type,int openMode,void ** _cookie)542 xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
543 const char *name, uint32 type, int openMode, void **_cookie)
544 {
545 return B_NOT_SUPPORTED;
546 }
547
548
549 static status_t
xfs_open_attr(fs_volume * _volume,fs_vnode * _node,const char * name,int openMode,void ** _cookie)550 xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
551 int openMode, void **_cookie)
552 {
553 TRACE("%s()\n", __FUNCTION__);
554
555 status_t status;
556
557 Inode* inode = (Inode*)_node->private_node;
558
559 int accessMode = open_mode_to_access(openMode) | (openMode & O_TRUNC ? W_OK : 0);
560 status = inode->CheckPermissions(accessMode);
561 if (status < B_OK)
562 return status;
563
564 Attribute* attribute = Attribute::Init(inode);
565
566 if (attribute == NULL)
567 return B_BAD_VALUE;
568
569 status = attribute->Open(name, openMode, (attr_cookie**)_cookie);
570 delete attribute;
571
572 return status;
573 }
574
575
576 static status_t
xfs_close_attr(fs_volume * _volume,fs_vnode * _node,void * cookie)577 xfs_close_attr(fs_volume *_volume, fs_vnode *_node,
578 void *cookie)
579 {
580 return B_OK;
581 }
582
583
584 static status_t
xfs_free_attr_cookie(fs_volume * _volume,fs_vnode * _node,void * cookie)585 xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node, void *cookie)
586 {
587 delete (attr_cookie*)cookie;
588 return B_OK;
589 }
590
591
592 static status_t
xfs_read_attr(fs_volume * _volume,fs_vnode * _node,void * _cookie,off_t pos,void * buffer,size_t * _length)593 xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
594 off_t pos, void *buffer, size_t *_length)
595 {
596 TRACE("%s()\n", __FUNCTION__);
597
598 attr_cookie* cookie = (attr_cookie*)_cookie;
599 Inode* inode = (Inode*)_node->private_node;
600
601 Attribute* attribute = Attribute::Init(inode);
602
603 if (attribute == NULL)
604 return B_BAD_VALUE;
605
606 status_t status = attribute->Read(cookie, pos, (uint8*)buffer, _length);
607 delete attribute;
608
609 return status;
610 }
611
612
613 static status_t
xfs_write_attr(fs_volume * _volume,fs_vnode * _node,void * cookie,off_t pos,const void * buffer,size_t * length)614 xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
615 off_t pos, const void *buffer, size_t *length)
616 {
617 return B_NOT_SUPPORTED;
618 }
619
620
621 static status_t
xfs_read_attr_stat(fs_volume * _volume,fs_vnode * _node,void * _cookie,struct stat * stat)622 xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
623 void *_cookie, struct stat *stat)
624 {
625 TRACE("%s()\n", __FUNCTION__);
626
627 attr_cookie* cookie = (attr_cookie*)_cookie;
628 Inode* inode = (Inode*)_node->private_node;
629
630 Attribute* attribute = Attribute::Init(inode);
631
632 if (attribute == NULL)
633 return B_BAD_VALUE;
634
635 status_t status = attribute->Stat(cookie, *stat);
636 delete attribute;
637
638 return status;
639 }
640
641
642 static status_t
xfs_write_attr_stat(fs_volume * _volume,fs_vnode * _node,void * cookie,const struct stat * stat,int statMask)643 xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
644 void *cookie, const struct stat *stat, int statMask)
645 {
646 return B_NOT_SUPPORTED;
647 }
648
649
650 static status_t
xfs_rename_attr(fs_volume * _volume,fs_vnode * fromVnode,const char * fromName,fs_vnode * toVnode,const char * toName)651 xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
652 const char *fromName, fs_vnode *toVnode, const char *toName)
653 {
654 return B_NOT_SUPPORTED;
655 }
656
657
658 static status_t
xfs_remove_attr(fs_volume * _volume,fs_vnode * vnode,const char * name)659 xfs_remove_attr(fs_volume *_volume, fs_vnode *vnode,
660 const char *name)
661 {
662 return B_NOT_SUPPORTED;
663 }
664
665
666 static uint32
xfs_get_supported_operations(partition_data * partition,uint32 mask)667 xfs_get_supported_operations(partition_data *partition, uint32 mask)
668 {
669 return B_NOT_SUPPORTED;
670 }
671
672
673 static status_t
xfs_initialize(int fd,partition_id partitionID,const char * name,const char * parameterString,off_t partitionSize,disk_job_id job)674 xfs_initialize(int fd, partition_id partitionID, const char *name,
675 const char *parameterString, off_t partitionSize, disk_job_id job)
676 {
677 return B_NOT_SUPPORTED;
678 }
679
680
681 static status_t
xfs_uninitialize(int fd,partition_id partitionID,off_t partitionSize,uint32 blockSize,disk_job_id job)682 xfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
683 uint32 blockSize, disk_job_id job)
684 {
685 return B_NOT_SUPPORTED;
686 }
687
688
689 // #pragma mark -
690
691
692 static status_t
xfs_std_ops(int32 op,...)693 xfs_std_ops(int32 op, ...)
694 {
695 switch (op)
696 {
697 case B_MODULE_INIT:
698 #ifdef XFS_DEBUGGER_COMMANDS
699 // Perform nothing at the moment
700 // add_debugger_commands();
701 #endif
702 return B_OK;
703 case B_MODULE_UNINIT:
704 #ifdef XFS_DEBUGGER_COMMANDS
705 // Perform nothing at the moment
706 // remove_debugger_commands();
707 #endif
708 return B_OK;
709
710 default:
711 return B_ERROR;
712 }
713 }
714
715
716 fs_volume_ops gxfsVolumeOps = {
717 &xfs_unmount,
718 &xfs_read_fs_info,
719 NULL, // write_fs_info()
720 NULL, // fs_sync,
721 &xfs_get_vnode,
722 };
723
724
725 fs_vnode_ops gxfsVnodeOps = {
726 /* vnode operations */
727 &xfs_lookup,
728 NULL, // xfs_get_vnode_name- optional, and we can't do better
729 // than the fallback implementation, so leave as NULL.
730 &xfs_put_vnode,
731 NULL, // xfs_remove_vnode,
732
733 /* VM file access */
734 &xfs_can_page,
735 &xfs_read_pages,
736 NULL, // xfs_write_pages,
737
738 &xfs_io, // io()
739 NULL, // cancel_io()
740
741 &xfs_get_file_map,
742
743 &xfs_ioctl,
744 NULL,
745 NULL, // fs_select
746 NULL, // fs_deselect
747 NULL, // fs_fsync,
748
749 &xfs_read_link,
750 NULL, // fs_create_symlink,
751
752 NULL, // fs_link,
753 &xfs_unlink,
754 NULL, // fs_rename,
755
756 &xfs_access,
757 &xfs_read_stat,
758 NULL, // fs_write_stat,
759 NULL, // fs_preallocate
760
761 /* file operations */
762 NULL, // fs_create,
763 &xfs_open,
764 &xfs_close,
765 &xfs_free_cookie,
766 &xfs_read,
767 NULL, // fs_write,
768
769 /* directory operations */
770 &xfs_create_dir,
771 &xfs_remove_dir,
772 &xfs_open_dir,
773 &xfs_close_dir,
774 &xfs_free_dir_cookie,
775 &xfs_read_dir,
776 &xfs_rewind_dir,
777
778 /* attribute directory operations */
779 &xfs_open_attr_dir,
780 &xfs_close_attr_dir,
781 &xfs_free_attr_dir_cookie,
782 &xfs_read_attr_dir,
783 &xfs_rewind_attr_dir,
784
785 /* attribute operations */
786 &xfs_create_attr,
787 &xfs_open_attr,
788 &xfs_close_attr,
789 &xfs_free_attr_cookie,
790 &xfs_read_attr,
791 &xfs_write_attr,
792 &xfs_read_attr_stat,
793 &xfs_write_attr_stat,
794 &xfs_rename_attr,
795 &xfs_remove_attr,
796 };
797
798
799 static
800 file_system_module_info sxfsFileSystem = {
801 {
802 "file_systems/xfs" B_CURRENT_FS_API_VERSION,
803 0,
804 xfs_std_ops,
805 },
806
807 "xfs", // short_name
808 "XFS File System", // pretty_name
809
810 // DDM flags
811 0 |B_DISK_SYSTEM_SUPPORTS_INITIALIZING |B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
812 // | B_DISK_SYSTEM_SUPPORTS_WRITING
813 ,
814
815 // scanning
816 xfs_identify_partition,
817 xfs_scan_partition,
818 xfs_free_identify_partition_cookie,
819 NULL, // free_partition_content_cookie()
820
821 &xfs_mount,
822
823 /* capability querying operations */
824 &xfs_get_supported_operations,
825
826 NULL, // validate_resize
827 NULL, // validate_move
828 NULL, // validate_set_content_name
829 NULL, // validate_set_content_parameters
830 NULL, // validate_initialize,
831
832 /* shadow partition modification */
833 NULL, // shadow_changed
834
835 /* writing */
836 NULL, // defragment
837 NULL, // repair
838 NULL, // resize
839 NULL, // move
840 NULL, // set_content_name
841 NULL, // set_content_parameters
842 xfs_initialize,
843 xfs_uninitialize};
844
845
846 module_info *modules[] = {
847 (module_info *)&sxfsFileSystem,
848 NULL,
849 };
850