fs/btrfs/export.c

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

File Facts

System
Linux kernel
Corpus path
fs/btrfs/export.c
Extension
.c
Size
8124 bytes
Lines
308
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 (parent_root_id != fid->root_objectid) {
			if (*max_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT)
				return FILEID_INVALID;
			fid->parent_root_objectid = parent_root_id;
			len = BTRFS_FID_SIZE_CONNECTABLE_ROOT;
			type = FILEID_BTRFS_WITH_PARENT_ROOT;
		} else {
			len = BTRFS_FID_SIZE_CONNECTABLE;
			type = FILEID_BTRFS_WITH_PARENT;
		}
	}

	*max_len = len;
	return type;
}

/*
 * Read dentry of inode with @objectid from filesystem root @root_objectid.
 *
 * @sb:             the filesystem super block
 * @objectid:       inode objectid
 * @root_objectid:  object id of the subvolume root where to look up the inode
 * @generation:     optional, if not zero, verify that the found inode
 *                  generation matches
 *
 * Return dentry alias for the inode, otherwise an error. In case the
 * generation does not match return ESTALE.
 */
struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
				u64 root_objectid, u64 generation)
{
	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
	struct btrfs_root *root;
	struct btrfs_inode *inode;

	if (objectid < BTRFS_FIRST_FREE_OBJECTID)
		return ERR_PTR(-ESTALE);

	root = btrfs_get_fs_root(fs_info, root_objectid, true);
	if (IS_ERR(root))
		return ERR_CAST(root);

	inode = btrfs_iget(objectid, root);
	btrfs_put_root(root);
	if (IS_ERR(inode))
		return ERR_CAST(inode);

	if (generation != 0 && generation != inode->vfs_inode.i_generation) {
		iput(&inode->vfs_inode);
		return ERR_PTR(-ESTALE);
	}

	return d_obtain_alias(&inode->vfs_inode);
}

static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh,
					 int fh_len, int fh_type)
{
	struct btrfs_fid *fid = (struct btrfs_fid *) fh;
	u64 objectid, root_objectid;
	u32 generation;

	if (fh_type == FILEID_BTRFS_WITH_PARENT) {
		if (fh_len <  BTRFS_FID_SIZE_CONNECTABLE)
			return NULL;
		root_objectid = fid->root_objectid;
	} else if (fh_type == FILEID_BTRFS_WITH_PARENT_ROOT) {
		if (fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT)
			return NULL;
		root_objectid = fid->parent_root_objectid;
	} else
		return NULL;

	objectid = fid->parent_objectid;
	generation = fid->parent_gen;

	return btrfs_get_dentry(sb, objectid, root_objectid, generation);
}

static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
					 int fh_len, int fh_type)
{
	struct btrfs_fid *fid = (struct btrfs_fid *) fh;
	u64 objectid, root_objectid;
	u32 generation;

	if ((fh_type != FILEID_BTRFS_WITH_PARENT ||
	     fh_len < BTRFS_FID_SIZE_CONNECTABLE) &&
	    (fh_type != FILEID_BTRFS_WITH_PARENT_ROOT ||
	     fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT) &&

Annotation

Implementation Notes