fs/xfs/scrub/xfile.c

Source file repositories/reference/linux-study-clean/fs/xfs/scrub/xfile.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/xfile.c
Extension
.c
Size
7656 bytes
Lines
326
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source 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

if (!folio) {
			/*
			 * No data stored at this offset, just zero the output
			 * buffer until the next page boundary.
			 */
			len = min_t(ssize_t, count,
				PAGE_SIZE - offset_in_page(pos));
			memset(buf, 0, len);
		} else {
			if (filemap_check_wb_err(inode->i_mapping, 0)) {
				folio_unlock(folio);
				folio_put(folio);
				break;
			}

			offset = offset_in_folio(folio, pos);
			len = min_t(ssize_t, count, folio_size(folio) - offset);
			memcpy(buf, folio_address(folio) + offset, len);

			folio_unlock(folio);
			folio_put(folio);
		}
		count -= len;
		pos += len;
		buf += len;
	}
	memalloc_nofs_restore(pflags);

	if (count)
		return -ENOMEM;
	return 0;
}

/*
 * Store an object.  Since we're treating this file as "memory", any error or
 * short IO is treated as a failure to allocate memory.
 */
int
xfile_store(
	struct xfile		*xf,
	const void		*buf,
	size_t			count,
	loff_t			pos)
{
	struct inode		*inode = file_inode(xf->file);
	unsigned int		pflags;

	if (count > MAX_RW_COUNT)
		return -ENOMEM;
	if (inode->i_sb->s_maxbytes - pos < count)
		return -ENOMEM;

	trace_xfile_store(xf, pos, count);

	/*
	 * Increase the file size first so that shmem_get_folio(..., SGP_CACHE),
	 * actually allocates a folio instead of erroring out.
	 */
	if (pos + count > i_size_read(inode))
		i_size_write(inode, pos + count);

	pflags = memalloc_nofs_save();
	while (count > 0) {
		struct folio	*folio;
		unsigned int	len;
		unsigned int	offset;

		if (shmem_get_folio(inode, pos >> PAGE_SHIFT, 0, &folio,
				SGP_CACHE) < 0)
			break;
		if (filemap_check_wb_err(inode->i_mapping, 0)) {
			folio_unlock(folio);
			folio_put(folio);
			break;
		}

		offset = offset_in_folio(folio, pos);
		len = min_t(ssize_t, count, folio_size(folio) - offset);
		memcpy(folio_address(folio) + offset, buf, len);

		folio_mark_dirty(folio);
		folio_unlock(folio);
		folio_put(folio);

		count -= len;
		pos += len;
		buf += len;
	}
	memalloc_nofs_restore(pflags);

Annotation

Implementation Notes