i += 1;
        }
 
+ out_unlock:
+       mutex_unlock(&pohmelfs_config_lock);
+       return err;
+}
+
+static int pohmelfs_cn_dump(struct cn_msg *msg)
+{
+       struct pohmelfs_config_group *g;
+       struct pohmelfs_config *c, *tmp;
+       int err = 0, i = 1;
+       int total_msg = 0;
+
+       if (msg->len != sizeof(struct pohmelfs_ctl))
+               return -EBADMSG;
+
+       mutex_lock(&pohmelfs_config_lock);
+
+       list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+               if (g)
+                       total_msg += g->num_entry;
+       }
+       if (total_msg == 0) {
+               if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+                       err = -ENOMEM;
+               goto out_unlock;
+       }
+
+       list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+               if (g) {
+                       list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+                               struct pohmelfs_ctl *sc = &c->state.ctl;
+                               if (pohmelfs_send_reply(err, total_msg - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+                                       err = -ENOMEM;
+                                       goto out_unlock;
+                               }
+                               i += 1;
+                       }
+               }
+       }
+
 out_unlock:
-        mutex_unlock(&pohmelfs_config_lock);
-        return err;
+       mutex_unlock(&pohmelfs_config_lock);
+       return err;
+}
+
+static int pohmelfs_cn_flush(struct cn_msg *msg)
+{
+       struct pohmelfs_config_group *g;
+       struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+       struct pohmelfs_config *c, *tmp;
+       int err = 0;
+
+       if (msg->len != sizeof(struct pohmelfs_ctl))
+               return -EBADMSG;
+
+       mutex_lock(&pohmelfs_config_lock);
+
+       if (ctl->idx != POHMELFS_NULL_IDX) {
+               g = pohmelfs_find_config_group(ctl->idx);
+
+               if (!g)
+                       goto out_unlock;
+
+               list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+                       list_del(&c->config_entry);
+                       g->num_entry--;
+                       kfree(c);
+               }
+       } else {
+               list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+                       if (g) {
+                               list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+                                       list_del(&c->config_entry);
+                                       g->num_entry--;
+                                       kfree(c);
+                               }
+                       }
+               }
+       }
+
+out_unlock:
+       mutex_unlock(&pohmelfs_config_lock);
+       pohmelfs_cn_dump(msg);
+
+       return err;
 }
 
 static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
 
        list_add_tail(&c->config_entry, &g->config_list);
 
-out_unlock:
+ out_unlock:
        mutex_unlock(&pohmelfs_config_lock);
        if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
                err = -ENOMEM;
        return 0;
 }
 
-
 static int pohmelfs_cn_crypto(struct cn_msg *msg)
 {
        struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
                case POHMELFS_FLAGS_MODIFY:
                        err = pohmelfs_cn_ctl(msg, msg->flags);
                        break;
+               case POHMELFS_FLAGS_FLUSH:
+                       err = pohmelfs_cn_flush(msg);
+                       break;
                case POHMELFS_FLAGS_SHOW:
                        err = pohmelfs_cn_disp(msg);
                        break;
+               case POHMELFS_FLAGS_DUMP:
+                       err = pohmelfs_cn_dump(msg);
+                       break;
                case POHMELFS_FLAGS_CRYPTO:
                        err = pohmelfs_cn_crypto(msg);
                        break;
 
 int __init pohmelfs_config_init(void)
 {
-       return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+       /* XXX remove (void *) cast when vanilla connector got synced */
+       return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
 }
 
 void pohmelfs_config_exit(void)
 
                                        timeout);
                        if (!err)
                                err = -ETIMEDOUT;
-                       else
+                       else if (err > 0)
                                err = complete.error;
                        break;
                default:
                        psb->wait_on_page_timeout);
        if (!err)
                err = -ETIMEDOUT;
-       else
+       else if (err > 0)
                err = -psb->flags;
 
        if (!err)
 
                        test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
        dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
        if (ret <= 0) {
-               err = -ETIMEDOUT;
+               err = ret;
+               if (!err)
+                       err = -ETIMEDOUT;
                goto err_out_exit;
        }
 
        err = 0;
        ret = wait_event_interruptible_timeout(psb->wait,
                        !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
-       if (ret == 0)
-               err = -ETIMEDOUT;
-       else if (signal_pending(current))
-               err = -EINTR;
+       if (ret <= 0) {
+               err = ret;
+               if (!err)
+                       err = -ETIMEDOUT;
+       }
 
        if (err)
                goto err_out_exit;
        struct pohmelfs_name *n;
        struct inode *inode = NULL;
        unsigned long ino = 0;
-       int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+       int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1;
        struct qstr str = dentry->d_name;
 
        if ((nd->intent.open.flags & O_ACCMODE) > 1)
                lock_type = POHMELFS_WRITE_LOCK;
 
-       need_lock = pohmelfs_need_lock(parent, lock_type);
+       if (test_bit(NETFS_INODE_OWNED, &parent->state)) {
+               if (lock_type == parent->lock_type)
+                       need_lock = 0;
+               if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK))
+                       need_lock = 0;
+       }
+
+       if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state))
+               need_lock = 1;
 
        str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
 
 
                inode->i_sb->s_op->write_inode(inode, 0);
        }
 
+#ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH
        truncate_inode_pages(inode->i_mapping, 0);
+#endif
 
        pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
        mutex_unlock(&inode->i_mutex);
        err = wait_event_interruptible_timeout(psb->wait,
                        (psb->flags != ~0),
                        psb->wait_on_page_timeout);
-       if (!err) {
+       if (!err)
                err = -ETIMEDOUT;
-       } else {
+       else if (err > 0)
                err = -psb->flags;
-       }
 
        if (err)
                goto err_out_exit;
 
 
        if (st->socket->ops->family == AF_INET) {
                struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
-               printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
-                       NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+               printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
+                       &sin->sin_addr.s_addr, ntohs(sin->sin_port));
        } else if (st->socket->ops->family == AF_INET6) {
                struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
-               printk(KERN_INFO "%s: (re)connected to peer "
-                       "%pi6:%d",
-                       __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+               printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
+                               &sin->sin6_addr, ntohs(sin->sin6_port));
        }
 
        return 0;
 
                if (st->socket->ops->family == AF_INET) {
                        struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
-                       printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
-                               NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+                       printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
+                               &sin->sin_addr.s_addr, ntohs(sin->sin_port));
                } else if (st->socket->ops->family == AF_INET6) {
                        struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
-                       printk("%s: disconnected from peer "
-                               "%pi6:%d",
-                               __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+                       printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
+                               &sin->sin6_addr, ntohs(sin->sin6_port));
                }
 
                sock_release(st->socket);
 
 #define POHMELFS_CTLINFO_ACK           1
 #define POHMELFS_NOINFO_ACK            2
 
+#define POHMELFS_NULL_IDX              65535
 
 /*
  * Network command structure.
        POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
        POHMELFS_FLAGS_CRYPTO,  /* Crypto data control message */
        POHMELFS_FLAGS_MODIFY,  /* Network state modification message */
+       POHMELFS_FLAGS_DUMP,    /* Network state control message for SHOW ALL */
+       POHMELFS_FLAGS_FLUSH,   /* Network state control message for FLUSH */
 };
 
 /*
                pohmelfs_mcache_free(psb, m);
 }
 
+//#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
+
 #endif /* __KERNEL__*/
 
 #endif /* __NETFS_H */
 
                                continue;
                }
 
-               if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio))
+               if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) &&
+                               (t->flags & NETFS_TRANS_SINGLE_DST))
                        st = &psb->active_state->state;
 
                err = netfs_trans_push(t, st);