diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-02-13 21:01:21 -0500 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2016-02-19 13:45:54 -0500 |
commit | ea2c9c9f6574e835cbc903c94b82b5a34a334866 (patch) | |
tree | 47637785f81f2e7edb746de19a7b1a3c6ccd9627 /fs/orangefs | |
parent | 178041848a6e7072cc6ebc1c6c7763e33f564722 (diff) |
orangefs: bufmap rewrite
new waiting-for-slot logics:
* make request for slot wait for bufmap to be set up if it
comes before it's installed *OR* while it's running down
* make closing control device wait for all slots to be freed
* waiting itself rewritten to (open-coded) analogues of wait_event_...
primitives - we would need wait_event_locked() and, pardon an obscenely
long name, wait_event_interruptible_exclusive_timeout_locked().
* we never wait for more than slot_timeout_secs in total and,
if during the wait the daemon goes away, we only allow
ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS for it to come back.
* (cosmetical) bitmap is used instead of an array of zeroes and ones
* old (and only reached if we are about to corrupt memory) waiting
for daemon restart in service_operation() removed.
[Martin's fixes folded]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs')
-rw-r--r-- | fs/orangefs/devorangefs-req.c | 15 | ||||
-rw-r--r-- | fs/orangefs/orangefs-bufmap.c | 341 | ||||
-rw-r--r-- | fs/orangefs/orangefs-bufmap.h | 4 | ||||
-rw-r--r-- | fs/orangefs/waitqueue.c | 61 |
4 files changed, 174 insertions, 247 deletions
diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 6a7df1204bfc..790855a72e32 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c | |||
@@ -508,8 +508,7 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) | |||
508 | __func__); | 508 | __func__); |
509 | 509 | ||
510 | mutex_lock(&devreq_mutex); | 510 | mutex_lock(&devreq_mutex); |
511 | if (orangefs_get_bufmap_init()) | 511 | orangefs_bufmap_finalize(); |
512 | orangefs_bufmap_finalize(); | ||
513 | 512 | ||
514 | open_access_count = -1; | 513 | open_access_count = -1; |
515 | 514 | ||
@@ -527,6 +526,9 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) | |||
527 | * them as purged and wake them up | 526 | * them as purged and wake them up |
528 | */ | 527 | */ |
529 | purge_inprogress_ops(); | 528 | purge_inprogress_ops(); |
529 | |||
530 | orangefs_bufmap_run_down(); | ||
531 | |||
530 | gossip_debug(GOSSIP_DEV_DEBUG, | 532 | gossip_debug(GOSSIP_DEV_DEBUG, |
531 | "pvfs2-client-core: device close complete\n"); | 533 | "pvfs2-client-core: device close complete\n"); |
532 | open_access_count = 0; | 534 | open_access_count = 0; |
@@ -607,13 +609,8 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) | |||
607 | (struct ORANGEFS_dev_map_desc __user *) | 609 | (struct ORANGEFS_dev_map_desc __user *) |
608 | arg, | 610 | arg, |
609 | sizeof(struct ORANGEFS_dev_map_desc)); | 611 | sizeof(struct ORANGEFS_dev_map_desc)); |
610 | if (orangefs_get_bufmap_init()) { | 612 | /* WTF -EIO and not -EFAULT? */ |
611 | return -EINVAL; | 613 | return ret ? -EIO : orangefs_bufmap_initialize(&user_desc); |
612 | } else { | ||
613 | return ret ? | ||
614 | -EIO : | ||
615 | orangefs_bufmap_initialize(&user_desc); | ||
616 | } | ||
617 | case ORANGEFS_DEV_REMOUNT_ALL: | 614 | case ORANGEFS_DEV_REMOUNT_ALL: |
618 | gossip_debug(GOSSIP_DEV_DEBUG, | 615 | gossip_debug(GOSSIP_DEV_DEBUG, |
619 | "%s: got ORANGEFS_DEV_REMOUNT_ALL\n", | 616 | "%s: got ORANGEFS_DEV_REMOUNT_ALL\n", |
diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index cd484665bf72..96faf4ee6529 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c | |||
@@ -7,7 +7,133 @@ | |||
7 | #include "orangefs-kernel.h" | 7 | #include "orangefs-kernel.h" |
8 | #include "orangefs-bufmap.h" | 8 | #include "orangefs-bufmap.h" |
9 | 9 | ||
10 | DECLARE_WAIT_QUEUE_HEAD(orangefs_bufmap_init_waitq); | 10 | struct slot_map { |
11 | int c; | ||
12 | wait_queue_head_t q; | ||
13 | int count; | ||
14 | unsigned long *map; | ||
15 | }; | ||
16 | |||
17 | static struct slot_map rw_map = { | ||
18 | .c = -1, | ||
19 | .q = __WAIT_QUEUE_HEAD_INITIALIZER(rw_map.q) | ||
20 | }; | ||
21 | static struct slot_map readdir_map = { | ||
22 | .c = -1, | ||
23 | .q = __WAIT_QUEUE_HEAD_INITIALIZER(readdir_map.q) | ||
24 | }; | ||
25 | |||
26 | |||
27 | static void install(struct slot_map *m, int count, unsigned long *map) | ||
28 | { | ||
29 | spin_lock(&m->q.lock); | ||
30 | m->c = m->count = count; | ||
31 | m->map = map; | ||
32 | wake_up_all_locked(&m->q); | ||
33 | spin_unlock(&m->q.lock); | ||
34 | } | ||
35 | |||
36 | static void mark_killed(struct slot_map *m) | ||
37 | { | ||
38 | spin_lock(&m->q.lock); | ||
39 | m->c -= m->count + 1; | ||
40 | spin_unlock(&m->q.lock); | ||
41 | } | ||
42 | |||
43 | static void run_down(struct slot_map *m) | ||
44 | { | ||
45 | DEFINE_WAIT(wait); | ||
46 | spin_lock(&m->q.lock); | ||
47 | if (m->c != -1) { | ||
48 | for (;;) { | ||
49 | if (likely(list_empty(&wait.task_list))) | ||
50 | __add_wait_queue_tail(&m->q, &wait); | ||
51 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
52 | |||
53 | if (m->c == -1) | ||
54 | break; | ||
55 | |||
56 | spin_unlock(&m->q.lock); | ||
57 | schedule(); | ||
58 | spin_lock(&m->q.lock); | ||
59 | } | ||
60 | __remove_wait_queue(&m->q, &wait); | ||
61 | __set_current_state(TASK_RUNNING); | ||
62 | } | ||
63 | m->map = NULL; | ||
64 | spin_unlock(&m->q.lock); | ||
65 | } | ||
66 | |||
67 | static void put(struct slot_map *m, int slot) | ||
68 | { | ||
69 | int v; | ||
70 | spin_lock(&m->q.lock); | ||
71 | __clear_bit(slot, m->map); | ||
72 | v = ++m->c; | ||
73 | if (unlikely(v == 1)) /* no free slots -> one free slot */ | ||
74 | wake_up_locked(&m->q); | ||
75 | else if (unlikely(v == -1)) /* finished dying */ | ||
76 | wake_up_all_locked(&m->q); | ||
77 | spin_unlock(&m->q.lock); | ||
78 | } | ||
79 | |||
80 | static int wait_for_free(struct slot_map *m) | ||
81 | { | ||
82 | long left = slot_timeout_secs * HZ; | ||
83 | DEFINE_WAIT(wait); | ||
84 | |||
85 | do { | ||
86 | long n = left, t; | ||
87 | if (likely(list_empty(&wait.task_list))) | ||
88 | __add_wait_queue_tail_exclusive(&m->q, &wait); | ||
89 | set_current_state(TASK_INTERRUPTIBLE); | ||
90 | |||
91 | if (m->c > 0) | ||
92 | break; | ||
93 | |||
94 | if (m->c < 0) { | ||
95 | /* we are waiting for map to be installed */ | ||
96 | /* it would better be there soon, or we go away */ | ||
97 | if (n > ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ) | ||
98 | n = ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ; | ||
99 | } | ||
100 | spin_unlock(&m->q.lock); | ||
101 | t = schedule_timeout(n); | ||
102 | spin_lock(&m->q.lock); | ||
103 | if (unlikely(!t) && n != left && m->c < 0) | ||
104 | left = t; | ||
105 | else | ||
106 | left = t + (left - n); | ||
107 | if (unlikely(signal_pending(current))) | ||
108 | left = -EINTR; | ||
109 | } while (left > 0); | ||
110 | |||
111 | if (!list_empty(&wait.task_list)) | ||
112 | list_del(&wait.task_list); | ||
113 | else if (left <= 0 && waitqueue_active(&m->q)) | ||
114 | __wake_up_locked_key(&m->q, TASK_INTERRUPTIBLE, NULL); | ||
115 | __set_current_state(TASK_RUNNING); | ||
116 | |||
117 | if (likely(left > 0)) | ||
118 | return 0; | ||
119 | |||
120 | return left < 0 ? -EINTR : -ETIMEDOUT; | ||
121 | } | ||
122 | |||
123 | static int get(struct slot_map *m) | ||
124 | { | ||
125 | int res = 0; | ||
126 | spin_lock(&m->q.lock); | ||
127 | if (unlikely(m->c <= 0)) | ||
128 | res = wait_for_free(m); | ||
129 | if (likely(!res)) { | ||
130 | m->c--; | ||
131 | res = find_first_zero_bit(m->map, m->count); | ||
132 | __set_bit(res, m->map); | ||
133 | } | ||
134 | spin_unlock(&m->q.lock); | ||
135 | return res; | ||
136 | } | ||
11 | 137 | ||
12 | /* used to describe mapped buffers */ | 138 | /* used to describe mapped buffers */ |
13 | struct orangefs_bufmap_desc { | 139 | struct orangefs_bufmap_desc { |
@@ -18,8 +144,6 @@ struct orangefs_bufmap_desc { | |||
18 | }; | 144 | }; |
19 | 145 | ||
20 | static struct orangefs_bufmap { | 146 | static struct orangefs_bufmap { |
21 | atomic_t refcnt; | ||
22 | |||
23 | int desc_size; | 147 | int desc_size; |
24 | int desc_shift; | 148 | int desc_shift; |
25 | int desc_count; | 149 | int desc_count; |
@@ -30,12 +154,12 @@ static struct orangefs_bufmap { | |||
30 | struct orangefs_bufmap_desc *desc_array; | 154 | struct orangefs_bufmap_desc *desc_array; |
31 | 155 | ||
32 | /* array to track usage of buffer descriptors */ | 156 | /* array to track usage of buffer descriptors */ |
33 | int *buffer_index_array; | 157 | unsigned long *buffer_index_array; |
34 | spinlock_t buffer_index_lock; | ||
35 | 158 | ||
36 | /* array to track usage of buffer descriptors for readdir */ | 159 | /* array to track usage of buffer descriptors for readdir */ |
37 | int readdir_index_array[ORANGEFS_READDIR_DEFAULT_DESC_COUNT]; | 160 | #define N DIV_ROUND_UP(ORANGEFS_READDIR_DEFAULT_DESC_COUNT, BITS_PER_LONG) |
38 | spinlock_t readdir_index_lock; | 161 | unsigned long readdir_index_array[N]; |
162 | #undef N | ||
39 | } *__orangefs_bufmap; | 163 | } *__orangefs_bufmap; |
40 | 164 | ||
41 | static DEFINE_SPINLOCK(orangefs_bufmap_lock); | 165 | static DEFINE_SPINLOCK(orangefs_bufmap_lock); |
@@ -58,30 +182,6 @@ orangefs_bufmap_free(struct orangefs_bufmap *bufmap) | |||
58 | kfree(bufmap); | 182 | kfree(bufmap); |
59 | } | 183 | } |
60 | 184 | ||
61 | static struct orangefs_bufmap *orangefs_bufmap_ref(void) | ||
62 | { | ||
63 | struct orangefs_bufmap *bufmap = NULL; | ||
64 | |||
65 | spin_lock(&orangefs_bufmap_lock); | ||
66 | if (__orangefs_bufmap) { | ||
67 | bufmap = __orangefs_bufmap; | ||
68 | atomic_inc(&bufmap->refcnt); | ||
69 | } | ||
70 | spin_unlock(&orangefs_bufmap_lock); | ||
71 | return bufmap; | ||
72 | } | ||
73 | |||
74 | static void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) | ||
75 | { | ||
76 | if (atomic_dec_and_lock(&bufmap->refcnt, &orangefs_bufmap_lock)) { | ||
77 | __orangefs_bufmap = NULL; | ||
78 | spin_unlock(&orangefs_bufmap_lock); | ||
79 | |||
80 | orangefs_bufmap_unmap(bufmap); | ||
81 | orangefs_bufmap_free(bufmap); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /* | 185 | /* |
86 | * XXX: Can the size and shift change while the caller gives up the | 186 | * XXX: Can the size and shift change while the caller gives up the |
87 | * XXX: lock between calling this and doing something useful? | 187 | * XXX: lock between calling this and doing something useful? |
@@ -137,21 +237,18 @@ orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) | |||
137 | if (!bufmap) | 237 | if (!bufmap) |
138 | goto out; | 238 | goto out; |
139 | 239 | ||
140 | atomic_set(&bufmap->refcnt, 1); | ||
141 | bufmap->total_size = user_desc->total_size; | 240 | bufmap->total_size = user_desc->total_size; |
142 | bufmap->desc_count = user_desc->count; | 241 | bufmap->desc_count = user_desc->count; |
143 | bufmap->desc_size = user_desc->size; | 242 | bufmap->desc_size = user_desc->size; |
144 | bufmap->desc_shift = ilog2(bufmap->desc_size); | 243 | bufmap->desc_shift = ilog2(bufmap->desc_size); |
145 | 244 | ||
146 | spin_lock_init(&bufmap->buffer_index_lock); | ||
147 | bufmap->buffer_index_array = | 245 | bufmap->buffer_index_array = |
148 | kcalloc(bufmap->desc_count, sizeof(int), GFP_KERNEL); | 246 | kzalloc(DIV_ROUND_UP(bufmap->desc_count, BITS_PER_LONG), GFP_KERNEL); |
149 | if (!bufmap->buffer_index_array) { | 247 | if (!bufmap->buffer_index_array) { |
150 | gossip_err("orangefs: could not allocate %d buffer indices\n", | 248 | gossip_err("orangefs: could not allocate %d buffer indices\n", |
151 | bufmap->desc_count); | 249 | bufmap->desc_count); |
152 | goto out_free_bufmap; | 250 | goto out_free_bufmap; |
153 | } | 251 | } |
154 | spin_lock_init(&bufmap->readdir_index_lock); | ||
155 | 252 | ||
156 | bufmap->desc_array = | 253 | bufmap->desc_array = |
157 | kcalloc(bufmap->desc_count, sizeof(struct orangefs_bufmap_desc), | 254 | kcalloc(bufmap->desc_count, sizeof(struct orangefs_bufmap_desc), |
@@ -294,24 +391,18 @@ int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc) | |||
294 | if (__orangefs_bufmap) { | 391 | if (__orangefs_bufmap) { |
295 | spin_unlock(&orangefs_bufmap_lock); | 392 | spin_unlock(&orangefs_bufmap_lock); |
296 | gossip_err("orangefs: error: bufmap already initialized.\n"); | 393 | gossip_err("orangefs: error: bufmap already initialized.\n"); |
297 | ret = -EALREADY; | 394 | ret = -EINVAL; |
298 | goto out_unmap_bufmap; | 395 | goto out_unmap_bufmap; |
299 | } | 396 | } |
300 | __orangefs_bufmap = bufmap; | 397 | __orangefs_bufmap = bufmap; |
398 | install(&rw_map, | ||
399 | bufmap->desc_count, | ||
400 | bufmap->buffer_index_array); | ||
401 | install(&readdir_map, | ||
402 | ORANGEFS_READDIR_DEFAULT_DESC_COUNT, | ||
403 | bufmap->readdir_index_array); | ||
301 | spin_unlock(&orangefs_bufmap_lock); | 404 | spin_unlock(&orangefs_bufmap_lock); |
302 | 405 | ||
303 | /* | ||
304 | * If there are operations in orangefs_bufmap_init_waitq, wake them up. | ||
305 | * This scenario occurs when the client-core is restarted and I/O | ||
306 | * requests in the in-progress or waiting tables are restarted. I/O | ||
307 | * requests cannot be restarted until the shared memory system is | ||
308 | * completely re-initialized, so we put the I/O requests in this | ||
309 | * waitq until initialization has completed. NOTE: the I/O requests | ||
310 | * are also on a timer, so they don't wait forever just in case the | ||
311 | * client-core doesn't come back up. | ||
312 | */ | ||
313 | wake_up_interruptible(&orangefs_bufmap_init_waitq); | ||
314 | |||
315 | gossip_debug(GOSSIP_BUFMAP_DEBUG, | 406 | gossip_debug(GOSSIP_BUFMAP_DEBUG, |
316 | "orangefs_bufmap_initialize: exiting normally\n"); | 407 | "orangefs_bufmap_initialize: exiting normally\n"); |
317 | return 0; | 408 | return 0; |
@@ -334,91 +425,28 @@ out: | |||
334 | */ | 425 | */ |
335 | void orangefs_bufmap_finalize(void) | 426 | void orangefs_bufmap_finalize(void) |
336 | { | 427 | { |
428 | struct orangefs_bufmap *bufmap = __orangefs_bufmap; | ||
429 | if (!bufmap) | ||
430 | return; | ||
337 | gossip_debug(GOSSIP_BUFMAP_DEBUG, "orangefs_bufmap_finalize: called\n"); | 431 | gossip_debug(GOSSIP_BUFMAP_DEBUG, "orangefs_bufmap_finalize: called\n"); |
338 | BUG_ON(!__orangefs_bufmap); | 432 | mark_killed(&rw_map); |
339 | orangefs_bufmap_unref(__orangefs_bufmap); | 433 | mark_killed(&readdir_map); |
340 | gossip_debug(GOSSIP_BUFMAP_DEBUG, | 434 | gossip_debug(GOSSIP_BUFMAP_DEBUG, |
341 | "orangefs_bufmap_finalize: exiting normally\n"); | 435 | "orangefs_bufmap_finalize: exiting normally\n"); |
342 | } | 436 | } |
343 | 437 | ||
344 | struct slot_args { | 438 | void orangefs_bufmap_run_down(void) |
345 | int slot_count; | ||
346 | int *slot_array; | ||
347 | spinlock_t *slot_lock; | ||
348 | wait_queue_head_t *slot_wq; | ||
349 | }; | ||
350 | |||
351 | static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) | ||
352 | { | 439 | { |
353 | int ret = -1; | 440 | struct orangefs_bufmap *bufmap = __orangefs_bufmap; |
354 | int i = 0; | 441 | if (!bufmap) |
355 | DEFINE_WAIT(wait_entry); | ||
356 | |||
357 | while (1) { | ||
358 | /* | ||
359 | * check for available desc, slot_lock is the appropriate | ||
360 | * index_lock | ||
361 | */ | ||
362 | spin_lock(slargs->slot_lock); | ||
363 | prepare_to_wait_exclusive(slargs->slot_wq, | ||
364 | &wait_entry, | ||
365 | TASK_INTERRUPTIBLE); | ||
366 | for (i = 0; i < slargs->slot_count; i++) | ||
367 | if (slargs->slot_array[i] == 0) { | ||
368 | slargs->slot_array[i] = 1; | ||
369 | *buffer_index = i; | ||
370 | ret = 0; | ||
371 | break; | ||
372 | } | ||
373 | spin_unlock(slargs->slot_lock); | ||
374 | |||
375 | /* if we acquired a buffer, then break out of while */ | ||
376 | if (ret == 0) | ||
377 | break; | ||
378 | |||
379 | if (!signal_pending(current)) { | ||
380 | gossip_debug(GOSSIP_BUFMAP_DEBUG, | ||
381 | "[BUFMAP]: waiting %d " | ||
382 | "seconds for a slot\n", | ||
383 | slot_timeout_secs); | ||
384 | if (!schedule_timeout(slot_timeout_secs * HZ)) { | ||
385 | gossip_debug(GOSSIP_BUFMAP_DEBUG, | ||
386 | "*** wait_for_a_slot timed out\n"); | ||
387 | ret = -ETIMEDOUT; | ||
388 | break; | ||
389 | } | ||
390 | gossip_debug(GOSSIP_BUFMAP_DEBUG, | ||
391 | "[BUFMAP]: woken up by a slot becoming available.\n"); | ||
392 | continue; | ||
393 | } | ||
394 | |||
395 | gossip_debug(GOSSIP_BUFMAP_DEBUG, "orangefs: %s interrupted.\n", | ||
396 | __func__); | ||
397 | ret = -EINTR; | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | spin_lock(slargs->slot_lock); | ||
402 | finish_wait(slargs->slot_wq, &wait_entry); | ||
403 | spin_unlock(slargs->slot_lock); | ||
404 | return ret; | ||
405 | } | ||
406 | |||
407 | static void put_back_slot(struct slot_args *slargs, int buffer_index) | ||
408 | { | ||
409 | /* slot_lock is the appropriate index_lock */ | ||
410 | spin_lock(slargs->slot_lock); | ||
411 | if (buffer_index < 0 || buffer_index >= slargs->slot_count) { | ||
412 | spin_unlock(slargs->slot_lock); | ||
413 | return; | 442 | return; |
414 | } | 443 | run_down(&rw_map); |
415 | 444 | run_down(&readdir_map); | |
416 | /* put the desc back on the queue */ | 445 | spin_lock(&orangefs_bufmap_lock); |
417 | slargs->slot_array[buffer_index] = 0; | 446 | __orangefs_bufmap = NULL; |
418 | spin_unlock(slargs->slot_lock); | 447 | spin_unlock(&orangefs_bufmap_lock); |
419 | 448 | orangefs_bufmap_unmap(bufmap); | |
420 | /* wake up anyone who may be sleeping on the queue */ | 449 | orangefs_bufmap_free(bufmap); |
421 | wake_up_interruptible(slargs->slot_wq); | ||
422 | } | 450 | } |
423 | 451 | ||
424 | /* | 452 | /* |
@@ -431,23 +459,12 @@ static void put_back_slot(struct slot_args *slargs, int buffer_index) | |||
431 | */ | 459 | */ |
432 | int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index) | 460 | int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index) |
433 | { | 461 | { |
434 | struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); | 462 | int ret = get(&rw_map); |
435 | struct slot_args slargs; | 463 | if (ret >= 0) { |
436 | int ret; | 464 | *mapp = __orangefs_bufmap; |
437 | 465 | *buffer_index = ret; | |
438 | if (!bufmap) { | 466 | ret = 0; |
439 | gossip_err("orangefs: please confirm that pvfs2-client daemon is running.\n"); | ||
440 | return -EIO; | ||
441 | } | 467 | } |
442 | |||
443 | slargs.slot_count = bufmap->desc_count; | ||
444 | slargs.slot_array = bufmap->buffer_index_array; | ||
445 | slargs.slot_lock = &bufmap->buffer_index_lock; | ||
446 | slargs.slot_wq = &bufmap_waitq; | ||
447 | ret = wait_for_a_slot(&slargs, buffer_index); | ||
448 | if (ret) | ||
449 | orangefs_bufmap_unref(bufmap); | ||
450 | *mapp = bufmap; | ||
451 | return ret; | 468 | return ret; |
452 | } | 469 | } |
453 | 470 | ||
@@ -460,15 +477,7 @@ int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index) | |||
460 | */ | 477 | */ |
461 | void orangefs_bufmap_put(int buffer_index) | 478 | void orangefs_bufmap_put(int buffer_index) |
462 | { | 479 | { |
463 | struct slot_args slargs; | 480 | put(&rw_map, buffer_index); |
464 | struct orangefs_bufmap *bufmap = __orangefs_bufmap; | ||
465 | |||
466 | slargs.slot_count = bufmap->desc_count; | ||
467 | slargs.slot_array = bufmap->buffer_index_array; | ||
468 | slargs.slot_lock = &bufmap->buffer_index_lock; | ||
469 | slargs.slot_wq = &bufmap_waitq; | ||
470 | put_back_slot(&slargs, buffer_index); | ||
471 | orangefs_bufmap_unref(bufmap); | ||
472 | } | 481 | } |
473 | 482 | ||
474 | /* | 483 | /* |
@@ -484,36 +493,18 @@ void orangefs_bufmap_put(int buffer_index) | |||
484 | */ | 493 | */ |
485 | int orangefs_readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) | 494 | int orangefs_readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) |
486 | { | 495 | { |
487 | struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); | 496 | int ret = get(&readdir_map); |
488 | struct slot_args slargs; | 497 | if (ret >= 0) { |
489 | int ret; | 498 | *mapp = __orangefs_bufmap; |
490 | 499 | *buffer_index = ret; | |
491 | if (!bufmap) { | 500 | ret = 0; |
492 | gossip_err("orangefs: please confirm that pvfs2-client daemon is running.\n"); | ||
493 | return -EIO; | ||
494 | } | 501 | } |
495 | |||
496 | slargs.slot_count = ORANGEFS_READDIR_DEFAULT_DESC_COUNT; | ||
497 | slargs.slot_array = bufmap->readdir_index_array; | ||
498 | slargs.slot_lock = &bufmap->readdir_index_lock; | ||
499 | slargs.slot_wq = &readdir_waitq; | ||
500 | ret = wait_for_a_slot(&slargs, buffer_index); | ||
501 | if (ret) | ||
502 | orangefs_bufmap_unref(bufmap); | ||
503 | *mapp = bufmap; | ||
504 | return ret; | 502 | return ret; |
505 | } | 503 | } |
506 | 504 | ||
507 | void orangefs_readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) | 505 | void orangefs_readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) |
508 | { | 506 | { |
509 | struct slot_args slargs; | 507 | put(&readdir_map, buffer_index); |
510 | |||
511 | slargs.slot_count = ORANGEFS_READDIR_DEFAULT_DESC_COUNT; | ||
512 | slargs.slot_array = bufmap->readdir_index_array; | ||
513 | slargs.slot_lock = &bufmap->readdir_index_lock; | ||
514 | slargs.slot_wq = &readdir_waitq; | ||
515 | put_back_slot(&slargs, buffer_index); | ||
516 | orangefs_bufmap_unref(bufmap); | ||
517 | } | 508 | } |
518 | 509 | ||
519 | /* | 510 | /* |
diff --git a/fs/orangefs/orangefs-bufmap.h b/fs/orangefs/orangefs-bufmap.h index 2a2d4269d03e..f0684f0085d1 100644 --- a/fs/orangefs/orangefs-bufmap.h +++ b/fs/orangefs/orangefs-bufmap.h | |||
@@ -15,10 +15,10 @@ int orangefs_bufmap_shift_query(void); | |||
15 | 15 | ||
16 | int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc); | 16 | int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc); |
17 | 17 | ||
18 | int orangefs_get_bufmap_init(void); | ||
19 | |||
20 | void orangefs_bufmap_finalize(void); | 18 | void orangefs_bufmap_finalize(void); |
21 | 19 | ||
20 | void orangefs_bufmap_run_down(void); | ||
21 | |||
22 | int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index); | 22 | int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index); |
23 | 23 | ||
24 | void orangefs_bufmap_put(int buffer_index); | 24 | void orangefs_bufmap_put(int buffer_index); |
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 378cdcf43252..36eedd6a8335 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c | |||
@@ -155,67 +155,6 @@ retry_servicing: | |||
155 | * system | 155 | * system |
156 | */ | 156 | */ |
157 | goto retry_servicing; | 157 | goto retry_servicing; |
158 | |||
159 | /* op uses shared memory */ | ||
160 | if (orangefs_get_bufmap_init() == 0) { | ||
161 | WARN_ON(1); | ||
162 | /* | ||
163 | * This operation uses the shared memory system AND | ||
164 | * the system is not yet ready. This situation occurs | ||
165 | * when the client-core is restarted AND there were | ||
166 | * operations waiting to be processed or were already | ||
167 | * in process. | ||
168 | */ | ||
169 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
170 | "uses_shared_memory is true.\n"); | ||
171 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
172 | "Client core in-service status(%d).\n", | ||
173 | is_daemon_in_service()); | ||
174 | gossip_debug(GOSSIP_WAIT_DEBUG, "bufmap_init:%d.\n", | ||
175 | orangefs_get_bufmap_init()); | ||
176 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
177 | "operation's status is 0x%0x.\n", | ||
178 | op->op_state); | ||
179 | |||
180 | /* | ||
181 | * let process sleep for a few seconds so shared | ||
182 | * memory system can be initialized. | ||
183 | */ | ||
184 | prepare_to_wait(&orangefs_bufmap_init_waitq, | ||
185 | &wait_entry, | ||
186 | TASK_INTERRUPTIBLE); | ||
187 | |||
188 | /* | ||
189 | * Wait for orangefs_bufmap_initialize() to wake me up | ||
190 | * within the allotted time. | ||
191 | */ | ||
192 | ret = schedule_timeout( | ||
193 | ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ); | ||
194 | |||
195 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
196 | "Value returned from schedule_timeout:" | ||
197 | "%d.\n", | ||
198 | ret); | ||
199 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
200 | "Is shared memory available? (%d).\n", | ||
201 | orangefs_get_bufmap_init()); | ||
202 | |||
203 | finish_wait(&orangefs_bufmap_init_waitq, &wait_entry); | ||
204 | |||
205 | if (orangefs_get_bufmap_init() == 0) { | ||
206 | gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted. Aborting user's request(%s).\n", | ||
207 | __func__, | ||
208 | ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS, | ||
209 | get_opname_string(op)); | ||
210 | return -EIO; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Return to the calling function and re-populate a | ||
215 | * shared memory buffer. | ||
216 | */ | ||
217 | return -EAGAIN; | ||
218 | } | ||
219 | } | 158 | } |
220 | 159 | ||
221 | out: | 160 | out: |