fs/ceph/export.c

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

File Facts

System
Linux kernel
Corpus path
fs/ceph/export.c
Extension
.c
Size
15310 bytes
Lines
619
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 ceph_nfs_fh {
	u64 ino;
} __attribute__ ((packed));

/*
 * Larger fh that includes parent ino.
 */
struct ceph_nfs_confh {
	u64 ino, parent_ino;
} __attribute__ ((packed));

/*
 * fh for snapped inode
 */
struct ceph_nfs_snapfh {
	u64 ino;
	u64 snapid;
	u64 parent_ino;
	u32 hash;
} __attribute__ ((packed));

#define BYTES_PER_U32		(sizeof(u32))
#define CEPH_FH_BASIC_SIZE \
	(sizeof(struct ceph_nfs_fh) / BYTES_PER_U32)
#define CEPH_FH_WITH_PARENT_SIZE \
	(sizeof(struct ceph_nfs_confh) / BYTES_PER_U32)
#define CEPH_FH_SNAPPED_INODE_SIZE \
	(sizeof(struct ceph_nfs_snapfh) / BYTES_PER_U32)

static int ceph_encode_snapfh(struct inode *inode, u32 *rawfh, int *max_len,
			      struct inode *parent_inode)
{
	struct ceph_client *cl = ceph_inode_to_client(inode);
	static const int snap_handle_length = CEPH_FH_SNAPPED_INODE_SIZE;
	struct ceph_nfs_snapfh *sfh = (void *)rawfh;
	u64 snapid = ceph_snap(inode);
	int ret;
	bool no_parent = true;

	if (*max_len < snap_handle_length) {
		*max_len = snap_handle_length;
		ret = FILEID_INVALID;
		goto out;
	}

	ret =  -EINVAL;
	if (snapid != CEPH_SNAPDIR) {
		struct inode *dir;
		struct dentry *dentry = d_find_alias(inode);
		if (!dentry)
			goto out;

		rcu_read_lock();
		dir = d_inode_rcu(dentry->d_parent);
		if (ceph_snap(dir) != CEPH_SNAPDIR) {
			sfh->parent_ino = ceph_ino(dir);
			sfh->hash = ceph_dentry_hash(dir, dentry);
			no_parent = false;
		}
		rcu_read_unlock();
		dput(dentry);
	}

	if (no_parent) {
		if (!S_ISDIR(inode->i_mode))
			goto out;
		sfh->parent_ino = sfh->ino;
		sfh->hash = 0;
	}
	sfh->ino = ceph_ino(inode);
	sfh->snapid = snapid;

	*max_len = snap_handle_length;
	ret = FILEID_BTRFS_WITH_PARENT;
out:
	doutc(cl, "%p %llx.%llx ret=%d\n", inode, ceph_vinop(inode), ret);
	return ret;
}

static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
			  struct inode *parent_inode)
{
	struct ceph_client *cl = ceph_inode_to_client(inode);
	static const int handle_length = CEPH_FH_BASIC_SIZE;
	static const int connected_handle_length = CEPH_FH_WITH_PARENT_SIZE;
	int type;

	if (ceph_snap(inode) != CEPH_NOSNAP)
		return ceph_encode_snapfh(inode, rawfh, max_len, parent_inode);

Annotation

Implementation Notes