diff options
author | Evgeniy Polyakov <zbr@ioremap.net> | 2009-03-27 08:04:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-17 14:06:30 -0400 |
commit | e0ca87391694dfacd01465d5c01c579c3b8b63e0 (patch) | |
tree | 7d295aa23034586fd7374b3e614e0844d39f351e | |
parent | f2739de19176009b14475207d5418cd79e7f0ba3 (diff) |
Staging: Pohmelfs: Added IO permissions and priorities.
Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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", |