fs/vboxsf/file.c

Source file repositories/reference/linux-study-clean/fs/vboxsf/file.c

File Facts

System
Linux kernel
Corpus path
fs/vboxsf/file.c
Extension
.c
Size
10804 bytes
Lines
396
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct file_operations vboxsf_reg_fops = {
	.llseek = generic_file_llseek,
	.read_iter = generic_file_read_iter,
	.write_iter = generic_file_write_iter,
	.mmap_prepare = vboxsf_file_mmap_prepare,
	.open = vboxsf_file_open,
	.release = vboxsf_file_release,
	.fsync = noop_fsync,
	.splice_read = filemap_splice_read,
};

const struct inode_operations vboxsf_reg_iops = {
	.getattr = vboxsf_getattr,
	.setattr = vboxsf_setattr,
	.fileattr_get = vboxsf_fileattr_get,
};

static int vboxsf_read_folio(struct file *file, struct folio *folio)
{
	struct vboxsf_handle *sf_handle = file->private_data;
	loff_t off = folio_pos(folio);
	u32 nread = PAGE_SIZE;
	u8 *buf;
	int err;

	buf = kmap_local_folio(folio, 0);

	err = vboxsf_read(sf_handle->root, sf_handle->handle, off, &nread, buf);
	buf = folio_zero_tail(folio, nread, buf + nread);

	kunmap_local(buf);
	folio_end_read(folio, err == 0);
	return err;
}

static struct vboxsf_handle *vboxsf_get_write_handle(struct vboxsf_inode *sf_i)
{
	struct vboxsf_handle *h, *sf_handle = NULL;

	mutex_lock(&sf_i->handle_list_mutex);
	list_for_each_entry(h, &sf_i->handle_list, head) {
		if (h->access_flags == SHFL_CF_ACCESS_WRITE ||
		    h->access_flags == SHFL_CF_ACCESS_READWRITE) {
			kref_get(&h->refcount);
			sf_handle = h;
			break;
		}
	}
	mutex_unlock(&sf_i->handle_list_mutex);

	return sf_handle;
}

static int vboxsf_writepages(struct address_space *mapping,
		struct writeback_control *wbc)
{
	struct inode *inode = mapping->host;
	struct folio *folio = NULL;
	struct vboxsf_inode *sf_i = VBOXSF_I(inode);
	struct vboxsf_handle *sf_handle;
	loff_t size = i_size_read(inode);
	int error;

	sf_handle = vboxsf_get_write_handle(sf_i);
	if (!sf_handle)
		return -EBADF;

	while ((folio = writeback_iter(mapping, wbc, folio, &error))) {
		loff_t off = folio_pos(folio);
		u32 nwrite = folio_size(folio);
		u8 *buf;

		if (nwrite > size - off)
			nwrite = size - off;

		buf = kmap_local_folio(folio, 0);
		error = vboxsf_write(sf_handle->root, sf_handle->handle,
				off, &nwrite, buf);
		kunmap_local(buf);

		folio_unlock(folio);
	}

	kref_put(&sf_handle->refcount, vboxsf_handle_release);

	/* mtime changed */
	if (error == 0)
		sf_i->force_restat = 1;
	return error;
}

Annotation

Implementation Notes