fs/nilfs2/sufile.c

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

File Facts

System
Linux kernel
Corpus path
fs/nilfs2/sufile.c
Extension
.c
Size
34664 bytes
Lines
1274
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

struct nilfs_sufile_info {
	struct nilfs_mdt_info mi;
	unsigned long ncleansegs;/* number of clean segments */
	__u64 allocmin;		/* lower limit of allocatable segment range */
	__u64 allocmax;		/* upper limit of allocatable segment range */
};

static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile)
{
	return (struct nilfs_sufile_info *)NILFS_MDT(sufile);
}

static inline unsigned long
nilfs_sufile_segment_usages_per_block(const struct inode *sufile)
{
	return NILFS_MDT(sufile)->mi_entries_per_block;
}

static unsigned long
nilfs_sufile_get_blkoff(const struct inode *sufile, __u64 segnum)
{
	__u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset;

	t = div64_ul(t, nilfs_sufile_segment_usages_per_block(sufile));
	return (unsigned long)t;
}

static unsigned long
nilfs_sufile_get_offset(const struct inode *sufile, __u64 segnum)
{
	__u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset;

	return do_div(t, nilfs_sufile_segment_usages_per_block(sufile));
}

static unsigned long
nilfs_sufile_segment_usages_in_block(const struct inode *sufile, __u64 curr,
				     __u64 max)
{
	return min_t(unsigned long,
		     nilfs_sufile_segment_usages_per_block(sufile) -
		     nilfs_sufile_get_offset(sufile, curr),
		     max - curr + 1);
}

/**
 * nilfs_sufile_segment_usage_offset - calculate the byte offset of a segment
 *                                     usage entry in the folio containing it
 * @sufile: segment usage file inode
 * @segnum: number of segment usage
 * @bh:     buffer head of block containing segment usage indexed by @segnum
 *
 * Return: Byte offset in the folio of the segment usage entry.
 */
static size_t nilfs_sufile_segment_usage_offset(const struct inode *sufile,
						__u64 segnum,
						struct buffer_head *bh)
{
	return offset_in_folio(bh->b_folio, bh->b_data) +
		nilfs_sufile_get_offset(sufile, segnum) *
		NILFS_MDT(sufile)->mi_entry_size;
}

static int nilfs_sufile_get_header_block(struct inode *sufile,
					 struct buffer_head **bhp)
{
	int err = nilfs_mdt_get_block(sufile, 0, 0, NULL, bhp);

	if (unlikely(err == -ENOENT)) {
		nilfs_error(sufile->i_sb,
			    "missing header block in segment usage metadata");
		err = -EIO;
	}
	return err;
}

static inline int
nilfs_sufile_get_segment_usage_block(struct inode *sufile, __u64 segnum,
				     int create, struct buffer_head **bhp)
{
	return nilfs_mdt_get_block(sufile,
				   nilfs_sufile_get_blkoff(sufile, segnum),
				   create, NULL, bhp);
}

static int nilfs_sufile_delete_segment_usage_block(struct inode *sufile,
						   __u64 segnum)
{
	return nilfs_mdt_delete_block(sufile,
				      nilfs_sufile_get_blkoff(sufile, segnum));

Annotation

Implementation Notes