Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb62c00a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: no .snap inside of snapped namespace
  libceph: fix msgr standby handling
  libceph: fix msgr keepalive flag
  libceph: fix msgr backoff
  libceph: retry after authorization failure
  libceph: fix handling of short returns from get_user_pages
  ceph: do not clear I_COMPLETE from d_release
  ceph: do not set I_COMPLETE
  Revert "ceph: keep reference to parent inode on ceph_dentry"
parents 5c4b4be3 455cec0a
Loading
Loading
Loading
Loading
+3 −25
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ int ceph_init_dentry(struct dentry *dentry)
	}
	di->dentry = dentry;
	di->lease_session = NULL;
	di->parent_inode = igrab(dentry->d_parent->d_inode);
	dentry->d_fsdata = di;
	dentry->d_time = jiffies;
	ceph_dentry_lru_add(dentry);
@@ -410,7 +409,7 @@ more:
	spin_lock(&inode->i_lock);
	if (ci->i_release_count == fi->dir_release_count) {
		dout(" marking %p complete\n", inode);
		ci->i_ceph_flags |= CEPH_I_COMPLETE;
		/* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
		ci->i_max_offset = filp->f_pos;
	}
	spin_unlock(&inode->i_lock);
@@ -497,6 +496,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,

	/* .snap dir? */
	if (err == -ENOENT &&
	    ceph_snap(parent) == CEPH_NOSNAP &&
	    strcmp(dentry->d_name.name,
		   fsc->mount_options->snapdir_name) == 0) {
		struct inode *inode = ceph_get_snapdir(parent);
@@ -1030,28 +1030,8 @@ out_touch:
static void ceph_dentry_release(struct dentry *dentry)
{
	struct ceph_dentry_info *di = ceph_dentry(dentry);
	struct inode *parent_inode = NULL;
	u64 snapid = CEPH_NOSNAP;

	if (!IS_ROOT(dentry)) {
		parent_inode = di->parent_inode;
		if (parent_inode)
			snapid = ceph_snap(parent_inode);
	}
	dout("dentry_release %p parent %p\n", dentry, parent_inode);
	if (parent_inode && snapid != CEPH_SNAPDIR) {
		struct ceph_inode_info *ci = ceph_inode(parent_inode);

		spin_lock(&parent_inode->i_lock);
		if (ci->i_shared_gen == di->lease_shared_gen ||
		    snapid <= CEPH_MAXSNAP) {
			dout(" clearing %p complete (d_release)\n",
			     parent_inode);
			ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
			ci->i_release_count++;
		}
		spin_unlock(&parent_inode->i_lock);
	}
	dout("dentry_release %p\n", dentry);
	if (di) {
		ceph_dentry_lru_del(dentry);
		if (di->lease_session)
@@ -1059,8 +1039,6 @@ static void ceph_dentry_release(struct dentry *dentry)
		kmem_cache_free(ceph_dentry_cachep, di);
		dentry->d_fsdata = NULL;
	}
	if (parent_inode)
		iput(parent_inode);
}

static int ceph_snapdir_d_revalidate(struct dentry *dentry,
+1 −1
Original line number Diff line number Diff line
@@ -707,7 +707,7 @@ static int fill_inode(struct inode *inode,
		    (issued & CEPH_CAP_FILE_EXCL) == 0 &&
		    (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
			dout(" marking %p complete (empty)\n", inode);
			ci->i_ceph_flags |= CEPH_I_COMPLETE;
			/* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
			ci->i_max_offset = 2;
		}
		break;
+0 −1
Original line number Diff line number Diff line
@@ -207,7 +207,6 @@ struct ceph_dentry_info {
	struct dentry *dentry;
	u64 time;
	u64 offset;
	struct inode *parent_inode;
};

struct ceph_inode_xattrs_info {
+1 −1
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ struct ceph_msg_pos {
#define SOCK_CLOSED	11 /* socket state changed to closed */
#define OPENING         13 /* open connection w/ (possibly new) peer */
#define DEAD            14 /* dead, about to kfree */
#define BACKOFF         15

/*
 * A single connection with another host.
@@ -160,7 +161,6 @@ struct ceph_connection {
	struct list_head out_queue;
	struct list_head out_sent;   /* sending or sent but unacked */
	u64 out_seq;		     /* last message queued for send */
	bool out_keepalive_pending;

	u64 in_seq, in_seq_acked;  /* last message received, acked */

+54 −17
Original line number Diff line number Diff line
@@ -336,7 +336,6 @@ static void reset_connection(struct ceph_connection *con)
		ceph_msg_put(con->out_msg);
		con->out_msg = NULL;
	}
	con->out_keepalive_pending = false;
	con->in_seq = 0;
	con->in_seq_acked = 0;
}
@@ -1248,8 +1247,6 @@ static int process_connect(struct ceph_connection *con)
		     con->auth_retry);
		if (con->auth_retry == 2) {
			con->error_msg = "connect authorization failure";
			reset_connection(con);
			set_bit(CLOSED, &con->state);
			return -1;
		}
		con->auth_retry = 1;
@@ -1715,14 +1712,6 @@ more:

	/* open the socket first? */
	if (con->sock == NULL) {
		/*
		 * if we were STANDBY and are reconnecting _this_
		 * connection, bump connect_seq now.  Always bump
		 * global_seq.
		 */
		if (test_and_clear_bit(STANDBY, &con->state))
			con->connect_seq++;

		prepare_write_banner(msgr, con);
		prepare_write_connect(msgr, con, 1);
		prepare_read_banner(con);
@@ -1951,7 +1940,24 @@ static void con_work(struct work_struct *work)
						   work.work);

	mutex_lock(&con->mutex);
	if (test_and_clear_bit(BACKOFF, &con->state)) {
		dout("con_work %p backing off\n", con);
		if (queue_delayed_work(ceph_msgr_wq, &con->work,
				       round_jiffies_relative(con->delay))) {
			dout("con_work %p backoff %lu\n", con, con->delay);
			mutex_unlock(&con->mutex);
			return;
		} else {
			con->ops->put(con);
			dout("con_work %p FAILED to back off %lu\n", con,
			     con->delay);
		}
	}

	if (test_bit(STANDBY, &con->state)) {
		dout("con_work %p STANDBY\n", con);
		goto done;
	}
	if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */
		dout("con_work CLOSED\n");
		con_close_socket(con);
@@ -2008,10 +2014,12 @@ static void ceph_fault(struct ceph_connection *con)
	/* Requeue anything that hasn't been acked */
	list_splice_init(&con->out_sent, &con->out_queue);

	/* If there are no messages in the queue, place the connection
	 * in a STANDBY state (i.e., don't try to reconnect just yet). */
	if (list_empty(&con->out_queue) && !con->out_keepalive_pending) {
		dout("fault setting STANDBY\n");
	/* If there are no messages queued or keepalive pending, place
	 * the connection in a STANDBY state */
	if (list_empty(&con->out_queue) &&
	    !test_bit(KEEPALIVE_PENDING, &con->state)) {
		dout("fault %p setting STANDBY clearing WRITE_PENDING\n", con);
		clear_bit(WRITE_PENDING, &con->state);
		set_bit(STANDBY, &con->state);
	} else {
		/* retry after a delay. */
@@ -2019,11 +2027,24 @@ static void ceph_fault(struct ceph_connection *con)
			con->delay = BASE_DELAY_INTERVAL;
		else if (con->delay < MAX_DELAY_INTERVAL)
			con->delay *= 2;
		dout("fault queueing %p delay %lu\n", con, con->delay);
		con->ops->get(con);
		if (queue_delayed_work(ceph_msgr_wq, &con->work,
				       round_jiffies_relative(con->delay)) == 0)
				       round_jiffies_relative(con->delay))) {
			dout("fault queued %p delay %lu\n", con, con->delay);
		} else {
			con->ops->put(con);
			dout("fault failed to queue %p delay %lu, backoff\n",
			     con, con->delay);
			/*
			 * In many cases we see a socket state change
			 * while con_work is running and end up
			 * queuing (non-delayed) work, such that we
			 * can't backoff with a delay.  Set a flag so
			 * that when con_work restarts we schedule the
			 * delay then.
			 */
			set_bit(BACKOFF, &con->state);
		}
	}

out_unlock:
@@ -2094,6 +2115,19 @@ void ceph_messenger_destroy(struct ceph_messenger *msgr)
}
EXPORT_SYMBOL(ceph_messenger_destroy);

static void clear_standby(struct ceph_connection *con)
{
	/* come back from STANDBY? */
	if (test_and_clear_bit(STANDBY, &con->state)) {
		mutex_lock(&con->mutex);
		dout("clear_standby %p and ++connect_seq\n", con);
		con->connect_seq++;
		WARN_ON(test_bit(WRITE_PENDING, &con->state));
		WARN_ON(test_bit(KEEPALIVE_PENDING, &con->state));
		mutex_unlock(&con->mutex);
	}
}

/*
 * Queue up an outgoing message on the given connection.
 */
@@ -2126,6 +2160,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)

	/* if there wasn't anything waiting to send before, queue
	 * new work */
	clear_standby(con);
	if (test_and_set_bit(WRITE_PENDING, &con->state) == 0)
		queue_con(con);
}
@@ -2191,6 +2226,8 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg)
 */
void ceph_con_keepalive(struct ceph_connection *con)
{
	dout("con_keepalive %p\n", con);
	clear_standby(con);
	if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 &&
	    test_and_set_bit(WRITE_PENDING, &con->state) == 0)
		queue_con(con);
Loading