/* in 2.6.x, our device mapping and config info contains our virtual gendisks
* as member "struct gendisk *vdisk;"
*/
-struct idr minors;
-struct list_head drbd_tconns; /* list of struct drbd_tconn */
+struct idr drbd_devices;
+struct list_head drbd_resources;
struct kmem_cache *drbd_request_cache;
struct kmem_cache *drbd_ee_cache; /* peer requests */
/**
* tl_release() - mark as BARRIER_ACKED all requests in the corresponding transfer log epoch
- * @tconn: DRBD connection.
+ * @connection: DRBD connection.
* @barrier_nr: Expected identifier of the DRBD write barrier packet.
* @set_size: Expected number of requests before that barrier.
*
* epoch of not yet barrier-acked requests, this function will cause a
* termination of the connection.
*/
-void tl_release(struct drbd_tconn *tconn, unsigned int barrier_nr,
+void tl_release(struct drbd_connection *connection, unsigned int barrier_nr,
unsigned int set_size)
{
struct drbd_request *r;
int expect_epoch = 0;
int expect_size = 0;
- spin_lock_irq(&tconn->req_lock);
+ spin_lock_irq(&connection->req_lock);
/* find oldest not yet barrier-acked write request,
* count writes in its epoch. */
- list_for_each_entry(r, &tconn->transfer_log, tl_requests) {
+ list_for_each_entry(r, &connection->transfer_log, tl_requests) {
const unsigned s = r->rq_state;
if (!req) {
if (!(s & RQ_WRITE))
/* first some paranoia code */
if (req == NULL) {
- conn_err(tconn, "BAD! BarrierAck #%u received, but no epoch in tl!?\n",
+ drbd_err(connection, "BAD! BarrierAck #%u received, but no epoch in tl!?\n",
barrier_nr);
goto bail;
}
if (expect_epoch != barrier_nr) {
- conn_err(tconn, "BAD! BarrierAck #%u received, expected #%u!\n",
+ drbd_err(connection, "BAD! BarrierAck #%u received, expected #%u!\n",
barrier_nr, expect_epoch);
goto bail;
}
if (expect_size != set_size) {
- conn_err(tconn, "BAD! BarrierAck #%u received with n_writes=%u, expected n_writes=%u!\n",
+ drbd_err(connection, "BAD! BarrierAck #%u received with n_writes=%u, expected n_writes=%u!\n",
barrier_nr, set_size, expect_size);
goto bail;
}
/* this extra list walk restart is paranoia,
* to catch requests being barrier-acked "unexpectedly".
* It usually should find the same req again, or some READ preceding it. */
- list_for_each_entry(req, &tconn->transfer_log, tl_requests)
+ list_for_each_entry(req, &connection->transfer_log, tl_requests)
if (req->epoch == expect_epoch)
break;
- list_for_each_entry_safe_from(req, r, &tconn->transfer_log, tl_requests) {
+ list_for_each_entry_safe_from(req, r, &connection->transfer_log, tl_requests) {
if (req->epoch != expect_epoch)
break;
_req_mod(req, BARRIER_ACKED);
}
- spin_unlock_irq(&tconn->req_lock);
+ spin_unlock_irq(&connection->req_lock);
return;
bail:
- spin_unlock_irq(&tconn->req_lock);
- conn_request_state(tconn, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
+ spin_unlock_irq(&connection->req_lock);
+ conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD);
}
* RESTART_FROZEN_DISK_IO.
*/
/* must hold resource->req_lock */
-void _tl_restart(struct drbd_tconn *tconn, enum drbd_req_event what)
+void _tl_restart(struct drbd_connection *connection, enum drbd_req_event what)
{
struct drbd_request *req, *r;
- list_for_each_entry_safe(req, r, &tconn->transfer_log, tl_requests)
+ list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests)
_req_mod(req, what);
}
-void tl_restart(struct drbd_tconn *tconn, enum drbd_req_event what)
+void tl_restart(struct drbd_connection *connection, enum drbd_req_event what)
{
- spin_lock_irq(&tconn->req_lock);
- _tl_restart(tconn, what);
- spin_unlock_irq(&tconn->req_lock);
+ spin_lock_irq(&connection->req_lock);
+ _tl_restart(connection, what);
+ spin_unlock_irq(&connection->req_lock);
}
/**
* by the requests on the transfer gets marked as our of sync. Called from the
* receiver thread and the worker thread.
*/
-void tl_clear(struct drbd_tconn *tconn)
+void tl_clear(struct drbd_connection *connection)
{
- tl_restart(tconn, CONNECTION_LOST_WHILE_PENDING);
+ tl_restart(connection, CONNECTION_LOST_WHILE_PENDING);
}
/**
*/
void tl_abort_disk_io(struct drbd_device *device)
{
- struct drbd_tconn *tconn = device->tconn;
+ struct drbd_connection *connection = first_peer_device(device)->connection;
struct drbd_request *req, *r;
- spin_lock_irq(&tconn->req_lock);
- list_for_each_entry_safe(req, r, &tconn->transfer_log, tl_requests) {
+ spin_lock_irq(&connection->req_lock);
+ list_for_each_entry_safe(req, r, &connection->transfer_log, tl_requests) {
if (!(req->rq_state & RQ_LOCAL_PENDING))
continue;
if (req->w.device != device)
continue;
_req_mod(req, ABORT_DISK_IO);
}
- spin_unlock_irq(&tconn->req_lock);
+ spin_unlock_irq(&connection->req_lock);
}
static int drbd_thread_setup(void *arg)
{
struct drbd_thread *thi = (struct drbd_thread *) arg;
- struct drbd_tconn *tconn = thi->tconn;
+ struct drbd_connection *connection = thi->connection;
unsigned long flags;
int retval;
snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s",
- thi->name[0], thi->tconn->name);
+ thi->name[0],
+ thi->connection->resource->name);
restart:
retval = thi->function(thi);
*/
if (thi->t_state == RESTARTING) {
- conn_info(tconn, "Restarting %s thread\n", thi->name);
+ drbd_info(connection, "Restarting %s thread\n", thi->name);
thi->t_state = RUNNING;
spin_unlock_irqrestore(&thi->t_lock, flags);
goto restart;
complete_all(&thi->stop);
spin_unlock_irqrestore(&thi->t_lock, flags);
- conn_info(tconn, "Terminating %s\n", current->comm);
+ drbd_info(connection, "Terminating %s\n", current->comm);
/* Release mod reference taken when thread was started */
- kref_put(&tconn->kref, &conn_destroy);
+ kref_put(&connection->kref, drbd_destroy_connection);
module_put(THIS_MODULE);
return retval;
}
-static void drbd_thread_init(struct drbd_tconn *tconn, struct drbd_thread *thi,
+static void drbd_thread_init(struct drbd_connection *connection, struct drbd_thread *thi,
int (*func) (struct drbd_thread *), char *name)
{
spin_lock_init(&thi->t_lock);
thi->task = NULL;
thi->t_state = NONE;
thi->function = func;
- thi->tconn = tconn;
+ thi->connection = connection;
strncpy(thi->name, name, ARRAY_SIZE(thi->name));
}
int drbd_thread_start(struct drbd_thread *thi)
{
- struct drbd_tconn *tconn = thi->tconn;
+ struct drbd_connection *connection = thi->connection;
struct task_struct *nt;
unsigned long flags;
switch (thi->t_state) {
case NONE:
- conn_info(tconn, "Starting %s thread (from %s [%d])\n",
+ drbd_info(connection, "Starting %s thread (from %s [%d])\n",
thi->name, current->comm, current->pid);
/* Get ref on module for thread - this is released when thread exits */
if (!try_module_get(THIS_MODULE)) {
- conn_err(tconn, "Failed to get module reference in drbd_thread_start\n");
+ drbd_err(connection, "Failed to get module reference in drbd_thread_start\n");
spin_unlock_irqrestore(&thi->t_lock, flags);
return false;
}
- kref_get(&thi->tconn->kref);
+ kref_get(&thi->connection->kref);
init_completion(&thi->stop);
thi->reset_cpu_mask = 1;
flush_signals(current); /* otherw. may get -ERESTARTNOINTR */
nt = kthread_create(drbd_thread_setup, (void *) thi,
- "drbd_%c_%s", thi->name[0], thi->tconn->name);
+ "drbd_%c_%s", thi->name[0], thi->connection->resource->name);
if (IS_ERR(nt)) {
- conn_err(tconn, "Couldn't start thread\n");
+ drbd_err(connection, "Couldn't start thread\n");
- kref_put(&tconn->kref, &conn_destroy);
+ kref_put(&connection->kref, drbd_destroy_connection);
module_put(THIS_MODULE);
return false;
}
break;
case EXITING:
thi->t_state = RESTARTING;
- conn_info(tconn, "Restarting %s thread (from %s [%d])\n",
+ drbd_info(connection, "Restarting %s thread (from %s [%d])\n",
thi->name, current->comm, current->pid);
/* fall through */
case RUNNING:
wait_for_completion(&thi->stop);
}
-static struct drbd_thread *drbd_task_to_thread(struct drbd_tconn *tconn, struct task_struct *task)
+static struct drbd_thread *drbd_task_to_thread(struct drbd_connection *connection, struct task_struct *task)
{
struct drbd_thread *thi =
- task == tconn->receiver.task ? &tconn->receiver :
- task == tconn->asender.task ? &tconn->asender :
- task == tconn->worker.task ? &tconn->worker : NULL;
+ task == connection->receiver.task ? &connection->receiver :
+ task == connection->asender.task ? &connection->asender :
+ task == connection->worker.task ? &connection->worker : NULL;
return thi;
}
-char *drbd_task_to_thread_name(struct drbd_tconn *tconn, struct task_struct *task)
+char *drbd_task_to_thread_name(struct drbd_connection *connection, struct task_struct *task)
{
- struct drbd_thread *thi = drbd_task_to_thread(tconn, task);
+ struct drbd_thread *thi = drbd_task_to_thread(connection, task);
return thi ? thi->name : task->comm;
}
-int conn_lowest_minor(struct drbd_tconn *tconn)
+int conn_lowest_minor(struct drbd_connection *connection)
{
- struct drbd_device *device;
- int vnr = 0, m;
+ struct drbd_peer_device *peer_device;
+ int vnr = 0, minor = -1;
rcu_read_lock();
- device = idr_get_next(&tconn->volumes, &vnr);
- m = device ? device_to_minor(device) : -1;
+ peer_device = idr_get_next(&connection->peer_devices, &vnr);
+ if (peer_device)
+ minor = device_to_minor(peer_device->device);
rcu_read_unlock();
- return m;
+ return minor;
}
#ifdef CONFIG_SMP
* Forces all threads of a device onto the same CPU. This is beneficial for
* DRBD's performance. May be overwritten by user's configuration.
*/
-void drbd_calc_cpu_mask(struct drbd_tconn *tconn)
+void drbd_calc_cpu_mask(struct drbd_connection *connection)
{
int ord, cpu;
/* user override. */
- if (cpumask_weight(tconn->cpu_mask))
+ if (cpumask_weight(connection->cpu_mask))
return;
- ord = conn_lowest_minor(tconn) % cpumask_weight(cpu_online_mask);
+ ord = conn_lowest_minor(connection) % cpumask_weight(cpu_online_mask);
for_each_online_cpu(cpu) {
if (ord-- == 0) {
- cpumask_set_cpu(cpu, tconn->cpu_mask);
+ cpumask_set_cpu(cpu, connection->cpu_mask);
return;
}
}
/* should not be reached */
- cpumask_setall(tconn->cpu_mask);
+ cpumask_setall(connection->cpu_mask);
}
/**
if (!thi->reset_cpu_mask)
return;
thi->reset_cpu_mask = 0;
- set_cpus_allowed_ptr(p, thi->tconn->cpu_mask);
+ set_cpus_allowed_ptr(p, thi->connection->cpu_mask);
}
#endif
* word aligned on 64-bit architectures. (The bitmap send and receive code
* relies on this.)
*/
-unsigned int drbd_header_size(struct drbd_tconn *tconn)
+unsigned int drbd_header_size(struct drbd_connection *connection)
{
- if (tconn->agreed_pro_version >= 100) {
+ if (connection->agreed_pro_version >= 100) {
BUILD_BUG_ON(!IS_ALIGNED(sizeof(struct p_header100), 8));
return sizeof(struct p_header100);
} else {
return sizeof(struct p_header100);
}
-static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr,
+static unsigned int prepare_header(struct drbd_connection *connection, int vnr,
void *buffer, enum drbd_packet cmd, int size)
{
- if (tconn->agreed_pro_version >= 100)
+ if (connection->agreed_pro_version >= 100)
return prepare_header100(buffer, cmd, size, vnr);
- else if (tconn->agreed_pro_version >= 95 &&
+ else if (connection->agreed_pro_version >= 95 &&
size > DRBD_MAX_SIZE_H80_PACKET)
return prepare_header95(buffer, cmd, size);
else
return prepare_header80(buffer, cmd, size);
}
-static void *__conn_prepare_command(struct drbd_tconn *tconn,
+static void *__conn_prepare_command(struct drbd_connection *connection,
struct drbd_socket *sock)
{
if (!sock->socket)
return NULL;
- return sock->sbuf + drbd_header_size(tconn);
+ return sock->sbuf + drbd_header_size(connection);
}
-void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
+void *conn_prepare_command(struct drbd_connection *connection, struct drbd_socket *sock)
{
void *p;
mutex_lock(&sock->mutex);
- p = __conn_prepare_command(tconn, sock);
+ p = __conn_prepare_command(connection, sock);
if (!p)
mutex_unlock(&sock->mutex);
void *drbd_prepare_command(struct drbd_device *device, struct drbd_socket *sock)
{
- return conn_prepare_command(device->tconn, sock);
+ return conn_prepare_command(first_peer_device(device)->connection, sock);
}
-static int __send_command(struct drbd_tconn *tconn, int vnr,
+static int __send_command(struct drbd_connection *connection, int vnr,
struct drbd_socket *sock, enum drbd_packet cmd,
unsigned int header_size, void *data,
unsigned int size)
*/
msg_flags = data ? MSG_MORE : 0;
- header_size += prepare_header(tconn, vnr, sock->sbuf, cmd,
+ header_size += prepare_header(connection, vnr, sock->sbuf, cmd,
header_size + size);
- err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
+ err = drbd_send_all(connection, sock->socket, sock->sbuf, header_size,
msg_flags);
if (data && !err)
- err = drbd_send_all(tconn, sock->socket, data, size, 0);
+ err = drbd_send_all(connection, sock->socket, data, size, 0);
return err;
}
-static int __conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
+static int __conn_send_command(struct drbd_connection *connection, struct drbd_socket *sock,
enum drbd_packet cmd, unsigned int header_size,
void *data, unsigned int size)
{
- return __send_command(tconn, 0, sock, cmd, header_size, data, size);
+ return __send_command(connection, 0, sock, cmd, header_size, data, size);
}
-int conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
+int conn_send_command(struct drbd_connection *connection, struct drbd_socket *sock,
enum drbd_packet cmd, unsigned int header_size,
void *data, unsigned int size)
{
int err;
- err = __conn_send_command(tconn, sock, cmd, header_size, data, size);
+ err = __conn_send_command(connection, sock, cmd, header_size, data, size);
mutex_unlock(&sock->mutex);
return err;
}
{
int err;
- err = __send_command(device->tconn, device->vnr, sock, cmd, header_size,
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, header_size,
data, size);
mutex_unlock(&sock->mutex);
return err;
}
-int drbd_send_ping(struct drbd_tconn *tconn)
+int drbd_send_ping(struct drbd_connection *connection)
{
struct drbd_socket *sock;
- sock = &tconn->meta;
- if (!conn_prepare_command(tconn, sock))
+ sock = &connection->meta;
+ if (!conn_prepare_command(connection, sock))
return -EIO;
- return conn_send_command(tconn, sock, P_PING, 0, NULL, 0);
+ return conn_send_command(connection, sock, P_PING, 0, NULL, 0);
}
-int drbd_send_ping_ack(struct drbd_tconn *tconn)
+int drbd_send_ping_ack(struct drbd_connection *connection)
{
struct drbd_socket *sock;
- sock = &tconn->meta;
- if (!conn_prepare_command(tconn, sock))
+ sock = &connection->meta;
+ if (!conn_prepare_command(connection, sock))
return -EIO;
- return conn_send_command(tconn, sock, P_PING_ACK, 0, NULL, 0);
+ return conn_send_command(connection, sock, P_PING_ACK, 0, NULL, 0);
}
int drbd_send_sync_param(struct drbd_device *device)
struct drbd_socket *sock;
struct p_rs_param_95 *p;
int size;
- const int apv = device->tconn->agreed_pro_version;
+ const int apv = first_peer_device(device)->connection->agreed_pro_version;
enum drbd_packet cmd;
struct net_conf *nc;
struct disk_conf *dc;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
rcu_read_lock();
- nc = rcu_dereference(device->tconn->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
size = apv <= 87 ? sizeof(struct p_rs_param)
: apv == 88 ? sizeof(struct p_rs_param)
return drbd_send_command(device, sock, cmd, size, NULL, 0);
}
-int __drbd_send_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd)
+int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cmd)
{
struct drbd_socket *sock;
struct p_protocol *p;
struct net_conf *nc;
int size, cf;
- sock = &tconn->data;
- p = __conn_prepare_command(tconn, sock);
+ sock = &connection->data;
+ p = __conn_prepare_command(connection, sock);
if (!p)
return -EIO;
rcu_read_lock();
- nc = rcu_dereference(tconn->net_conf);
+ nc = rcu_dereference(connection->net_conf);
- if (nc->tentative && tconn->agreed_pro_version < 92) {
+ if (nc->tentative && connection->agreed_pro_version < 92) {
rcu_read_unlock();
mutex_unlock(&sock->mutex);
- conn_err(tconn, "--dry-run is not supported by peer");
+ drbd_err(connection, "--dry-run is not supported by peer");
return -EOPNOTSUPP;
}
size = sizeof(*p);
- if (tconn->agreed_pro_version >= 87)
+ if (connection->agreed_pro_version >= 87)
size += strlen(nc->integrity_alg) + 1;
p->protocol = cpu_to_be32(nc->wire_protocol);
cf |= CF_DRY_RUN;
p->conn_flags = cpu_to_be32(cf);
- if (tconn->agreed_pro_version >= 87)
+ if (connection->agreed_pro_version >= 87)
strcpy(p->integrity_alg, nc->integrity_alg);
rcu_read_unlock();
- return __conn_send_command(tconn, sock, cmd, size, NULL, 0);
+ return __conn_send_command(connection, sock, cmd, size, NULL, 0);
}
-int drbd_send_protocol(struct drbd_tconn *tconn)
+int drbd_send_protocol(struct drbd_connection *connection)
{
int err;
- mutex_lock(&tconn->data.mutex);
- err = __drbd_send_protocol(tconn, P_PROTOCOL);
- mutex_unlock(&tconn->data.mutex);
+ mutex_lock(&connection->data.mutex);
+ err = __drbd_send_protocol(connection, P_PROTOCOL);
+ mutex_unlock(&connection->data.mutex);
return err;
}
if (!get_ldev_if_state(device, D_NEGOTIATING))
return 0;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p) {
put_ldev(device);
device->comm_bm_set = drbd_bm_total_weight(device);
p->uuid[UI_SIZE] = cpu_to_be64(device->comm_bm_set);
rcu_read_lock();
- uuid_flags |= rcu_dereference(device->tconn->net_conf)->discard_my_data ? 1 : 0;
+ uuid_flags |= rcu_dereference(first_peer_device(device)->connection->net_conf)->discard_my_data ? 1 : 0;
rcu_read_unlock();
uuid_flags |= test_bit(CRASHED_PRIMARY, &device->flags) ? 2 : 0;
uuid_flags |= device->new_state_tmp.disk == D_INCONSISTENT ? 4 : 0;
{
if (get_ldev_if_state(device, D_NEGOTIATING)) {
u64 *uuid = device->ldev->md.uuid;
- dev_info(DEV, "%s %016llX:%016llX:%016llX:%016llX\n",
+ drbd_info(device, "%s %016llX:%016llX:%016llX:%016llX\n",
text,
(unsigned long long)uuid[UI_CURRENT],
(unsigned long long)uuid[UI_BITMAP],
(unsigned long long)uuid[UI_HISTORY_END]);
put_ldev(device);
} else {
- dev_info(DEV, "%s effective data uuid: %016llX\n",
+ drbd_info(device, "%s effective data uuid: %016llX\n",
text,
(unsigned long long)device->ed_uuid);
}
struct p_rs_uuid *p;
u64 uuid;
- D_ASSERT(device->state.disk == D_UP_TO_DATE);
+ D_ASSERT(device, device->state.disk == D_UP_TO_DATE);
uuid = device->ldev->md.uuid[UI_BITMAP];
if (uuid && uuid != UUID_JUST_CREATED)
drbd_print_uuids(device, "updated sync UUID");
drbd_md_sync(device);
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (p) {
p->uuid = cpu_to_be64(uuid);
unsigned int max_bio_size;
if (get_ldev_if_state(device, D_NEGOTIATING)) {
- D_ASSERT(device->ldev->backing_bdev);
+ D_ASSERT(device, device->ldev->backing_bdev);
d_size = drbd_get_max_capacity(device->ldev);
rcu_read_lock();
u_size = rcu_dereference(device->ldev->disk_conf)->disk_size;
max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
}
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
- if (device->tconn->agreed_pro_version <= 94)
+ if (first_peer_device(device)->connection->agreed_pro_version <= 94)
max_bio_size = min(max_bio_size, DRBD_MAX_SIZE_H80_PACKET);
- else if (device->tconn->agreed_pro_version < 100)
+ else if (first_peer_device(device)->connection->agreed_pro_version < 100)
max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE_P95);
p->d_size = cpu_to_be64(d_size);
struct drbd_socket *sock;
struct p_state *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
struct drbd_socket *sock;
struct p_state *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
struct drbd_socket *sock;
struct p_req_state *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
return drbd_send_command(device, sock, P_STATE_CHG_REQ, sizeof(*p), NULL, 0);
}
-int conn_send_state_req(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val)
+int conn_send_state_req(struct drbd_connection *connection, union drbd_state mask, union drbd_state val)
{
enum drbd_packet cmd;
struct drbd_socket *sock;
struct p_req_state *p;
- cmd = tconn->agreed_pro_version < 100 ? P_STATE_CHG_REQ : P_CONN_ST_CHG_REQ;
- sock = &tconn->data;
- p = conn_prepare_command(tconn, sock);
+ cmd = connection->agreed_pro_version < 100 ? P_STATE_CHG_REQ : P_CONN_ST_CHG_REQ;
+ sock = &connection->data;
+ p = conn_prepare_command(connection, sock);
if (!p)
return -EIO;
p->mask = cpu_to_be32(mask.i);
p->val = cpu_to_be32(val.i);
- return conn_send_command(tconn, sock, cmd, sizeof(*p), NULL, 0);
+ return conn_send_command(connection, sock, cmd, sizeof(*p), NULL, 0);
}
void drbd_send_sr_reply(struct drbd_device *device, enum drbd_state_rv retcode)
struct drbd_socket *sock;
struct p_req_state_reply *p;
- sock = &device->tconn->meta;
+ sock = &first_peer_device(device)->connection->meta;
p = drbd_prepare_command(device, sock);
if (p) {
p->retcode = cpu_to_be32(retcode);
}
}
-void conn_send_sr_reply(struct drbd_tconn *tconn, enum drbd_state_rv retcode)
+void conn_send_sr_reply(struct drbd_connection *connection, enum drbd_state_rv retcode)
{
struct drbd_socket *sock;
struct p_req_state_reply *p;
- enum drbd_packet cmd = tconn->agreed_pro_version < 100 ? P_STATE_CHG_REPLY : P_CONN_ST_CHG_REPLY;
+ enum drbd_packet cmd = connection->agreed_pro_version < 100 ? P_STATE_CHG_REPLY : P_CONN_ST_CHG_REPLY;
- sock = &tconn->meta;
- p = conn_prepare_command(tconn, sock);
+ sock = &connection->meta;
+ p = conn_prepare_command(connection, sock);
if (p) {
p->retcode = cpu_to_be32(retcode);
- conn_send_command(tconn, sock, cmd, sizeof(*p), NULL, 0);
+ conn_send_command(connection, sock, cmd, sizeof(*p), NULL, 0);
}
}
/* may we use this feature? */
rcu_read_lock();
- use_rle = rcu_dereference(device->tconn->net_conf)->use_rle;
+ use_rle = rcu_dereference(first_peer_device(device)->connection->net_conf)->use_rle;
rcu_read_unlock();
- if (!use_rle || device->tconn->agreed_pro_version < 90)
+ if (!use_rle || first_peer_device(device)->connection->agreed_pro_version < 90)
return 0;
if (c->bit_offset >= c->bm_bits)
/* paranoia: catch zero runlength.
* can only happen if bitmap is modified while we scan it. */
if (rl == 0) {
- dev_err(DEV, "unexpected zero runlength while encoding bitmap "
+ drbd_err(device, "unexpected zero runlength while encoding bitmap "
"t:%u bo:%lu\n", toggle, c->bit_offset);
return -1;
}
if (bits == -ENOBUFS) /* buffer full */
break;
if (bits <= 0) {
- dev_err(DEV, "error while encoding bitmap: %d\n", bits);
+ drbd_err(device, "error while encoding bitmap: %d\n", bits);
return 0;
}
static int
send_bitmap_rle_or_plain(struct drbd_device *device, struct bm_xfer_ctx *c)
{
- struct drbd_socket *sock = &device->tconn->data;
- unsigned int header_size = drbd_header_size(device->tconn);
+ struct drbd_socket *sock = &first_peer_device(device)->connection->data;
+ unsigned int header_size = drbd_header_size(first_peer_device(device)->connection);
struct p_compressed_bm *p = sock->sbuf + header_size;
int len, err;
if (len) {
dcbp_set_code(p, RLE_VLI_Bits);
- err = __send_command(device->tconn, device->vnr, sock,
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock,
P_COMPRESSED_BITMAP, sizeof(*p) + len,
NULL, 0);
c->packets[0]++;
len = num_words * sizeof(*p);
if (len)
drbd_bm_get_lel(device, c->word_offset, num_words, p);
- err = __send_command(device->tconn, device->vnr, sock, P_BITMAP, len, NULL, 0);
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_BITMAP, len, NULL, 0);
c->word_offset += num_words;
c->bit_offset = c->word_offset * BITS_PER_LONG;
if (get_ldev(device)) {
if (drbd_md_test_flag(device->ldev, MDF_FULL_SYNC)) {
- dev_info(DEV, "Writing the whole bitmap, MDF_FullSync was set.\n");
+ drbd_info(device, "Writing the whole bitmap, MDF_FullSync was set.\n");
drbd_bm_set_all(device);
if (drbd_bm_write(device)) {
/* write_bm did fail! Leave full sync flag set in Meta P_DATA
* but otherwise process as per normal - need to tell other
* side that a full resync is required! */
- dev_err(DEV, "Failed to write bitmap to disk!\n");
+ drbd_err(device, "Failed to write bitmap to disk!\n");
} else {
drbd_md_clear_flag(device, MDF_FULL_SYNC);
drbd_md_sync(device);
int drbd_send_bitmap(struct drbd_device *device)
{
- struct drbd_socket *sock = &device->tconn->data;
+ struct drbd_socket *sock = &first_peer_device(device)->connection->data;
int err = -1;
mutex_lock(&sock->mutex);
return err;
}
-void drbd_send_b_ack(struct drbd_tconn *tconn, u32 barrier_nr, u32 set_size)
+void drbd_send_b_ack(struct drbd_connection *connection, u32 barrier_nr, u32 set_size)
{
struct drbd_socket *sock;
struct p_barrier_ack *p;
- if (tconn->cstate < C_WF_REPORT_PARAMS)
+ if (connection->cstate < C_WF_REPORT_PARAMS)
return;
- sock = &tconn->meta;
- p = conn_prepare_command(tconn, sock);
+ sock = &connection->meta;
+ p = conn_prepare_command(connection, sock);
if (!p)
return;
p->barrier = barrier_nr;
p->set_size = cpu_to_be32(set_size);
- conn_send_command(tconn, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0);
+ conn_send_command(connection, sock, P_BARRIER_ACK, sizeof(*p), NULL, 0);
}
/**
if (device->state.conn < C_CONNECTED)
return -EIO;
- sock = &device->tconn->meta;
+ sock = &first_peer_device(device)->connection->meta;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
void drbd_send_ack_dp(struct drbd_device *device, enum drbd_packet cmd,
struct p_data *dp, int data_size)
{
- if (device->tconn->peer_integrity_tfm)
- data_size -= crypto_hash_digestsize(device->tconn->peer_integrity_tfm);
+ if (first_peer_device(device)->connection->peer_integrity_tfm)
+ data_size -= crypto_hash_digestsize(first_peer_device(device)->connection->peer_integrity_tfm);
_drbd_send_ack(device, cmd, dp->sector, cpu_to_be32(data_size),
dp->block_id);
}
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
/* FIXME: Put the digest into the preallocated socket buffer. */
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
struct drbd_socket *sock;
struct p_block_req *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
* returns false if we should retry,
* true if we think connection is dead
*/
-static int we_should_drop_the_connection(struct drbd_tconn *tconn, struct socket *sock)
+static int we_should_drop_the_connection(struct drbd_connection *connection, struct socket *sock)
{
int drop_it;
/* long elapsed = (long)(jiffies - device->last_received); */
- drop_it = tconn->meta.socket == sock
- || !tconn->asender.task
- || get_t_state(&tconn->asender) != RUNNING
- || tconn->cstate < C_WF_REPORT_PARAMS;
+ drop_it = connection->meta.socket == sock
+ || !connection->asender.task
+ || get_t_state(&connection->asender) != RUNNING
+ || connection->cstate < C_WF_REPORT_PARAMS;
if (drop_it)
return true;
- drop_it = !--tconn->ko_count;
+ drop_it = !--connection->ko_count;
if (!drop_it) {
- conn_err(tconn, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
- current->comm, current->pid, tconn->ko_count);
- request_ping(tconn);
+ drbd_err(connection, "[%s/%d] sock_sendmsg time expired, ko = %u\n",
+ current->comm, current->pid, connection->ko_count);
+ request_ping(connection);
}
return drop_it; /* && (device->state == R_PRIMARY) */;
}
-static void drbd_update_congested(struct drbd_tconn *tconn)
+static void drbd_update_congested(struct drbd_connection *connection)
{
- struct sock *sk = tconn->data.socket->sk;
+ struct sock *sk = connection->data.socket->sk;
if (sk->sk_wmem_queued > sk->sk_sndbuf * 4 / 5)
- set_bit(NET_CONGESTED, &tconn->flags);
+ set_bit(NET_CONGESTED, &connection->flags);
}
/* The idea of sendpage seems to be to put some kind of reference
void *addr;
int err;
- socket = device->tconn->data.socket;
+ socket = first_peer_device(device)->connection->data.socket;
addr = kmap(page) + offset;
- err = drbd_send_all(device->tconn, socket, addr, size, msg_flags);
+ err = drbd_send_all(first_peer_device(device)->connection, socket, addr, size, msg_flags);
kunmap(page);
if (!err)
device->send_cnt += size >> 9;
static int _drbd_send_page(struct drbd_device *device, struct page *page,
int offset, size_t size, unsigned msg_flags)
{
- struct socket *socket = device->tconn->data.socket;
+ struct socket *socket = first_peer_device(device)->connection->data.socket;
mm_segment_t oldfs = get_fs();
int len = size;
int err = -EIO;
return _drbd_no_send_page(device, page, offset, size, msg_flags);
msg_flags |= MSG_NOSIGNAL;
- drbd_update_congested(device->tconn);
+ drbd_update_congested(first_peer_device(device)->connection);
set_fs(KERNEL_DS);
do {
int sent;
sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
if (sent <= 0) {
if (sent == -EAGAIN) {
- if (we_should_drop_the_connection(device->tconn, socket))
+ if (we_should_drop_the_connection(first_peer_device(device)->connection, socket))
break;
continue;
}
- dev_warn(DEV, "%s: size=%d len=%d sent=%d\n",
+ drbd_warn(device, "%s: size=%d len=%d sent=%d\n",
__func__, (int)size, len, sent);
if (sent < 0)
err = sent;
offset += sent;
} while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
set_fs(oldfs);
- clear_bit(NET_CONGESTED, &device->tconn->flags);
+ clear_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags);
if (len == 0) {
err = 0;
static u32 bio_flags_to_wire(struct drbd_device *device, unsigned long bi_rw)
{
- if (device->tconn->agreed_pro_version >= 95)
+ if (first_peer_device(device)->connection->agreed_pro_version >= 95)
return (bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
(bi_rw & REQ_FUA ? DP_FUA : 0) |
(bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
int dgs;
int err;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
- dgs = device->tconn->integrity_tfm ? crypto_hash_digestsize(device->tconn->integrity_tfm) : 0;
+ dgs = first_peer_device(device)->connection->integrity_tfm ?
+ crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
if (device->state.conn >= C_SYNC_SOURCE &&
device->state.conn <= C_PAUSED_SYNC_T)
dp_flags |= DP_MAY_SET_IN_SYNC;
- if (device->tconn->agreed_pro_version >= 100) {
+ if (first_peer_device(device)->connection->agreed_pro_version >= 100) {
if (req->rq_state & RQ_EXP_RECEIVE_ACK)
dp_flags |= DP_SEND_RECEIVE_ACK;
if (req->rq_state & RQ_EXP_WRITE_ACK)
}
p->dp_flags = cpu_to_be32(dp_flags);
if (dgs)
- drbd_csum_bio(device, device->tconn->integrity_tfm, req->master_bio, p + 1);
- err = __send_command(device->tconn, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
+ drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, p + 1);
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, P_DATA, sizeof(*p) + dgs, NULL, req->i.size);
if (!err) {
/* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away
/* 64 byte, 512 bit, is the largest digest size
* currently supported in kernel crypto. */
unsigned char digest[64];
- drbd_csum_bio(device, device->tconn->integrity_tfm, req->master_bio, digest);
+ drbd_csum_bio(device, first_peer_device(device)->connection->integrity_tfm, req->master_bio, digest);
if (memcmp(p + 1, digest, dgs)) {
- dev_warn(DEV,
+ drbd_warn(device,
"Digest mismatch, buffer modified by upper layers during write: %llus +%u\n",
(unsigned long long)req->i.sector, req->i.size);
}
int err;
int dgs;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
- dgs = device->tconn->integrity_tfm ? crypto_hash_digestsize(device->tconn->integrity_tfm) : 0;
+ dgs = first_peer_device(device)->connection->integrity_tfm ?
+ crypto_hash_digestsize(first_peer_device(device)->connection->integrity_tfm) : 0;
if (!p)
return -EIO;
p->seq_num = 0; /* unused */
p->dp_flags = 0;
if (dgs)
- drbd_csum_ee(device, device->tconn->integrity_tfm, peer_req, p + 1);
- err = __send_command(device->tconn, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
+ drbd_csum_ee(device, first_peer_device(device)->connection->integrity_tfm, peer_req, p + 1);
+ err = __send_command(first_peer_device(device)->connection, device->vnr, sock, cmd, sizeof(*p) + dgs, NULL, peer_req->i.size);
if (!err)
err = _drbd_send_zc_ee(device, peer_req);
mutex_unlock(&sock->mutex); /* locked by drbd_prepare_command() */
struct drbd_socket *sock;
struct p_block_desc *p;
- sock = &device->tconn->data;
+ sock = &first_peer_device(device)->connection->data;
p = drbd_prepare_command(device, sock);
if (!p)
return -EIO;
/*
* you must have down()ed the appropriate [m]sock_mutex elsewhere!
*/
-int drbd_send(struct drbd_tconn *tconn, struct socket *sock,
+int drbd_send(struct drbd_connection *connection, struct socket *sock,
void *buf, size_t size, unsigned msg_flags)
{
struct kvec iov;
msg.msg_controllen = 0;
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
- if (sock == tconn->data.socket) {
+ if (sock == connection->data.socket) {
rcu_read_lock();
- tconn->ko_count = rcu_dereference(tconn->net_conf)->ko_count;
+ connection->ko_count = rcu_dereference(connection->net_conf)->ko_count;
rcu_read_unlock();
- drbd_update_congested(tconn);
+ drbd_update_congested(connection);
}
do {
/* STRANGE
*/
rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
if (rv == -EAGAIN) {
- if (we_should_drop_the_connection(tconn, sock))
+ if (we_should_drop_the_connection(connection, sock))
break;
else
continue;
iov.iov_len -= rv;
} while (sent < size);
- if (sock == tconn->data.socket)
- clear_bit(NET_CONGESTED, &tconn->flags);
+ if (sock == connection->data.socket)
+ clear_bit(NET_CONGESTED, &connection->flags);
if (rv <= 0) {
if (rv != -EAGAIN) {
- conn_err(tconn, "%s_sendmsg returned %d\n",
- sock == tconn->meta.socket ? "msock" : "sock",
+ drbd_err(connection, "%s_sendmsg returned %d\n",
+ sock == connection->meta.socket ? "msock" : "sock",
rv);
- conn_request_state(tconn, NS(conn, C_BROKEN_PIPE), CS_HARD);
+ conn_request_state(connection, NS(conn, C_BROKEN_PIPE), CS_HARD);
} else
- conn_request_state(tconn, NS(conn, C_TIMEOUT), CS_HARD);
+ conn_request_state(connection, NS(conn, C_TIMEOUT), CS_HARD);
}
return sent;
*
* Returns 0 upon success and a negative error value otherwise.
*/
-int drbd_send_all(struct drbd_tconn *tconn, struct socket *sock, void *buffer,
+int drbd_send_all(struct drbd_connection *connection, struct socket *sock, void *buffer,
size_t size, unsigned msg_flags)
{
int err;
- err = drbd_send(tconn, sock, buffer, size, msg_flags);
+ err = drbd_send(connection, sock, buffer, size, msg_flags);
if (err < 0)
return err;
if (err != size)
int rv = 0;
mutex_lock(&drbd_main_mutex);
- spin_lock_irqsave(&device->tconn->req_lock, flags);
+ spin_lock_irqsave(&first_peer_device(device)->connection->req_lock, flags);
/* to have a stable device->state.role
* and no race with updating open_cnt */
if (!rv)
device->open_cnt++;
- spin_unlock_irqrestore(&device->tconn->req_lock, flags);
+ spin_unlock_irqrestore(&first_peer_device(device)->connection->req_lock, flags);
mutex_unlock(&drbd_main_mutex);
return rv;
void drbd_device_cleanup(struct drbd_device *device)
{
int i;
- if (device->tconn->receiver.t_state != NONE)
- dev_err(DEV, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
- device->tconn->receiver.t_state);
+ if (first_peer_device(device)->connection->receiver.t_state != NONE)
+ drbd_err(device, "ASSERT FAILED: receiver t_state == %d expected 0.\n",
+ first_peer_device(device)->connection->receiver.t_state);
device->al_writ_cnt =
device->bm_writ_cnt =
device->rs_mark_left[i] = 0;
device->rs_mark_time[i] = 0;
}
- D_ASSERT(device->tconn->net_conf == NULL);
+ D_ASSERT(device, first_peer_device(device)->connection->net_conf == NULL);
drbd_set_my_capacity(device, 0);
if (device->bitmap) {
clear_bit(AL_SUSPENDED, &device->flags);
- D_ASSERT(list_empty(&device->active_ee));
- D_ASSERT(list_empty(&device->sync_ee));
- D_ASSERT(list_empty(&device->done_ee));
- D_ASSERT(list_empty(&device->read_ee));
- D_ASSERT(list_empty(&device->net_ee));
- D_ASSERT(list_empty(&device->resync_reads));
- D_ASSERT(list_empty(&device->tconn->sender_work.q));
- D_ASSERT(list_empty(&device->resync_work.list));
- D_ASSERT(list_empty(&device->unplug_work.list));
- D_ASSERT(list_empty(&device->go_diskless.list));
+ D_ASSERT(device, list_empty(&device->active_ee));
+ D_ASSERT(device, list_empty(&device->sync_ee));
+ D_ASSERT(device, list_empty(&device->done_ee));
+ D_ASSERT(device, list_empty(&device->read_ee));
+ D_ASSERT(device, list_empty(&device->net_ee));
+ D_ASSERT(device, list_empty(&device->resync_reads));
+ D_ASSERT(device, list_empty(&first_peer_device(device)->connection->sender_work.q));
+ D_ASSERT(device, list_empty(&device->resync_work.list));
+ D_ASSERT(device, list_empty(&device->unplug_work.list));
+ D_ASSERT(device, list_empty(&device->go_diskless.list));
drbd_set_defaults(device);
}
drbd_pp_vacant--;
}
- /* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */
+ /* D_ASSERT(device, atomic_read(&drbd_pp_vacant)==0); */
if (drbd_md_io_bio_set)
bioset_free(drbd_md_io_bio_set);
rr = drbd_free_peer_reqs(device, &device->active_ee);
if (rr)
- dev_err(DEV, "%d EEs in active list found!\n", rr);
+ drbd_err(device, "%d EEs in active list found!\n", rr);
rr = drbd_free_peer_reqs(device, &device->sync_ee);
if (rr)
- dev_err(DEV, "%d EEs in sync list found!\n", rr);
+ drbd_err(device, "%d EEs in sync list found!\n", rr);
rr = drbd_free_peer_reqs(device, &device->read_ee);
if (rr)
- dev_err(DEV, "%d EEs in read list found!\n", rr);
+ drbd_err(device, "%d EEs in read list found!\n", rr);
rr = drbd_free_peer_reqs(device, &device->done_ee);
if (rr)
- dev_err(DEV, "%d EEs in done list found!\n", rr);
+ drbd_err(device, "%d EEs in done list found!\n", rr);
rr = drbd_free_peer_reqs(device, &device->net_ee);
if (rr)
- dev_err(DEV, "%d EEs in net list found!\n", rr);
+ drbd_err(device, "%d EEs in net list found!\n", rr);
}
/* caution. no locking. */
-void drbd_minor_destroy(struct kref *kref)
+void drbd_destroy_device(struct kref *kref)
{
struct drbd_device *device = container_of(kref, struct drbd_device, kref);
- struct drbd_tconn *tconn = device->tconn;
+ struct drbd_resource *resource = device->resource;
+ struct drbd_connection *connection;
del_timer_sync(&device->request_timer);
/* paranoia asserts */
- D_ASSERT(device->open_cnt == 0);
+ D_ASSERT(device, device->open_cnt == 0);
/* end paranoia asserts */
/* cleanup stuff that may have been allocated during
put_disk(device->vdisk);
blk_cleanup_queue(device->rq_queue);
kfree(device->rs_plan_s);
+ kfree(first_peer_device(device));
kfree(device);
- kref_put(&tconn->kref, &conn_destroy);
+ for_each_connection(connection, resource)
+ kref_put(&connection->kref, drbd_destroy_connection);
+ kref_put(&resource->kref, drbd_destroy_resource);
}
/* One global retry thread, if we need to push back some bio and have it
(req->rq_state & RQ_LOCAL_ABORTED) != 0);
if (!expected)
- dev_err(DEV, "req=%p completion_ref=%d rq_state=%x\n",
+ drbd_err(device, "req=%p completion_ref=%d rq_state=%x\n",
req, atomic_read(&req->completion_ref),
req->rq_state);
queue_work(retry.wq, &retry.worker);
}
+void drbd_destroy_resource(struct kref *kref)
+{
+ struct drbd_resource *resource =
+ container_of(kref, struct drbd_resource, kref);
+
+ idr_destroy(&resource->devices);
+ kfree(resource->name);
+ kfree(resource);
+}
+
+void drbd_free_resource(struct drbd_resource *resource)
+{
+ struct drbd_connection *connection, *tmp;
+
+ for_each_connection_safe(connection, tmp, resource) {
+ list_del(&connection->connections);
+ kref_put(&connection->kref, drbd_destroy_connection);
+ }
+ kref_put(&resource->kref, drbd_destroy_resource);
+}
static void drbd_cleanup(void)
{
unsigned int i;
struct drbd_device *device;
- struct drbd_tconn *tconn, *tmp;
+ struct drbd_resource *resource, *tmp;
unregister_reboot_notifier(&drbd_notifier);
drbd_genl_unregister();
- idr_for_each_entry(&minors, device, i) {
- idr_remove(&minors, device_to_minor(device));
- idr_remove(&device->tconn->volumes, device->vnr);
- destroy_workqueue(device->submit.wq);
- del_gendisk(device->vdisk);
- /* synchronize_rcu(); No other threads running at this point */
- kref_put(&device->kref, &drbd_minor_destroy);
- }
+ idr_for_each_entry(&drbd_devices, device, i)
+ drbd_delete_device(device);
/* not _rcu since, no other updater anymore. Genl already unregistered */
- list_for_each_entry_safe(tconn, tmp, &drbd_tconns, all_tconn) {
- list_del(&tconn->all_tconn); /* not _rcu no proc, not other threads */
- /* synchronize_rcu(); */
- kref_put(&tconn->kref, &conn_destroy);
+ for_each_resource_safe(resource, tmp, &drbd_resources) {
+ list_del(&resource->resources);
+ drbd_free_resource(resource);
}
drbd_destroy_mempools();
unregister_blkdev(DRBD_MAJOR, "drbd");
- idr_destroy(&minors);
+ idr_destroy(&drbd_devices);
printk(KERN_INFO "drbd: module cleanup done.\n");
}
goto out;
}
- if (test_bit(CALLBACK_PENDING, &device->tconn->flags)) {
+ if (test_bit(CALLBACK_PENDING, &first_peer_device(device)->connection->flags)) {
r |= (1 << BDI_async_congested);
/* Without good local data, we would need to read from remote,
* and that would need the worker thread as well, which is
reason = 'b';
}
- if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &device->tconn->flags)) {
+ if (bdi_bits & (1 << BDI_async_congested) &&
+ test_bit(NET_CONGESTED, &first_peer_device(device)->connection->flags)) {
r |= (1 << BDI_async_congested);
reason = reason == 'b' ? 'a' : 'n';
}
init_waitqueue_head(&wq->q_wait);
}
-struct drbd_tconn *conn_get_by_name(const char *name)
+struct drbd_resource *drbd_find_resource(const char *name)
{
- struct drbd_tconn *tconn;
+ struct drbd_resource *resource;
if (!name || !name[0])
return NULL;
rcu_read_lock();
- list_for_each_entry_rcu(tconn, &drbd_tconns, all_tconn) {
- if (!strcmp(tconn->name, name)) {
- kref_get(&tconn->kref);
+ for_each_resource_rcu(resource, &drbd_resources) {
+ if (!strcmp(resource->name, name)) {
+ kref_get(&resource->kref);
goto found;
}
}
- tconn = NULL;
+ resource = NULL;
found:
rcu_read_unlock();
- return tconn;
+ return resource;
}
-struct drbd_tconn *conn_get_by_addrs(void *my_addr, int my_addr_len,
+struct drbd_connection *conn_get_by_addrs(void *my_addr, int my_addr_len,
void *peer_addr, int peer_addr_len)
{
- struct drbd_tconn *tconn;
+ struct drbd_resource *resource;
+ struct drbd_connection *connection;
rcu_read_lock();
- list_for_each_entry_rcu(tconn, &drbd_tconns, all_tconn) {
- if (tconn->my_addr_len == my_addr_len &&
- tconn->peer_addr_len == peer_addr_len &&
- !memcmp(&tconn->my_addr, my_addr, my_addr_len) &&
- !memcmp(&tconn->peer_addr, peer_addr, peer_addr_len)) {
- kref_get(&tconn->kref);
- goto found;
+ for_each_resource_rcu(resource, &drbd_resources) {
+ for_each_connection_rcu(connection, resource) {
+ if (connection->my_addr_len == my_addr_len &&
+ connection->peer_addr_len == peer_addr_len &&
+ !memcmp(&connection->my_addr, my_addr, my_addr_len) &&
+ !memcmp(&connection->peer_addr, peer_addr, peer_addr_len)) {
+ kref_get(&connection->kref);
+ goto found;
+ }
}
}
- tconn = NULL;
+ connection = NULL;
found:
rcu_read_unlock();
- return tconn;
+ return connection;
}
static int drbd_alloc_socket(struct drbd_socket *socket)
free_page((unsigned long) socket->rbuf);
}
-void conn_free_crypto(struct drbd_tconn *tconn)
+void conn_free_crypto(struct drbd_connection *connection)
{
- drbd_free_sock(tconn);
+ drbd_free_sock(connection);
- crypto_free_hash(tconn->csums_tfm);
- crypto_free_hash(tconn->verify_tfm);
- crypto_free_hash(tconn->cram_hmac_tfm);
- crypto_free_hash(tconn->integrity_tfm);
- crypto_free_hash(tconn->peer_integrity_tfm);
- kfree(tconn->int_dig_in);
- kfree(tconn->int_dig_vv);
+ crypto_free_hash(connection->csums_tfm);
+ crypto_free_hash(connection->verify_tfm);
+ crypto_free_hash(connection->cram_hmac_tfm);
+ crypto_free_hash(connection->integrity_tfm);
+ crypto_free_hash(connection->peer_integrity_tfm);
+ kfree(connection->int_dig_in);
+ kfree(connection->int_dig_vv);
- tconn->csums_tfm = NULL;
- tconn->verify_tfm = NULL;
- tconn->cram_hmac_tfm = NULL;
- tconn->integrity_tfm = NULL;
- tconn->peer_integrity_tfm = NULL;
- tconn->int_dig_in = NULL;
- tconn->int_dig_vv = NULL;
+ connection->csums_tfm = NULL;
+ connection->verify_tfm = NULL;
+ connection->cram_hmac_tfm = NULL;
+ connection->integrity_tfm = NULL;
+ connection->peer_integrity_tfm = NULL;
+ connection->int_dig_in = NULL;
+ connection->int_dig_vv = NULL;
}
-int set_resource_options(struct drbd_tconn *tconn, struct res_opts *res_opts)
+int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts)
{
+ struct drbd_connection *connection;
cpumask_var_t new_cpu_mask;
int err;
err = bitmap_parse(res_opts->cpu_mask, 32,
cpumask_bits(new_cpu_mask), nr_cpu_ids);
if (err) {
- conn_warn(tconn, "bitmap_parse() failed with %d\n", err);
+ drbd_warn(resource, "bitmap_parse() failed with %d\n", err);
/* retcode = ERR_CPU_MASK_PARSE; */
goto fail;
}
}
- tconn->res_opts = *res_opts;
- if (!cpumask_equal(tconn->cpu_mask, new_cpu_mask)) {
- cpumask_copy(tconn->cpu_mask, new_cpu_mask);
- drbd_calc_cpu_mask(tconn);
- tconn->receiver.reset_cpu_mask = 1;
- tconn->asender.reset_cpu_mask = 1;
- tconn->worker.reset_cpu_mask = 1;
+ resource->res_opts = *res_opts;
+ for_each_connection_rcu(connection, resource) {
+ if (!cpumask_equal(connection->cpu_mask, new_cpu_mask)) {
+ cpumask_copy(connection->cpu_mask, new_cpu_mask);
+ drbd_calc_cpu_mask(connection);
+ connection->receiver.reset_cpu_mask = 1;
+ connection->asender.reset_cpu_mask = 1;
+ connection->worker.reset_cpu_mask = 1;
+ }
}
err = 0;
}
-/* caller must be under genl_lock() */
-struct drbd_tconn *conn_create(const char *name, struct res_opts *res_opts)
+struct drbd_resource *drbd_create_resource(const char *name)
{
- struct drbd_tconn *tconn;
+ struct drbd_resource *resource;
- tconn = kzalloc(sizeof(struct drbd_tconn), GFP_KERNEL);
- if (!tconn)
+ resource = kmalloc(sizeof(struct drbd_resource), GFP_KERNEL);
+ if (!resource)
+ return NULL;
+ resource->name = kstrdup(name, GFP_KERNEL);
+ if (!resource->name) {
+ kfree(resource);
return NULL;
+ }
+ kref_init(&resource->kref);
+ idr_init(&resource->devices);
+ INIT_LIST_HEAD(&resource->connections);
+ list_add_tail_rcu(&resource->resources, &drbd_resources);
+ return resource;
+}
- tconn->name = kstrdup(name, GFP_KERNEL);
- if (!tconn->name)
- goto fail;
+/* caller must be under genl_lock() */
+struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts)
+{
+ struct drbd_resource *resource;
+ struct drbd_connection *connection;
+
+ connection = kzalloc(sizeof(struct drbd_connection), GFP_KERNEL);
+ if (!connection)
+ return NULL;
- if (drbd_alloc_socket(&tconn->data))
+ if (drbd_alloc_socket(&connection->data))
goto fail;
- if (drbd_alloc_socket(&tconn->meta))
+ if (drbd_alloc_socket(&connection->meta))
goto fail;
- if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&connection->cpu_mask, GFP_KERNEL))
goto fail;
- if (set_resource_options(tconn, res_opts))
+ connection->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
+ if (!connection->current_epoch)
goto fail;
- tconn->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL);
- if (!tconn->current_epoch)
- goto fail;
+ INIT_LIST_HEAD(&connection->transfer_log);
+
+ INIT_LIST_HEAD(&connection->current_epoch->list);
+ connection->epochs = 1;
+ spin_lock_init(&connection->epoch_lock);
+ connection->write_ordering = WO_bdev_flush;
- INIT_LIST_HEAD(&tconn->transfer_log);
+ connection->send.seen_any_write_yet = false;
+ connection->send.current_epoch_nr = 0;
+ connection->send.current_epoch_writes = 0;
- INIT_LIST_HEAD(&tconn->current_epoch->list);
- tconn->epochs = 1;
- spin_lock_init(&tconn->epoch_lock);
- tconn->write_ordering = WO_bdev_flush;
+ resource = drbd_create_resource(name);
+ if (!resource)
+ goto fail;
- tconn->send.seen_any_write_yet = false;
- tconn->send.current_epoch_nr = 0;
- tconn->send.current_epoch_writes = 0;
+ connection->cstate = C_STANDALONE;
+ mutex_init(&connection->cstate_mutex);
+ spin_lock_init(&connection->req_lock);
+ mutex_init(&connection->conf_update);
+ init_waitqueue_head(&connection->ping_wait);
+ idr_init(&connection->peer_devices);
- tconn->cstate = C_STANDALONE;
- mutex_init(&tconn->cstate_mutex);
- spin_lock_init(&tconn->req_lock);
- mutex_init(&tconn->conf_update);
- init_waitqueue_head(&tconn->ping_wait);
- idr_init(&tconn->volumes);
+ drbd_init_workqueue(&connection->sender_work);
+ mutex_init(&connection->data.mutex);
+ mutex_init(&connection->meta.mutex);
- drbd_init_workqueue(&tconn->sender_work);
- mutex_init(&tconn->data.mutex);
- mutex_init(&tconn->meta.mutex);
+ drbd_thread_init(connection, &connection->receiver, drbdd_init, "receiver");
+ drbd_thread_init(connection, &connection->worker, drbd_worker, "worker");
+ drbd_thread_init(connection, &connection->asender, drbd_asender, "asender");
- drbd_thread_init(tconn, &tconn->receiver, drbdd_init, "receiver");
- drbd_thread_init(tconn, &tconn->worker, drbd_worker, "worker");
- drbd_thread_init(tconn, &tconn->asender, drbd_asender, "asender");
+ kref_init(&connection->kref);
- kref_init(&tconn->kref);
- list_add_tail_rcu(&tconn->all_tconn, &drbd_tconns);
+ connection->resource = resource;
- return tconn;
+ if (set_resource_options(resource, res_opts))
+ goto fail_resource;
-fail:
- kfree(tconn->current_epoch);
- free_cpumask_var(tconn->cpu_mask);
- drbd_free_socket(&tconn->meta);
- drbd_free_socket(&tconn->data);
- kfree(tconn->name);
- kfree(tconn);
+ kref_get(&resource->kref);
+ list_add_tail_rcu(&connection->connections, &resource->connections);
+ return connection;
+fail_resource:
+ list_del(&resource->resources);
+ drbd_free_resource(resource);
+fail:
+ kfree(connection->current_epoch);
+ free_cpumask_var(connection->cpu_mask);
+ drbd_free_socket(&connection->meta);
+ drbd_free_socket(&connection->data);
+ kfree(connection);
return NULL;
}
-void conn_destroy(struct kref *kref)
+void drbd_destroy_connection(struct kref *kref)
{
- struct drbd_tconn *tconn = container_of(kref, struct drbd_tconn, kref);
+ struct drbd_connection *connection = container_of(kref, struct drbd_connection, kref);
+ struct drbd_resource *resource = connection->resource;
- if (atomic_read(&tconn->current_epoch->epoch_size) != 0)
- conn_err(tconn, "epoch_size:%d\n", atomic_read(&tconn->current_epoch->epoch_size));
- kfree(tconn->current_epoch);
+ if (atomic_read(&connection->current_epoch->epoch_size) != 0)
+ drbd_err(connection, "epoch_size:%d\n", atomic_read(&connection->current_epoch->epoch_size));
+ kfree(connection->current_epoch);
- idr_destroy(&tconn->volumes);
+ idr_destroy(&connection->peer_devices);
- free_cpumask_var(tconn->cpu_mask);
- drbd_free_socket(&tconn->meta);
- drbd_free_socket(&tconn->data);
- kfree(tconn->name);
- kfree(tconn->int_dig_in);
- kfree(tconn->int_dig_vv);
- kfree(tconn);
+ free_cpumask_var(connection->cpu_mask);
+ drbd_free_socket(&connection->meta);
+ drbd_free_socket(&connection->data);
+ kfree(connection->int_dig_in);
+ kfree(connection->int_dig_vv);
+ kfree(connection);
+ kref_put(&resource->kref, drbd_destroy_resource);
}
static int init_submitter(struct drbd_device *device)
return 0;
}
-enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr)
+enum drbd_ret_code drbd_create_device(struct drbd_resource *resource, unsigned int minor, int vnr)
{
+ struct drbd_connection *connection;
struct drbd_device *device;
+ struct drbd_peer_device *peer_device, *tmp_peer_device;
struct gendisk *disk;
struct request_queue *q;
- int vnr_got = vnr;
- int minor_got = minor;
+ int id;
enum drbd_ret_code err = ERR_NOMEM;
device = minor_to_device(minor);
device = kzalloc(sizeof(struct drbd_device), GFP_KERNEL);
if (!device)
return ERR_NOMEM;
+ kref_init(&device->kref);
- kref_get(&tconn->kref);
- device->tconn = tconn;
-
+ kref_get(&resource->kref);
+ device->resource = resource;
device->minor = minor;
device->vnr = vnr;
blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
blk_queue_merge_bvec(q, drbd_merge_bvec);
- q->queue_lock = &device->tconn->req_lock; /* needed since we use */
+ q->queue_lock = &connection->req_lock;
device->md_io_page = alloc_page(GFP_KERNEL);
if (!device->md_io_page)
device->read_requests = RB_ROOT;
device->write_requests = RB_ROOT;
- minor_got = idr_alloc(&minors, device, minor, minor + 1, GFP_KERNEL);
- if (minor_got < 0) {
- if (minor_got == -ENOSPC) {
+ id = idr_alloc(&drbd_devices, device, minor, minor + 1, GFP_KERNEL);
+ if (id < 0) {
+ if (id == -ENOSPC) {
err = ERR_MINOR_EXISTS;
drbd_msg_put_info("requested minor exists already");
}
goto out_no_minor_idr;
}
+ kref_get(&device->kref);
- vnr_got = idr_alloc(&tconn->volumes, device, vnr, vnr + 1, GFP_KERNEL);
- if (vnr_got < 0) {
- if (vnr_got == -ENOSPC) {
- err = ERR_INVALID_REQUEST;
- drbd_msg_put_info("requested volume exists already");
+ id = idr_alloc(&resource->devices, device, vnr, vnr + 1, GFP_KERNEL);
+ if (id < 0) {
+ if (id == -ENOSPC) {
+ err = ERR_MINOR_EXISTS;
+ drbd_msg_put_info("requested minor exists already");
}
goto out_idr_remove_minor;
}
+ kref_get(&device->kref);
+
+ INIT_LIST_HEAD(&device->peer_devices);
+ for_each_connection(connection, resource) {
+ peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
+ if (!peer_device)
+ goto out_idr_remove_from_resource;
+ peer_device->connection = connection;
+ peer_device->device = device;
+
+ list_add(&peer_device->peer_devices, &device->peer_devices);
+ kref_get(&device->kref);
+
+ id = idr_alloc(&connection->peer_devices, peer_device, vnr, vnr + 1, GFP_KERNEL);
+ if (id < 0) {
+ if (id == -ENOSPC) {
+ err = ERR_INVALID_REQUEST;
+ drbd_msg_put_info("requested volume exists already");
+ }
+ goto out_idr_remove_from_resource;
+ }
+ kref_get(&connection->kref);
+ }
if (init_submitter(device)) {
err = ERR_NOMEM;
}
add_disk(disk);
- kref_init(&device->kref); /* one ref for both idrs and the the add_disk */
/* inherit the connection state */
- device->state.conn = tconn->cstate;
+ device->state.conn = first_connection(resource)->cstate;
if (device->state.conn == C_WF_REPORT_PARAMS)
drbd_connected(device);
return NO_ERROR;
out_idr_remove_vol:
- idr_remove(&tconn->volumes, vnr_got);
+ idr_remove(&connection->peer_devices, vnr);
+out_idr_remove_from_resource:
+ for_each_connection(connection, resource) {
+ peer_device = idr_find(&connection->peer_devices, vnr);
+ if (peer_device) {
+ idr_remove(&connection->peer_devices, vnr);
+ kref_put(&connection->kref, drbd_destroy_connection);
+ }
+ }
+ for_each_peer_device_safe(peer_device, tmp_peer_device, device) {
+ list_del(&peer_device->peer_devices);
+ kfree(peer_device);
+ }
+ idr_remove(&resource->devices, vnr);
out_idr_remove_minor:
- idr_remove(&minors, minor_got);
+ idr_remove(&drbd_devices, minor);
synchronize_rcu();
out_no_minor_idr:
drbd_bm_cleanup(device);
out_no_disk:
blk_cleanup_queue(q);
out_no_q:
+ kref_put(&resource->kref, drbd_destroy_resource);
kfree(device);
- kref_put(&tconn->kref, &conn_destroy);
return err;
}
+void drbd_delete_device(struct drbd_device *device)
+{
+ struct drbd_resource *resource = device->resource;
+ struct drbd_connection *connection;
+ int refs = 3;
+
+ for_each_connection(connection, resource) {
+ idr_remove(&connection->peer_devices, device->vnr);
+ refs++;
+ }
+ idr_remove(&resource->devices, device->vnr);
+ idr_remove(&drbd_devices, device_to_minor(device));
+ del_gendisk(device->vdisk);
+ synchronize_rcu();
+ kref_sub(&device->kref, refs, drbd_destroy_device);
+}
+
int __init drbd_init(void)
{
int err;
init_waitqueue_head(&drbd_pp_wait);
drbd_proc = NULL; /* play safe for drbd_cleanup */
- idr_init(&minors);
+ idr_init(&drbd_devices);
rwlock_init(&global_state_lock);
- INIT_LIST_HEAD(&drbd_tconns);
+ INIT_LIST_HEAD(&drbd_resources);
err = drbd_genl_register();
if (err) {
kfree(ldev);
}
-void drbd_free_sock(struct drbd_tconn *tconn)
+void drbd_free_sock(struct drbd_connection *connection)
{
- if (tconn->data.socket) {
- mutex_lock(&tconn->data.mutex);
- kernel_sock_shutdown(tconn->data.socket, SHUT_RDWR);
- sock_release(tconn->data.socket);
- tconn->data.socket = NULL;
- mutex_unlock(&tconn->data.mutex);
+ if (connection->data.socket) {
+ mutex_lock(&connection->data.mutex);
+ kernel_sock_shutdown(connection->data.socket, SHUT_RDWR);
+ sock_release(connection->data.socket);
+ connection->data.socket = NULL;
+ mutex_unlock(&connection->data.mutex);
}
- if (tconn->meta.socket) {
- mutex_lock(&tconn->meta.mutex);
- kernel_sock_shutdown(tconn->meta.socket, SHUT_RDWR);
- sock_release(tconn->meta.socket);
- tconn->meta.socket = NULL;
- mutex_unlock(&tconn->meta.mutex);
+ if (connection->meta.socket) {
+ mutex_lock(&connection->meta.mutex);
+ kernel_sock_shutdown(connection->meta.socket, SHUT_RDWR);
+ sock_release(connection->meta.socket);
+ connection->meta.socket = NULL;
+ mutex_unlock(&connection->meta.mutex);
}
}
/* meta data management */
-void conn_md_sync(struct drbd_tconn *tconn)
+void conn_md_sync(struct drbd_connection *connection)
{
- struct drbd_device *device;
+ struct drbd_peer_device *peer_device;
int vnr;
rcu_read_lock();
- idr_for_each_entry(&tconn->volumes, device, vnr) {
+ idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
+ struct drbd_device *device = peer_device->device;
+
kref_get(&device->kref);
rcu_read_unlock();
drbd_md_sync(device);
- kref_put(&device->kref, &drbd_minor_destroy);
+ kref_put(&device->kref, drbd_destroy_device);
rcu_read_lock();
}
rcu_read_unlock();
buffer->al_stripes = cpu_to_be32(device->ldev->md.al_stripes);
buffer->al_stripe_size_4k = cpu_to_be32(device->ldev->md.al_stripe_size_4k);
- D_ASSERT(drbd_md_ss(device->ldev) == device->ldev->md.md_offset);
+ D_ASSERT(device, drbd_md_ss(device->ldev) == device->ldev->md.md_offset);
sector = device->ldev->md.md_offset;
if (drbd_md_sync_page_io(device, device->ldev, sector, WRITE)) {
/* this was a try anyways ... */
- dev_err(DEV, "meta data update failed!\n");
+ drbd_err(device, "meta data update failed!\n");
drbd_chk_io_error(device, 1, DRBD_META_IO_ERROR);
}
}
return 0;
err:
- dev_err(DEV, "invalid activity log striping: al_stripes=%u, al_stripe_size_4k=%u\n",
+ drbd_err(device, "invalid activity log striping: al_stripes=%u, al_stripe_size_4k=%u\n",
al_stripes, al_stripe_size_4k);
return -EINVAL;
}
return 0;
err:
- dev_err(DEV, "meta data offsets don't make sense: idx=%d "
+ drbd_err(device, "meta data offsets don't make sense: idx=%d "
"al_s=%u, al_sz4k=%u, al_offset=%d, bm_offset=%d, "
"md_size_sect=%u, la_size=%llu, md_capacity=%llu\n",
in_core->meta_dev_idx,
if (drbd_md_sync_page_io(device, bdev, bdev->md.md_offset, READ)) {
/* NOTE: can't do normal error processing here as this is
called BEFORE disk is attached */
- dev_err(DEV, "Error while reading metadata.\n");
+ drbd_err(device, "Error while reading metadata.\n");
rv = ERR_IO_MD_DISK;
goto err;
}
if (magic == DRBD_MD_MAGIC_84_UNCLEAN ||
(magic == DRBD_MD_MAGIC_08 && !(flags & MDF_AL_CLEAN))) {
/* btw: that's Activity Log clean, not "all" clean. */
- dev_err(DEV, "Found unclean meta data. Did you \"drbdadm apply-al\"?\n");
+ drbd_err(device, "Found unclean meta data. Did you \"drbdadm apply-al\"?\n");
rv = ERR_MD_UNCLEAN;
goto err;
}
rv = ERR_MD_INVALID;
if (magic != DRBD_MD_MAGIC_08) {
if (magic == DRBD_MD_MAGIC_07)
- dev_err(DEV, "Found old (0.7) meta data magic. Did you \"drbdadm create-md\"?\n");
+ drbd_err(device, "Found old (0.7) meta data magic. Did you \"drbdadm create-md\"?\n");
else
- dev_err(DEV, "Meta data magic not found. Did you \"drbdadm create-md\"?\n");
+ drbd_err(device, "Meta data magic not found. Did you \"drbdadm create-md\"?\n");
goto err;
}
if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) {
- dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
+ drbd_err(device, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
goto err;
}
goto err;
if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) {
- dev_err(DEV, "unexpected bm_offset: %d (expected %d)\n",
+ drbd_err(device, "unexpected bm_offset: %d (expected %d)\n",
be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset);
goto err;
}
if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) {
- dev_err(DEV, "unexpected md_size: %u (expected %u)\n",
+ drbd_err(device, "unexpected md_size: %u (expected %u)\n",
be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect);
goto err;
}
rv = NO_ERROR;
- spin_lock_irq(&device->tconn->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (device->state.conn < C_CONNECTED) {
unsigned int peer;
peer = be32_to_cpu(buffer->la_peer_max_bio_size);
peer = max(peer, DRBD_MAX_BIO_SIZE_SAFE);
device->peer_max_bio_size = peer;
}
- spin_unlock_irq(&device->tconn->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
err:
drbd_md_put_buffer(device);
bm_uuid = device->ldev->md.uuid[UI_BITMAP];
if (bm_uuid)
- dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid);
+ drbd_warn(device, "bm UUID was already set: %llX\n", bm_uuid);
device->ldev->md.uuid[UI_BITMAP] = device->ldev->md.uuid[UI_CURRENT];
__drbd_uuid_set(device, UI_CURRENT, val);
} else {
unsigned long long bm_uuid = device->ldev->md.uuid[UI_BITMAP];
if (bm_uuid)
- dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid);
+ drbd_warn(device, "bm UUID was already set: %llX\n", bm_uuid);
device->ldev->md.uuid[UI_BITMAP] = val & ~((u64)1);
}
struct drbd_device *device = w->device;
int rv = -EIO;
- D_ASSERT(atomic_read(&device->ap_bio_cnt) == 0);
+ D_ASSERT(device, atomic_read(&device->ap_bio_cnt) == 0);
if (get_ldev(device)) {
drbd_bm_lock(device, work->why, work->flags);
{
struct drbd_device *device = w->device;
- D_ASSERT(device->state.disk == D_FAILED);
+ D_ASSERT(device, device->state.disk == D_FAILED);
/* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
* inc/dec it frequently. Once we are D_DISKLESS, no one will touch
* the protected members anymore, though, so once put_ldev reaches zero
void (*done)(struct drbd_device *, int),
char *why, enum bm_flag flags)
{
- D_ASSERT(current == device->tconn->worker.task);
+ D_ASSERT(device, current == first_peer_device(device)->connection->worker.task);
- D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &device->flags));
- D_ASSERT(!test_bit(BITMAP_IO, &device->flags));
- D_ASSERT(list_empty(&device->bm_io_work.w.list));
+ D_ASSERT(device, !test_bit(BITMAP_IO_QUEUED, &device->flags));
+ D_ASSERT(device, !test_bit(BITMAP_IO, &device->flags));
+ D_ASSERT(device, list_empty(&device->bm_io_work.w.list));
if (device->bm_io_work.why)
- dev_err(DEV, "FIXME going to queue '%s' but '%s' still pending?\n",
+ drbd_err(device, "FIXME going to queue '%s' but '%s' still pending?\n",
why, device->bm_io_work.why);
device->bm_io_work.io_fn = io_fn;
device->bm_io_work.why = why;
device->bm_io_work.flags = flags;
- spin_lock_irq(&device->tconn->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
set_bit(BITMAP_IO, &device->flags);
if (atomic_read(&device->ap_bio_cnt) == 0) {
if (!test_and_set_bit(BITMAP_IO_QUEUED, &device->flags))
- drbd_queue_work(&device->tconn->sender_work, &device->bm_io_work.w);
+ drbd_queue_work(&first_peer_device(device)->connection->sender_work, &device->bm_io_work.w);
}
- spin_unlock_irq(&device->tconn->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
}
/**
{
int rv;
- D_ASSERT(current != device->tconn->worker.task);
+ D_ASSERT(device, current != first_peer_device(device)->connection->worker.task);
if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
drbd_suspend_io(device);
/* must not double-queue! */
if (list_empty(&device->md_sync_work.list))
- drbd_queue_work_front(&device->tconn->sender_work, &device->md_sync_work);
+ drbd_queue_work_front(&first_peer_device(device)->connection->sender_work, &device->md_sync_work);
}
static int w_md_sync(struct drbd_work *w, int unused)
{
struct drbd_device *device = w->device;
- dev_warn(DEV, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
+ drbd_warn(device, "md_sync_timer expired! Worker calls drbd_md_sync().\n");
#ifdef DEBUG
- dev_warn(DEV, "last md_mark_dirty: %s:%u\n",
+ drbd_warn(device, "last md_mark_dirty: %s:%u\n",
device->last_md_mark_dirty.func, device->last_md_mark_dirty.line);
#endif
drbd_md_sync(device);
long timeout;
rcu_read_lock();
- nc = rcu_dereference(device->tconn->net_conf);
+ nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
if (!nc) {
rcu_read_unlock();
return -ETIMEDOUT;
/* Indicate to wake up device->misc_wait on progress. */
i->waiting = true;
prepare_to_wait(&device->misc_wait, &wait, TASK_INTERRUPTIBLE);
- spin_unlock_irq(&device->tconn->req_lock);
+ spin_unlock_irq(&first_peer_device(device)->connection->req_lock);
timeout = schedule_timeout(timeout);
finish_wait(&device->misc_wait, &wait);
- spin_lock_irq(&device->tconn->req_lock);
+ spin_lock_irq(&first_peer_device(device)->connection->req_lock);
if (!timeout || device->state.conn < C_CONNECTED)
return -ETIMEDOUT;
if (signal_pending(current))
fault_count++;
if (__ratelimit(&drbd_ratelimit_state))
- dev_warn(DEV, "***Simulating %s failure\n",
+ drbd_warn(device, "***Simulating %s failure\n",
_drbd_fault_str(type));
}