static status_t btrfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request) { Volume* volume = (Volume*)_volume->private_volume; Inode* inode = (Inode*)_node->private_node; #ifndef BTRFS_SHELL if (io_request_is_write(request) && volume->IsReadOnly()) { notify_io_request(request, B_READ_ONLY_DEVICE); return B_READ_ONLY_DEVICE; } #endif if (inode->FileCache() == NULL) { #ifndef BTRFS_SHELL notify_io_request(request, B_BAD_VALUE); #endif return B_BAD_VALUE; } // We lock the node here and will unlock it in the "finished" hook. rw_lock_read_lock(inode->Lock()); return do_iterative_fd_io(volume->Device(), request, iterative_io_get_vecs_hook, iterative_io_finished_hook, inode); }
static status_t btrfs_open(fs_volume* /*_volume*/, fs_vnode* _node, int openMode, void** _cookie) { Inode* inode = (Inode*)_node->private_node; // opening a directory read-only is allowed, although you can't read // any data from it. if (inode->IsDirectory() && (openMode & O_RWMASK) != 0) return B_IS_A_DIRECTORY; status_t status = inode->CheckPermissions(open_mode_to_access(openMode) | (openMode & O_TRUNC ? W_OK : 0)); if (status != B_OK) return status; // Prepare the cookie file_cookie* cookie = new(std::nothrow) file_cookie; if (cookie == NULL) return B_NO_MEMORY; ObjectDeleter<file_cookie> cookieDeleter(cookie); cookie->open_mode = openMode & BTRFS_OPEN_MODE_USER_MASK; cookie->last_size = inode->Size(); cookie->last_notification = system_time(); if ((openMode & O_NOCACHE) != 0 && inode->FileCache() != NULL) { // Disable the file cache, if requested? status = file_cache_disable(inode->FileCache()); if (status != B_OK) return status; } cookieDeleter.Detach(); *_cookie = cookie; return B_OK; }
static status_t ext2_write_pages(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos, const iovec* vecs, size_t count, size_t* _numBytes) { Volume* volume = (Volume*)_volume->private_volume; Inode* inode = (Inode*)_node->private_node; if (volume->IsReadOnly()) return B_READ_ONLY_DEVICE; if (inode->FileCache() == NULL) return B_BAD_VALUE; rw_lock_read_lock(inode->Lock()); uint32 vecIndex = 0; size_t vecOffset = 0; size_t bytesLeft = *_numBytes; status_t status; while (true) { file_io_vec fileVecs[8]; size_t fileVecCount = 8; status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs, &fileVecCount, 0); if (status != B_OK && status != B_BUFFER_OVERFLOW) break; bool bufferOverflow = status == B_BUFFER_OVERFLOW; size_t bytes = bytesLeft; status = write_file_io_vec_pages(volume->Device(), fileVecs, fileVecCount, vecs, count, &vecIndex, &vecOffset, &bytes); if (status != B_OK || !bufferOverflow) break; pos += bytes; bytesLeft -= bytes; } rw_lock_read_unlock(inode->Lock()); return status; }