perf cpumap: Add new map type for aggregation
[linux-2.6-microblaze.git] / fs / ocfs2 / slot_map.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* -*- mode: c; c-basic-offset: 8; -*-
3  * vim: noexpandtab sw=8 ts=8 sts=0:
4  *
5  * slot_map.c
6  *
7  * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
8  */
9
10 #include <linux/types.h>
11 #include <linux/slab.h>
12 #include <linux/highmem.h>
13
14 #include <cluster/masklog.h>
15
16 #include "ocfs2.h"
17
18 #include "dlmglue.h"
19 #include "extent_map.h"
20 #include "heartbeat.h"
21 #include "inode.h"
22 #include "slot_map.h"
23 #include "super.h"
24 #include "sysfile.h"
25 #include "ocfs2_trace.h"
26
27 #include "buffer_head_io.h"
28
29
30 struct ocfs2_slot {
31         int sl_valid;
32         unsigned int sl_node_num;
33 };
34
35 struct ocfs2_slot_info {
36         int si_extended;
37         int si_slots_per_block;
38         struct inode *si_inode;
39         unsigned int si_blocks;
40         struct buffer_head **si_bh;
41         unsigned int si_num_slots;
42         struct ocfs2_slot si_slots[];
43 };
44
45
46 static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
47                                     unsigned int node_num);
48
49 static void ocfs2_invalidate_slot(struct ocfs2_slot_info *si,
50                                   int slot_num)
51 {
52         BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots));
53         si->si_slots[slot_num].sl_valid = 0;
54 }
55
56 static void ocfs2_set_slot(struct ocfs2_slot_info *si,
57                            int slot_num, unsigned int node_num)
58 {
59         BUG_ON((slot_num < 0) || (slot_num >= si->si_num_slots));
60
61         si->si_slots[slot_num].sl_valid = 1;
62         si->si_slots[slot_num].sl_node_num = node_num;
63 }
64
65 /* This version is for the extended slot map */
66 static void ocfs2_update_slot_info_extended(struct ocfs2_slot_info *si)
67 {
68         int b, i, slotno;
69         struct ocfs2_slot_map_extended *se;
70
71         slotno = 0;
72         for (b = 0; b < si->si_blocks; b++) {
73                 se = (struct ocfs2_slot_map_extended *)si->si_bh[b]->b_data;
74                 for (i = 0;
75                      (i < si->si_slots_per_block) &&
76                      (slotno < si->si_num_slots);
77                      i++, slotno++) {
78                         if (se->se_slots[i].es_valid)
79                                 ocfs2_set_slot(si, slotno,
80                                                le32_to_cpu(se->se_slots[i].es_node_num));
81                         else
82                                 ocfs2_invalidate_slot(si, slotno);
83                 }
84         }
85 }
86
87 /*
88  * Post the slot information on disk into our slot_info struct.
89  * Must be protected by osb_lock.
90  */
91 static void ocfs2_update_slot_info_old(struct ocfs2_slot_info *si)
92 {
93         int i;
94         struct ocfs2_slot_map *sm;
95
96         sm = (struct ocfs2_slot_map *)si->si_bh[0]->b_data;
97
98         for (i = 0; i < si->si_num_slots; i++) {
99                 if (le16_to_cpu(sm->sm_slots[i]) == (u16)OCFS2_INVALID_SLOT)
100                         ocfs2_invalidate_slot(si, i);
101                 else
102                         ocfs2_set_slot(si, i, le16_to_cpu(sm->sm_slots[i]));
103         }
104 }
105
106 static void ocfs2_update_slot_info(struct ocfs2_slot_info *si)
107 {
108         /*
109          * The slot data will have been refreshed when ocfs2_super_lock
110          * was taken.
111          */
112         if (si->si_extended)
113                 ocfs2_update_slot_info_extended(si);
114         else
115                 ocfs2_update_slot_info_old(si);
116 }
117
118 int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
119 {
120         int ret;
121         struct ocfs2_slot_info *si = osb->slot_info;
122
123         if (si == NULL)
124                 return 0;
125
126         BUG_ON(si->si_blocks == 0);
127         BUG_ON(si->si_bh == NULL);
128
129         trace_ocfs2_refresh_slot_info(si->si_blocks);
130
131         /*
132          * We pass -1 as blocknr because we expect all of si->si_bh to
133          * be !NULL.  Thus, ocfs2_read_blocks() will ignore blocknr.  If
134          * this is not true, the read of -1 (UINT64_MAX) will fail.
135          */
136         ret = ocfs2_read_blocks(INODE_CACHE(si->si_inode), -1, si->si_blocks,
137                                 si->si_bh, OCFS2_BH_IGNORE_CACHE, NULL);
138         if (ret == 0) {
139                 spin_lock(&osb->osb_lock);
140                 ocfs2_update_slot_info(si);
141                 spin_unlock(&osb->osb_lock);
142         }
143
144         return ret;
145 }
146
147 /* post the our slot info stuff into it's destination bh and write it
148  * out. */
149 static void ocfs2_update_disk_slot_extended(struct ocfs2_slot_info *si,
150                                             int slot_num,
151                                             struct buffer_head **bh)
152 {
153         int blkind = slot_num / si->si_slots_per_block;
154         int slotno = slot_num % si->si_slots_per_block;
155         struct ocfs2_slot_map_extended *se;
156
157         BUG_ON(blkind >= si->si_blocks);
158
159         se = (struct ocfs2_slot_map_extended *)si->si_bh[blkind]->b_data;
160         se->se_slots[slotno].es_valid = si->si_slots[slot_num].sl_valid;
161         if (si->si_slots[slot_num].sl_valid)
162                 se->se_slots[slotno].es_node_num =
163                         cpu_to_le32(si->si_slots[slot_num].sl_node_num);
164         *bh = si->si_bh[blkind];
165 }
166
167 static void ocfs2_update_disk_slot_old(struct ocfs2_slot_info *si,
168                                        int slot_num,
169                                        struct buffer_head **bh)
170 {
171         int i;
172         struct ocfs2_slot_map *sm;
173
174         sm = (struct ocfs2_slot_map *)si->si_bh[0]->b_data;
175         for (i = 0; i < si->si_num_slots; i++) {
176                 if (si->si_slots[i].sl_valid)
177                         sm->sm_slots[i] =
178                                 cpu_to_le16(si->si_slots[i].sl_node_num);
179                 else
180                         sm->sm_slots[i] = cpu_to_le16(OCFS2_INVALID_SLOT);
181         }
182         *bh = si->si_bh[0];
183 }
184
185 static int ocfs2_update_disk_slot(struct ocfs2_super *osb,
186                                   struct ocfs2_slot_info *si,
187                                   int slot_num)
188 {
189         int status;
190         struct buffer_head *bh;
191
192         spin_lock(&osb->osb_lock);
193         if (si->si_extended)
194                 ocfs2_update_disk_slot_extended(si, slot_num, &bh);
195         else
196                 ocfs2_update_disk_slot_old(si, slot_num, &bh);
197         spin_unlock(&osb->osb_lock);
198
199         status = ocfs2_write_block(osb, bh, INODE_CACHE(si->si_inode));
200         if (status < 0)
201                 mlog_errno(status);
202
203         return status;
204 }
205
206 /*
207  * Calculate how many bytes are needed by the slot map.  Returns
208  * an error if the slot map file is too small.
209  */
210 static int ocfs2_slot_map_physical_size(struct ocfs2_super *osb,
211                                         struct inode *inode,
212                                         unsigned long long *bytes)
213 {
214         unsigned long long bytes_needed;
215
216         if (ocfs2_uses_extended_slot_map(osb)) {
217                 bytes_needed = osb->max_slots *
218                         sizeof(struct ocfs2_extended_slot);
219         } else {
220                 bytes_needed = osb->max_slots * sizeof(__le16);
221         }
222         if (bytes_needed > i_size_read(inode)) {
223                 mlog(ML_ERROR,
224                      "Slot map file is too small!  (size %llu, needed %llu)\n",
225                      i_size_read(inode), bytes_needed);
226                 return -ENOSPC;
227         }
228
229         *bytes = bytes_needed;
230         return 0;
231 }
232
233 /* try to find global node in the slot info. Returns -ENOENT
234  * if nothing is found. */
235 static int __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
236                                     unsigned int node_num)
237 {
238         int i, ret = -ENOENT;
239
240         for(i = 0; i < si->si_num_slots; i++) {
241                 if (si->si_slots[i].sl_valid &&
242                     (node_num == si->si_slots[i].sl_node_num)) {
243                         ret = i;
244                         break;
245                 }
246         }
247
248         return ret;
249 }
250
251 static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si,
252                                    int preferred)
253 {
254         int i, ret = -ENOSPC;
255
256         if ((preferred >= 0) && (preferred < si->si_num_slots)) {
257                 if (!si->si_slots[preferred].sl_valid ||
258                     !si->si_slots[preferred].sl_node_num) {
259                         ret = preferred;
260                         goto out;
261                 }
262         }
263
264         for(i = 0; i < si->si_num_slots; i++) {
265                 if (!si->si_slots[i].sl_valid ||
266                     !si->si_slots[i].sl_node_num) {
267                         ret = i;
268                         break;
269                 }
270         }
271 out:
272         return ret;
273 }
274
275 int ocfs2_node_num_to_slot(struct ocfs2_super *osb, unsigned int node_num)
276 {
277         int slot;
278         struct ocfs2_slot_info *si = osb->slot_info;
279
280         spin_lock(&osb->osb_lock);
281         slot = __ocfs2_node_num_to_slot(si, node_num);
282         spin_unlock(&osb->osb_lock);
283
284         return slot;
285 }
286
287 int ocfs2_slot_to_node_num_locked(struct ocfs2_super *osb, int slot_num,
288                                   unsigned int *node_num)
289 {
290         struct ocfs2_slot_info *si = osb->slot_info;
291
292         assert_spin_locked(&osb->osb_lock);
293
294         BUG_ON(slot_num < 0);
295         BUG_ON(slot_num >= osb->max_slots);
296
297         if (!si->si_slots[slot_num].sl_valid)
298                 return -ENOENT;
299
300         *node_num = si->si_slots[slot_num].sl_node_num;
301         return 0;
302 }
303
304 static void __ocfs2_free_slot_info(struct ocfs2_slot_info *si)
305 {
306         unsigned int i;
307
308         if (si == NULL)
309                 return;
310
311         iput(si->si_inode);
312         if (si->si_bh) {
313                 for (i = 0; i < si->si_blocks; i++) {
314                         if (si->si_bh[i]) {
315                                 brelse(si->si_bh[i]);
316                                 si->si_bh[i] = NULL;
317                         }
318                 }
319                 kfree(si->si_bh);
320         }
321
322         kfree(si);
323 }
324
325 int ocfs2_clear_slot(struct ocfs2_super *osb, int slot_num)
326 {
327         struct ocfs2_slot_info *si = osb->slot_info;
328
329         if (si == NULL)
330                 return 0;
331
332         spin_lock(&osb->osb_lock);
333         ocfs2_invalidate_slot(si, slot_num);
334         spin_unlock(&osb->osb_lock);
335
336         return ocfs2_update_disk_slot(osb, osb->slot_info, slot_num);
337 }
338
339 static int ocfs2_map_slot_buffers(struct ocfs2_super *osb,
340                                   struct ocfs2_slot_info *si)
341 {
342         int status = 0;
343         u64 blkno;
344         unsigned long long blocks, bytes = 0;
345         unsigned int i;
346         struct buffer_head *bh;
347
348         status = ocfs2_slot_map_physical_size(osb, si->si_inode, &bytes);
349         if (status)
350                 goto bail;
351
352         blocks = ocfs2_blocks_for_bytes(si->si_inode->i_sb, bytes);
353         BUG_ON(blocks > UINT_MAX);
354         si->si_blocks = blocks;
355         if (!si->si_blocks)
356                 goto bail;
357
358         if (si->si_extended)
359                 si->si_slots_per_block =
360                         (osb->sb->s_blocksize /
361                          sizeof(struct ocfs2_extended_slot));
362         else
363                 si->si_slots_per_block = osb->sb->s_blocksize / sizeof(__le16);
364
365         /* The size checks above should ensure this */
366         BUG_ON((osb->max_slots / si->si_slots_per_block) > blocks);
367
368         trace_ocfs2_map_slot_buffers(bytes, si->si_blocks);
369
370         si->si_bh = kcalloc(si->si_blocks, sizeof(struct buffer_head *),
371                             GFP_KERNEL);
372         if (!si->si_bh) {
373                 status = -ENOMEM;
374                 mlog_errno(status);
375                 goto bail;
376         }
377
378         for (i = 0; i < si->si_blocks; i++) {
379                 status = ocfs2_extent_map_get_blocks(si->si_inode, i,
380                                                      &blkno, NULL, NULL);
381                 if (status < 0) {
382                         mlog_errno(status);
383                         goto bail;
384                 }
385
386                 trace_ocfs2_map_slot_buffers_block((unsigned long long)blkno, i);
387
388                 bh = NULL;  /* Acquire a fresh bh */
389                 status = ocfs2_read_blocks(INODE_CACHE(si->si_inode), blkno,
390                                            1, &bh, OCFS2_BH_IGNORE_CACHE, NULL);
391                 if (status < 0) {
392                         mlog_errno(status);
393                         goto bail;
394                 }
395
396                 si->si_bh[i] = bh;
397         }
398
399 bail:
400         return status;
401 }
402
403 int ocfs2_init_slot_info(struct ocfs2_super *osb)
404 {
405         int status;
406         struct inode *inode = NULL;
407         struct ocfs2_slot_info *si;
408
409         si = kzalloc(struct_size(si, si_slots, osb->max_slots), GFP_KERNEL);
410         if (!si) {
411                 status = -ENOMEM;
412                 mlog_errno(status);
413                 return status;
414         }
415
416         si->si_extended = ocfs2_uses_extended_slot_map(osb);
417         si->si_num_slots = osb->max_slots;
418
419         inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE,
420                                             OCFS2_INVALID_SLOT);
421         if (!inode) {
422                 status = -EINVAL;
423                 mlog_errno(status);
424                 goto bail;
425         }
426
427         si->si_inode = inode;
428         status = ocfs2_map_slot_buffers(osb, si);
429         if (status < 0) {
430                 mlog_errno(status);
431                 goto bail;
432         }
433
434         osb->slot_info = (struct ocfs2_slot_info *)si;
435 bail:
436         if (status < 0)
437                 __ocfs2_free_slot_info(si);
438
439         return status;
440 }
441
442 void ocfs2_free_slot_info(struct ocfs2_super *osb)
443 {
444         struct ocfs2_slot_info *si = osb->slot_info;
445
446         osb->slot_info = NULL;
447         __ocfs2_free_slot_info(si);
448 }
449
450 int ocfs2_find_slot(struct ocfs2_super *osb)
451 {
452         int status;
453         int slot;
454         struct ocfs2_slot_info *si;
455
456         si = osb->slot_info;
457
458         spin_lock(&osb->osb_lock);
459         ocfs2_update_slot_info(si);
460
461         if (ocfs2_mount_local(osb))
462                 /* use slot 0 directly in local mode */
463                 slot = 0;
464         else {
465                 /* search for ourselves first and take the slot if it already
466                  * exists. Perhaps we need to mark this in a variable for our
467                  * own journal recovery? Possibly not, though we certainly
468                  * need to warn to the user */
469                 slot = __ocfs2_node_num_to_slot(si, osb->node_num);
470                 if (slot < 0) {
471                         /* if no slot yet, then just take 1st available
472                          * one. */
473                         slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
474                         if (slot < 0) {
475                                 spin_unlock(&osb->osb_lock);
476                                 mlog(ML_ERROR, "no free slots available!\n");
477                                 status = -EINVAL;
478                                 goto bail;
479                         }
480                 } else
481                         printk(KERN_INFO "ocfs2: Slot %d on device (%s) was "
482                                "already allocated to this node!\n",
483                                slot, osb->dev_str);
484         }
485
486         ocfs2_set_slot(si, slot, osb->node_num);
487         osb->slot_num = slot;
488         spin_unlock(&osb->osb_lock);
489
490         trace_ocfs2_find_slot(osb->slot_num);
491
492         status = ocfs2_update_disk_slot(osb, si, osb->slot_num);
493         if (status < 0) {
494                 mlog_errno(status);
495                 /*
496                  * if write block failed, invalidate slot to avoid overwrite
497                  * slot during dismount in case another node rightly has mounted
498                  */
499                 spin_lock(&osb->osb_lock);
500                 ocfs2_invalidate_slot(si, osb->slot_num);
501                 osb->slot_num = OCFS2_INVALID_SLOT;
502                 spin_unlock(&osb->osb_lock);
503         }
504
505 bail:
506         return status;
507 }
508
509 void ocfs2_put_slot(struct ocfs2_super *osb)
510 {
511         int status, slot_num;
512         struct ocfs2_slot_info *si = osb->slot_info;
513
514         if (!si)
515                 return;
516
517         spin_lock(&osb->osb_lock);
518         ocfs2_update_slot_info(si);
519
520         slot_num = osb->slot_num;
521         ocfs2_invalidate_slot(si, osb->slot_num);
522         osb->slot_num = OCFS2_INVALID_SLOT;
523         spin_unlock(&osb->osb_lock);
524
525         status = ocfs2_update_disk_slot(osb, si, slot_num);
526         if (status < 0)
527                 mlog_errno(status);
528
529         ocfs2_free_slot_info(osb);
530 }