// SPDX-License-Identifier: GPL-2.0
#include <linux/ceph/ceph_debug.h>
#include <linux/ceph/striper.h>

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/writeback.h>
#include <linux/falloc.h>
#include <linux/iversion.h>
#include <linux/ktime.h>
#include <linux/splice.h>

#include "super.h"
#include "mds_client.h"
#include "cache.h"
#include "io.h"
#include "metric.h"
#include "subvolume_metrics.h"

/*
 * Record I/O for subvolume metrics tracking.
 *
 * Callers must ensure bytes > 0 for reads (ret > 0 check) to avoid counting
 * EOF as an I/O operation. For writes, the condition is (ret >= 0 && len > 0).
 */
static inline void ceph_record_subvolume_io(struct inode *inode, bool is_write,
					    ktime_t start, ktime_t end,
					    size_t bytes)
{
	if (!bytes)
		return;

	ceph_subvolume_metrics_record_io(ceph_sb_to_mdsc(inode->i_sb),
					 ceph_inode(inode),
					 is_write, bytes, start, end);
}

static __le32 ceph_flags_sys2wire(struct ceph_mds_client *mdsc, u32 flags)
{
	struct ceph_client *cl = mdsc->fsc->client;
	u32 wire_flags = 0;

	switch (flags & O_ACCMODE) {
	case O_RDONLY:
		wire_flags |= CEPH_O_RDONLY;
		break;
	case O_WRONLY:
		wire_flags |= CEPH_O_WRONLY;
		break;
	case O_RDWR:
		wire_flags |= CEPH_O_RDWR;
		break;
	}

	flags &= ~O_ACCMODE;

#define ceph_sys2wire(a) if (flags & a) { wire_flags |= CEPH_##a; flags &= ~a; }

	ceph_sys2wire(O_CREAT);
	ceph_sys2wire(O_EXCL);
	ceph_sys2wire(O_TRUNC);
	ceph_sys2wire(O_DIRECTORY);
	ceph_sys2wire(O_NOFOLLOW);

#undef ceph_sys2wire

	if (flags)
		doutc(cl, "unused open flags: %x\n", flags);

	return cpu_to_le32(wire_flags);
}

/*
 * Ceph file operations
 *
 * Implement basic open/close functionality, and implement
 * read/write.
 *
 * We implement three modes of file I/O:
 *  - buffered uses the generic_file_aio_{read,write} helpers
 *
 *  - synchronous is used when there is multi-client read/write
 *    sharing, avoids the page cache, and synchronously waits for an
 *    ack from the OSD.
 *
 *  - direct io takes the variant of the sync path that references
 *    user pages directly.
 *
 * fsync() flushes and waits on dirty pages, but just queues metadata
 * for writeback: since the MDS can recover size and mtime there is no
 * need to wait for MDS acknowledgement.
 */

/*
 * How many pages to get in one call to iov_iter_get_pages().  This
 * determines the size of the on-stack array used as a buffer.
 */
#define ITER_GET_BVECS_PAGES	64

static ssize_t __iter_get_bvecs(struct iov_iter *iter, size_t maxsize,
				struct bio_vec *bvecs)
{
	size_t size = 0;
	int bvec_idx = 0;

	if (maxsize > iov_iter_count(iter))
		maxsize = iov_iter_count(iter);

	while (size < maxsize) {
		struct page *pages[ITER_GET_BVECS_PAGES];
		ssize_t bytes;
		size_t start;
		int idx = 0;

		bytes = iov_iter_get_pages2(iter, pages, maxsize - size,
					   ITER_GET_BVECS_PAGES, &start);
		if (bytes < 0)
			return size ?: bytes;

		size += bytes;

		for ( ; bytes; idx++, bvec_idx++) {
			int len = min_t(int, bytes, PAGE_SIZE - start);

			bvec_set_page(&bvecs[bvec_idx], pages[idx], len, start);
			bytes -= len;
			start = 0;
		}
	}

	return size;
}

/*
 * iov_iter_get_pages() only considers one iov_iter segment, no matter
 * what maxsize or maxpages are given.  For ITER_BVEC that is a single
 * page.
 *
 * Attempt to get up to @maxsize bytes worth of pages from @iter.
 * Return the number of bytes in the created bio_vec array, or an error.
 */
static ssize_t iter_get_bvecs_alloc(struct iov_iter *iter, size_t maxsize,
				    struct bio_vec **bvecs, int *num_bvecs)
{
	struct bio_vec *bv;
	size_t orig_count = iov_iter_count(iter);
	ssize_t bytes;
	int npages;

	iov_iter_truncate(iter, maxsize);
	npages = iov_iter_npages(iter, INT_MAX);
	iov_iter_reexpand(iter, orig_count);

	/*
	 * __iter_get_bvecs() may populate only part of the array -- zero it
	 * out.
	 */
	bv = kvmalloc_objs(*bv, npages, GFP_KERNEL | __GFP_ZERO);
	if (!bv)
		return -ENOMEM;

	bytes = __iter_get_bvecs(iter, maxsize, bv);
	if (bytes < 0) {
		/*
		 * No pages were pinned -- just free the array.
		 */
		kvfree(bv);
		return bytes;
	}

	*bvecs = bv;
	*num_bvecs = npages;
	return bytes;
}

static void put_bvecs(struct bio_vec *bvecs, int num_bvecs, bool should_dirty)
{
	int i;

	for (i = 0; i < num_bvecs; i++) {
		if (bvecs[i].bv_page) {
			if (should_dirty)
				set_page_dirty_lock(bvecs[i].bv_page);
			put_page(bvecs[i].bv_page);
		}
	}
	kvfree(bvecs);
}

/*
 * Prepare an open request.  Preallocate ceph_cap to avoid an
 * inopportune ENOMEM later.
 */
static struct ceph_mds_request *
prepare_open_request(struct super_block *sb, int flags, int create_mode)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(sb);
	struct ceph_mds_request *req;
	int want_auth = USE_ANY_MDS;
	int op = (flags & O_CREAT) ? CEPH_MDS_OP_CREATE : CEPH_MDS_OP_OPEN;

	if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC))
		want_auth = USE_AUTH_MDS;

	req = ceph_mdsc_create_request(mdsc, op, want_auth);
	if (IS_ERR(req))
		goto out;
	req->r_fmode = ceph_flags_to_mode(flags);
	req->r_args.open.flags = ceph_flags_sys2wire(mdsc, flags);
	req->r_args.open.mode = cpu_to_le32(create_mode);
out:
	return req;
}

static int ceph_init_file_info(struct inode *inode, struct file *file,
					int fmode, bool isdir)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_mount_options *opt =
		ceph_inode_to_fs_client(&ci->netfs.inode)->mount_options;
	struct ceph_client *cl = ceph_inode_to_client(inode);
	struct ceph_file_info *fi;
	int ret;

	doutc(cl, "%p %llx.%llx %p 0%o (%s)\n", inode, ceph_vinop(inode),
	      file, inode->i_mode, isdir ? "dir" : "regular");
	BUG_ON(inode->i_fop->release != ceph_release);

	if (isdir) {
		struct ceph_dir_file_info *dfi =
			kmem_cache_zalloc(ceph_dir_file_cachep, GFP_KERNEL);
		if (!dfi)
			return -ENOMEM;

		file->private_data = dfi;
		fi = &dfi->file_info;
		dfi->next_offset = 2;
		dfi->readdir_cache_idx = -1;
	} else {
		fi = kmem_cache_zalloc(ceph_file_cachep, GFP_KERNEL);
		if (!fi)
			return -ENOMEM;

		if (opt->flags & CEPH_MOUNT_OPT_NOPAGECACHE)
			fi->flags |= CEPH_F_SYNC;

		file->private_data = fi;
	}

	ceph_get_fmode(ci, fmode, 1);
	fi->fmode = fmode;

	spin_lock_init(&fi->rw_contexts_lock);
	INIT_LIST_HEAD(&fi->rw_contexts);
	fi->filp_gen = READ_ONCE(ceph_inode_to_fs_client(inode)->filp_gen);

	if ((file->f_mode & FMODE_WRITE) && ceph_has_inline_data(ci)) {
		ret = ceph_uninline_data(file);
		if (ret < 0)
			goto error;
	}

	return 0;

error:
	ceph_fscache_unuse_cookie(inode, file->f_mode & FMODE_WRITE);
	ceph_put_fmode(ci, fi->fmode, 1);
	kmem_cache_free(ceph_file_cachep, fi);
	/* wake up anyone waiting for caps on this inode */
	wake_up_all(&ci->i_cap_wq);
	return ret;
}

/*
 * initialize private struct file data.
 * if we fail, clean up by dropping fmode reference on the ceph_inode
 */
static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
{
	struct ceph_client *cl = ceph_inode_to_client(inode);
	int ret = 0;

	switch (inode->i_mode & S_IFMT) {
	case S_IFREG:
		ceph_fscache_use_cookie(inode, file->f_mode & FMODE_WRITE);
		fallthrough;
	case S_IFDIR:
		ret = ceph_init_file_info(inode, file, fmode,
						S_ISDIR(inode->i_mode));
		break;

	case S_IFLNK:
		doutc(cl, "%p %llx.%llx %p 0%o (symlink)\n", inode,
		      ceph_vinop(inode), file, inode->i_mode);
		break;

	default:
		doutc(cl, "%p %llx.%llx %p 0%o (special)\n", inode,
		      ceph_vinop(inode), file, inode->i_mode);
		/*
		 * we need to drop the open ref now, since we don't
		 * have .release set to ceph_release.
		 */
		BUG_ON(inode->i_fop->release == ceph_release);

		/* call the proper open fop */
		ret = inode->i_fop->open(inode, file);
	}
	return ret;
}

/*
 * Retry cap acquisition after a stale session or a lost cap update.
 */
int ceph_renew_caps(struct inode *inode, int fmode)
{
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
	struct ceph_client *cl = mdsc->fsc->client;
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_mds_request *req;
	int err, flags, wanted, issued;

	spin_lock(&ci->i_ceph_lock);
	__ceph_touch_fmode(ci, mdsc, fmode);
	wanted = __ceph_caps_file_wanted(ci);
	issued = __ceph_caps_issued(ci, NULL);
	if (__ceph_is_any_real_caps(ci) &&
	    (!(wanted & CEPH_CAP_ANY_WR) || ci->i_auth_cap) &&
	    (issued & wanted) == wanted) {
		spin_unlock(&ci->i_ceph_lock);
		doutc(cl, "%p %llx.%llx want %s issued %s updating mds_wanted\n",
		      inode, ceph_vinop(inode), ceph_cap_string(wanted),
		      ceph_cap_string(issued));
		ceph_check_caps(ci, 0);
		return 0;
	}
	spin_unlock(&ci->i_ceph_lock);

	flags = 0;
	if ((wanted & CEPH_CAP_FILE_RD) && (wanted & CEPH_CAP_FILE_WR))
		flags = O_RDWR;
	else if (wanted & CEPH_CAP_FILE_RD)
		flags = O_RDONLY;
	else if (wanted & CEPH_CAP_FILE_WR)
		flags = O_WRONLY;
#ifdef O_LAZY
	if (wanted & CEPH_CAP_FILE_LAZYIO)
		flags |= O_LAZY;
#endif

	req = prepare_open_request(inode->i_sb, flags, 0);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		goto out;
	}

	req->r_inode = inode;
	ihold(inode);
	req->r_num_caps = 1;

	err = ceph_mdsc_do_request(mdsc, NULL, req);
	ceph_mdsc_put_request(req);
out:
	doutc(cl, "%p %llx.%llx open result=%d\n", inode, ceph_vinop(inode),
	      err);
	return err < 0 ? err : 0;
}

/*
 * If we already have the requisite capabilities, we can satisfy
 * the open request locally (no need to request new caps from the
 * MDS).  We do, however, need to inform the MDS (asynchronously)
 * if our wanted caps set expands.
 */
int ceph_open(struct inode *inode, struct file *file)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_sb_to_fs_client(inode->i_sb);
	struct ceph_client *cl = fsc->client;
	struct ceph_mds_client *mdsc = fsc->mdsc;
	struct ceph_mds_request *req;
	struct ceph_file_info *fi = file->private_data;
	int err;
	int flags, fmode, wanted;
	struct dentry *dentry;
	char *path;
	bool do_sync = false;
	int mask = MAY_READ;

	if (fi) {
		doutc(cl, "file %p is already opened\n", file);
		return 0;
	}

	/* filter out O_CREAT|O_EXCL; vfs did that already.  yuck. */
	flags = file->f_flags & ~(O_CREAT|O_EXCL);
	if (S_ISDIR(inode->i_mode)) {
		flags = O_DIRECTORY;  /* mds likes to know */
	} else if (S_ISREG(inode->i_mode)) {
		err = fscrypt_file_open(inode, file);
		if (err)
			return err;
	}

	doutc(cl, "%p %llx.%llx file %p flags %d (%d)\n", inode,
	      ceph_vinop(inode), file, flags, file->f_flags);
	fmode = ceph_flags_to_mode(flags);
	wanted = ceph_caps_for_mode(fmode);

	if (fmode & CEPH_FILE_MODE_WR)
		mask |= MAY_WRITE;
	dentry = d_find_alias(inode);
	if (!dentry) {
		do_sync = true;
	} else {
		struct ceph_path_info path_info = {0};
		path = ceph_mdsc_build_path(mdsc, dentry, &path_info, 0);
		if (IS_ERR(path)) {
			do_sync = true;
			err = 0;
		} else {
			err = ceph_mds_check_access(mdsc, path, mask);
		}
		ceph_mdsc_free_path_info(&path_info);
		dput(dentry);

		/* For none EACCES cases will let the MDS do the mds auth check */
		if (err == -EACCES) {
			return err;
		} else if (err < 0) {
			do_sync = true;
			err = 0;
		}
	}

	/* snapped files are read-only */
	if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
		return -EROFS;

	/* trivially open snapdir */
	if (ceph_snap(inode) == CEPH_SNAPDIR) {
		return ceph_init_file(inode, file, fmode);
	}

	/*
	 * No need to block if we have caps on the auth MDS (for
	 * write) or any MDS (for read).  Update wanted set
	 * asynchronously.
	 */
	spin_lock(&ci->i_ceph_lock);
	if (!do_sync && __ceph_is_any_real_caps(ci) &&
	    (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) {
		int mds_wanted = __ceph_caps_mds_wanted(ci, true);
		int issued = __ceph_caps_issued(ci, NULL);

		doutc(cl, "open %p fmode %d want %s issued %s using existing\n",
		      inode, fmode, ceph_cap_string(wanted),
		      ceph_cap_string(issued));
		__ceph_touch_fmode(ci, mdsc, fmode);
		spin_unlock(&ci->i_ceph_lock);

		/* adjust wanted? */
		if ((issued & wanted) != wanted &&
		    (mds_wanted & wanted) != wanted &&
		    ceph_snap(inode) != CEPH_SNAPDIR)
			ceph_check_caps(ci, 0);

		return ceph_init_file(inode, file, fmode);
	} else if (!do_sync && ceph_snap(inode) != CEPH_NOSNAP &&
		   (ci->i_snap_caps & wanted) == wanted) {
		__ceph_touch_fmode(ci, mdsc, fmode);
		spin_unlock(&ci->i_ceph_lock);
		return ceph_init_file(inode, file, fmode);
	}

	spin_unlock(&ci->i_ceph_lock);

	doutc(cl, "open fmode %d wants %s\n", fmode, ceph_cap_string(wanted));
	req = prepare_open_request(inode->i_sb, flags, 0);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		goto out;
	}
	req->r_inode = inode;
	ihold(inode);

	req->r_num_caps = 1;
	err = ceph_mdsc_do_request(mdsc, NULL, req);
	if (!err)
		err = ceph_init_file(inode, file, req->r_fmode);
	ceph_mdsc_put_request(req);
	doutc(cl, "open result=%d on %llx.%llx\n", err, ceph_vinop(inode));
out:
	return err;
}

/* Clone the layout from a synchronous create, if the dir now has Dc caps */
static void
cache_file_layout(struct inode *dst, struct inode *src)
{
	struct ceph_inode_info *cdst = ceph_inode(dst);
	struct ceph_inode_info *csrc = ceph_inode(src);

	spin_lock(&cdst->i_ceph_lock);
	if ((__ceph_caps_issued(cdst, NULL) & CEPH_CAP_DIR_CREATE) &&
	    !ceph_file_layout_is_valid(&cdst->i_cached_layout)) {
		memcpy(&cdst->i_cached_layout, &csrc->i_layout,
			sizeof(cdst->i_cached_layout));
		rcu_assign_pointer(cdst->i_cached_layout.pool_ns,
				   ceph_try_get_string(csrc->i_layout.pool_ns));
	}
	spin_unlock(&cdst->i_ceph_lock);
}

/*
 * Try to set up an async create. We need caps, a file layout, and inode number,
 * and either a lease on the dentry or complete dir info. If any of those
 * criteria are not satisfied, then return false and the caller can go
 * synchronous.
 */
static int try_prep_async_create(struct inode *dir, struct dentry *dentry,
				 struct ceph_file_layout *lo, u64 *pino)
{
	struct ceph_inode_info *ci = ceph_inode(dir);
	struct ceph_dentry_info *di = ceph_dentry(dentry);
	int got = 0, want = CEPH_CAP_FILE_EXCL | CEPH_CAP_DIR_CREATE;
	u64 ino;

	spin_lock(&ci->i_ceph_lock);
	/* No auth cap means no chance for Dc caps */
	if (!ci->i_auth_cap)
		goto no_async;

	/* Any delegated inos? */
	if (xa_empty(&ci->i_auth_cap->session->s_delegated_inos))
		goto no_async;

	if (!ceph_file_layout_is_valid(&ci->i_cached_layout))
		goto no_async;

	if ((__ceph_caps_issued(ci, NULL) & want) != want)
		goto no_async;

	if (d_in_lookup(dentry)) {
		if (!__ceph_dir_is_complete(ci))
			goto no_async;
		spin_lock(&dentry->d_lock);
		di->lease_shared_gen = atomic_read(&ci->i_shared_gen);
		spin_unlock(&dentry->d_lock);
	} else if (atomic_read(&ci->i_shared_gen) !=
		   READ_ONCE(di->lease_shared_gen)) {
		goto no_async;
	}

	ino = ceph_get_deleg_ino(ci->i_auth_cap->session);
	if (!ino)
		goto no_async;

	*pino = ino;
	ceph_take_cap_refs(ci, want, false);
	memcpy(lo, &ci->i_cached_layout, sizeof(*lo));
	rcu_assign_pointer(lo->pool_ns,
			   ceph_try_get_string(ci->i_cached_layout.pool_ns));
	got = want;
no_async:
	spin_unlock(&ci->i_ceph_lock);
	return got;
}

static void restore_deleg_ino(struct inode *dir, u64 ino)
{
	struct ceph_client *cl = ceph_inode_to_client(dir);
	struct ceph_inode_info *ci = ceph_inode(dir);
	struct ceph_mds_session *s = NULL;

	spin_lock(&ci->i_ceph_lock);
	if (ci->i_auth_cap)
		s = ceph_get_mds_session(ci->i_auth_cap->session);
	spin_unlock(&ci->i_ceph_lock);
	if (s) {
		int err = ceph_restore_deleg_ino(s, ino);
		if (err)
			pr_warn_client(cl,
				"unable to restore delegated ino 0x%llx to session: %d\n",
				ino, err);
		ceph_put_mds_session(s);
	}
}

static void wake_async_create_waiters(struct inode *inode,
				      struct ceph_mds_session *session)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	bool check_cap = false;

	spin_lock(&ci->i_ceph_lock);
	if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
		/* Serialized by i_ceph_lock; the two ops touch different bits. */
		clear_and_wake_up_bit(CEPH_I_ASYNC_CREATE_BIT, &ci->i_ceph_flags);

		if (test_and_clear_bit(CEPH_I_ASYNC_CHECK_CAPS_BIT,
				      &ci->i_ceph_flags))
			check_cap = true;
	}
	ceph_kick_flushing_inode_caps(session, ci);
	spin_unlock(&ci->i_ceph_lock);

	if (check_cap)
		ceph_check_caps(ci, CHECK_CAPS_FLUSH);
}

static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
                                 struct ceph_mds_request *req)
{
	struct ceph_client *cl = mdsc->fsc->client;
	struct dentry *dentry = req->r_dentry;
	struct inode *dinode = d_inode(dentry);
	struct inode *tinode = req->r_target_inode;
	int result = req->r_err ? req->r_err :
			le32_to_cpu(req->r_reply_info.head->result);

	WARN_ON_ONCE(dinode && tinode && dinode != tinode);

	/* MDS changed -- caller must resubmit */
	if (result == -EJUKEBOX)
		goto out;

	mapping_set_error(req->r_parent->i_mapping, result);

	if (result) {
		struct ceph_path_info path_info = {0};
		char *path = ceph_mdsc_build_path(mdsc, req->r_dentry, &path_info, 0);

		pr_warn_client(cl,
			"async create failure path=(%llx)%s result=%d!\n",
			path_info.vino.ino, IS_ERR(path) ? "<<bad>>" : path, result);
		ceph_mdsc_free_path_info(&path_info);

		ceph_dir_clear_complete(req->r_parent);
		if (!d_unhashed(dentry))
			d_drop(dentry);

		if (dinode) {
			mapping_set_error(dinode->i_mapping, result);
			ceph_inode_shutdown(dinode);
			wake_async_create_waiters(dinode, req->r_session);
		}
	}

	if (tinode) {
		u64 ino = ceph_vino(tinode).ino;

		if (req->r_deleg_ino != ino)
			pr_warn_client(cl,
				"inode number mismatch! err=%d deleg_ino=0x%llx target=0x%llx\n",
				req->r_err, req->r_deleg_ino, ino);

		mapping_set_error(tinode->i_mapping, result);
		wake_async_create_waiters(tinode, req->r_session);
	} else if (!result) {
		pr_warn_client(cl, "no req->r_target_inode for 0x%llx\n",
			       req->r_deleg_ino);
	}
out:
	ceph_mdsc_release_dir_caps(req);
}

static int ceph_finish_async_create(struct inode *dir, struct inode *inode,
				    struct dentry *dentry,
				    struct file *file, umode_t mode,
				    struct ceph_mds_request *req,
				    struct ceph_acl_sec_ctx *as_ctx,
				    struct ceph_file_layout *lo)
{
	int ret;
	char xattr_buf[4];
	struct ceph_mds_reply_inode in = { };
	struct ceph_mds_reply_info_in iinfo = { .in = &in };
	struct ceph_inode_info *ci = ceph_inode(dir);
	struct ceph_dentry_info *di = ceph_dentry(dentry);
	struct timespec64 now;
	struct ceph_string *pool_ns;
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
	struct ceph_client *cl = mdsc->fsc->client;
	struct ceph_vino vino = { .ino = req->r_deleg_ino,
				  .snap = CEPH_NOSNAP };

	ktime_get_real_ts64(&now);

	iinfo.inline_version = CEPH_INLINE_NONE;
	iinfo.change_attr = 1;
	ceph_encode_timespec64(&iinfo.btime, &now);

	if (req->r_pagelist) {
		iinfo.xattr_len = req->r_pagelist->length;
		iinfo.xattr_data = req->r_pagelist->mapped_tail;
	} else {
		/* fake it */
		iinfo.xattr_len = ARRAY_SIZE(xattr_buf);
		iinfo.xattr_data = xattr_buf;
		memset(iinfo.xattr_data, 0, iinfo.xattr_len);
	}

	in.ino = cpu_to_le64(vino.ino);
	in.snapid = cpu_to_le64(CEPH_NOSNAP);
	in.version = cpu_to_le64(1);	// ???
	in.cap.caps = in.cap.wanted = cpu_to_le32(CEPH_CAP_ALL_FILE);
	in.cap.cap_id = cpu_to_le64(1);
	in.cap.realm = cpu_to_le64(ci->i_snap_realm->ino);
	in.cap.flags = CEPH_CAP_FLAG_AUTH;
	in.ctime = in.mtime = in.atime = iinfo.btime;
	in.truncate_seq = cpu_to_le32(1);
	in.truncate_size = cpu_to_le64(-1ULL);
	in.xattr_version = cpu_to_le64(1);
	in.uid = cpu_to_le32(from_kuid(&init_user_ns,
				       mapped_fsuid(req->r_mnt_idmap,
						    &init_user_ns)));
	if (dir->i_mode & S_ISGID) {
		in.gid = cpu_to_le32(from_kgid(&init_user_ns, dir->i_gid));

		/* Directories always inherit the setgid bit. */
		if (S_ISDIR(mode))
			mode |= S_ISGID;
	} else {
		in.gid = cpu_to_le32(from_kgid(&init_user_ns,
				     mapped_fsgid(req->r_mnt_idmap,
						  &init_user_ns)));
	}
	in.mode = cpu_to_le32((u32)mode);

	in.nlink = cpu_to_le32(1);
	in.max_size = cpu_to_le64(lo->stripe_unit);

	ceph_file_layout_to_legacy(lo, &in.layout);
	/* lo is private, so pool_ns can't change */
	pool_ns = rcu_dereference_raw(lo->pool_ns);
	if (pool_ns) {
		iinfo.pool_ns_len = pool_ns->len;
		iinfo.pool_ns_data = pool_ns->str;
	}

	down_read(&mdsc->snap_rwsem);
	ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session,
			      req->r_fmode, NULL);
	up_read(&mdsc->snap_rwsem);
	if (ret) {
		doutc(cl, "failed to fill inode: %d\n", ret);
		ceph_dir_clear_complete(dir);
		if (!d_unhashed(dentry))
			d_drop(dentry);
		discard_new_inode(inode);
	} else {
		struct dentry *dn;

		doutc(cl, "d_adding new inode 0x%llx to 0x%llx/%s\n",
		      vino.ino, ceph_ino(dir), dentry->d_name.name);
		ceph_dir_clear_ordered(dir);
		ceph_init_inode_acls(inode, as_ctx);
		if (inode_state_read_once(inode) & I_NEW) {
			/*
			 * If it's not I_NEW, then someone created this before
			 * we got here. Assume the server is aware of it at
			 * that point and don't worry about setting
			 * CEPH_I_ASYNC_CREATE.
			 */
			set_bit(CEPH_I_ASYNC_CREATE_BIT,
				&ceph_inode(inode)->i_ceph_flags);
			unlock_new_inode(inode);
		}
		if (d_in_lookup(dentry) || d_really_is_negative(dentry)) {
			if (!d_unhashed(dentry))
				d_drop(dentry);
			dn = d_splice_alias(inode, dentry);
			WARN_ON_ONCE(dn && dn != dentry);
		}
		file->f_mode |= FMODE_CREATED;
		ret = finish_open(file, dentry, ceph_open);
	}

	spin_lock(&dentry->d_lock);
	clear_and_wake_up_bit(CEPH_DENTRY_ASYNC_CREATE_BIT, &di->flags);
	spin_unlock(&dentry->d_lock);

	return ret;
}

/*
 * Do a lookup + open with a single request.  If we get a non-existent
 * file or symlink, return 1 so the VFS can retry.
 */
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
		     struct file *file, unsigned flags, umode_t mode)
{
	struct mnt_idmap *idmap = file_mnt_idmap(file);
	struct ceph_fs_client *fsc = ceph_sb_to_fs_client(dir->i_sb);
	struct ceph_client *cl = fsc->client;
	struct ceph_mds_client *mdsc = fsc->mdsc;
	struct ceph_mds_request *req;
	struct inode *new_inode = NULL;
	struct dentry *dn;
	struct ceph_acl_sec_ctx as_ctx = {};
	bool try_async = ceph_test_mount_opt(fsc, ASYNC_DIROPS);
	int mask;
	int err;
	char *path;

	doutc(cl, "%p %llx.%llx dentry %p '%pd' %s flags %d mode 0%o\n",
	      dir, ceph_vinop(dir), dentry, dentry,
	      d_unhashed(dentry) ? "unhashed" : "hashed", flags, mode);

	if (dentry->d_name.len > NAME_MAX)
		return -ENAMETOOLONG;

	err = ceph_wait_on_conflict_unlink(dentry);
	if (err)
		return err;
	/*
	 * Do not truncate the file, since atomic_open is called before the
	 * permission check. The caller will do the truncation afterward.
	 */
	flags &= ~O_TRUNC;

	dn = d_find_alias(dir);
	if (!dn) {
		try_async = false;
	} else {
		struct ceph_path_info path_info = {0};
		path = ceph_mdsc_build_path(mdsc, dn, &path_info, 0);
		if (IS_ERR(path)) {
			try_async = false;
			err = 0;
		} else {
			int fmode = ceph_flags_to_mode(flags);

			mask = MAY_READ;
			if (fmode & CEPH_FILE_MODE_WR)
				mask |= MAY_WRITE;
			err = ceph_mds_check_access(mdsc, path, mask);
		}
		ceph_mdsc_free_path_info(&path_info);
		dput(dn);

		/* For none EACCES cases will let the MDS do the mds auth check */
		if (err == -EACCES) {
			return err;
		} else if (err < 0) {
			try_async = false;
			err = 0;
		}
	}

retry:
	if (flags & O_CREAT) {
		if (ceph_quota_is_max_files_exceeded(dir))
			return -EDQUOT;

		new_inode = ceph_new_inode(dir, dentry, &mode, &as_ctx);
		if (IS_ERR(new_inode)) {
			err = PTR_ERR(new_inode);
			goto out_ctx;
		}
		/* Async create can't handle more than a page of xattrs */
		if (as_ctx.pagelist &&
		    !list_is_singular(&as_ctx.pagelist->head))
			try_async = false;
	} else if (!d_in_lookup(dentry)) {
		/* If it's not being looked up, it's negative */
		return -ENOENT;
	}

	/* do the open */
	req = prepare_open_request(dir->i_sb, flags, mode);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		goto out_ctx;
	}
	req->r_dentry = dget(dentry);
	req->r_num_caps = 2;
	mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
	if (ceph_security_xattr_wanted(dir))
		mask |= CEPH_CAP_XATTR_SHARED;
	req->r_args.open.mask = cpu_to_le32(mask);
	req->r_parent = dir;
	if (req->r_op == CEPH_MDS_OP_CREATE)
		req->r_mnt_idmap = mnt_idmap_get(idmap);
	ihold(dir);
	if (IS_ENCRYPTED(dir)) {
		set_bit(CEPH_MDS_R_FSCRYPT_FILE, &req->r_req_flags);
		err = fscrypt_prepare_lookup_partial(dir, dentry);
		if (err < 0)
			goto out_req;
	}

	if (flags & O_CREAT) {
		struct ceph_file_layout lo;

		req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL |
				     CEPH_CAP_XATTR_EXCL;
		req->r_dentry_unless = CEPH_CAP_FILE_EXCL;

		ceph_as_ctx_to_req(req, &as_ctx);

		if (try_async && (req->r_dir_caps =
				  try_prep_async_create(dir, dentry, &lo,
							&req->r_deleg_ino))) {
			struct ceph_vino vino = { .ino = req->r_deleg_ino,
						  .snap = CEPH_NOSNAP };
			struct ceph_dentry_info *di = ceph_dentry(dentry);

			set_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags);
			req->r_args.open.flags |= cpu_to_le32(CEPH_O_EXCL);
			req->r_callback = ceph_async_create_cb;

			/* Hash inode before RPC */
			new_inode = ceph_get_inode(dir->i_sb, vino, new_inode);
			if (IS_ERR(new_inode)) {
				err = PTR_ERR(new_inode);
				new_inode = NULL;
				goto out_req;
			}
			WARN_ON_ONCE(!(inode_state_read_once(new_inode) & I_NEW));

			spin_lock(&dentry->d_lock);
			di->flags |= CEPH_DENTRY_ASYNC_CREATE;
			spin_unlock(&dentry->d_lock);

			err = ceph_mdsc_submit_request(mdsc, dir, req);
			if (!err) {
				err = ceph_finish_async_create(dir, new_inode,
							       dentry, file,
							       mode, req,
							       &as_ctx, &lo);
				new_inode = NULL;
			} else if (err == -EJUKEBOX) {
				restore_deleg_ino(dir, req->r_deleg_ino);
				ceph_mdsc_put_request(req);
				discard_new_inode(new_inode);
				ceph_release_acl_sec_ctx(&as_ctx);
				memset(&as_ctx, 0, sizeof(as_ctx));
				new_inode = NULL;
				try_async = false;
				ceph_put_string(rcu_dereference_raw(lo.pool_ns));
				goto retry;
			}
			ceph_put_string(rcu_dereference_raw(lo.pool_ns));
			goto out_req;
		}
	}

	set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
	req->r_new_inode = new_inode;
	new_inode = NULL;
	err = ceph_mdsc_do_request(mdsc, (flags & O_CREAT) ? dir : NULL, req);
	if (err == -ENOENT) {
		dentry = ceph_handle_snapdir(req, dentry);
		if (IS_ERR(dentry)) {
			err = PTR_ERR(dentry);
			goto out_req;
		}
		err = 0;
	}

	if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
		err = ceph_handle_notrace_create(dir, dentry);

	if (d_in_lookup(dentry)) {
		dn = ceph_finish_lookup(req, dentry, err);
		if (IS_ERR(dn))
			err = PTR_ERR(dn);
	} else {
		/* we were given a hashed negative dentry */
		dn = NULL;
	}
	if (err)
		goto out_req;
	if (dn || d_really_is_negative(dentry) || d_is_symlink(dentry)) {
		/* make vfs retry on splice, ENOENT, or symlink */
		doutc(cl, "finish_no_open on dn %p\n", dn);
		err = finish_no_open(file, dn);
	} else {
		if (IS_ENCRYPTED(dir) &&
		    !fscrypt_has_permitted_context(dir, d_inode(dentry))) {
			pr_warn_client(cl,
				"Inconsistent encryption context (parent %llx:%llx child %llx:%llx)\n",
				ceph_vinop(dir), ceph_vinop(d_inode(dentry)));
			goto out_req;
		}

		doutc(cl, "finish_open on dn %p\n", dn);
		if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) {
			struct inode *newino = d_inode(dentry);

			cache_file_layout(dir, newino);
			ceph_init_inode_acls(newino, &as_ctx);
			file->f_mode |= FMODE_CREATED;
		}
		if ((flags & __O_REGULAR) && !d_is_reg(dentry)) {
			err = -EFTYPE;
			goto out_req;
		}
		err = finish_open(file, dentry, ceph_open);
	}
out_req:
	ceph_mdsc_put_request(req);
	iput(new_inode);
out_ctx:
	ceph_release_acl_sec_ctx(&as_ctx);
	doutc(cl, "result=%d\n", err);
	return err;
}

int ceph_release(struct inode *inode, struct file *file)
{
	struct ceph_client *cl = ceph_inode_to_client(inode);
	struct ceph_inode_info *ci = ceph_inode(inode);

	if (S_ISDIR(inode->i_mode)) {
		struct ceph_dir_file_info *dfi = file->private_data;
		doutc(cl, "%p %llx.%llx dir file %p\n", inode,
		      ceph_vinop(inode), file);
		WARN_ON(!list_empty(&dfi->file_info.rw_contexts));

		ceph_put_fmode(ci, dfi->file_info.fmode, 1);

		if (dfi->last_readdir)
			ceph_mdsc_put_request(dfi->last_readdir);
		kfree(dfi->last_name);
		kfree(dfi->dir_info);
		kmem_cache_free(ceph_dir_file_cachep, dfi);
	} else {
		struct ceph_file_info *fi = file->private_data;
		doutc(cl, "%p %llx.%llx regular file %p\n", inode,
		      ceph_vinop(inode), file);
		WARN_ON(!list_empty(&fi->rw_contexts));

		ceph_fscache_unuse_cookie(inode, file->f_mode & FMODE_WRITE);
		ceph_put_fmode(ci, fi->fmode, 1);

		kmem_cache_free(ceph_file_cachep, fi);
	}

	/* wake up anyone waiting for caps on this inode */
	wake_up_all(&ci->i_cap_wq);
	return 0;
}

enum {
	HAVE_RETRIED = 1,
	CHECK_EOF =    2,
	READ_INLINE =  3,
};

/*
 * Completely synchronous read and write methods.  Direct from __user
 * buffer to osd, or directly to user pages (if O_DIRECT).
 *
 * If the read spans object boundary, just do multiple reads.  (That's not
 * atomic, but good enough for now.)
 *
 * If we get a short result from the OSD, check against i_size; we need to
 * only return a short read to the caller if we hit EOF.
 */
ssize_t __ceph_sync_read(struct inode *inode, loff_t *ki_pos,
			 struct iov_iter *to, int *retry_op,
			 u64 *last_objver)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
	struct ceph_client *cl = fsc->client;
	struct ceph_osd_client *osdc = &fsc->client->osdc;
	ssize_t ret;
	u64 off = *ki_pos;
	u64 len = iov_iter_count(to);
	u64 i_size = i_size_read(inode);
	bool sparse = IS_ENCRYPTED(inode) || ceph_test_mount_opt(fsc, SPARSEREAD);
	u64 objver = 0;

	doutc(cl, "on inode %p %llx.%llx %llx~%llx\n", inode,
	      ceph_vinop(inode), *ki_pos, len);

	if (ceph_inode_is_shutdown(inode))
		return -EIO;

	if (!len || !i_size)
		return 0;
	/*
	 * flush any page cache pages in this range.  this
	 * will make concurrent normal and sync io slow,
	 * but it will at least behave sensibly when they are
	 * in sequence.
	 */
	ret = filemap_write_and_wait_range(inode->i_mapping,
					   off, off + len - 1);
	if (ret < 0)
		return ret;

	ret = 0;
	while ((len = iov_iter_count(to)) > 0) {
		struct ceph_osd_request *req;
		struct page **pages;
		int num_pages;
		size_t page_off;
		bool more;
		int idx = 0;
		size_t left;
		struct ceph_osd_req_op *op;
		u64 read_off = off;
		u64 read_len = len;
		int extent_cnt;

		/* determine new offset/length if encrypted */
		ceph_fscrypt_adjust_off_and_len(inode, &read_off, &read_len);

		doutc(cl, "orig %llu~%llu reading %llu~%llu", off, len,
		      read_off, read_len);

		req = ceph_osdc_new_request(osdc, &ci->i_layout,
					ci->i_vino, read_off, &read_len, 0, 1,
					sparse ? CEPH_OSD_OP_SPARSE_READ :
						 CEPH_OSD_OP_READ,
					CEPH_OSD_FLAG_READ,
					NULL, ci->i_truncate_seq,
					ci->i_truncate_size, false);
		if (IS_ERR(req)) {
			ret = PTR_ERR(req);
			break;
		}

		/* adjust len downward if the request truncated the len */
		if (off + len > read_off + read_len)
			len = read_off + read_len - off;
		more = len < iov_iter_count(to);

		op = &req->r_ops[0];
		if (sparse) {
			extent_cnt = __ceph_sparse_read_ext_count(inode, read_len);
			ret = ceph_alloc_sparse_ext_map(op, extent_cnt);
			if (ret) {
				ceph_osdc_put_request(req);
				break;
			}
		}

		num_pages = calc_pages_for(read_off, read_len);
		page_off = offset_in_page(off);
		pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
		if (IS_ERR(pages)) {
			ceph_osdc_put_request(req);
			ret = PTR_ERR(pages);
			break;
		}

		osd_req_op_extent_osd_data_pages(req, 0, pages, read_len,
						 offset_in_page(read_off),
						 false, true);

		ceph_osdc_start_request(osdc, req);
		ret = ceph_osdc_wait_request(osdc, req);

		ceph_update_read_metrics(&fsc->mdsc->metric,
					 req->r_start_latency,
					 req->r_end_latency,
					 read_len, ret);
		/*
		 * Only record subvolume metrics for actual bytes read.
		 * ret == 0 means EOF (no data), not an I/O operation.
		 */
		if (ret > 0)
			ceph_record_subvolume_io(inode, false,
						 req->r_start_latency,
						 req->r_end_latency,
						 ret);

		if (ret > 0)
			objver = req->r_version;

		i_size = i_size_read(inode);
		doutc(cl, "%llu~%llu got %zd i_size %llu%s\n", off, len,
		      ret, i_size, (more ? " MORE" : ""));

		/* Fix it to go to end of extent map */
		if (sparse && ret >= 0)
			ret = ceph_sparse_ext_map_end(op);
		else if (ret == -ENOENT)
			ret = 0;

		if (ret < 0) {
			ceph_osdc_put_request(req);
			if (ret == -EBLOCKLISTED)
				fsc->blocklisted = true;
			break;
		}

		if (IS_ENCRYPTED(inode)) {
			int fret;

			fret = ceph_fscrypt_decrypt_extents(inode, pages,
					read_off, op->extent.sparse_ext,
					op->extent.sparse_ext_cnt);
			if (fret < 0) {
				ret = fret;
				ceph_osdc_put_request(req);
				break;
			}

			/* account for any partial block at the beginning */
			fret -= (off - read_off);

			/*
			 * Short read after big offset adjustment?
			 * Nothing is usable, just call it a zero
			 * len read.
			 */
			fret = max(fret, 0);

			/* account for partial block at the end */
			ret = min_t(ssize_t, fret, len);
		}

		/* Short read but not EOF? Zero out the remainder. */
		if (ret < len && (off + ret < i_size)) {
			int zlen = min(len - ret, i_size - off - ret);
			int zoff = page_off + ret;

			doutc(cl, "zero gap %llu~%llu\n", off + ret,
			      off + ret + zlen);
			ceph_zero_page_vector_range(zoff, zlen, pages);
			ret += zlen;
		}

		if (off + ret > i_size)
			left = (i_size > off) ? i_size - off : 0;
		else
			left = ret;

		while (left > 0) {
			size_t plen, copied;

			plen = min_t(size_t, left, PAGE_SIZE - page_off);
			SetPageUptodate(pages[idx]);
			copied = copy_page_to_iter(pages[idx++],
						   page_off, plen, to);
			off += copied;
			left -= copied;
			page_off = 0;
			if (copied < plen) {
				ret = -EFAULT;
				break;
			}
		}

		ceph_osdc_put_request(req);

		if (off >= i_size || !more)
			break;
	}

	if (ret > 0) {
		if (off >= i_size) {
			*retry_op = CHECK_EOF;
			ret = i_size - *ki_pos;
			*ki_pos = i_size;
		} else {
			ret = off - *ki_pos;
			*ki_pos = off;
		}

		if (last_objver)
			*last_objver = objver;
	}
	doutc(cl, "result %zd retry_op %d\n", ret, *retry_op);
	return ret;
}

static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
			      int *retry_op)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	struct ceph_client *cl = ceph_inode_to_client(inode);

	doutc(cl, "on file %p %llx~%zx %s\n", file, iocb->ki_pos,
	      iov_iter_count(to),
	      (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");

	return __ceph_sync_read(inode, &iocb->ki_pos, to, retry_op, NULL);
}

struct ceph_aio_request {
	struct kiocb *iocb;
	size_t total_len;
	bool write;
	bool should_dirty;
	int error;
	struct list_head osd_reqs;
	unsigned num_reqs;
	atomic_t pending_reqs;
	struct timespec64 mtime;
	struct ceph_cap_flush *prealloc_cf;
};

struct ceph_aio_work {
	struct work_struct work;
	struct ceph_osd_request *req;
};

static void ceph_aio_retry_work(struct work_struct *work);

static void ceph_aio_complete(struct inode *inode,
			      struct ceph_aio_request *aio_req)
{
	struct ceph_client *cl = ceph_inode_to_client(inode);
	struct ceph_inode_info *ci = ceph_inode(inode);
	int ret;

	if (!atomic_dec_and_test(&aio_req->pending_reqs))
		return;

	if (aio_req->iocb->ki_flags & IOCB_DIRECT)
		inode_dio_end(inode);

	ret = aio_req->error;
	if (!ret)
		ret = aio_req->total_len;

	doutc(cl, "%p %llx.%llx rc %d\n", inode, ceph_vinop(inode), ret);

	if (ret >= 0 && aio_req->write) {
		int dirty;

		loff_t endoff = aio_req->iocb->ki_pos + aio_req->total_len;
		if (endoff > i_size_read(inode)) {
			if (ceph_inode_set_size(inode, endoff))
				ceph_check_caps(ci, CHECK_CAPS_AUTHONLY);
		}

		spin_lock(&ci->i_ceph_lock);
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
					       &aio_req->prealloc_cf);
		spin_unlock(&ci->i_ceph_lock);
		if (dirty)
			__mark_inode_dirty(inode, dirty);

	}

	ceph_put_cap_refs(ci, (aio_req->write ? CEPH_CAP_FILE_WR :
						CEPH_CAP_FILE_RD));

	aio_req->iocb->ki_complete(aio_req->iocb, ret);

	ceph_free_cap_flush(aio_req->prealloc_cf);
	kfree(aio_req);
}

static void ceph_aio_complete_req(struct ceph_osd_request *req)
{
	int rc = req->r_result;
	struct inode *inode = req->r_inode;
	struct ceph_aio_request *aio_req = req->r_priv;
	struct ceph_osd_data *osd_data = osd_req_op_extent_osd_data(req, 0);
	struct ceph_osd_req_op *op = &req->r_ops[0];
	struct ceph_client_metric *metric = &ceph_sb_to_mdsc(inode->i_sb)->metric;
	unsigned int len = osd_data->bvec_pos.iter.bi_size;
	bool sparse = (op->op == CEPH_OSD_OP_SPARSE_READ);
	struct ceph_client *cl = ceph_inode_to_client(inode);

	BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_BVECS);
	BUG_ON(!osd_data->num_bvecs);

	doutc(cl, "req %p inode %p %llx.%llx, rc %d bytes %u\n", req,
	      inode, ceph_vinop(inode), rc, len);

	if (rc == -EOLDSNAPC) {
		struct ceph_aio_work *aio_work;
		BUG_ON(!aio_req->write);

		aio_work = kmalloc_obj(*aio_work, GFP_NOFS);
		if (aio_work) {
			INIT_WORK(&aio_work->work, ceph_aio_retry_work);
			aio_work->req = req;
			queue_work(ceph_inode_to_fs_client(inode)->inode_wq,
				   &aio_work->work);
			return;
		}
		rc = -ENOMEM;
	} else if (!aio_req->write) {
		if (sparse && rc >= 0)
			rc = ceph_sparse_ext_map_end(op);
		if (rc == -ENOENT)
			rc = 0;
		if (rc >= 0 && len > rc) {
			struct iov_iter i;
			int zlen = len - rc;

			/*
			 * If read is satisfied by single OSD request,
			 * it can pass EOF. Otherwise read is within
			 * i_size.
			 */
			if (aio_req->num_reqs == 1) {
				loff_t i_size = i_size_read(inode);
				loff_t endoff = aio_req->iocb->ki_pos + rc;
				if (endoff < i_size)
					zlen = min_t(size_t, zlen,
						     i_size - endoff);
				aio_req->total_len = rc + zlen;
			}

			iov_iter_bvec(&i, ITER_DEST, osd_data->bvec_pos.bvecs,
				      osd_data->num_bvecs, len);
			iov_iter_advance(&i, rc);
			iov_iter_zero(zlen, &i);
		}
	}

	/* r_start_latency == 0 means the request was not submitted */
	if (req->r_start_latency) {
		if (aio_req->write) {
			ceph_update_write_metrics(metric, req->r_start_latency,
						  req->r_end_latency, len, rc);
			if (rc >= 0 && len)
				ceph_record_subvolume_io(inode, true,
							 req->r_start_latency,
							 req->r_end_latency,
							 len);
		} else {
			ceph_update_read_metrics(metric, req->r_start_latency,
						 req->r_end_latency, len, rc);
			if (rc > 0)
				ceph_record_subvolume_io(inode, false,
							 req->r_start_latency,
							 req->r_end_latency,
							 rc);
		}
	}

	put_bvecs(osd_data->bvec_pos.bvecs, osd_data->num_bvecs,
		  aio_req->should_dirty);
	ceph_osdc_put_request(req);

	if (rc < 0)
		cmpxchg(&aio_req->error, 0, rc);

	ceph_aio_complete(inode, aio_req);
	return;
}

static void ceph_aio_retry_work(struct work_struct *work)
{
	struct ceph_aio_work *aio_work =
		container_of(work, struct ceph_aio_work, work);
	struct ceph_osd_request *orig_req = aio_work->req;
	struct ceph_aio_request *aio_req = orig_req->r_priv;
	struct inode *inode = orig_req->r_inode;
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_snap_context *snapc;
	struct ceph_osd_request *req;
	int ret;

	spin_lock(&ci->i_ceph_lock);
	if (__ceph_have_pending_cap_snap(ci)) {
		struct ceph_cap_snap *capsnap =
			list_last_entry(&ci->i_cap_snaps,
					struct ceph_cap_snap,
					ci_item);
		snapc = ceph_get_snap_context(capsnap->context);
	} else {
		BUG_ON(!ci->i_head_snapc);
		snapc = ceph_get_snap_context(ci->i_head_snapc);
	}
	spin_unlock(&ci->i_ceph_lock);

	req = ceph_osdc_alloc_request(orig_req->r_osdc, snapc, 1,
			false, GFP_NOFS);
	if (!req) {
		ret = -ENOMEM;
		req = orig_req;
		goto out;
	}

	req->r_flags = /* CEPH_OSD_FLAG_ORDERSNAP | */ CEPH_OSD_FLAG_WRITE;
	ceph_oloc_copy(&req->r_base_oloc, &orig_req->r_base_oloc);
	ceph_oid_copy(&req->r_base_oid, &orig_req->r_base_oid);

	req->r_ops[0] = orig_req->r_ops[0];

	req->r_mtime = aio_req->mtime;
	req->r_data_offset = req->r_ops[0].extent.offset;

	ret = ceph_osdc_alloc_messages(req, GFP_NOFS);
	if (ret) {
		ceph_osdc_put_request(req);
		req = orig_req;
		goto out;
	}

	ceph_osdc_put_request(orig_req);

	req->r_callback = ceph_aio_complete_req;
	req->r_inode = inode;
	req->r_priv = aio_req;

	ceph_osdc_start_request(req->r_osdc, req);
out:
	if (ret < 0) {
		req->r_result = ret;
		ceph_aio_complete_req(req);
	}

	ceph_put_snap_context(snapc);
	kfree(aio_work);
}

static ssize_t
ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
		       struct ceph_snap_context *snapc,
		       struct ceph_cap_flush **pcf)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
	struct ceph_client *cl = fsc->client;
	struct ceph_client_metric *metric = &fsc->mdsc->metric;
	struct ceph_vino vino;
	struct ceph_osd_request *req;
	struct bio_vec *bvecs;
	struct ceph_aio_request *aio_req = NULL;
	int num_pages = 0;
	int flags;
	int ret = 0;
	struct timespec64 mtime = current_time(inode);
	size_t count = iov_iter_count(iter);
	loff_t pos = iocb->ki_pos;
	bool write = iov_iter_rw(iter) == WRITE;
	bool should_dirty = !write && user_backed_iter(iter);
	bool sparse = ceph_test_mount_opt(fsc, SPARSEREAD);

	if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
		return -EROFS;

	doutc(cl, "sync_direct_%s on file %p %lld~%u snapc %p seq %lld\n",
	      (write ? "write" : "read"), file, pos, (unsigned)count,
	      snapc, snapc ? snapc->seq : 0);

	if (write) {
		int ret2;

		ceph_fscache_invalidate(inode, true);

		ret2 = invalidate_inode_pages2_range(inode->i_mapping,
					pos >> PAGE_SHIFT,
					(pos + count - 1) >> PAGE_SHIFT);
		if (ret2 < 0)
			doutc(cl, "invalidate_inode_pages2_range returned %d\n",
			      ret2);

		flags = /* CEPH_OSD_FLAG_ORDERSNAP | */ CEPH_OSD_FLAG_WRITE;
	} else {
		flags = CEPH_OSD_FLAG_READ;
	}

	while (iov_iter_count(iter) > 0) {
		u64 size = iov_iter_count(iter);
		ssize_t len;
		struct ceph_osd_req_op *op;
		int readop = sparse ? CEPH_OSD_OP_SPARSE_READ : CEPH_OSD_OP_READ;
		int extent_cnt;

		if (write)
			size = min_t(u64, size, fsc->mount_options->wsize);
		else
			size = min_t(u64, size, fsc->mount_options->rsize);

		vino = ceph_vino(inode);
		req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
					    vino, pos, &size, 0,
					    1,
					    write ? CEPH_OSD_OP_WRITE : readop,
					    flags, snapc,
					    ci->i_truncate_seq,
					    ci->i_truncate_size,
					    false);
		if (IS_ERR(req)) {
			ret = PTR_ERR(req);
			break;
		}

		op = &req->r_ops[0];
		if (!write && sparse) {
			extent_cnt = __ceph_sparse_read_ext_count(inode, size);
			ret = ceph_alloc_sparse_ext_map(op, extent_cnt);
			if (ret) {
				ceph_osdc_put_request(req);
				break;
			}
		}

		len = iter_get_bvecs_alloc(iter, size, &bvecs, &num_pages);
		if (len < 0) {
			ceph_osdc_put_request(req);
			ret = len;
			break;
		}
		if (len != size)
			osd_req_op_extent_update(req, 0, len);

		osd_req_op_extent_osd_data_bvecs(req, 0, bvecs, num_pages, len);

		/*
		 * To simplify error handling, allow AIO when IO within i_size
		 * or IO can be satisfied by single OSD request.
		 */
		if (pos == iocb->ki_pos && !is_sync_kiocb(iocb) &&
		    (len == count || pos + count <= i_size_read(inode))) {
			aio_req = kzalloc_obj(*aio_req);
			if (aio_req) {
				aio_req->iocb = iocb;
				aio_req->write = write;
				aio_req->should_dirty = should_dirty;
				INIT_LIST_HEAD(&aio_req->osd_reqs);
				if (write) {
					aio_req->mtime = mtime;
					swap(aio_req->prealloc_cf, *pcf);
				}
			}
			/* ignore error */
		}

		if (write) {
			/*
			 * throw out any page cache pages in this range. this
			 * may block.
			 */
			truncate_inode_pages_range(inode->i_mapping, pos,
						   PAGE_ALIGN(pos + len) - 1);

			req->r_mtime = mtime;
		}

		if (aio_req) {
			aio_req->total_len += len;
			aio_req->num_reqs++;
			atomic_inc(&aio_req->pending_reqs);

			req->r_callback = ceph_aio_complete_req;
			req->r_inode = inode;
			req->r_priv = aio_req;
			list_add_tail(&req->r_private_item, &aio_req->osd_reqs);

			pos += len;
			continue;
		}

		ceph_osdc_start_request(req->r_osdc, req);
		ret = ceph_osdc_wait_request(&fsc->client->osdc, req);

		if (write) {
			ceph_update_write_metrics(metric, req->r_start_latency,
						  req->r_end_latency, len, ret);
			if (ret >= 0 && len)
				ceph_record_subvolume_io(inode, true,
							 req->r_start_latency,
							 req->r_end_latency,
							 len);
		} else {
			ceph_update_read_metrics(metric, req->r_start_latency,
						 req->r_end_latency, len, ret);
			if (ret > 0)
				ceph_record_subvolume_io(inode, false,
							 req->r_start_latency,
							 req->r_end_latency,
							 ret);
		}

		size = i_size_read(inode);
		if (!write) {
			if (sparse && ret >= 0)
				ret = ceph_sparse_ext_map_end(op);
			else if (ret == -ENOENT)
				ret = 0;

			if (ret >= 0 && ret < len && pos + ret < size) {
				struct iov_iter i;
				int zlen = min_t(size_t, len - ret,
						 size - pos - ret);

				iov_iter_bvec(&i, ITER_DEST, bvecs, num_pages, len);
				iov_iter_advance(&i, ret);
				iov_iter_zero(zlen, &i);
				ret += zlen;
			}
			if (ret >= 0)
				len = ret;
		}

		put_bvecs(bvecs, num_pages, should_dirty);
		ceph_osdc_put_request(req);
		if (ret < 0)
			break;

		pos += len;
		if (!write && pos >= size)
			break;

		if (write && pos > size) {
			if (ceph_inode_set_size(inode, pos))
				ceph_check_caps(ceph_inode(inode),
						CHECK_CAPS_AUTHONLY);
		}
	}

	if (aio_req) {
		LIST_HEAD(osd_reqs);

		if (aio_req->num_reqs == 0) {
			kfree(aio_req);
			return ret;
		}

		ceph_get_cap_refs(ci, write ? CEPH_CAP_FILE_WR :
					      CEPH_CAP_FILE_RD);

		list_splice(&aio_req->osd_reqs, &osd_reqs);
		inode_dio_begin(inode);
		while (!list_empty(&osd_reqs)) {
			req = list_first_entry(&osd_reqs,
					       struct ceph_osd_request,
					       r_private_item);
			list_del_init(&req->r_private_item);
			if (ret >= 0)
				ceph_osdc_start_request(req->r_osdc, req);
			if (ret < 0) {
				req->r_result = ret;
				ceph_aio_complete_req(req);
			}
		}
		return -EIOCBQUEUED;
	}

	if (ret != -EOLDSNAPC && pos > iocb->ki_pos) {
		ret = pos - iocb->ki_pos;
		iocb->ki_pos = pos;
	}
	return ret;
}

/*
 * Synchronous write, straight from __user pointer or user pages.
 *
 * If write spans object boundary, just do multiple writes.  (For a
 * correct atomic write, we should e.g. take write locks on all
 * objects, rollback on failure, etc.)
 */
static ssize_t
ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
		struct ceph_snap_context *snapc)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
	struct ceph_client *cl = fsc->client;
	struct ceph_osd_client *osdc = &fsc->client->osdc;
	struct ceph_osd_request *req;
	struct page **pages;
	u64 len;
	int num_pages;
	int written = 0;
	int ret;
	bool check_caps = false;
	struct timespec64 mtime = current_time(inode);
	size_t count = iov_iter_count(from);

	if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
		return -EROFS;

	doutc(cl, "on file %p %lld~%u snapc %p seq %lld\n", file, pos,
	      (unsigned)count, snapc, snapc->seq);

	ret = filemap_write_and_wait_range(inode->i_mapping,
					   pos, pos + count - 1);
	if (ret < 0)
		return ret;

	ceph_fscache_invalidate(inode, false);

	while ((len = iov_iter_count(from)) > 0) {
		size_t left;
		int n;
		u64 write_pos = pos;
		u64 write_len = len;
		u64 objnum, objoff;
		u32 xlen;
		u64 assert_ver = 0;
		bool rmw;
		bool first, last;
		struct iov_iter saved_iter = *from;
		size_t off;

		ceph_fscrypt_adjust_off_and_len(inode, &write_pos, &write_len);

		/* clamp the length to the end of first object */
		ceph_calc_file_object_mapping(&ci->i_layout, write_pos,
					      write_len, &objnum, &objoff,
					      &xlen);
		write_len = xlen;

		/* adjust len downward if it goes beyond current object */
		if (pos + len > write_pos + write_len)
			len = write_pos + write_len - pos;

		/*
		 * If we had to adjust the length or position to align with a
		 * crypto block, then we must do a read/modify/write cycle. We
		 * use a version assertion to redrive the thing if something
		 * changes in between.
		 */
		first = pos != write_pos;
		last = (pos + len) != (write_pos + write_len);
		rmw = first || last;

		doutc(cl, "ino %llx %lld~%llu adjusted %lld~%llu -- %srmw\n",
		      ci->i_vino.ino, pos, len, write_pos, write_len,
		      rmw ? "" : "no ");

		/*
		 * The data is emplaced into the page as it would be if it were
		 * in an array of pagecache pages.
		 */
		num_pages = calc_pages_for(write_pos, write_len);
		pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
		if (IS_ERR(pages)) {
			ret = PTR_ERR(pages);
			break;
		}

		/* Do we need to preload the pages? */
		if (rmw) {
			u64 first_pos = write_pos;
			u64 last_pos = (write_pos + write_len) - CEPH_FSCRYPT_BLOCK_SIZE;
			u64 read_len = CEPH_FSCRYPT_BLOCK_SIZE;
			struct ceph_osd_req_op *op;

			/* We should only need to do this for encrypted inodes */
			WARN_ON_ONCE(!IS_ENCRYPTED(inode));

			/* No need to do two reads if first and last blocks are same */
			if (first && last_pos == first_pos)
				last = false;

			/*
			 * Allocate a read request for one or two extents,
			 * depending on how the request was aligned.
			 */
			req = ceph_osdc_new_request(osdc, &ci->i_layout,
					ci->i_vino, first ? first_pos : last_pos,
					&read_len, 0, (first && last) ? 2 : 1,
					CEPH_OSD_OP_SPARSE_READ, CEPH_OSD_FLAG_READ,
					NULL, ci->i_truncate_seq,
					ci->i_truncate_size, false);
			if (IS_ERR(req)) {
				ceph_release_page_vector(pages, num_pages);
				ret = PTR_ERR(req);
				break;
			}

			/* Something is misaligned! */
			if (read_len != CEPH_FSCRYPT_BLOCK_SIZE) {
				ceph_osdc_put_request(req);
				ceph_release_page_vector(pages, num_pages);
				ret = -EIO;
				break;
			}

			/* Add extent for first block? */
			op = &req->r_ops[0];

			if (first) {
				osd_req_op_extent_osd_data_pages(req, 0, pages,
							 CEPH_FSCRYPT_BLOCK_SIZE,
							 offset_in_page(first_pos),
							 false, false);
				/* We only expect a single extent here */
				ret = __ceph_alloc_sparse_ext_map(op, 1);
				if (ret) {
					ceph_osdc_put_request(req);
					ceph_release_page_vector(pages, num_pages);
					break;
				}
			}

			/* Add extent for last block */
			if (last) {
				/* Init the other extent if first extent has been used */
				if (first) {
					op = &req->r_ops[1];
					osd_req_op_extent_init(req, 1,
							CEPH_OSD_OP_SPARSE_READ,
							last_pos, CEPH_FSCRYPT_BLOCK_SIZE,
							ci->i_truncate_size,
							ci->i_truncate_seq);
				}

				ret = __ceph_alloc_sparse_ext_map(op, 1);
				if (ret) {
					ceph_osdc_put_request(req);
					ceph_release_page_vector(pages, num_pages);
					break;
				}

				osd_req_op_extent_osd_data_pages(req, first ? 1 : 0,
							&pages[num_pages - 1],
							CEPH_FSCRYPT_BLOCK_SIZE,
							offset_in_page(last_pos),
							false, false);
			}

			ceph_osdc_start_request(osdc, req);
			ret = ceph_osdc_wait_request(osdc, req);

			/* FIXME: length field is wrong if there are 2 extents */
			ceph_update_read_metrics(&fsc->mdsc->metric,
						 req->r_start_latency,
						 req->r_end_latency,
						 read_len, ret);
			if (ret > 0)
				ceph_record_subvolume_io(inode, false,
							 req->r_start_latency,
							 req->r_end_latency,
							 ret);

			/* Ok if object is not already present */
			if (ret == -ENOENT) {
				/*
				 * If there is no object, then we can't assert
				 * on its version. Set it to 0, and we'll use an
				 * exclusive create instead.
				 */
				ceph_osdc_put_request(req);
				ret = 0;

				/*
				 * zero out the soon-to-be uncopied parts of the
				 * first and last pages.
				 */
				if (first)
					zero_user_segment(pages[0], 0,
							  offset_in_page(first_pos));
				if (last)
					zero_user_segment(pages[num_pages - 1],
							  offset_in_page(last_pos),
							  PAGE_SIZE);
			} else {
				if (ret < 0) {
					ceph_osdc_put_request(req);
					ceph_release_page_vector(pages, num_pages);
					break;
				}

				op = &req->r_ops[0];
				if (op->extent.sparse_ext_cnt == 0) {
					if (first)
						zero_user_segment(pages[0], 0,
								  offset_in_page(first_pos));
					else
						zero_user_segment(pages[num_pages - 1],
								  offset_in_page(last_pos),
								  PAGE_SIZE);
				} else if (op->extent.sparse_ext_cnt != 1 ||
					   ceph_sparse_ext_map_end(op) !=
						CEPH_FSCRYPT_BLOCK_SIZE) {
					ret = -EIO;
					ceph_osdc_put_request(req);
					ceph_release_page_vector(pages, num_pages);
					break;
				}

				if (first && last) {
					op = &req->r_ops[1];
					if (op->extent.sparse_ext_cnt == 0) {
						zero_user_segment(pages[num_pages - 1],
								  offset_in_page(last_pos),
								  PAGE_SIZE);
					} else if (op->extent.sparse_ext_cnt != 1 ||
						   ceph_sparse_ext_map_end(op) !=
							CEPH_FSCRYPT_BLOCK_SIZE) {
						ret = -EIO;
						ceph_osdc_put_request(req);
						ceph_release_page_vector(pages, num_pages);
						break;
					}
				}

				/* Grab assert version. It must be non-zero. */
				assert_ver = req->r_version;
				WARN_ON_ONCE(ret > 0 && assert_ver == 0);

				ceph_osdc_put_request(req);
				if (first) {
					ret = ceph_fscrypt_decrypt_block_inplace(inode,
							pages[0], CEPH_FSCRYPT_BLOCK_SIZE,
							offset_in_page(first_pos),
							first_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
					if (ret < 0) {
						ceph_release_page_vector(pages, num_pages);
						break;
					}
				}
				if (last) {
					ret = ceph_fscrypt_decrypt_block_inplace(inode,
							pages[num_pages - 1],
							CEPH_FSCRYPT_BLOCK_SIZE,
							offset_in_page(last_pos),
							last_pos >> CEPH_FSCRYPT_BLOCK_SHIFT);
					if (ret < 0) {
						ceph_release_page_vector(pages, num_pages);
						break;
					}
				}
			}
		}

		left = len;
		off = offset_in_page(pos);
		for (n = 0; n < num_pages; n++) {
			size_t plen = min_t(size_t, left, PAGE_SIZE - off);

			/* copy the data */
			ret = copy_page_from_iter(pages[n], off, plen, from);
			if (ret != plen) {
				ret = -EFAULT;
				break;
			}
			off = 0;
			left -= ret;
		}
		if (ret < 0) {
			doutc(cl, "write failed with %d\n", ret);
			ceph_release_page_vector(pages, num_pages);
			break;
		}

		if (IS_ENCRYPTED(inode)) {
			ret = ceph_fscrypt_encrypt_pages(inode, pages,
							 write_pos, write_len);
			if (ret < 0) {
				doutc(cl, "encryption failed with %d\n", ret);
				ceph_release_page_vector(pages, num_pages);
				break;
			}
		}

		req = ceph_osdc_new_request(osdc, &ci->i_layout,
					    ci->i_vino, write_pos, &write_len,
					    rmw ? 1 : 0, rmw ? 2 : 1,
					    CEPH_OSD_OP_WRITE,
					    CEPH_OSD_FLAG_WRITE,
					    snapc, ci->i_truncate_seq,
					    ci->i_truncate_size, false);
		if (IS_ERR(req)) {
			ret = PTR_ERR(req);
			ceph_release_page_vector(pages, num_pages);
			break;
		}

		doutc(cl, "write op %lld~%llu\n", write_pos, write_len);
		osd_req_op_extent_osd_data_pages(req, rmw ? 1 : 0, pages, write_len,
						 offset_in_page(write_pos), false,
						 true);
		req->r_inode = inode;
		req->r_mtime = mtime;

		/* Set up the assertion */
		if (rmw) {
			/*
			 * Set up the assertion. If we don't have a version
			 * number, then the object doesn't exist yet. Use an
			 * exclusive create instead of a version assertion in
			 * that case.
			 */
			if (assert_ver) {
				osd_req_op_init(req, 0, CEPH_OSD_OP_ASSERT_VER, 0);
				req->r_ops[0].assert_ver.ver = assert_ver;
			} else {
				osd_req_op_init(req, 0, CEPH_OSD_OP_CREATE,
						CEPH_OSD_OP_FLAG_EXCL);
			}
		}

		ceph_osdc_start_request(osdc, req);
		ret = ceph_osdc_wait_request(osdc, req);

		ceph_update_write_metrics(&fsc->mdsc->metric, req->r_start_latency,
					  req->r_end_latency, len, ret);
		if (ret >= 0 && write_len)
			ceph_record_subvolume_io(inode, true,
						 req->r_start_latency,
						 req->r_end_latency,
						 write_len);
		ceph_osdc_put_request(req);
		if (ret != 0) {
			doutc(cl, "osd write returned %d\n", ret);
			/* Version changed! Must re-do the rmw cycle */
			if ((assert_ver && (ret == -ERANGE || ret == -EOVERFLOW)) ||
			    (!assert_ver && ret == -EEXIST)) {
				/* We should only ever see this on a rmw */
				WARN_ON_ONCE(!rmw);

				/* The version should never go backward */
				WARN_ON_ONCE(ret == -EOVERFLOW);

				*from = saved_iter;

				/* FIXME: limit number of times we loop? */
				continue;
			}
			ceph_set_error_write(ci);
			break;
		}

		ceph_clear_error_write(ci);

		/*
		 * We successfully wrote to a range of the file. Declare
		 * that region of the pagecache invalid.
		 */
		ret = invalidate_inode_pages2_range(
				inode->i_mapping,
				pos >> PAGE_SHIFT,
				(pos + len - 1) >> PAGE_SHIFT);
		if (ret < 0) {
			doutc(cl, "invalidate_inode_pages2_range returned %d\n",
			      ret);
			ret = 0;
		}
		pos += len;
		written += len;
		doutc(cl, "written %d\n", written);
		if (pos > i_size_read(inode)) {
			check_caps = ceph_inode_set_size(inode, pos);
			if (check_caps)
				ceph_check_caps(ceph_inode(inode),
						CHECK_CAPS_AUTHONLY);
		}

	}

	if (ret != -EOLDSNAPC && written > 0) {
		ret = written;
		iocb->ki_pos = pos;
	}
	doutc(cl, "returning %d\n", ret);
	return ret;
}

/*
 * Wrap generic_file_aio_read with checks for cap bits on the inode.
 * Atomically grab references, so that those bits are not released
 * back to the MDS mid-read.
 *
 * Hmm, the sync read case isn't actually async... should it be?
 */
static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
	struct file *filp = iocb->ki_filp;
	struct ceph_file_info *fi = filp->private_data;
	size_t len = iov_iter_count(to);
	struct inode *inode = file_inode(filp);
	struct ceph_inode_info *ci = ceph_inode(inode);
	bool direct_lock = iocb->ki_flags & IOCB_DIRECT;
	struct ceph_client *cl = ceph_inode_to_client(inode);
	ssize_t ret;
	int want = 0, got = 0;
	int retry_op = 0, read = 0;

again:
	doutc(cl, "%llu~%u trying to get caps on %p %llx.%llx\n",
	      iocb->ki_pos, (unsigned)len, inode, ceph_vinop(inode));

	if (ceph_inode_is_shutdown(inode))
		return -ESTALE;

	ret = direct_lock ? ceph_start_io_direct(inode) :
			    ceph_start_io_read(inode);
	if (ret)
		return ret;

	if (!(fi->flags & CEPH_F_SYNC) && !direct_lock)
		want |= CEPH_CAP_FILE_CACHE;
	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want |= CEPH_CAP_FILE_LAZYIO;

	ret = ceph_get_caps(filp, CEPH_CAP_FILE_RD, want, -1, &got);
	if (ret < 0) {
		if (direct_lock)
			ceph_end_io_direct(inode);
		else
			ceph_end_io_read(inode);
		return ret;
	}

	if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
	    (iocb->ki_flags & IOCB_DIRECT) ||
	    (fi->flags & CEPH_F_SYNC)) {

		doutc(cl, "sync %p %llx.%llx %llu~%u got cap refs on %s\n",
		      inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
		      ceph_cap_string(got));

		if (!ceph_has_inline_data(ci)) {
			if (!retry_op &&
			    (iocb->ki_flags & IOCB_DIRECT) &&
			    !IS_ENCRYPTED(inode)) {
				ret = ceph_direct_read_write(iocb, to,
							     NULL, NULL);
				if (ret >= 0 && ret < len)
					retry_op = CHECK_EOF;
			} else {
				ret = ceph_sync_read(iocb, to, &retry_op);
			}
		} else {
			retry_op = READ_INLINE;
		}
	} else {
		CEPH_DEFINE_RW_CONTEXT(rw_ctx, got);
		doutc(cl, "async %p %llx.%llx %llu~%u got cap refs on %s\n",
		      inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
		      ceph_cap_string(got));
		ceph_add_rw_context(fi, &rw_ctx);
		ret = generic_file_read_iter(iocb, to);
		ceph_del_rw_context(fi, &rw_ctx);
	}

	doutc(cl, "%p %llx.%llx dropping cap refs on %s = %d\n",
	      inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
	ceph_put_cap_refs(ci, got);

	if (direct_lock)
		ceph_end_io_direct(inode);
	else
		ceph_end_io_read(inode);

	if (retry_op > HAVE_RETRIED && ret >= 0) {
		int statret;
		struct page *page = NULL;
		loff_t i_size;
		int mask = CEPH_STAT_CAP_SIZE;
		if (retry_op == READ_INLINE) {
			page = __page_cache_alloc(GFP_KERNEL);
			if (!page)
				return -ENOMEM;

			mask = CEPH_STAT_CAP_INLINE_DATA;
		}

		statret = __ceph_do_getattr(inode, page, mask, !!page);
		if (statret < 0) {
			if (page)
				__free_page(page);
			if (statret == -ENODATA) {
				BUG_ON(retry_op != READ_INLINE);
				goto again;
			}
			return statret;
		}

		i_size = i_size_read(inode);
		if (retry_op == READ_INLINE) {
			BUG_ON(ret > 0 || read > 0);
			if (iocb->ki_pos < i_size &&
			    iocb->ki_pos < PAGE_SIZE) {
				loff_t end = min_t(loff_t, i_size,
						   iocb->ki_pos + len);
				end = min_t(loff_t, end, PAGE_SIZE);
				if (statret < end)
					zero_user_segment(page, statret, end);
				ret = copy_page_to_iter(page,
						iocb->ki_pos & ~PAGE_MASK,
						end - iocb->ki_pos, to);
				iocb->ki_pos += ret;
				read += ret;
			}
			if (iocb->ki_pos < i_size && read < len) {
				size_t zlen = min_t(size_t, len - read,
						    i_size - iocb->ki_pos);
				ret = iov_iter_zero(zlen, to);
				iocb->ki_pos += ret;
				read += ret;
			}
			__free_pages(page, 0);
			return read;
		}

		/* hit EOF or hole? */
		if (retry_op == CHECK_EOF && iocb->ki_pos < i_size &&
		    ret < len) {
			doutc(cl, "may hit hole, ppos %lld < size %lld, reading more\n",
			      iocb->ki_pos, i_size);

			read += ret;
			len -= ret;
			retry_op = HAVE_RETRIED;
			goto again;
		}
	}

	if (ret >= 0)
		ret += read;

	return ret;
}

/*
 * Wrap filemap_splice_read with checks for cap bits on the inode.
 * Atomically grab references, so that those bits are not released
 * back to the MDS mid-read.
 */
static ssize_t ceph_splice_read(struct file *in, loff_t *ppos,
				struct pipe_inode_info *pipe,
				size_t len, unsigned int flags)
{
	struct ceph_file_info *fi = in->private_data;
	struct inode *inode = file_inode(in);
	struct ceph_inode_info *ci = ceph_inode(inode);
	ssize_t ret;
	int want = 0, got = 0;
	CEPH_DEFINE_RW_CONTEXT(rw_ctx, 0);

	dout("splice_read %p %llx.%llx %llu~%zu trying to get caps on %p\n",
	     inode, ceph_vinop(inode), *ppos, len, inode);

	if (ceph_inode_is_shutdown(inode))
		return -ESTALE;

	if (ceph_has_inline_data(ci) ||
	    (fi->flags & CEPH_F_SYNC))
		return copy_splice_read(in, ppos, pipe, len, flags);

	ret = ceph_start_io_read(inode);
	if (ret)
		return ret;

	want = CEPH_CAP_FILE_CACHE;
	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want |= CEPH_CAP_FILE_LAZYIO;

	ret = ceph_get_caps(in, CEPH_CAP_FILE_RD, want, -1, &got);
	if (ret < 0)
		goto out_end;

	if ((got & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO)) == 0) {
		dout("splice_read/sync %p %llx.%llx %llu~%zu got cap refs on %s\n",
		     inode, ceph_vinop(inode), *ppos, len,
		     ceph_cap_string(got));

		ceph_put_cap_refs(ci, got);
		ceph_end_io_read(inode);
		return copy_splice_read(in, ppos, pipe, len, flags);
	}

	dout("splice_read %p %llx.%llx %llu~%zu got cap refs on %s\n",
	     inode, ceph_vinop(inode), *ppos, len, ceph_cap_string(got));

	rw_ctx.caps = got;
	ceph_add_rw_context(fi, &rw_ctx);
	ret = filemap_splice_read(in, ppos, pipe, len, flags);
	ceph_del_rw_context(fi, &rw_ctx);

	dout("splice_read %p %llx.%llx dropping cap refs on %s = %zd\n",
	     inode, ceph_vinop(inode), ceph_cap_string(got), ret);

	ceph_put_cap_refs(ci, got);
out_end:
	ceph_end_io_read(inode);
	return ret;
}

/*
 * Take cap references to avoid releasing caps to MDS mid-write.
 *
 * If we are synchronous, and write with an old snap context, the OSD
 * may return EOLDSNAPC.  In that case, retry the write.. _after_
 * dropping our cap refs and allowing the pending snap to logically
 * complete _before_ this write occurs.
 *
 * If requested, nearfull writes are synced to preserve the legacy
 * client-side backpressure behavior.
 */
static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	struct ceph_file_info *fi = file->private_data;
	struct inode *inode = file_inode(file);
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
	struct ceph_client *cl = fsc->client;
	struct ceph_osd_client *osdc = &fsc->client->osdc;
	struct ceph_cap_flush *prealloc_cf;
	ssize_t count, written = 0;
	int err, want = 0, got;
	bool direct_lock = false;
	u32 map_flags;
	u64 pool_flags;
	loff_t pos;
	loff_t limit = max(i_size_read(inode), fsc->max_file_size);

	if (ceph_inode_is_shutdown(inode))
		return -ESTALE;

	if (ceph_snap(inode) != CEPH_NOSNAP)
		return -EROFS;

	prealloc_cf = ceph_alloc_cap_flush();
	if (!prealloc_cf)
		return -ENOMEM;

	if ((iocb->ki_flags & (IOCB_DIRECT | IOCB_APPEND)) == IOCB_DIRECT)
		direct_lock = true;

retry_snap:
	err = direct_lock ? ceph_start_io_direct(inode) :
			    ceph_start_io_write(inode);
	if (err)
		goto out_unlocked;

	if (iocb->ki_flags & IOCB_APPEND) {
		err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
		if (err < 0)
			goto out;
	}

	err = generic_write_checks(iocb, from);
	if (err <= 0)
		goto out;

	pos = iocb->ki_pos;
	if (unlikely(pos >= limit)) {
		err = -EFBIG;
		goto out;
	} else {
		iov_iter_truncate(from, limit - pos);
	}

	count = iov_iter_count(from);
	if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) {
		err = -EDQUOT;
		goto out;
	}

	down_read(&osdc->lock);
	map_flags = osdc->osdmap->flags;
	pool_flags = ceph_pg_pool_flags(osdc->osdmap, ci->i_layout.pool_id);
	up_read(&osdc->lock);
	if ((map_flags & CEPH_OSDMAP_FULL) ||
	    (pool_flags & CEPH_POOL_FLAG_FULL)) {
		err = -ENOSPC;
		goto out;
	}

	err = file_remove_privs(file);
	if (err)
		goto out;

	doutc(cl, "%p %llx.%llx %llu~%zd getting caps. i_size %llu\n",
	      inode, ceph_vinop(inode), pos, count,
	      i_size_read(inode));
	if (!(fi->flags & CEPH_F_SYNC) && !direct_lock)
		want |= CEPH_CAP_FILE_BUFFER;
	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want |= CEPH_CAP_FILE_LAZYIO;
	got = 0;
	err = ceph_get_caps(file, CEPH_CAP_FILE_WR, want, pos + count, &got);
	if (err < 0)
		goto out;

	/*
	 * For O_APPEND writes we may have waited for Fwx exclusive caps
	 * while the previous Fwx holder (another client) extended the
	 * file.  i_size has been updated via the cap grant message from
	 * the MDS, but ki_pos is still the old EOF.  Re-read i_size here
	 * (no extra MDS round-trip needed) and adjust ki_pos to the true
	 * EOF.  Since we hold Fwx, no other client can change the file.
	 */
	if (iocb->ki_flags & IOCB_APPEND) {
		loff_t cur_eof = i_size_read(inode);

		if (cur_eof != pos) {
			doutc(cl,
			      "%p %llx.%llx O_APPEND: pos adjusted %lld -> %lld\n",
			      inode, ceph_vinop(inode), pos, cur_eof);
			iocb->ki_pos = cur_eof;
			pos = cur_eof;
			if (pos >= limit) {
				err = -EFBIG;
				goto out_caps;
			}
			iov_iter_truncate(from, limit - pos);
			count = iov_iter_count(from);

			/*
			 * ceph_get_caps() validated the old endoff
			 * against i_max_size; adjusting ki_pos forward
			 * may have shifted the write range beyond the
			 * granted max_size.  Re-check and truncate if
			 * necessary.
			 */
			spin_lock(&ci->i_ceph_lock);
			if (pos + count > (loff_t)ci->i_max_size) {
				loff_t max_size = ci->i_max_size;

				spin_unlock(&ci->i_ceph_lock);
				if (pos >= max_size) {
					err = -EFBIG;
					goto out_caps;
				}
				iov_iter_truncate(from, max_size - pos);
				count = iov_iter_count(from);
			} else {
				spin_unlock(&ci->i_ceph_lock);
			}
		}
	}

	err = file_update_time(file);
	if (err)
		goto out_caps;

	inode_inc_iversion_raw(inode);

	doutc(cl, "%p %llx.%llx %llu~%zd got cap refs on %s\n",
	      inode, ceph_vinop(inode), pos, count, ceph_cap_string(got));

	if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
	    (iocb->ki_flags & IOCB_DIRECT) || (fi->flags & CEPH_F_SYNC) ||
	    test_bit(CEPH_I_ERROR_WRITE_BIT, &ci->i_ceph_flags)) {
		struct ceph_snap_context *snapc;
		struct iov_iter data;

		spin_lock(&ci->i_ceph_lock);
		if (__ceph_have_pending_cap_snap(ci)) {
			struct ceph_cap_snap *capsnap =
					list_last_entry(&ci->i_cap_snaps,
							struct ceph_cap_snap,
							ci_item);
			snapc = ceph_get_snap_context(capsnap->context);
		} else {
			BUG_ON(!ci->i_head_snapc);
			snapc = ceph_get_snap_context(ci->i_head_snapc);
		}
		spin_unlock(&ci->i_ceph_lock);

		/* we might need to revert back to that point */
		data = *from;
		if ((iocb->ki_flags & IOCB_DIRECT) && !IS_ENCRYPTED(inode))
			written = ceph_direct_read_write(iocb, &data, snapc,
							 &prealloc_cf);
		else
			written = ceph_sync_write(iocb, &data, pos, snapc);
		if (direct_lock)
			ceph_end_io_direct(inode);
		else
			ceph_end_io_write(inode);
		if (written > 0)
			iov_iter_advance(from, written);
		ceph_put_snap_context(snapc);
	} else {
		/*
		 * No need to acquire the i_truncate_mutex. Because
		 * the MDS revokes Fwb caps before sending truncate
		 * message to us. We can't get Fwb cap while there
		 * are pending vmtruncate. So write and vmtruncate
		 * can not run at the same time
		 */
		written = generic_perform_write(iocb, from);
		ceph_end_io_write(inode);
	}

	if (written >= 0) {
		int dirty;

		spin_lock(&ci->i_ceph_lock);
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
					       &prealloc_cf);
		spin_unlock(&ci->i_ceph_lock);
		if (dirty)
			__mark_inode_dirty(inode, dirty);
		if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
			ceph_check_caps(ci, CHECK_CAPS_FLUSH);
	}

	doutc(cl, "%p %llx.%llx %llu~%u  dropping cap refs on %s\n",
	      inode, ceph_vinop(inode), pos, (unsigned)count,
	      ceph_cap_string(got));
	ceph_put_cap_refs(ci, got);

	if (written == -EOLDSNAPC) {
		doutc(cl, "%p %llx.%llx %llu~%u" "got EOLDSNAPC, retrying\n",
		      inode, ceph_vinop(inode), pos, (unsigned)count);
		goto retry_snap;
	}

	if (written >= 0) {
		if (ceph_test_mount_opt(fsc, NEARFULL_SYNC) &&
		    ((map_flags & CEPH_OSDMAP_NEARFULL) ||
		     (pool_flags & CEPH_POOL_FLAG_NEARFULL)))
			iocb->ki_flags |= IOCB_DSYNC;
		written = generic_write_sync(iocb, written);
	}

	goto out_unlocked;
out_caps:
	ceph_put_cap_refs(ci, got);
out:
	if (direct_lock)
		ceph_end_io_direct(inode);
	else
		ceph_end_io_write(inode);
out_unlocked:
	ceph_free_cap_flush(prealloc_cf);
	return written ? written : err;
}

/*
 * llseek.  be sure to verify file size on SEEK_END.
 */
static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
{
	if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) {
		struct inode *inode = file_inode(file);
		int ret;

		ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
		if (ret < 0)
			return ret;
	}
	return generic_file_llseek(file, offset, whence);
}

static inline void ceph_zero_partial_page(struct inode *inode,
		loff_t offset, size_t size)
{
	struct folio *folio;

	folio = filemap_lock_folio(inode->i_mapping, offset >> PAGE_SHIFT);
	if (IS_ERR(folio))
		return;

	folio_wait_writeback(folio);
	folio_zero_range(folio, offset_in_folio(folio, offset), size);
	folio_unlock(folio);
	folio_put(folio);
}

static void ceph_zero_pagecache_range(struct inode *inode, loff_t offset,
				      loff_t length)
{
	loff_t nearly = round_up(offset, PAGE_SIZE);
	if (offset < nearly) {
		loff_t size = nearly - offset;
		if (length < size)
			size = length;
		ceph_zero_partial_page(inode, offset, size);
		offset += size;
		length -= size;
	}
	if (length >= PAGE_SIZE) {
		loff_t size = round_down(length, PAGE_SIZE);
		truncate_pagecache_range(inode, offset, offset + size - 1);
		offset += size;
		length -= size;
	}
	if (length)
		ceph_zero_partial_page(inode, offset, length);
}

static int ceph_zero_partial_object(struct inode *inode,
				    loff_t offset, loff_t *length)
{
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode);
	struct ceph_osd_request *req;
	struct ceph_snap_context *snapc;
	int ret = 0;
	loff_t zero = 0;
	int op;

	if (ceph_inode_is_shutdown(inode))
		return -EIO;

	if (!length) {
		op = offset ? CEPH_OSD_OP_DELETE : CEPH_OSD_OP_TRUNCATE;
		length = &zero;
	} else {
		op = CEPH_OSD_OP_ZERO;
	}

	spin_lock(&ci->i_ceph_lock);
	if (__ceph_have_pending_cap_snap(ci)) {
		struct ceph_cap_snap *capsnap =
				list_last_entry(&ci->i_cap_snaps,
						struct ceph_cap_snap,
						ci_item);
		snapc = ceph_get_snap_context(capsnap->context);
	} else {
		BUG_ON(!ci->i_head_snapc);
		snapc = ceph_get_snap_context(ci->i_head_snapc);
	}
	spin_unlock(&ci->i_ceph_lock);

	req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
					ceph_vino(inode),
					offset, length,
					0, 1, op,
					CEPH_OSD_FLAG_WRITE,
					snapc, 0, 0, false);
	if (IS_ERR(req)) {
		ret = PTR_ERR(req);
		goto out;
	}

	req->r_mtime = inode_get_mtime(inode);
	ceph_osdc_start_request(&fsc->client->osdc, req);
	ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
	if (ret == -ENOENT)
		ret = 0;
	ceph_osdc_put_request(req);

out:
	ceph_put_snap_context(snapc);
	return ret;
}

static int ceph_zero_objects(struct inode *inode, loff_t offset, loff_t length)
{
	int ret = 0;
	struct ceph_inode_info *ci = ceph_inode(inode);
	s32 stripe_unit = ci->i_layout.stripe_unit;
	s32 stripe_count = ci->i_layout.stripe_count;
	s32 object_size = ci->i_layout.object_size;
	u64 object_set_size = (u64) object_size * stripe_count;
	u64 nearly, t;

	/* round offset up to next period boundary */
	nearly = offset + object_set_size - 1;
	t = nearly;
	nearly -= do_div(t, object_set_size);

	while (length && offset < nearly) {
		loff_t size = length;
		ret = ceph_zero_partial_object(inode, offset, &size);
		if (ret < 0)
			return ret;
		offset += size;
		length -= size;
	}
	while (length >= object_set_size) {
		int i;
		loff_t pos = offset;
		for (i = 0; i < stripe_count; ++i) {
			ret = ceph_zero_partial_object(inode, pos, NULL);
			if (ret < 0)
				return ret;
			pos += stripe_unit;
		}
		offset += object_set_size;
		length -= object_set_size;
	}
	while (length) {
		loff_t size = length;
		ret = ceph_zero_partial_object(inode, offset, &size);
		if (ret < 0)
			return ret;
		offset += size;
		length -= size;
	}
	return ret;
}

static long ceph_fallocate(struct file *file, int mode,
				loff_t offset, loff_t length)
{
	struct ceph_file_info *fi = file->private_data;
	struct inode *inode = file_inode(file);
	struct ceph_inode_info *ci = ceph_inode(inode);
	struct ceph_cap_flush *prealloc_cf;
	struct ceph_client *cl = ceph_inode_to_client(inode);
	int want, got = 0;
	int dirty;
	int ret = 0;
	loff_t endoff = 0;
	loff_t size;

	doutc(cl, "%p %llx.%llx mode %x, offset %llu length %llu\n",
	      inode, ceph_vinop(inode), mode, offset, length);

	if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
		return -EOPNOTSUPP;

	if (!S_ISREG(inode->i_mode))
		return -EOPNOTSUPP;

	if (IS_ENCRYPTED(inode))
		return -EOPNOTSUPP;

	prealloc_cf = ceph_alloc_cap_flush();
	if (!prealloc_cf)
		return -ENOMEM;

	inode_lock(inode);

	if (ceph_snap(inode) != CEPH_NOSNAP) {
		ret = -EROFS;
		goto unlock;
	}

	size = i_size_read(inode);

	/* Are we punching a hole beyond EOF? */
	if (offset >= size)
		goto unlock;
	if ((offset + length) > size)
		length = size - offset;

	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
	else
		want = CEPH_CAP_FILE_BUFFER;

	ret = ceph_get_caps(file, CEPH_CAP_FILE_WR, want, endoff, &got);
	if (ret < 0)
		goto unlock;

	ret = file_modified(file);
	if (ret)
		goto put_caps;

	filemap_invalidate_lock(inode->i_mapping);
	ceph_fscache_invalidate(inode, false);
	ceph_zero_pagecache_range(inode, offset, length);
	ret = ceph_zero_objects(inode, offset, length);

	if (!ret) {
		spin_lock(&ci->i_ceph_lock);
		dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR,
					       &prealloc_cf);
		spin_unlock(&ci->i_ceph_lock);
		if (dirty)
			__mark_inode_dirty(inode, dirty);
	}
	filemap_invalidate_unlock(inode->i_mapping);

put_caps:
	ceph_put_cap_refs(ci, got);
unlock:
	inode_unlock(inode);
	ceph_free_cap_flush(prealloc_cf);
	return ret;
}

/*
 * This function tries to get FILE_WR capabilities for dst_ci and FILE_RD for
 * src_ci.  Two attempts are made to obtain both caps, and an error is return if
 * this fails; zero is returned on success.
 */
static int get_rd_wr_caps(struct file *src_filp, int *src_got,
			  struct file *dst_filp,
			  loff_t dst_endoff, int *dst_got)
{
	int ret = 0;
	bool retrying = false;

retry_caps:
	ret = ceph_get_caps(dst_filp, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
			    dst_endoff, dst_got);
	if (ret < 0)
		return ret;

	/*
	 * Since we're already holding the FILE_WR capability for the dst file,
	 * we would risk a deadlock by using ceph_get_caps.  Thus, we'll do some
	 * retry dance instead to try to get both capabilities.
	 */
	ret = ceph_try_get_caps(file_inode(src_filp),
				CEPH_CAP_FILE_RD, CEPH_CAP_FILE_SHARED,
				false, src_got);
	if (ret <= 0) {
		/* Start by dropping dst_ci caps and getting src_ci caps */
		ceph_put_cap_refs(ceph_inode(file_inode(dst_filp)), *dst_got);
		if (retrying) {
			if (!ret)
				/* ceph_try_get_caps masks EAGAIN */
				ret = -EAGAIN;
			return ret;
		}
		ret = ceph_get_caps(src_filp, CEPH_CAP_FILE_RD,
				    CEPH_CAP_FILE_SHARED, -1, src_got);
		if (ret < 0)
			return ret;
		/*... drop src_ci caps too, and retry */
		ceph_put_cap_refs(ceph_inode(file_inode(src_filp)), *src_got);
		retrying = true;
		goto retry_caps;
	}
	return ret;
}

static void put_rd_wr_caps(struct ceph_inode_info *src_ci, int src_got,
			   struct ceph_inode_info *dst_ci, int dst_got)
{
	ceph_put_cap_refs(src_ci, src_got);
	ceph_put_cap_refs(dst_ci, dst_got);
}

/*
 * This function does several size-related checks, returning an error if:
 *  - source file is smaller than off+len
 *  - destination file size is not OK (inode_newsize_ok())
 *  - max bytes quotas is exceeded
 */
static int is_file_size_ok(struct inode *src_inode, struct inode *dst_inode,
			   loff_t src_off, loff_t dst_off, size_t len)
{
	struct ceph_client *cl = ceph_inode_to_client(src_inode);
	loff_t size, endoff;

	size = i_size_read(src_inode);
	/*
	 * Don't copy beyond source file EOF.  Instead of simply setting length
	 * to (size - src_off), just drop to VFS default implementation, as the
	 * local i_size may be stale due to other clients writing to the source
	 * inode.
	 */
	if (src_off + len > size) {
		doutc(cl, "Copy beyond EOF (%llu + %zu > %llu)\n", src_off,
		      len, size);
		return -EOPNOTSUPP;
	}
	size = i_size_read(dst_inode);

	endoff = dst_off + len;
	if (inode_newsize_ok(dst_inode, endoff))
		return -EOPNOTSUPP;

	if (ceph_quota_is_max_bytes_exceeded(dst_inode, endoff))
		return -EDQUOT;

	return 0;
}

static struct ceph_osd_request *
ceph_alloc_copyfrom_request(struct ceph_osd_client *osdc,
			    u64 src_snapid,
			    struct ceph_object_id *src_oid,
			    struct ceph_object_locator *src_oloc,
			    struct ceph_object_id *dst_oid,
			    struct ceph_object_locator *dst_oloc,
			    u32 truncate_seq, u64 truncate_size)
{
	struct ceph_osd_request *req;
	int ret;
	u32 src_fadvise_flags =
		CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
		CEPH_OSD_OP_FLAG_FADVISE_NOCACHE;
	u32 dst_fadvise_flags =
		CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
		CEPH_OSD_OP_FLAG_FADVISE_DONTNEED;

	req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_KERNEL);
	if (!req)
		return ERR_PTR(-ENOMEM);

	req->r_flags = CEPH_OSD_FLAG_WRITE;

	ceph_oloc_copy(&req->r_t.base_oloc, dst_oloc);
	ceph_oid_copy(&req->r_t.base_oid, dst_oid);

	ret = osd_req_op_copy_from_init(req, src_snapid, 0,
					src_oid, src_oloc,
					src_fadvise_flags,
					dst_fadvise_flags,
					truncate_seq,
					truncate_size,
					CEPH_OSD_COPY_FROM_FLAG_TRUNCATE_SEQ);
	if (ret)
		goto out;

	ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
	if (ret)
		goto out;

	return req;

out:
	ceph_osdc_put_request(req);
	return ERR_PTR(ret);
}

static ssize_t ceph_do_objects_copy(struct ceph_inode_info *src_ci, u64 *src_off,
				    struct ceph_inode_info *dst_ci, u64 *dst_off,
				    struct ceph_fs_client *fsc,
				    size_t len, unsigned int flags)
{
	struct ceph_object_locator src_oloc, dst_oloc;
	struct ceph_object_id src_oid, dst_oid;
	struct ceph_osd_client *osdc;
	struct ceph_osd_request *req;
	ssize_t bytes = 0;
	u64 src_objnum, src_objoff, dst_objnum, dst_objoff;
	u32 src_objlen, dst_objlen;
	u32 object_size = src_ci->i_layout.object_size;
	struct ceph_client *cl = fsc->client;
	int ret;

	src_oloc.pool = src_ci->i_layout.pool_id;
	src_oloc.pool_ns = ceph_try_get_string(src_ci->i_layout.pool_ns);
	dst_oloc.pool = dst_ci->i_layout.pool_id;
	dst_oloc.pool_ns = ceph_try_get_string(dst_ci->i_layout.pool_ns);
	osdc = &fsc->client->osdc;

	while (len >= object_size) {
		ceph_calc_file_object_mapping(&src_ci->i_layout, *src_off,
					      object_size, &src_objnum,
					      &src_objoff, &src_objlen);
		ceph_calc_file_object_mapping(&dst_ci->i_layout, *dst_off,
					      object_size, &dst_objnum,
					      &dst_objoff, &dst_objlen);
		ceph_oid_init(&src_oid);
		ceph_oid_printf(&src_oid, "%llx.%08llx",
				src_ci->i_vino.ino, src_objnum);
		ceph_oid_init(&dst_oid);
		ceph_oid_printf(&dst_oid, "%llx.%08llx",
				dst_ci->i_vino.ino, dst_objnum);
		/* Do an object remote copy */
		req = ceph_alloc_copyfrom_request(osdc, src_ci->i_vino.snap,
						  &src_oid, &src_oloc,
						  &dst_oid, &dst_oloc,
						  dst_ci->i_truncate_seq,
						  dst_ci->i_truncate_size);
		if (IS_ERR(req))
			ret = PTR_ERR(req);
		else {
			ceph_osdc_start_request(osdc, req);
			ret = ceph_osdc_wait_request(osdc, req);
			ceph_update_copyfrom_metrics(&fsc->mdsc->metric,
						     req->r_start_latency,
						     req->r_end_latency,
						     object_size, ret);
			ceph_osdc_put_request(req);
		}
		if (ret) {
			if (ret == -EOPNOTSUPP) {
				fsc->have_copy_from2 = false;
				pr_notice_client(cl,
					"OSDs don't support copy-from2; disabling copy offload\n");
			}
			doutc(cl, "returned %d\n", ret);
			if (bytes <= 0)
				bytes = ret;
			goto out;
		}
		len -= object_size;
		bytes += object_size;
		*src_off += object_size;
		*dst_off += object_size;
	}

out:
	ceph_oloc_destroy(&src_oloc);
	ceph_oloc_destroy(&dst_oloc);
	return bytes;
}

static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
				      struct file *dst_file, loff_t dst_off,
				      size_t len, unsigned int flags)
{
	struct inode *src_inode = file_inode(src_file);
	struct inode *dst_inode = file_inode(dst_file);
	struct ceph_inode_info *src_ci = ceph_inode(src_inode);
	struct ceph_inode_info *dst_ci = ceph_inode(dst_inode);
	struct ceph_cap_flush *prealloc_cf;
	struct ceph_fs_client *src_fsc = ceph_inode_to_fs_client(src_inode);
	struct ceph_client *cl = src_fsc->client;
	loff_t size;
	ssize_t ret = -EIO, bytes;
	u64 src_objnum, dst_objnum, src_objoff, dst_objoff;
	u32 src_objlen, dst_objlen;
	int src_got = 0, dst_got = 0, err, dirty;

	if (src_inode->i_sb != dst_inode->i_sb) {
		struct ceph_fs_client *dst_fsc = ceph_inode_to_fs_client(dst_inode);

		if (ceph_fsid_compare(&src_fsc->client->fsid,
				      &dst_fsc->client->fsid)) {
			dout("Copying files across clusters: src: %pU dst: %pU\n",
			     &src_fsc->client->fsid, &dst_fsc->client->fsid);
			return -EXDEV;
		}
	}
	if (ceph_snap(dst_inode) != CEPH_NOSNAP)
		return -EROFS;

	/*
	 * Some of the checks below will return -EOPNOTSUPP, which will force a
	 * fallback to the default VFS copy_file_range implementation.  This is
	 * desirable in several cases (for ex, the 'len' is smaller than the
	 * size of the objects, or in cases where that would be more
	 * efficient).
	 */

	if (ceph_test_mount_opt(src_fsc, NOCOPYFROM))
		return -EOPNOTSUPP;

	if (!src_fsc->have_copy_from2)
		return -EOPNOTSUPP;

	/*
	 * Striped file layouts require that we copy partial objects, but the
	 * OSD copy-from operation only supports full-object copies.  Limit
	 * this to non-striped file layouts for now.
	 */
	if ((src_ci->i_layout.stripe_unit != dst_ci->i_layout.stripe_unit) ||
	    (src_ci->i_layout.stripe_count != 1) ||
	    (dst_ci->i_layout.stripe_count != 1) ||
	    (src_ci->i_layout.object_size != dst_ci->i_layout.object_size)) {
		doutc(cl, "Invalid src/dst files layout\n");
		return -EOPNOTSUPP;
	}

	/* Every encrypted inode gets its own key, so we can't offload them */
	if (IS_ENCRYPTED(src_inode) || IS_ENCRYPTED(dst_inode))
		return -EOPNOTSUPP;

	if (len < src_ci->i_layout.object_size)
		return -EOPNOTSUPP; /* no remote copy will be done */

	prealloc_cf = ceph_alloc_cap_flush();
	if (!prealloc_cf)
		return -ENOMEM;

	/* Start by sync'ing the source and destination files */
	ret = file_write_and_wait_range(src_file, src_off, (src_off + len));
	if (ret < 0) {
		doutc(cl, "failed to write src file (%zd)\n", ret);
		goto out;
	}
	ret = file_write_and_wait_range(dst_file, dst_off, (dst_off + len));
	if (ret < 0) {
		doutc(cl, "failed to write dst file (%zd)\n", ret);
		goto out;
	}

	/*
	 * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other
	 * clients may have dirty data in their caches.  And OSDs know nothing
	 * about caps, so they can't safely do the remote object copies.
	 */
	err = get_rd_wr_caps(src_file, &src_got,
			     dst_file, (dst_off + len), &dst_got);
	if (err < 0) {
		doutc(cl, "get_rd_wr_caps returned %d\n", err);
		ret = -EOPNOTSUPP;
		goto out;
	}

	ret = is_file_size_ok(src_inode, dst_inode, src_off, dst_off, len);
	if (ret < 0)
		goto out_caps;

	/* Drop dst file cached pages */
	ceph_fscache_invalidate(dst_inode, false);
	ret = invalidate_inode_pages2_range(dst_inode->i_mapping,
					    dst_off >> PAGE_SHIFT,
					    (dst_off + len) >> PAGE_SHIFT);
	if (ret < 0) {
		doutc(cl, "Failed to invalidate inode pages (%zd)\n",
			    ret);
		ret = 0; /* XXX */
	}
	ceph_calc_file_object_mapping(&src_ci->i_layout, src_off,
				      src_ci->i_layout.object_size,
				      &src_objnum, &src_objoff, &src_objlen);
	ceph_calc_file_object_mapping(&dst_ci->i_layout, dst_off,
				      dst_ci->i_layout.object_size,
				      &dst_objnum, &dst_objoff, &dst_objlen);
	/* object-level offsets need to the same */
	if (src_objoff != dst_objoff) {
		ret = -EOPNOTSUPP;
		goto out_caps;
	}

	/*
	 * Do a manual copy if the object offset isn't object aligned.
	 * 'src_objlen' contains the bytes left until the end of the object,
	 * starting at the src_off
	 */
	if (src_objoff) {
		doutc(cl, "Initial partial copy of %u bytes\n", src_objlen);

		/*
		 * we need to temporarily drop all caps as we'll be calling
		 * {read,write}_iter, which will get caps again.
		 */
		put_rd_wr_caps(src_ci, src_got, dst_ci, dst_got);
		ret = splice_file_range(src_file, &src_off, dst_file, &dst_off,
					src_objlen);
		/* Abort on short copies or on error */
		if (ret < (long)src_objlen) {
			doutc(cl, "Failed partial copy (%zd)\n", ret);
			goto out;
		}
		len -= ret;
		err = get_rd_wr_caps(src_file, &src_got,
				     dst_file, (dst_off + len), &dst_got);
		if (err < 0)
			goto out;
		err = is_file_size_ok(src_inode, dst_inode,
				      src_off, dst_off, len);
		if (err < 0)
			goto out_caps;
	}

	size = i_size_read(dst_inode);
	bytes = ceph_do_objects_copy(src_ci, &src_off, dst_ci, &dst_off,
				     src_fsc, len, flags);
	if (bytes <= 0) {
		if (!ret)
			ret = bytes;
		goto out_caps;
	}
	doutc(cl, "Copied %zu bytes out of %zu\n", bytes, len);
	len -= bytes;
	ret += bytes;

	file_update_time(dst_file);
	inode_inc_iversion_raw(dst_inode);

	if (dst_off > size) {
		/* Let the MDS know about dst file size change */
		if (ceph_inode_set_size(dst_inode, dst_off) ||
		    ceph_quota_is_max_bytes_approaching(dst_inode, dst_off))
			ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH);
	}
	/* Mark Fw dirty */
	spin_lock(&dst_ci->i_ceph_lock);
	dirty = __ceph_mark_dirty_caps(dst_ci, CEPH_CAP_FILE_WR, &prealloc_cf);
	spin_unlock(&dst_ci->i_ceph_lock);
	if (dirty)
		__mark_inode_dirty(dst_inode, dirty);

out_caps:
	put_rd_wr_caps(src_ci, src_got, dst_ci, dst_got);

	/*
	 * Do the final manual copy if we still have some bytes left, unless
	 * there were errors in remote object copies (len >= object_size).
	 */
	if (len && (len < src_ci->i_layout.object_size)) {
		doutc(cl, "Final partial copy of %zu bytes\n", len);
		bytes = splice_file_range(src_file, &src_off, dst_file,
					  &dst_off, len);
		if (bytes > 0)
			ret += bytes;
		else
			doutc(cl, "Failed partial copy (%zd)\n", bytes);
	}

out:
	ceph_free_cap_flush(prealloc_cf);

	return ret;
}

static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
				    struct file *dst_file, loff_t dst_off,
				    size_t len, unsigned int flags)
{
	ssize_t ret;

	ret = __ceph_copy_file_range(src_file, src_off, dst_file, dst_off,
				     len, flags);

	if (ret == -EOPNOTSUPP || ret == -EXDEV)
		ret = splice_copy_file_range(src_file, src_off, dst_file,
					     dst_off, len);
	return ret;
}

const struct file_operations ceph_file_fops = {
	.open = ceph_open,
	.release = ceph_release,
	.llseek = ceph_llseek,
	.read_iter = ceph_read_iter,
	.write_iter = ceph_write_iter,
	.mmap_prepare = ceph_mmap_prepare,
	.fsync = ceph_fsync,
	.lock = ceph_lock,
	.flock = ceph_flock,
	.splice_read = ceph_splice_read,
	.splice_write = iter_file_splice_write,
	.unlocked_ioctl = ceph_ioctl,
	.compat_ioctl = compat_ptr_ioctl,
	.fallocate	= ceph_fallocate,
	.copy_file_range = ceph_copy_file_range,
};
