diff options
| -rw-r--r-- | Documentation/filesystems/pohmelfs/design_notes.txt | 5 | ||||
| -rw-r--r-- | Documentation/filesystems/pohmelfs/info.txt | 21 | ||||
| -rw-r--r-- | drivers/staging/pohmelfs/config.c | 61 | ||||
| -rw-r--r-- | drivers/staging/pohmelfs/netfs.h | 1 | ||||
| -rw-r--r-- | drivers/staging/pohmelfs/trans.c | 30 |
5 files changed, 86 insertions, 32 deletions
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt index 6d6db60d567d..dcf833587162 100644 --- a/Documentation/filesystems/pohmelfs/design_notes.txt +++ b/Documentation/filesystems/pohmelfs/design_notes.txt | |||
| @@ -56,9 +56,10 @@ workloads and can fully utilize the bandwidth to the servers when doing bulk | |||
| 56 | data transfers. | 56 | data transfers. |
| 57 | 57 | ||
| 58 | POHMELFS clients operate with a working set of servers and are capable of balancing read-only | 58 | POHMELFS clients operate with a working set of servers and are capable of balancing read-only |
| 59 | operations (like lookups or directory listings) between them. | 59 | operations (like lookups or directory listings) between them according to IO priorities. |
| 60 | Administrators can add or remove servers from the set at run-time via special commands (described | 60 | Administrators can add or remove servers from the set at run-time via special commands (described |
| 61 | in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers. | 61 | in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers, which are connected |
| 62 | with write permission turned on. IO priority and permissions can be changed in run-time. | ||
| 62 | 63 | ||
| 63 | POHMELFS is capable of full data channel encryption and/or strong crypto hashing. | 64 | POHMELFS is capable of full data channel encryption and/or strong crypto hashing. |
| 64 | One can select any kernel supported cipher, encryption mode, hash type and operation mode | 65 | One can select any kernel supported cipher, encryption mode, hash type and operation mode |
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt index 4e3d50157083..db2e41393626 100644 --- a/Documentation/filesystems/pohmelfs/info.txt +++ b/Documentation/filesystems/pohmelfs/info.txt | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | POHMELFS usage information. | 1 | POHMELFS usage information. |
| 2 | 2 | ||
| 3 | Mount options: | 3 | Mount options. |
| 4 | All but index, number of crypto threads and maximum IO size can changed via remount. | ||
| 5 | |||
| 4 | idx=%u | 6 | idx=%u |
| 5 | Each mountpoint is associated with a special index via this option. | 7 | Each mountpoint is associated with a special index via this option. |
| 6 | Administrator can add or remove servers from the given index, so all mounts, | 8 | Administrator can add or remove servers from the given index, so all mounts, |
| @@ -52,16 +54,27 @@ mcache_timeout=%u | |||
| 52 | 54 | ||
| 53 | Usage examples. | 55 | Usage examples. |
| 54 | 56 | ||
| 55 | Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx | 57 | Add server server1.net:1025 into the working set with index $idx |
| 56 | with appropriate hash algorithm and key file and cipher algorithm, mode and key file: | 58 | with appropriate hash algorithm and key file and cipher algorithm, mode and key file: |
| 57 | $cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key | 59 | $cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key |
| 58 | 60 | ||
| 59 | Mount filesystem with given index $idx to /mnt mountpoint. | 61 | Mount filesystem with given index $idx to /mnt mountpoint. |
| 60 | Client will connect to all servers specified in the working set via previous command: | 62 | Client will connect to all servers specified in the working set via previous command: |
| 61 | mount -t pohmel -o idx=$idx q /mnt | 63 | mount -t pohmel -o idx=$idx q /mnt |
| 62 | 64 | ||
| 63 | One can add or remove servers from working set after mounting too. | 65 | Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw): |
| 66 | $cfg A modify -a server1.net -p 1025 -i $idx -I 1 | ||
| 67 | |||
| 68 | Change IO priority to 123 (node with the highest priority gets read requests). | ||
| 69 | $cfg A modify -a server1.net -p 1025 -i $idx -P 123 | ||
| 64 | 70 | ||
| 71 | One can check currect status of all connections in the mountstats file: | ||
| 72 | # cat /proc/$PID/mountstats | ||
| 73 | ... | ||
| 74 | device none mounted on /mnt with fstype pohmel | ||
| 75 | idx addr(:port) socket_type protocol active priority permissions | ||
| 76 | 0 server1.net:1026 1 6 1 250 1 | ||
| 77 | 0 server2.net:1025 1 6 1 123 3 | ||
| 65 | 78 | ||
| 66 | Server installation. | 79 | Server installation. |
| 67 | 80 | ||
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 3e67da9ea381..a6eaa42fb669 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c | |||
| @@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned | |||
| 81 | return g; | 81 | return g; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst) | ||
| 85 | { | ||
| 86 | struct pohmelfs_config *tmp; | ||
| 87 | |||
| 88 | INIT_LIST_HEAD(&dst->config_entry); | ||
| 89 | |||
| 90 | list_for_each_entry(tmp, &psb->state_list, config_entry) { | ||
| 91 | if (dst->state.ctl.prio > tmp->state.ctl.prio) | ||
| 92 | list_add_tail(&dst->config_entry, &tmp->config_entry); | ||
| 93 | } | ||
| 94 | if (list_empty(&dst->config_entry)) | ||
| 95 | list_add_tail(&dst->config_entry, &psb->state_list); | ||
| 96 | } | ||
| 97 | |||
| 98 | static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb, | ||
| 99 | struct pohmelfs_config *dst, struct pohmelfs_config *new) | ||
| 100 | { | ||
| 101 | if ((dst->state.ctl.prio == new->state.ctl.prio) && | ||
| 102 | (dst->state.ctl.perm == new->state.ctl.perm)) | ||
| 103 | return 0; | ||
| 104 | |||
| 105 | dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n", | ||
| 106 | __func__, dst->state.ctl.prio, dst->state.ctl.perm, | ||
| 107 | new->state.ctl.prio, new->state.ctl.perm); | ||
| 108 | dst->state.ctl.prio = new->state.ctl.prio; | ||
| 109 | dst->state.ctl.perm = new->state.ctl.perm; | ||
| 110 | |||
| 111 | list_del_init(&dst->config_entry); | ||
| 112 | pohmelfs_insert_config_entry(psb, dst); | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 117 | * pohmelfs_copy_config() is used to copy new state configs from the | ||
| 118 | * config group (controlled by the netlink messages) into the superblock. | ||
| 119 | * This happens either at startup time where no transactions can access | ||
| 120 | * the list of the configs (and thus list of the network states), or at | ||
| 121 | * run-time, where it is protected by the psb->state_lock. | ||
| 122 | */ | ||
| 84 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) | 123 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) |
| 85 | { | 124 | { |
| 86 | struct pohmelfs_config_group *g; | 125 | struct pohmelfs_config_group *g; |
| @@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
| 103 | err = 0; | 142 | err = 0; |
| 104 | list_for_each_entry(dst, &psb->state_list, config_entry) { | 143 | list_for_each_entry(dst, &psb->state_list, config_entry) { |
| 105 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { | 144 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { |
| 106 | err = -EEXIST; | 145 | err = pohmelfs_move_config_entry(psb, dst, c); |
| 146 | if (!err) | ||
| 147 | err = -EEXIST; | ||
| 107 | break; | 148 | break; |
| 108 | } | 149 | } |
| 109 | } | 150 | } |
| @@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
| 119 | 160 | ||
| 120 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); | 161 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); |
| 121 | 162 | ||
| 122 | list_add_tail(&dst->config_entry, &psb->state_list); | 163 | pohmelfs_insert_config_entry(psb, dst); |
| 123 | 164 | ||
| 124 | err = pohmelfs_state_init_one(psb, dst); | 165 | err = pohmelfs_state_init_one(psb, dst); |
| 125 | if (err) { | 166 | if (err) { |
| @@ -248,6 +289,13 @@ out_unlock: | |||
| 248 | return err; | 289 | return err; |
| 249 | } | 290 | } |
| 250 | 291 | ||
| 292 | static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new) | ||
| 293 | { | ||
| 294 | old->perm = new->perm; | ||
| 295 | old->prio = new->prio; | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 251 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | 299 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) |
| 252 | { | 300 | { |
| 253 | struct pohmelfs_config_group *g; | 301 | struct pohmelfs_config_group *g; |
| @@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
| 278 | g->num_entry--; | 326 | g->num_entry--; |
| 279 | kfree(c); | 327 | kfree(c); |
| 280 | goto out_unlock; | 328 | goto out_unlock; |
| 329 | } else if (action == POHMELFS_FLAGS_MODIFY) { | ||
| 330 | err = pohmelfs_modify_config(sc, ctl); | ||
| 331 | goto out_unlock; | ||
| 281 | } else { | 332 | } else { |
| 282 | err = -EEXIST; | 333 | err = -EEXIST; |
| 283 | goto out_unlock; | 334 | goto out_unlock; |
| @@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
| 296 | } | 347 | } |
| 297 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); | 348 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); |
| 298 | g->num_entry++; | 349 | g->num_entry++; |
| 350 | |||
| 299 | list_add_tail(&c->config_entry, &g->config_list); | 351 | list_add_tail(&c->config_entry, &g->config_list); |
| 300 | 352 | ||
| 301 | out_unlock: | 353 | out_unlock: |
| @@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data) | |||
| 401 | 453 | ||
| 402 | switch (msg->flags) { | 454 | switch (msg->flags) { |
| 403 | case POHMELFS_FLAGS_ADD: | 455 | case POHMELFS_FLAGS_ADD: |
| 404 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD); | ||
| 405 | break; | ||
| 406 | case POHMELFS_FLAGS_DEL: | 456 | case POHMELFS_FLAGS_DEL: |
| 407 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL); | 457 | case POHMELFS_FLAGS_MODIFY: |
| 458 | err = pohmelfs_cn_ctl(msg, msg->flags); | ||
| 408 | break; | 459 | break; |
| 409 | case POHMELFS_FLAGS_SHOW: | 460 | case POHMELFS_FLAGS_SHOW: |
| 410 | err = pohmelfs_cn_disp(msg); | 461 | err = pohmelfs_cn_disp(msg); |
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 7700e2bf3cc7..c78cfcb042fb 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h | |||
| @@ -87,6 +87,7 @@ enum { | |||
| 87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ | 87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ |
| 88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ | 88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ |
| 89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ | 89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ |
| 90 | POHMELFS_FLAGS_MODIFY, /* Network state modification message */ | ||
| 90 | }; | 91 | }; |
| 91 | 92 | ||
| 92 | /* | 93 | /* |
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c index b89f9f36b350..168fc8998c32 100644 --- a/drivers/staging/pohmelfs/trans.c +++ b/drivers/staging/pohmelfs/trans.c | |||
| @@ -456,34 +456,22 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb) | |||
| 456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); | 456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); |
| 457 | #endif | 457 | #endif |
| 458 | mutex_lock(&psb->state_lock); | 458 | mutex_lock(&psb->state_lock); |
| 459 | |||
| 460 | if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) { | ||
| 461 | st = &psb->active_state->state; | ||
| 462 | |||
| 463 | err = -EPIPE; | ||
| 464 | if (netfs_state_poll(st) & POLLOUT) { | ||
| 465 | err = netfs_trans_push_dst(t, st); | ||
| 466 | if (!err) { | ||
| 467 | err = netfs_trans_send(t, st); | ||
| 468 | if (err) { | ||
| 469 | netfs_trans_drop_last(t, st); | ||
| 470 | } else { | ||
| 471 | pohmelfs_switch_active(psb); | ||
| 472 | goto out; | ||
| 473 | } | ||
| 474 | } | ||
| 475 | } | ||
| 476 | pohmelfs_switch_active(psb); | ||
| 477 | } | ||
| 478 | |||
| 479 | list_for_each_entry(c, &psb->state_list, config_entry) { | 459 | list_for_each_entry(c, &psb->state_list, config_entry) { |
| 480 | st = &c->state; | 460 | st = &c->state; |
| 481 | 461 | ||
| 462 | if (t->flags & NETFS_TRANS_SINGLE_DST) { | ||
| 463 | if (!(st->ctl.perm & POHMELFS_IO_PERM_READ)) | ||
| 464 | continue; | ||
| 465 | } else { | ||
| 466 | if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE)) | ||
| 467 | continue; | ||
| 468 | } | ||
| 469 | |||
| 482 | err = netfs_trans_push(t, st); | 470 | err = netfs_trans_push(t, st); |
| 483 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) | 471 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) |
| 484 | break; | 472 | break; |
| 485 | } | 473 | } |
| 486 | out: | 474 | |
| 487 | mutex_unlock(&psb->state_lock); | 475 | mutex_unlock(&psb->state_lock); |
| 488 | #if 0 | 476 | #if 0 |
| 489 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", | 477 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", |
