Commit edf54d9d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ceph-for-5.13-rc8' of https://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
 "Two regression fixes from the merge window: one in the auth code
  affecting old clusters and one in the filesystem for proper
  propagation of MDS request errors.

  Also included a locking fix for async creates, marked for stable"

* tag 'ceph-for-5.13-rc8' of https://github.com/ceph/ceph-client:
  libceph: set global_id as soon as we get an auth ticket
  libceph: don't pass result into ac->ops->handle_reply()
  ceph: fix error handling in ceph_atomic_open and ceph_lookup
  ceph: must hold snap_rwsem when filling inode for async create
parents 9e736cf7 03af4c7b
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -668,14 +668,13 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
 * Handle lookups for the hidden .snap directory.
 */
struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
				   struct dentry *dentry, int err)
				   struct dentry *dentry)
{
	struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
	struct inode *parent = d_inode(dentry->d_parent); /* we hold i_mutex */

	/* .snap dir? */
	if (err == -ENOENT &&
	    ceph_snap(parent) == CEPH_NOSNAP &&
	if (ceph_snap(parent) == CEPH_NOSNAP &&
	    strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) {
		struct dentry *res;
		struct inode *inode = ceph_get_snapdir(parent);
@@ -742,7 +741,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
	struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
	struct ceph_mds_request *req;
	struct dentry *res;
	int op;
	int mask;
	int err;
@@ -793,13 +791,17 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
	req->r_parent = dir;
	set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
	err = ceph_mdsc_do_request(mdsc, NULL, req);
	res = ceph_handle_snapdir(req, dentry, err);
	if (err == -ENOENT) {
		struct dentry *res;

		res = ceph_handle_snapdir(req, dentry);
		if (IS_ERR(res)) {
			err = PTR_ERR(res);
		} else {
			dentry = res;
			err = 0;
		}
	}
	dentry = ceph_finish_lookup(req, dentry, err);
	ceph_mdsc_put_request(req);  /* will dput(dentry) */
	dout("lookup result=%p\n", dentry);
+11 −6
Original line number Diff line number Diff line
@@ -578,6 +578,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
	struct ceph_inode_info *ci = ceph_inode(dir);
	struct inode *inode;
	struct timespec64 now;
	struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
	struct ceph_vino vino = { .ino = req->r_deleg_ino,
				  .snap = CEPH_NOSNAP };

@@ -615,8 +616,10 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,

	ceph_file_layout_to_legacy(lo, &in.layout);

	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) {
		dout("%s failed to fill inode: %d\n", __func__, ret);
		ceph_dir_clear_complete(dir);
@@ -739,14 +742,16 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
	err = ceph_mdsc_do_request(mdsc,
				   (flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
				   req);
	dentry = ceph_handle_snapdir(req, dentry, err);
	if (err == -ENOENT) {
		dentry = ceph_handle_snapdir(req, dentry);
		if (IS_ERR(dentry)) {
			err = PTR_ERR(dentry);
			goto out_req;
		}
		err = 0;
	}

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

	if (d_in_lookup(dentry)) {
+2 −0
Original line number Diff line number Diff line
@@ -777,6 +777,8 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
	umode_t mode = le32_to_cpu(info->mode);
	dev_t rdev = le32_to_cpu(info->rdev);

	lockdep_assert_held(&mdsc->snap_rwsem);

	dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__,
	     inode, ceph_vinop(inode), le64_to_cpu(info->version),
	     ci->i_version);
+1 −1
Original line number Diff line number Diff line
@@ -1218,7 +1218,7 @@ extern const struct dentry_operations ceph_dentry_ops;
extern loff_t ceph_make_fpos(unsigned high, unsigned off, bool hash_order);
extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
extern struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
			       struct dentry *dentry, int err);
			       struct dentry *dentry);
extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
					 struct dentry *dentry, int err);

+3 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ struct ceph_auth_client_ops {
	 * another request.
	 */
	int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
	int (*handle_reply)(struct ceph_auth_client *ac, int result,
	int (*handle_reply)(struct ceph_auth_client *ac, u64 global_id,
			    void *buf, void *end, u8 *session_key,
			    int *session_key_len, u8 *con_secret,
			    int *con_secret_len);
@@ -104,6 +104,8 @@ struct ceph_auth_client {
	struct mutex mutex;
};

void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id);

struct ceph_auth_client *ceph_auth_init(const char *name,
					const struct ceph_crypto_key *key,
					const int *con_modes);
Loading