fs/gfs2/trans.c

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

File Facts

System
Linux kernel
Corpus path
fs/gfs2/trans.c
Extension
.c
Size
10185 bytes
Lines
363
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 (bh->b_private) {
			kmem_cache_free(gfs2_bufdata_cachep, bd);
			bd = bh->b_private;
		} else {
			bh->b_private = bd;
		}
	}
	gfs2_assert(sdp, bd->bd_gl == gl);
	set_bit(TR_TOUCHED, &tr->tr_flags);
	if (list_empty(&bd->bd_list)) {
		set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
		set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
		gfs2_pin(sdp, bd->bd_bh);
		tr->tr_num_databuf_new++;
		list_add_tail(&bd->bd_list, &tr->tr_databuf);
	}
	spin_unlock(&sdp->sd_log_lock);
out:
	unlock_buffer(bh);
}

void gfs2_trans_add_databufs(struct gfs2_glock *gl, struct folio *folio,
			     size_t from, size_t len)
{
	struct buffer_head *head = folio_buffers(folio);
	unsigned int bsize = head->b_size;
	struct buffer_head *bh;
	size_t to = from + len;
	size_t start, end;

	for (bh = head, start = 0; bh != head || !start;
	     bh = bh->b_this_page, start = end) {
		end = start + bsize;
		if (end <= from)
			continue;
		if (start >= to)
			break;
		set_buffer_uptodate(bh);
		gfs2_trans_add_data(gl, bh);
	}
}

void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
{

	struct gfs2_sbd *sdp = glock_sbd(gl);
	struct super_block *sb = sdp->sd_vfs;
	struct gfs2_bufdata *bd;
	struct gfs2_meta_header *mh;
	struct gfs2_trans *tr = current->journal_info;

	lock_buffer(bh);
	if (buffer_pinned(bh)) {
		set_bit(TR_TOUCHED, &tr->tr_flags);
		goto out;
	}
	spin_lock(&sdp->sd_log_lock);
	bd = bh->b_private;
	if (bd == NULL) {
		spin_unlock(&sdp->sd_log_lock);
		unlock_buffer(bh);
		bd = gfs2_alloc_bufdata(gl, bh);
		lock_buffer(bh);
		spin_lock(&sdp->sd_log_lock);
		if (bh->b_private) {
			kmem_cache_free(gfs2_bufdata_cachep, bd);
			bd = bh->b_private;
		} else {
			bh->b_private = bd;
		}
	}
	gfs2_assert(sdp, bd->bd_gl == gl);
	set_bit(TR_TOUCHED, &tr->tr_flags);
	if (!list_empty(&bd->bd_list))
		goto out_unlock;
	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
	mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
	if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) {
		fs_err(sdp, "Attempting to add uninitialised block to "
		       "journal (inplace block=%lld)\n",
		       (unsigned long long)bd->bd_bh->b_blocknr);
		BUG();
	}
	if (gfs2_withdrawn(sdp)) {
		fs_info(sdp, "GFS2:adding buf while withdrawn! 0x%llx\n",
			(unsigned long long)bd->bd_bh->b_blocknr);
		goto out_unlock;
	}
	if (unlikely(sb->s_writers.frozen == SB_FREEZE_COMPLETE)) {

Annotation

Implementation Notes