Skip to content

Commit

Permalink
Staging: Pohmelfs: Added IO permissions and priorities.
Browse files Browse the repository at this point in the history
Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Evgeniy Polyakov authored and Greg Kroah-Hartman committed Apr 17, 2009
1 parent f2739de commit e0ca873
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 32 deletions.
5 changes: 3 additions & 2 deletions Documentation/filesystems/pohmelfs/design_notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ workloads and can fully utilize the bandwidth to the servers when doing bulk
data transfers.

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
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.
One can select any kernel supported cipher, encryption mode, hash type and operation mode
Expand Down
21 changes: 17 additions & 4 deletions Documentation/filesystems/pohmelfs/info.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
POHMELFS usage information.

Mount options:
Mount options.
All but index, number of crypto threads and maximum IO size can changed via remount.

idx=%u
Each mountpoint is associated with a special index via this option.
Administrator can add or remove servers from the given index, so all mounts,
Expand Down Expand Up @@ -52,16 +54,27 @@ mcache_timeout=%u

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:
$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.
Client will connect to all servers specified in the working set via previous command:
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.

Expand Down
61 changes: 56 additions & 5 deletions drivers/staging/pohmelfs/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned
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)
{
struct pohmelfs_config_group *g;
Expand All @@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)
err = 0;
list_for_each_entry(dst, &psb->state_list, config_entry) {
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;
}
}
Expand All @@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb)

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);
if (err) {
Expand Down Expand Up @@ -248,6 +289,13 @@ static int pohmelfs_cn_disp(struct cn_msg *msg)
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)
{
struct pohmelfs_config_group *g;
Expand Down Expand Up @@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
g->num_entry--;
kfree(c);
goto out_unlock;
} else if (action == POHMELFS_FLAGS_MODIFY) {
err = pohmelfs_modify_config(sc, ctl);
goto out_unlock;
} else {
err = -EEXIST;
goto out_unlock;
Expand All @@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
}
memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
g->num_entry++;

list_add_tail(&c->config_entry, &g->config_list);

out_unlock:
Expand Down Expand Up @@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data)

switch (msg->flags) {
case POHMELFS_FLAGS_ADD:
err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
break;
case POHMELFS_FLAGS_DEL:
err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL);
case POHMELFS_FLAGS_MODIFY:
err = pohmelfs_cn_ctl(msg, msg->flags);
break;
case POHMELFS_FLAGS_SHOW:
err = pohmelfs_cn_disp(msg);
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/pohmelfs/netfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enum {
POHMELFS_FLAGS_DEL, /* Network state control message for DEL */
POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */
POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */
POHMELFS_FLAGS_MODIFY, /* Network state modification message */
};

/*
Expand Down
30 changes: 9 additions & 21 deletions drivers/staging/pohmelfs/trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
#endif
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) {
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);
if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
break;
}
out:

mutex_unlock(&psb->state_lock);
#if 0
dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
Expand Down

0 comments on commit e0ca873

Please sign in to comment.