Staging: Pohmelfs: Added IO permissions and priorities.
Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
f2739de191
commit
e0ca873916
5 changed files with 86 additions and 32 deletions
|
@ -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
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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 {
|
||||||
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)
|
||||||
__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",
|
||||||
|
|
Loading…
Reference in a new issue