fs/backing-file.c

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

File Facts

System
Linux kernel
Corpus path
fs/backing-file.c
Extension
.c
Size
8767 bytes
Lines
367
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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

error = vfs_open(real_path, f);
	if (error) {
		fput(f);
		f = ERR_PTR(error);
	}

	return f;
}
EXPORT_SYMBOL_GPL(backing_file_open);

struct file *backing_tmpfile_open(const struct file *user_file, int flags,
				  const struct path *real_parentpath,
				  umode_t mode, const struct cred *cred)
{
	struct mnt_idmap *real_idmap = mnt_idmap(real_parentpath->mnt);
	const struct path *user_path = &user_file->f_path;
	struct file *f;
	int error;

	f = alloc_empty_backing_file(flags, cred, user_file);
	if (IS_ERR(f))
		return f;

	path_get(user_path);
	backing_file_set_user_path(f, user_path);
	error = vfs_tmpfile(real_idmap, real_parentpath, f, mode);
	if (error) {
		fput(f);
		f = ERR_PTR(error);
	}
	return f;
}
EXPORT_SYMBOL(backing_tmpfile_open);

struct backing_aio {
	struct kiocb iocb;
	refcount_t ref;
	struct kiocb *orig_iocb;
	/* used for aio completion */
	void (*end_write)(struct kiocb *iocb, ssize_t);
	struct work_struct work;
	long res;
};

static struct kmem_cache *backing_aio_cachep;

#define BACKING_IOCB_MASK \
	(IOCB_NOWAIT | IOCB_HIPRI | IOCB_DSYNC | IOCB_SYNC | IOCB_APPEND)

static rwf_t iocb_to_rw_flags(int flags)
{
	return (__force rwf_t)(flags & BACKING_IOCB_MASK);
}

static void backing_aio_put(struct backing_aio *aio)
{
	if (refcount_dec_and_test(&aio->ref)) {
		fput(aio->iocb.ki_filp);
		kmem_cache_free(backing_aio_cachep, aio);
	}
}

static void backing_aio_cleanup(struct backing_aio *aio, long res)
{
	struct kiocb *iocb = &aio->iocb;
	struct kiocb *orig_iocb = aio->orig_iocb;

	orig_iocb->ki_pos = iocb->ki_pos;
	if (aio->end_write)
		aio->end_write(orig_iocb, res);

	backing_aio_put(aio);
}

static void backing_aio_rw_complete(struct kiocb *iocb, long res)
{
	struct backing_aio *aio = container_of(iocb, struct backing_aio, iocb);
	struct kiocb *orig_iocb = aio->orig_iocb;

	if (iocb->ki_flags & IOCB_WRITE)
		kiocb_end_write(iocb);

	backing_aio_cleanup(aio, res);
	orig_iocb->ki_complete(orig_iocb, res);
}

static void backing_aio_complete_work(struct work_struct *work)
{
	struct backing_aio *aio = container_of(work, struct backing_aio, work);

Annotation

Implementation Notes