mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:02:45 +00:00 
			
		
		
		
	Kernel: Generalize VFS metadata lookup and use it in mount() and stat()
Refactored VFS::stat() into VFS::lookup_metadata(), which can now be used for general VFS metadata lookup by path.
This commit is contained in:
		
							parent
							
								
									ae4d707684
								
							
						
					
					
						commit
						a6fb055028
					
				
					 3 changed files with 21 additions and 21 deletions
				
			
		|  | @ -145,12 +145,12 @@ KResult VFS::utime(StringView path, Custody& base, time_t atime, time_t mtime) | ||||||
|     return KSuccess; |     return KSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| KResult VFS::stat(StringView path, int options, Custody& base, struct stat& statbuf) | KResultOr<InodeMetadata> VFS::lookup_metadata(StringView path, Custody& base, int options) | ||||||
| { | { | ||||||
|     auto custody_or_error = resolve_path(path, base, nullptr, options); |     auto custody_or_error = resolve_path(path, base, nullptr, options); | ||||||
|     if (custody_or_error.is_error()) |     if (custody_or_error.is_error()) | ||||||
|         return custody_or_error.error(); |         return custody_or_error.error(); | ||||||
|     return custody_or_error.value()->inode().metadata().stat(statbuf); |     return custody_or_error.value()->inode().metadata(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base) | KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options, mode_t mode, Custody& base) | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ public: | ||||||
|     KResult chown(StringView path, uid_t, gid_t, Custody& base); |     KResult chown(StringView path, uid_t, gid_t, Custody& base); | ||||||
|     KResult chown(Inode&, uid_t, gid_t); |     KResult chown(Inode&, uid_t, gid_t); | ||||||
|     KResult access(StringView path, int mode, Custody& base); |     KResult access(StringView path, int mode, Custody& base); | ||||||
|     KResult stat(StringView path, int options, Custody& base, struct stat&); |     KResultOr<InodeMetadata> lookup_metadata(StringView path, Custody& base, int options = 0); | ||||||
|     KResult utime(StringView path, Custody& base, time_t atime, time_t mtime); |     KResult utime(StringView path, Custody& base, time_t atime, time_t mtime); | ||||||
|     KResult rename(StringView oldpath, StringView newpath, Custody& base); |     KResult rename(StringView oldpath, StringView newpath, Custody& base); | ||||||
|     KResult mknod(StringView path, mode_t, dev_t, Custody& base); |     KResult mknod(StringView path, mode_t, dev_t, Custody& base); | ||||||
|  |  | ||||||
|  | @ -1077,14 +1077,20 @@ int Process::sys$lstat(const char* path, stat* statbuf) | ||||||
| { | { | ||||||
|     if (!validate_write_typed(statbuf)) |     if (!validate_write_typed(statbuf)) | ||||||
|         return -EFAULT; |         return -EFAULT; | ||||||
|     return VFS::the().stat(StringView(path), O_NOFOLLOW_NOERROR, current_directory(), *statbuf); |     auto metadata_or_error = VFS::the().lookup_metadata(StringView(path), current_directory(), O_NOFOLLOW_NOERROR); | ||||||
|  |     if (metadata_or_error.is_error()) | ||||||
|  |         return metadata_or_error.error(); | ||||||
|  |     return metadata_or_error.value().stat(*statbuf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Process::sys$stat(const char* path, stat* statbuf) | int Process::sys$stat(const char* path, stat* statbuf) | ||||||
| { | { | ||||||
|     if (!validate_write_typed(statbuf)) |     if (!validate_write_typed(statbuf)) | ||||||
|         return -EFAULT; |         return -EFAULT; | ||||||
|     return VFS::the().stat(StringView(path), 0, current_directory(), *statbuf); |     auto metadata_or_error = VFS::the().lookup_metadata(StringView(path), current_directory()); | ||||||
|  |     if (metadata_or_error.is_error()) | ||||||
|  |         return metadata_or_error.error(); | ||||||
|  |     return metadata_or_error.value().stat(*statbuf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Process::sys$readlink(const char* path, char* buffer, ssize_t size) | int Process::sys$readlink(const char* path, char* buffer, ssize_t size) | ||||||
|  | @ -2727,15 +2733,15 @@ int Process::sys$reboot() | ||||||
|     return ESUCCESS; |     return ESUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Process::sys$mount(const char* device, const char* mountpoint) | int Process::sys$mount(const char* device_path, const char* mountpoint) | ||||||
| { | { | ||||||
|     if (!is_superuser()) |     if (!is_superuser()) | ||||||
|         return -EPERM; |         return -EPERM; | ||||||
| 
 | 
 | ||||||
|     if (!validate_read_str(device) || !validate_read_str(mountpoint)) |     if (!validate_read_str(device_path) || !validate_read_str(mountpoint)) | ||||||
|         return -EFAULT; |         return -EFAULT; | ||||||
| 
 | 
 | ||||||
|     dbg() << "mount: device " << device << " @ " << mountpoint; |     dbg() << "mount: device " << device_path << " @ " << mountpoint; | ||||||
| 
 | 
 | ||||||
|     auto custody_or_error = VFS::the().resolve_path(mountpoint, current_directory()); |     auto custody_or_error = VFS::the().resolve_path(mountpoint, current_directory()); | ||||||
|     if (custody_or_error.is_error()) |     if (custody_or_error.is_error()) | ||||||
|  | @ -2743,18 +2749,12 @@ int Process::sys$mount(const char* device, const char* mountpoint) | ||||||
| 
 | 
 | ||||||
|     auto& mountpoint_custody = custody_or_error.value(); |     auto& mountpoint_custody = custody_or_error.value(); | ||||||
| 
 | 
 | ||||||
|     // Let's do a stat to get some information about the device..
 |     auto metadata_or_error = VFS::the().lookup_metadata(device_path, current_directory()); | ||||||
|     // Let's use lstat so we can convert devname into a major/minor device pair!
 |     if (metadata_or_error.is_error()) | ||||||
|     struct stat st; |         return metadata_or_error.error(); | ||||||
|     int rc = sys$stat(device, &st); |  | ||||||
|     if (rc < 0) { |  | ||||||
|         dbg() << "mount: call to sys$stat failed!"; |  | ||||||
|         return -ENODEV; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     int major = (st.st_rdev & 0xfff00u) >> 8u; |  | ||||||
|     int minor = (st.st_rdev & 0xffu) | ((st.st_rdev >> 12u) & 0xfff00u); |  | ||||||
| 
 | 
 | ||||||
|  |     auto major = metadata_or_error.value().major_device; | ||||||
|  |     auto minor = metadata_or_error.value().minor_device; | ||||||
|     auto* dev = VFS::the().get_device(major, minor); |     auto* dev = VFS::the().get_device(major, minor); | ||||||
|     auto* disk_device = static_cast<DiskDevice*>(dev); |     auto* disk_device = static_cast<DiskDevice*>(dev); | ||||||
| 
 | 
 | ||||||
|  | @ -2767,13 +2767,13 @@ int Process::sys$mount(const char* device, const char* mountpoint) | ||||||
|     // We currently only support ext2. Sorry :^)
 |     // We currently only support ext2. Sorry :^)
 | ||||||
|     auto ext2fs = Ext2FS::create(*disk_device); |     auto ext2fs = Ext2FS::create(*disk_device); | ||||||
|     if (!ext2fs->initialize()) { |     if (!ext2fs->initialize()) { | ||||||
|         dbg() << "mount: could not find ext2 filesystem on " << device; |         dbg() << "mount: could not find ext2 filesystem on " << device_path; | ||||||
|         return -ENODEV; // Hmmm, this doesn't seem quite right....
 |         return -ENODEV; // Hmmm, this doesn't seem quite right....
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Let's mount the volume now
 |     // Let's mount the volume now
 | ||||||
|     auto result = VFS::the().mount(ext2fs, mountpoint_custody); |     auto result = VFS::the().mount(ext2fs, mountpoint_custody); | ||||||
|     dbg() << "mount: successfully mounted " << device << " on " << mountpoint; |     dbg() << "mount: successfully mounted " << device_path << " on " << mountpoint; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling