drbd: Introduce new primitives for sending commands
authorAndreas Gruenbacher <agruen@linbit.com>
Tue, 29 Mar 2011 14:55:40 +0000 (16:55 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 8 Nov 2012 15:45:07 +0000 (16:45 +0100)
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c

index aa42ccb5f544cd01a37af5a1da5701c0bef528be..632ca9aecef394a786a7ca9ca5f5b74d6d2ad35f 100644 (file)
@@ -1903,6 +1903,15 @@ static inline int drbd_send_short_cmd(struct drbd_conf *mdev,
        return drbd_send_cmd(mdev, &mdev->tconn->data, cmd, &h, sizeof(h));
 }
 
+extern void *conn_prepare_command(struct drbd_tconn *, struct drbd_socket *);
+extern void *drbd_prepare_command(struct drbd_conf *, struct drbd_socket *);
+extern int conn_send_command(struct drbd_tconn *, struct drbd_socket *,
+                            enum drbd_packet, unsigned int, void *,
+                            unsigned int);
+extern int drbd_send_command(struct drbd_conf *, struct drbd_socket *,
+                            enum drbd_packet, unsigned int, void *,
+                            unsigned int);
+
 extern int drbd_send_ping(struct drbd_tconn *tconn);
 extern int drbd_send_ping_ack(struct drbd_tconn *tconn);
 
index 7e766ff94e1ae65aebc4306df310a73b127cd7c8..699ab11256beb9bb1605514bb4a3b7d5b86370a5 100644 (file)
@@ -765,6 +765,70 @@ int conn_send_cmd2(struct drbd_tconn *tconn, enum drbd_packet cmd, char *data,
        return err;
 }
 
+void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock)
+{
+       mutex_lock(&sock->mutex);
+       if (!sock->socket) {
+               mutex_unlock(&sock->mutex);
+               return NULL;
+       }
+       return sock->sbuf;
+}
+
+void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock)
+{
+       return conn_prepare_command(mdev->tconn, sock);
+}
+
+static int __send_command(struct drbd_tconn *tconn, int vnr,
+                         struct drbd_socket *sock, enum drbd_packet cmd,
+                         unsigned int header_size, void *data,
+                         unsigned int size)
+{
+       int msg_flags;
+       int err;
+
+       /*
+        * Called with @data == NULL and the size of the data blocks in @size
+        * for commands that send data blocks.  For those commands, omit the
+        * MSG_MORE flag: this will increase the likelihood that data blocks
+        * which are page aligned on the sender will end up page aligned on the
+        * receiver.
+        */
+       msg_flags = data ? MSG_MORE : 0;
+
+       _prepare_header(tconn, vnr, sock->sbuf, cmd,
+                       header_size - sizeof(struct p_header) + size);
+       err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size,
+                           msg_flags);
+       if (data && !err)
+               err = drbd_send_all(tconn, sock->socket, data, size, 0);
+       return err;
+}
+
+int conn_send_command(struct drbd_tconn *tconn, struct drbd_socket *sock,
+                     enum drbd_packet cmd, unsigned int header_size,
+                     void *data, unsigned int size)
+{
+       int err;
+
+       err = __send_command(tconn, 0, sock, cmd, header_size, data, size);
+       mutex_unlock(&sock->mutex);
+       return err;
+}
+
+int drbd_send_command(struct drbd_conf *mdev, struct drbd_socket *sock,
+                     enum drbd_packet cmd, unsigned int header_size,
+                     void *data, unsigned int size)
+{
+       int err;
+
+       err = __send_command(mdev->tconn, mdev->vnr, sock, cmd, header_size,
+                            data, size);
+       mutex_unlock(&sock->mutex);
+       return err;
+}
+
 int drbd_send_ping(struct drbd_tconn *tconn)
 {
        struct p_header h;
This page took 0.030477 seconds and 5 git commands to generate.