Commit e0ca8739 authored by Evgeniy Polyakov's avatar Evgeniy Polyakov Committed by Greg Kroah-Hartman

Staging: Pohmelfs: Added IO permissions and priorities.

Signed-off-by: default avatarEvgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f2739de1
...@@ -56,9 +56,10 @@ workloads and can fully utilize the bandwidth to the servers when doing bulk ...@@ -56,9 +56,10 @@ workloads and can fully utilize the bandwidth to the servers when doing bulk
data transfers. data transfers.
POHMELFS clients operate with a working set of servers and are capable of balancing read-only POHMELFS clients operate with a working set of servers and are capable of balancing read-only
operations (like lookups or directory listings) between them. operations (like lookups or directory listings) between them according to IO priorities.
Administrators can add or remove servers from the set at run-time via special commands (described Administrators can add or remove servers from the set at run-time via special commands (described
in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers. in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers, which are connected
with write permission turned on. IO priority and permissions can be changed in run-time.
POHMELFS is capable of full data channel encryption and/or strong crypto hashing. POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
One can select any kernel supported cipher, encryption mode, hash type and operation mode One can select any kernel supported cipher, encryption mode, hash type and operation mode
......
POHMELFS usage information. POHMELFS usage information.
Mount options: Mount options.
All but index, number of crypto threads and maximum IO size can changed via remount.
idx=%u idx=%u
Each mountpoint is associated with a special index via this option. Each mountpoint is associated with a special index via this option.
Administrator can add or remove servers from the given index, so all mounts, Administrator can add or remove servers from the given index, so all mounts,
...@@ -52,16 +54,27 @@ mcache_timeout=%u ...@@ -52,16 +54,27 @@ mcache_timeout=%u
Usage examples. Usage examples.
Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx Add server server1.net:1025 into the working set with index $idx
with appropriate hash algorithm and key file and cipher algorithm, mode and key file: with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
$cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key $cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
Mount filesystem with given index $idx to /mnt mountpoint. Mount filesystem with given index $idx to /mnt mountpoint.
Client will connect to all servers specified in the working set via previous command: Client will connect to all servers specified in the working set via previous command:
mount -t pohmel -o idx=$idx q /mnt mount -t pohmel -o idx=$idx q /mnt
One can add or remove servers from working set after mounting too. Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw):
$cfg A modify -a server1.net -p 1025 -i $idx -I 1
Change IO priority to 123 (node with the highest priority gets read requests).
$cfg A modify -a server1.net -p 1025 -i $idx -P 123
One can check currect status of all connections in the mountstats file:
# cat /proc/$PID/mountstats
...
device none mounted on /mnt with fstype pohmel
idx addr(:port) socket_type protocol active priority permissions
0 server1.net:1026 1 6 1 250 1
0 server2.net:1025 1 6 1 123 3
Server installation. Server installation.
......
...@@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned ...@@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned
return g; return g;
} }
static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst)
{
struct pohmelfs_config *tmp;
INIT_LIST_HEAD(&dst->config_entry);
list_for_each_entry(tmp, &psb->state_list, config_entry) {
if (dst->state.ctl.prio > tmp->state.ctl.prio)
list_add_tail(&dst->config_entry, &tmp->config_entry);
}
if (list_empty(&dst->config_entry))
list_add_tail(&dst->config_entry, &psb->state_list);
}
static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb,
struct pohmelfs_config *dst, struct pohmelfs_config *new)
{
if ((dst->state.ctl.prio == new->state.ctl.prio) &&
(dst->state.ctl.perm == new->state.ctl.perm))
return 0;
dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n",
__func__, dst->state.ctl.prio, dst->state.ctl.perm,
new->state.ctl.prio, new->state.ctl.perm);
dst->state.ctl.prio = new->state.ctl.prio;
dst->state.ctl.perm = new->state.ctl.perm;
list_del_init(&dst->config_entry);
pohmelfs_insert_config_entry(psb, dst);
return 0;
}
/*
* pohmelfs_copy_config() is used to copy new state configs from the
* config group (controlled by the netlink messages) into the superblock.
* This happens either at startup time where no transactions can access
* the list of the configs (and thus list of the network states), or at
* run-time, where it is protected by the psb->state_lock.
*/
int pohmelfs_copy_config(struct pohmelfs_sb *psb) int pohmelfs_copy_config(struct pohmelfs_sb *psb)
{ {
struct pohmelfs_config_group *g; struct pohmelfs_config_group *g;
...@@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) ...@@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)
err = 0; err = 0;
list_for_each_entry(dst, &psb->state_list, config_entry) { list_for_each_entry(dst, &psb->state_list, config_entry) {
if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
err = -EEXIST; err = pohmelfs_move_config_entry(psb, dst, c);
if (!err)
err = -EEXIST;
break; break;
} }
} }
...@@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) ...@@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)
memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
list_add_tail(&dst->config_entry, &psb->state_list); pohmelfs_insert_config_entry(psb, dst);
err = pohmelfs_state_init_one(psb, dst); err = pohmelfs_state_init_one(psb, dst);
if (err) { if (err) {
...@@ -248,6 +289,13 @@ static int pohmelfs_cn_disp(struct cn_msg *msg) ...@@ -248,6 +289,13 @@ static int pohmelfs_cn_disp(struct cn_msg *msg)
return err; return err;
} }
static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
{
old->perm = new->perm;
old->prio = new->prio;
return 0;
}
static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
{ {
struct pohmelfs_config_group *g; struct pohmelfs_config_group *g;
...@@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) ...@@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
g->num_entry--; g->num_entry--;
kfree(c); kfree(c);
goto out_unlock; goto out_unlock;
} else if (action == POHMELFS_FLAGS_MODIFY) {
err = pohmelfs_modify_config(sc, ctl);
goto out_unlock;
} else { } else {
err = -EEXIST; err = -EEXIST;
goto out_unlock; goto out_unlock;
...@@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) ...@@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
} }
memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
g->num_entry++; g->num_entry++;
list_add_tail(&c->config_entry, &g->config_list); list_add_tail(&c->config_entry, &g->config_list);
out_unlock: out_unlock:
...@@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data) ...@@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data)
switch (msg->flags) { switch (msg->flags) {
case POHMELFS_FLAGS_ADD: case POHMELFS_FLAGS_ADD:
err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
break;
case POHMELFS_FLAGS_DEL: case POHMELFS_FLAGS_DEL:
err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL); case POHMELFS_FLAGS_MODIFY:
err = pohmelfs_cn_ctl(msg, msg->flags);
break; break;
case POHMELFS_FLAGS_SHOW: case POHMELFS_FLAGS_SHOW:
err = pohmelfs_cn_disp(msg); err = pohmelfs_cn_disp(msg);
......
...@@ -87,6 +87,7 @@ enum { ...@@ -87,6 +87,7 @@ enum {
POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ POHMELFS_FLAGS_DEL, /* Network state control message for DEL */
POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */
POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */
POHMELFS_FLAGS_MODIFY, /* Network state modification message */
}; };
/* /*
......
...@@ -456,34 +456,22 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb) ...@@ -456,34 +456,22 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
__func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
#endif #endif
mutex_lock(&psb->state_lock); mutex_lock(&psb->state_lock);
if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) {
st = &psb->active_state->state;
err = -EPIPE;
if (netfs_state_poll(st) & POLLOUT) {
err = netfs_trans_push_dst(t, st);
if (!err) {
err = netfs_trans_send(t, st);
if (err) {
netfs_trans_drop_last(t, st);
} else {
pohmelfs_switch_active(psb);
goto out;
}
}
}
pohmelfs_switch_active(psb);
}
list_for_each_entry(c, &psb->state_list, config_entry) { list_for_each_entry(c, &psb->state_list, config_entry) {
st = &c->state; st = &c->state;
if (t->flags & NETFS_TRANS_SINGLE_DST) {
if (!(st->ctl.perm & POHMELFS_IO_PERM_READ))
continue;
} else {
if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE))
continue;
}
err = netfs_trans_push(t, st); err = netfs_trans_push(t, st);
if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
break; break;
} }
out:
mutex_unlock(&psb->state_lock); mutex_unlock(&psb->state_lock);
#if 0 #if 0
dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment