[Devel] [PATCH RHEL8 COMMIT] fs/fuse kio: drop external cs connection

Konstantin Khorenko khorenko at virtuozzo.com
Thu Oct 15 10:37:33 MSK 2020


The commit is pushed to "branch-rh8-4.18.0-193.6.3.vz8.4.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-193.6.3.vz8.4.13
------>
commit b3b28a9c02b22324658228e085ae948493b4033f
Author: Pavel Butsykin <pbutsykin at virtuozzo.com>
Date:   Thu Oct 15 10:37:33 2020 +0300

    fs/fuse kio: drop external cs connection
    
    Remove the old implementation of creating cs connection through usermode.
    
    https://pmc.acronis.com/browse/VSTOR-4310
    
    Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_cluster.h      |   1 -
 fs/fuse/kio/pcs/pcs_cs.c           |  17 +----
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 132 -------------------------------------
 fs/fuse/kio/pcs/pcs_ioctl.h        |  11 ----
 fs/fuse/kio/pcs/pcs_rpc.c          |  35 ----------
 fs/fuse/kio/pcs/pcs_rpc.h          |   1 -
 fs/fuse/kio/pcs/pcs_sock_conn.c    |   2 +-
 fs/fuse/kio/pcs/pcs_sock_io.c      |  81 ++---------------------
 fs/fuse/kio/pcs/pcs_sock_io.h      |   4 +-
 9 files changed, 10 insertions(+), 274 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_cluster.h b/fs/fuse/kio/pcs/pcs_cluster.h
index 65b34f8b657f..fd7ad76b70c6 100644
--- a/fs/fuse/kio/pcs/pcs_cluster.h
+++ b/fs/fuse/kio/pcs/pcs_cluster.h
@@ -120,7 +120,6 @@ void pcs_cc_fini(struct pcs_cluster_core *cc);
 
 void pcs_fuse_prep_io(struct pcs_fuse_req *r, unsigned short type, off_t offset, size_t size, u64 aux);
 void pcs_fuse_prep_fallocate(struct pcs_fuse_req *r);
-int fuse_pcs_csconn_send(struct fuse_conn *fc, struct pcs_rpc *ep, int flags);
 
 
 static inline void pcs_cc_set_abort_timeout(struct pcs_cluster_core *cc, int timeout)
diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c
index 79b11a52c438..7ecd54fcf494 100644
--- a/fs/fuse/kio/pcs/pcs_cs.c
+++ b/fs/fuse/kio/pcs/pcs_cs.c
@@ -35,8 +35,7 @@ static void cs_aborting(struct pcs_rpc *ep, int error);
 static struct pcs_msg *cs_get_hdr(struct pcs_rpc *ep, struct pcs_rpc_hdr *h);
 static int cs_input(struct pcs_rpc *ep, struct pcs_msg *msg);
 static void cs_keep_waiting(struct pcs_rpc *ep, struct pcs_msg *req, struct pcs_msg *msg);
-static void cs_user_connect(struct pcs_rpc *ep);
-static void cs_kernel_connect(struct pcs_rpc *ep);
+static void cs_connect(struct pcs_rpc *ep);
 static void pcs_cs_isolate(struct pcs_cs *cs, struct list_head *dispose);
 static void pcs_cs_destroy(struct pcs_cs *cs);
 
@@ -45,7 +44,7 @@ struct pcs_rpc_ops cn_rpc_ops = {
 	.get_hdr		= cs_get_hdr,
 	.state_change		= cs_aborting,
 	.keep_waiting		= cs_keep_waiting,
-	.connect		= cs_kernel_connect,
+	.connect		= cs_connect,
 };
 
 static int pcs_cs_percpu_stat_alloc(struct pcs_cs *cs)
@@ -436,7 +435,7 @@ static void cs_get_read_response_iter(struct pcs_msg *msg, int offset, struct io
 	}
 }
 
-static void cs_kernel_connect(struct pcs_rpc *ep)
+static void cs_connect(struct pcs_rpc *ep)
 {
 	if (ep->flags & PCS_RPC_F_LOCAL) {
 		char path[128];
@@ -475,16 +474,6 @@ static void cs_kernel_connect(struct pcs_rpc *ep)
 	return;
 }
 
-__maybe_unused static void cs_user_connect(struct pcs_rpc *ep)
-{
-	struct pcs_cluster_core *cc = cc_from_rpc(ep->eng);
-	struct pcs_fuse_cluster *pfc = pcs_cluster_from_cc(cc);
-
-	ep->state = PCS_RPC_CONNECT;
-	if (fuse_pcs_csconn_send(pfc->fc, ep, PCS_IOC_CS_OPEN))
-		pcs_rpc_reset(ep);
-}
-
 static struct pcs_msg *cs_get_hdr(struct pcs_rpc *ep, struct pcs_rpc_hdr *h)
 {
 	struct pcs_msg *msg, *resp;
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index e5f417387572..9a40434ba841 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -564,137 +564,6 @@ int fuse_map_resolve(struct pcs_map_entry *m, int direction)
 
 	return 0;
 }
-static void pfocess_pcs_csconn_work(struct work_struct *w)
-{
-	struct pcs_fuse_work *work = container_of(w, struct pcs_fuse_work, work);
-	struct pcs_rpc *ep  = (struct pcs_rpc *)work->ctx;
-	struct socket *sock = (struct socket *)work->ctx2;
-	BUG_ON(!ep);
-
-	if (pcs_if_error(&work->status)) {
-		mutex_lock(&ep->mutex);
-		pcs_rpc_reset(ep);
-		mutex_unlock(&ep->mutex);
-		TRACE(PEER_FMT" fail with %d\n", PEER_ARGS(ep), work->status.value);
-	} else	{
-		if (sock)
-			rpc_connect_done(ep, sock);
-	}
-	pcs_rpc_put(ep);
-	kfree(work);
-}
-
-static void process_pcs_csconn_reply(struct fuse_conn *fc, struct fuse_args *args,
-				     int error)
-{
-	struct fuse_io_args *ia = container_of(args, typeof(*ia), ap.args);
-	struct pcs_ioc_csconn *csconn = (struct pcs_ioc_csconn *)args->in_args[1].value;
-	struct fuse_ioctl_out *arg = &ia->ioctl.out;
-	struct pcs_fuse_work *work = (struct pcs_fuse_work*) ia->ioctl.ctx;
-	int is_open = csconn->flags & PCS_IOC_CS_OPEN;
-
-	if (error || arg->result < 0) {
-		pcs_set_local_error(&work->status, PCS_ERR_PROTOCOL);
-		goto out;
-	}
-	/* Grab socket from caller's context (fuse-evloop) and do the rest in kwork */
-	if (is_open) {
-		struct socket *sock;
-		struct file* filp;
-		int err;
-
-		filp = fget((unsigned int)arg->result);
-		arg->result = 0;
-		if (!filp) {
-			pcs_set_local_error(&work->status, PCS_ERR_PROTOCOL);
-			goto out;
-		}
-		sock = sock_from_file(filp, &err);
-		if (!sock) {
-			fput(filp);
-			pcs_set_local_error(&work->status, PCS_ERR_PROTOCOL);
-		} else
-			TRACE("id: "NODE_FMT" sock:%p\n", NODE_ARGS(csconn->id), sock);
-		work->ctx2 = sock;
-	}
-out:
-	kfree(csconn);
-	pcs_fuse_reply_handle(fc, args, error);
-
-}
-
-int fuse_pcs_csconn_send(struct fuse_conn *fc, struct pcs_rpc *ep, int flags)
-{
-	struct fuse_io_args *ia;
-	struct fuse_ioctl_in *inarg;
-	struct fuse_ioctl_out *outarg;
-	struct pcs_ioc_csconn *csconn;
-	struct pcs_fuse_work *reply_work;
-	int err;
-
-	/* Socket must being freed from kernelspace before requesting new one*/
-	BUG_ON(!(flags & PCS_IOC_CS_REOPEN));
-
-	TRACE("start %s cmd:%ld id:%lld flags:%x\n", __FUNCTION__,
-	      PCS_IOC_CSCONN, ep->peer_id.val, flags);
-
-	csconn = kzalloc(sizeof(*csconn), GFP_NOIO);
-	if (!csconn)
-		return -ENOMEM;
-
-	reply_work = kzalloc(sizeof(*reply_work), GFP_NOIO);
-	if (!reply_work) {
-		kfree(csconn);
-		return -ENOMEM;
-	}
-
-	ia = kzalloc(sizeof(*ia), GFP_NOIO);
-	if (!ia) {
-		kfree(csconn);
-		kfree(reply_work);
-		return -ENOMEM;
-	}
-
-	ia->ap.args.kio_internal = true;
-	inarg = &ia->ioctl.in;
-	outarg = &ia->ioctl.out;
-
-	inarg->cmd = PCS_IOC_CSCONN;
-	inarg->fh = 0;
-	inarg->arg = 0;
-	inarg->flags = 0;
-
-	csconn->id.val = ep->peer_id.val;
-	memcpy(&csconn->address, &ep->addr, sizeof(ep->addr));
-	csconn->flags = flags;
-
-	if (ep->flags & PCS_RPC_F_LOCAL)
-		csconn->address.type = PCS_ADDRTYPE_UNIX;
-
-	ia->ap.args.opcode = FUSE_IOCTL;
-	ia->ap.args.in_numargs = 2;
-	ia->ap.args.in_args[0].size = sizeof(*inarg);
-	ia->ap.args.in_args[0].value = inarg;
-	ia->ap.args.in_args[1].size = sizeof(*csconn);
-	ia->ap.args.in_args[1].value = csconn;
-
-	ia->ap.args.out_numargs = 1;
-	ia->ap.args.out_args[0].size = sizeof(*outarg);
-	ia->ap.args.out_args[0].value = outarg;
-
-	INIT_WORK(&reply_work->work, pfocess_pcs_csconn_work);
-	reply_work->ctx = pcs_rpc_get(ep);
-	reply_work->ctx2 = NULL; /* return socket should be here */
-	ia->ioctl.ctx = reply_work;
-
-	ia->ap.args.end = process_pcs_csconn_reply;
-	ia->ap.args.nonblocking = true;
-	err = fuse_simple_background(fc, &ia->ap.args, GFP_NOIO);
-	if (err)
-		process_pcs_csconn_reply(fc, &ia->ap.args, err);
-
-	return 0;
-}
 
 struct fuse_req *kpcs_req_alloc(struct fuse_conn *fc, gfp_t flags)
 {
@@ -1268,7 +1137,6 @@ static int pcs_kio_classify_req(struct fuse_conn *fc, struct fuse_req *req, bool
 			case PCS_IOC_NOWRITEDELAY:
 				return -EOPNOTSUPP;
 			case PCS_IOC_INIT_KDIRECT:
-			case PCS_IOC_CSCONN:
 			case PCS_IOC_GETFILEINFO:
 			case PCS_IOC_KDIRECT_CLAIM:
 			case PCS_IOC_KDIRECT_RELEASE:
diff --git a/fs/fuse/kio/pcs/pcs_ioctl.h b/fs/fuse/kio/pcs/pcs_ioctl.h
index b86d670466cc..3c646b1df489 100644
--- a/fs/fuse/kio/pcs/pcs_ioctl.h
+++ b/fs/fuse/kio/pcs/pcs_ioctl.h
@@ -69,23 +69,12 @@ struct pcs_ioc_getmap
 	struct pcs_cs_info	cs[0];		/* Array of CS including root */
 };
 
-struct pcs_ioc_csconn
-{
-	PCS_NODE_ID_T		id;
-	PCS_NET_ADDR_T		address;
-	u32			flags;
-#define PCS_IOC_CS_OPEN		0x1
-#define PCS_IOC_CS_CLOSE	0x2
-#define PCS_IOC_CS_REOPEN	(PCS_IOC_CS_OPEN|PCS_IOC_CS_CLOSE)
-};
-
 #define PCS_IOC_NOCSUMONREAD	_IOW('V',3,u32)
 # define PCS_IOC_NOCSUMONREAD_DATA	1
 # define PCS_IOC_NOCSUMONREAD_METADATA	2
 #define PCS_IOC_NOWRITEDELAY	_IOW('V',4,u32)
 
 #define PCS_IOC_INIT_KDIRECT	_IOR('V',32, struct pcs_ioc_init_kdirect)
-#define PCS_IOC_CSCONN		_IOR('V',33, struct pcs_ioc_csconn)
 #define PCS_IOC_GETFILEINFO	_IOR('V',34, struct pcs_ioc_fileinfo)
 #define PCS_IOC_KDIRECT_CLAIM	_IO('V',35)
 #define PCS_IOC_KDIRECT_RELEASE _IO('V',36)
diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c
index b419915bddc1..d2ad9537418a 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.c
+++ b/fs/fuse/kio/pcs/pcs_rpc.c
@@ -1402,41 +1402,6 @@ void pcs_rpc_set_memlimits(struct pcs_rpc_engine * eng, u64 thresh, u64 limit)
 	eng->mem_limit = limit;
 }
 
-void rpc_connect_done(struct pcs_rpc *ep, struct socket *sock)
-{
-	struct pcs_sockio * sio;
-
-	mutex_lock(&ep->mutex);
-
-	TRACE(PEER_FMT " ->state:%d sock:%p\n", PEER_ARGS(ep), ep->state, sock);
-	cancel_delayed_work(&ep->timer_work);
-
-	if (ep->state != PCS_RPC_CONNECT) {
-		FUSE_KLOG(cc_from_rpc(ep->eng)->fc, LOG_ERR, "Invalid state: %u", ep->state);
-		BUG();
-	}
-
-	sio = pcs_sockio_init(sock, ep->params.alloc_hdr_size,
-			      sizeof(struct pcs_rpc_hdr));
-	if (sio == NULL)
-		BUG();
-
-	ep->conn = &sio->ioconn;
-	sio->parent = pcs_rpc_get(ep);
-	sio->get_msg = rpc_get_hdr;
-	sio->eof = rpc_eof_cb;
-	//pcs_ioconn_register(ep->conn);
-	if (ep->gc)
-		list_lru_add(&ep->gc->lru, &ep->lru_link);
-
-	if (ep->flags & PCS_RPC_F_CLNT_PEER_ID)
-		ep->flags |= PCS_RPC_F_PEER_ID;
-	ep->state = PCS_RPC_APPWAIT;
-	pcs_rpc_enable(ep, 0);
-	mutex_unlock(&ep->mutex);
-
-}
-
 static const char *s_rpc_state_names[] = {
 	[PCS_RPC_UNCONN]	= "UNCONN",	/* Not connected */
 	[PCS_RPC_CONNECT]	= "CONNECT",	/* Connect in progress */
diff --git a/fs/fuse/kio/pcs/pcs_rpc.h b/fs/fuse/kio/pcs/pcs_rpc.h
index b0b9b42f2349..ffa08cce7a18 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.h
+++ b/fs/fuse/kio/pcs/pcs_rpc.h
@@ -299,7 +299,6 @@ int pcs_cluster_id_eq(PCS_CLUSTER_ID_T *id1, PCS_CLUSTER_ID_T *id2);
 void rpc_trace_health(struct pcs_rpc * ep);
 void pcs_rpc_enumerate_rpc(struct pcs_rpc_engine *eng, void (*cb)(struct pcs_rpc *ep, void *arg), void *arg);
 void pcs_rpc_set_sock(struct pcs_rpc *ep, struct pcs_sockio * sio);
-void rpc_connect_done(struct pcs_rpc *ep, struct socket *sock);
 void pcs_rpc_enable(struct pcs_rpc * ep, int error);
 void rpc_eof_cb(struct pcs_sockio *sio);
 
diff --git a/fs/fuse/kio/pcs/pcs_sock_conn.c b/fs/fuse/kio/pcs/pcs_sock_conn.c
index bee9972dec17..039fcf80dea6 100644
--- a/fs/fuse/kio/pcs/pcs_sock_conn.c
+++ b/fs/fuse/kio/pcs/pcs_sock_conn.c
@@ -622,7 +622,7 @@ void pcs_sockconnect_start(struct pcs_rpc *ep)
 	sio->eof = rpc_eof_cb;
 	sio->send_timeout = PCS_SIO_TIMEOUT;
 	sio->ioconn.socket = sock;
-	sio->ioconn.destruct = pcs_sock_internal_ioconn_destruct;
+	sio->ioconn.destruct = pcs_sock_ioconn_destruct;
 	if (ep->gc)
 		list_lru_add(&ep->gc->lru, &ep->lru_link);
 
diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c
index 80b32415664a..4191943540a3 100644
--- a/fs/fuse/kio/pcs/pcs_sock_io.c
+++ b/fs/fuse/kio/pcs/pcs_sock_io.c
@@ -36,11 +36,6 @@ void sio_push(struct pcs_sockio * sio)
 	}
 }
 
-//// TODO:dmonakhov@ implement unregister and close,
-//// socket close must being synchronized with userspace THINK
-//// caseA: userspace close socket and wait for kernelspace
-//// caseB: kernelspace want to close socket and have to somehow
-////	    notify about this to userspace (NEW API REQUIRED)
 static void pcs_ioconn_unregister(struct pcs_ioconn *ioconn)
 {
 	if (!test_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags))
@@ -503,11 +498,11 @@ static void sio_destroy_rcu(struct rcu_head *head)
 	kfree(sio);
 }
 
-static void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn, bool internal)
+void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn)
 {
 	struct pcs_sockio * sio = sio_from_ioconn(ioconn);
 
-	TRACE("Sock destruct_cb, sio: %p, internal: %d", sio, internal);
+	TRACE("Sock destruct_cb, sio: %p", sio);
 
 	BUG_ON(sio->current_msg);
 	BUG_ON(!list_empty(&sio->write_queue));
@@ -515,10 +510,7 @@ static void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn, bool internal)
 
 	if (ioconn->socket) {
 		pcs_restore_sockets(ioconn);
-		if (internal)
-			sock_release(ioconn->socket);
-		else
-			fput(ioconn->socket->file);
+		sock_release(ioconn->socket);
 		ioconn->socket = NULL;
 	}
 
@@ -526,21 +518,11 @@ static void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn, bool internal)
 	call_rcu(&sio->rcu, sio_destroy_rcu);
 }
 
-void pcs_sock_internal_ioconn_destruct(struct pcs_ioconn *ioconn)
-{
-	pcs_sock_ioconn_destruct(ioconn, true);
-}
-
-void pcs_sock_external_ioconn_destruct(struct pcs_ioconn *ioconn)
-{
-	pcs_sock_ioconn_destruct(ioconn, false);
-}
-
 static void pcs_sk_kick_queue(struct sock *sk)
 {
 	struct pcs_sockio *sio;
 
-	smp_rmb(); /* Pairs with smp_wmb() in pcs_sockio_init() */
+	smp_rmb(); /* Pairs with smp_wmb() in pcs_sockconnect_start() */
 
 	rcu_read_lock();
 	sio = rcu_dereference_sk_user_data(sk);
@@ -566,7 +548,7 @@ void pcs_sk_error_report(struct sock *sk)
 {
 	struct pcs_sockio *sio;
 
-	smp_rmb(); /* Pairs with smp_wmb() in pcs_sockio_init() */
+	smp_rmb(); /* Pairs with smp_wmb() in pcs_sockconnect_start() */
 
 	rcu_read_lock();
 	sio = rcu_dereference_sk_user_data(sk);
@@ -584,59 +566,6 @@ void pcs_sk_error_report(struct sock *sk)
 	rcu_read_unlock();
 }
 
-struct pcs_sockio * pcs_sockio_init(struct socket *sock,
-				    int alloc_max, int hdr_max)
-{
-	struct pcs_sockio * sio;
-	struct sock *sk;
-
-	sio = kzalloc(sizeof(struct pcs_sockio) + alloc_max, GFP_NOIO);
-	if (!sio)
-		return NULL;
-
-	INIT_LIST_HEAD(&sio->write_queue);
-	iov_iter_kvec(&sio->read_iter, READ, NULL, 0, 0);
-	iov_iter_kvec(&sio->write_iter, WRITE, NULL, 0, 0);
-	sio->hdr_max = hdr_max;
-	sio->flags = sock->sk->sk_family != AF_UNIX ? PCS_SOCK_F_CORK : 0;
-
-	//// TODO:dmonakhov init ioconn here
-	INIT_LIST_HEAD(&sio->ioconn.list);
-	sk = sock->sk;
-	write_lock_bh(&sk->sk_callback_lock);
-
-	/*
-	 * Backup original callbaks.
-	 * TCP and unix sockets do not have sk_user_data set.
-	 * So we avoid taking sk_callback_lock in callbacks,
-	 * since this seems to be able to result in performance.
-	 */
-	WARN_ON_ONCE(sk->sk_user_data);
-	sio->ioconn.orig.user_data = sk->sk_user_data;
-	sio->ioconn.orig.data_ready = sk->sk_data_ready;
-	sio->ioconn.orig.write_space = sk->sk_write_space;
-	sio->ioconn.orig.error_report = sk->sk_error_report;
-	//sio->ioconn.orig_state_change = sk->sk_state_change;
-
-	//sock->sk->sk_state_change = pcs_state_chage;
-
-	sk->sk_sndtimeo = PCS_SIO_TIMEOUT;
-	sk->sk_allocation = GFP_NOFS;
-	sio->send_timeout = PCS_SIO_TIMEOUT;
-	sio->ioconn.socket = sock;
-	sio->ioconn.destruct = pcs_sock_external_ioconn_destruct;
-
-	rcu_assign_sk_user_data(sk, sio);
-	smp_wmb(); /* Pairs with smp_rmb() in callbacks */
-	sk->sk_data_ready = pcs_sk_data_ready;
-	sk->sk_write_space = pcs_sk_write_space;
-	sk->sk_error_report = pcs_sk_error_report;
-	write_unlock_bh(&sock->sk->sk_callback_lock);
-
-	pcs_clear_error(&sio->error);
-	return sio;
-}
-
 void pcs_sockio_start(struct pcs_sockio * sio)
 {
 	//// TODO: dmonakhov
diff --git a/fs/fuse/kio/pcs/pcs_sock_io.h b/fs/fuse/kio/pcs/pcs_sock_io.h
index c0bedbd0754d..35bf12c9f53a 100644
--- a/fs/fuse/kio/pcs/pcs_sock_io.h
+++ b/fs/fuse/kio/pcs/pcs_sock_io.h
@@ -149,7 +149,6 @@ struct pcs_sockio
 
 #define sio_from_ioconn(conn) container_of(conn, struct pcs_sockio, ioconn)
 
-struct pcs_sockio * pcs_sockio_init(struct socket* sock, int alloc_max, int hdr_max);
 void pcs_sockio_start(struct pcs_sockio * sio);
 void pcs_sock_sendmsg(struct pcs_sockio * sio, struct pcs_msg *msg);
 int pcs_sock_cancel_msg(struct pcs_msg * msg);
@@ -190,8 +189,7 @@ static inline void iov_iter_get_kvec(struct iov_iter *i, struct kvec *vec)
 	iov_iter_for_each_range(i, iov_iter_single_seg_count(i),
 			iov_iter_get_kvec_callback, vec);
 }
-void pcs_sock_internal_ioconn_destruct(struct pcs_ioconn *ioconn);
-void pcs_sock_external_ioconn_destruct(struct pcs_ioconn *ioconn);
+void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn);
 
 static inline void * msg_inline_head(struct pcs_msg * msg)
 {


More information about the Devel mailing list