fs/gfs2/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/gfs2/inode.c
Extension
.c
Size
56272 bytes
Lines
2340
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 (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
			/*
			 * The GL_SKIP flag indicates to skip reading the inode
			 * block.  We read the inode when instantiating it
			 * after possibly checking the block type.
			 */
			error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE,
						   GL_SKIP, &i_gh);
			if (error)
				goto fail;

			error = -ESTALE;
			if (no_formal_ino &&
			    gfs2_inode_already_deleted(ip->i_gl, no_formal_ino))
				goto fail;

			if (blktype != GFS2_BLKST_FREE) {
				error = gfs2_check_blk_type(sdp, no_addr,
							    blktype);
				if (error)
					goto fail;
			}
		}

		set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);

		/* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */
		inode_set_atime(inode,
				1LL << (8 * sizeof(inode_get_atime_sec(inode)) - 1),
				0);

		glock_set_object(ip->i_gl, ip);

		if (type == DT_UNKNOWN) {
			/* Inode glock must be locked already */
			error = gfs2_instantiate(&i_gh);
			if (error) {
				glock_clear_object(ip->i_gl, ip);
				goto fail;
			}
		} else {
			ip->i_no_formal_ino = no_formal_ino;
			inode->i_mode = DT2IF(type);
		}

		if (gfs2_holder_initialized(&i_gh))
			gfs2_glock_dq_uninit(&i_gh);
		glock_set_object(ip->i_iopen_gh.gh_gl, ip);

		gfs2_set_iop(inode);
		unlock_new_inode(inode);
	}

	if (no_formal_ino && ip->i_no_formal_ino &&
	    no_formal_ino != ip->i_no_formal_ino) {
		iput(inode);
		return ERR_PTR(-ESTALE);
	}

	return inode;

fail:
	if (error == GLR_TRYFAILED)
		error = -EAGAIN;
	if (gfs2_holder_initialized(&ip->i_iopen_gh))
		gfs2_glock_dq_uninit(&ip->i_iopen_gh);
	if (gfs2_holder_initialized(&i_gh))
		gfs2_glock_dq_uninit(&i_gh);
	if (ip->i_gl) {
		gfs2_glock_put(ip->i_gl);
		ip->i_gl = NULL;
	}
	iget_failed(inode);
	return ERR_PTR(error);
}

/**
 * gfs2_lookup_by_inum - look up an inode by inode number
 * @sdp: The super block
 * @no_addr: The inode number
 * @no_formal_ino: The inode generation number (0 for any)
 * @blktype: Requested block type (see gfs2_inode_lookup)
 */
struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
				  u64 no_formal_ino, unsigned int blktype)
{
	struct super_block *sb = sdp->sd_vfs;
	struct inode *inode;
	int error;

Annotation

Implementation Notes