Merge commit 'upstream-x86-entry' into WIP.x86/mm
[linux-2.6-microblaze.git] / fs / hfsplus / bnode.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/fs/hfsplus/bnode.c
4  *
5  * Copyright (C) 2001
6  * Brad Boyer (flar@allandria.com)
7  * (C) 2003 Ardis Technologies <roman@ardistech.com>
8  *
9  * Handle basic btree node operations
10  */
11
12 #include <linux/string.h>
13 #include <linux/slab.h>
14 #include <linux/pagemap.h>
15 #include <linux/fs.h>
16 #include <linux/swap.h>
17
18 #include "hfsplus_fs.h"
19 #include "hfsplus_raw.h"
20
21 /* Copy a specified range of bytes from the raw data of a node */
22 void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
23 {
24         struct page **pagep;
25         int l;
26
27         off += node->page_offset;
28         pagep = node->page + (off >> PAGE_SHIFT);
29         off &= ~PAGE_MASK;
30
31         l = min_t(int, len, PAGE_SIZE - off);
32         memcpy(buf, kmap(*pagep) + off, l);
33         kunmap(*pagep);
34
35         while ((len -= l) != 0) {
36                 buf += l;
37                 l = min_t(int, len, PAGE_SIZE);
38                 memcpy(buf, kmap(*++pagep), l);
39                 kunmap(*pagep);
40         }
41 }
42
43 u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
44 {
45         __be16 data;
46         /* TODO: optimize later... */
47         hfs_bnode_read(node, &data, off, 2);
48         return be16_to_cpu(data);
49 }
50
51 u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off)
52 {
53         u8 data;
54         /* TODO: optimize later... */
55         hfs_bnode_read(node, &data, off, 1);
56         return data;
57 }
58
59 void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
60 {
61         struct hfs_btree *tree;
62         int key_len;
63
64         tree = node->tree;
65         if (node->type == HFS_NODE_LEAF ||
66             tree->attributes & HFS_TREE_VARIDXKEYS ||
67             node->tree->cnid == HFSPLUS_ATTR_CNID)
68                 key_len = hfs_bnode_read_u16(node, off) + 2;
69         else
70                 key_len = tree->max_key_len + 2;
71
72         hfs_bnode_read(node, key, off, key_len);
73 }
74
75 void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
76 {
77         struct page **pagep;
78         int l;
79
80         off += node->page_offset;
81         pagep = node->page + (off >> PAGE_SHIFT);
82         off &= ~PAGE_MASK;
83
84         l = min_t(int, len, PAGE_SIZE - off);
85         memcpy(kmap(*pagep) + off, buf, l);
86         set_page_dirty(*pagep);
87         kunmap(*pagep);
88
89         while ((len -= l) != 0) {
90                 buf += l;
91                 l = min_t(int, len, PAGE_SIZE);
92                 memcpy(kmap(*++pagep), buf, l);
93                 set_page_dirty(*pagep);
94                 kunmap(*pagep);
95         }
96 }
97
98 void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data)
99 {
100         __be16 v = cpu_to_be16(data);
101         /* TODO: optimize later... */
102         hfs_bnode_write(node, &v, off, 2);
103 }
104
105 void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
106 {
107         struct page **pagep;
108         int l;
109
110         off += node->page_offset;
111         pagep = node->page + (off >> PAGE_SHIFT);
112         off &= ~PAGE_MASK;
113
114         l = min_t(int, len, PAGE_SIZE - off);
115         memset(kmap(*pagep) + off, 0, l);
116         set_page_dirty(*pagep);
117         kunmap(*pagep);
118
119         while ((len -= l) != 0) {
120                 l = min_t(int, len, PAGE_SIZE);
121                 memset(kmap(*++pagep), 0, l);
122                 set_page_dirty(*pagep);
123                 kunmap(*pagep);
124         }
125 }
126
127 void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
128                     struct hfs_bnode *src_node, int src, int len)
129 {
130         struct hfs_btree *tree;
131         struct page **src_page, **dst_page;
132         int l;
133
134         hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len);
135         if (!len)
136                 return;
137         tree = src_node->tree;
138         src += src_node->page_offset;
139         dst += dst_node->page_offset;
140         src_page = src_node->page + (src >> PAGE_SHIFT);
141         src &= ~PAGE_MASK;
142         dst_page = dst_node->page + (dst >> PAGE_SHIFT);
143         dst &= ~PAGE_MASK;
144
145         if (src == dst) {
146                 l = min_t(int, len, PAGE_SIZE - src);
147                 memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l);
148                 kunmap(*src_page);
149                 set_page_dirty(*dst_page);
150                 kunmap(*dst_page);
151
152                 while ((len -= l) != 0) {
153                         l = min_t(int, len, PAGE_SIZE);
154                         memcpy(kmap(*++dst_page), kmap(*++src_page), l);
155                         kunmap(*src_page);
156                         set_page_dirty(*dst_page);
157                         kunmap(*dst_page);
158                 }
159         } else {
160                 void *src_ptr, *dst_ptr;
161
162                 do {
163                         src_ptr = kmap(*src_page) + src;
164                         dst_ptr = kmap(*dst_page) + dst;
165                         if (PAGE_SIZE - src < PAGE_SIZE - dst) {
166                                 l = PAGE_SIZE - src;
167                                 src = 0;
168                                 dst += l;
169                         } else {
170                                 l = PAGE_SIZE - dst;
171                                 src += l;
172                                 dst = 0;
173                         }
174                         l = min(len, l);
175                         memcpy(dst_ptr, src_ptr, l);
176                         kunmap(*src_page);
177                         set_page_dirty(*dst_page);
178                         kunmap(*dst_page);
179                         if (!dst)
180                                 dst_page++;
181                         else
182                                 src_page++;
183                 } while ((len -= l));
184         }
185 }
186
187 void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
188 {
189         struct page **src_page, **dst_page;
190         int l;
191
192         hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len);
193         if (!len)
194                 return;
195         src += node->page_offset;
196         dst += node->page_offset;
197         if (dst > src) {
198                 src += len - 1;
199                 src_page = node->page + (src >> PAGE_SHIFT);
200                 src = (src & ~PAGE_MASK) + 1;
201                 dst += len - 1;
202                 dst_page = node->page + (dst >> PAGE_SHIFT);
203                 dst = (dst & ~PAGE_MASK) + 1;
204
205                 if (src == dst) {
206                         while (src < len) {
207                                 memmove(kmap(*dst_page), kmap(*src_page), src);
208                                 kunmap(*src_page);
209                                 set_page_dirty(*dst_page);
210                                 kunmap(*dst_page);
211                                 len -= src;
212                                 src = PAGE_SIZE;
213                                 src_page--;
214                                 dst_page--;
215                         }
216                         src -= len;
217                         memmove(kmap(*dst_page) + src,
218                                 kmap(*src_page) + src, len);
219                         kunmap(*src_page);
220                         set_page_dirty(*dst_page);
221                         kunmap(*dst_page);
222                 } else {
223                         void *src_ptr, *dst_ptr;
224
225                         do {
226                                 src_ptr = kmap(*src_page) + src;
227                                 dst_ptr = kmap(*dst_page) + dst;
228                                 if (src < dst) {
229                                         l = src;
230                                         src = PAGE_SIZE;
231                                         dst -= l;
232                                 } else {
233                                         l = dst;
234                                         src -= l;
235                                         dst = PAGE_SIZE;
236                                 }
237                                 l = min(len, l);
238                                 memmove(dst_ptr - l, src_ptr - l, l);
239                                 kunmap(*src_page);
240                                 set_page_dirty(*dst_page);
241                                 kunmap(*dst_page);
242                                 if (dst == PAGE_SIZE)
243                                         dst_page--;
244                                 else
245                                         src_page--;
246                         } while ((len -= l));
247                 }
248         } else {
249                 src_page = node->page + (src >> PAGE_SHIFT);
250                 src &= ~PAGE_MASK;
251                 dst_page = node->page + (dst >> PAGE_SHIFT);
252                 dst &= ~PAGE_MASK;
253
254                 if (src == dst) {
255                         l = min_t(int, len, PAGE_SIZE - src);
256                         memmove(kmap(*dst_page) + src,
257                                 kmap(*src_page) + src, l);
258                         kunmap(*src_page);
259                         set_page_dirty(*dst_page);
260                         kunmap(*dst_page);
261
262                         while ((len -= l) != 0) {
263                                 l = min_t(int, len, PAGE_SIZE);
264                                 memmove(kmap(*++dst_page),
265                                         kmap(*++src_page), l);
266                                 kunmap(*src_page);
267                                 set_page_dirty(*dst_page);
268                                 kunmap(*dst_page);
269                         }
270                 } else {
271                         void *src_ptr, *dst_ptr;
272
273                         do {
274                                 src_ptr = kmap(*src_page) + src;
275                                 dst_ptr = kmap(*dst_page) + dst;
276                                 if (PAGE_SIZE - src <
277                                                 PAGE_SIZE - dst) {
278                                         l = PAGE_SIZE - src;
279                                         src = 0;
280                                         dst += l;
281                                 } else {
282                                         l = PAGE_SIZE - dst;
283                                         src += l;
284                                         dst = 0;
285                                 }
286                                 l = min(len, l);
287                                 memmove(dst_ptr, src_ptr, l);
288                                 kunmap(*src_page);
289                                 set_page_dirty(*dst_page);
290                                 kunmap(*dst_page);
291                                 if (!dst)
292                                         dst_page++;
293                                 else
294                                         src_page++;
295                         } while ((len -= l));
296                 }
297         }
298 }
299
300 void hfs_bnode_dump(struct hfs_bnode *node)
301 {
302         struct hfs_bnode_desc desc;
303         __be32 cnid;
304         int i, off, key_off;
305
306         hfs_dbg(BNODE_MOD, "bnode: %d\n", node->this);
307         hfs_bnode_read(node, &desc, 0, sizeof(desc));
308         hfs_dbg(BNODE_MOD, "%d, %d, %d, %d, %d\n",
309                 be32_to_cpu(desc.next), be32_to_cpu(desc.prev),
310                 desc.type, desc.height, be16_to_cpu(desc.num_recs));
311
312         off = node->tree->node_size - 2;
313         for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) {
314                 key_off = hfs_bnode_read_u16(node, off);
315                 hfs_dbg(BNODE_MOD, " %d", key_off);
316                 if (i && node->type == HFS_NODE_INDEX) {
317                         int tmp;
318
319                         if (node->tree->attributes & HFS_TREE_VARIDXKEYS ||
320                                         node->tree->cnid == HFSPLUS_ATTR_CNID)
321                                 tmp = hfs_bnode_read_u16(node, key_off) + 2;
322                         else
323                                 tmp = node->tree->max_key_len + 2;
324                         hfs_dbg_cont(BNODE_MOD, " (%d", tmp);
325                         hfs_bnode_read(node, &cnid, key_off + tmp, 4);
326                         hfs_dbg_cont(BNODE_MOD, ",%d)", be32_to_cpu(cnid));
327                 } else if (i && node->type == HFS_NODE_LEAF) {
328                         int tmp;
329
330                         tmp = hfs_bnode_read_u16(node, key_off);
331                         hfs_dbg_cont(BNODE_MOD, " (%d)", tmp);
332                 }
333         }
334         hfs_dbg_cont(BNODE_MOD, "\n");
335 }
336
337 void hfs_bnode_unlink(struct hfs_bnode *node)
338 {
339         struct hfs_btree *tree;
340         struct hfs_bnode *tmp;
341         __be32 cnid;
342
343         tree = node->tree;
344         if (node->prev) {
345                 tmp = hfs_bnode_find(tree, node->prev);
346                 if (IS_ERR(tmp))
347                         return;
348                 tmp->next = node->next;
349                 cnid = cpu_to_be32(tmp->next);
350                 hfs_bnode_write(tmp, &cnid,
351                         offsetof(struct hfs_bnode_desc, next), 4);
352                 hfs_bnode_put(tmp);
353         } else if (node->type == HFS_NODE_LEAF)
354                 tree->leaf_head = node->next;
355
356         if (node->next) {
357                 tmp = hfs_bnode_find(tree, node->next);
358                 if (IS_ERR(tmp))
359                         return;
360                 tmp->prev = node->prev;
361                 cnid = cpu_to_be32(tmp->prev);
362                 hfs_bnode_write(tmp, &cnid,
363                         offsetof(struct hfs_bnode_desc, prev), 4);
364                 hfs_bnode_put(tmp);
365         } else if (node->type == HFS_NODE_LEAF)
366                 tree->leaf_tail = node->prev;
367
368         /* move down? */
369         if (!node->prev && !node->next)
370                 hfs_dbg(BNODE_MOD, "hfs_btree_del_level\n");
371         if (!node->parent) {
372                 tree->root = 0;
373                 tree->depth = 0;
374         }
375         set_bit(HFS_BNODE_DELETED, &node->flags);
376 }
377
378 static inline int hfs_bnode_hash(u32 num)
379 {
380         num = (num >> 16) + num;
381         num += num >> 8;
382         return num & (NODE_HASH_SIZE - 1);
383 }
384
385 struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid)
386 {
387         struct hfs_bnode *node;
388
389         if (cnid >= tree->node_count) {
390                 pr_err("request for non-existent node %d in B*Tree\n",
391                        cnid);
392                 return NULL;
393         }
394
395         for (node = tree->node_hash[hfs_bnode_hash(cnid)];
396                         node; node = node->next_hash)
397                 if (node->this == cnid)
398                         return node;
399         return NULL;
400 }
401
402 static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
403 {
404         struct super_block *sb;
405         struct hfs_bnode *node, *node2;
406         struct address_space *mapping;
407         struct page *page;
408         int size, block, i, hash;
409         loff_t off;
410
411         if (cnid >= tree->node_count) {
412                 pr_err("request for non-existent node %d in B*Tree\n",
413                        cnid);
414                 return NULL;
415         }
416
417         sb = tree->inode->i_sb;
418         size = sizeof(struct hfs_bnode) + tree->pages_per_bnode *
419                 sizeof(struct page *);
420         node = kzalloc(size, GFP_KERNEL);
421         if (!node)
422                 return NULL;
423         node->tree = tree;
424         node->this = cnid;
425         set_bit(HFS_BNODE_NEW, &node->flags);
426         atomic_set(&node->refcnt, 1);
427         hfs_dbg(BNODE_REFS, "new_node(%d:%d): 1\n",
428                 node->tree->cnid, node->this);
429         init_waitqueue_head(&node->lock_wq);
430         spin_lock(&tree->hash_lock);
431         node2 = hfs_bnode_findhash(tree, cnid);
432         if (!node2) {
433                 hash = hfs_bnode_hash(cnid);
434                 node->next_hash = tree->node_hash[hash];
435                 tree->node_hash[hash] = node;
436                 tree->node_hash_cnt++;
437         } else {
438                 spin_unlock(&tree->hash_lock);
439                 kfree(node);
440                 wait_event(node2->lock_wq,
441                         !test_bit(HFS_BNODE_NEW, &node2->flags));
442                 return node2;
443         }
444         spin_unlock(&tree->hash_lock);
445
446         mapping = tree->inode->i_mapping;
447         off = (loff_t)cnid << tree->node_size_shift;
448         block = off >> PAGE_SHIFT;
449         node->page_offset = off & ~PAGE_MASK;
450         for (i = 0; i < tree->pages_per_bnode; block++, i++) {
451                 page = read_mapping_page(mapping, block, NULL);
452                 if (IS_ERR(page))
453                         goto fail;
454                 if (PageError(page)) {
455                         put_page(page);
456                         goto fail;
457                 }
458                 node->page[i] = page;
459         }
460
461         return node;
462 fail:
463         set_bit(HFS_BNODE_ERROR, &node->flags);
464         return node;
465 }
466
467 void hfs_bnode_unhash(struct hfs_bnode *node)
468 {
469         struct hfs_bnode **p;
470
471         hfs_dbg(BNODE_REFS, "remove_node(%d:%d): %d\n",
472                 node->tree->cnid, node->this, atomic_read(&node->refcnt));
473         for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)];
474              *p && *p != node; p = &(*p)->next_hash)
475                 ;
476         BUG_ON(!*p);
477         *p = node->next_hash;
478         node->tree->node_hash_cnt--;
479 }
480
481 /* Load a particular node out of a tree */
482 struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num)
483 {
484         struct hfs_bnode *node;
485         struct hfs_bnode_desc *desc;
486         int i, rec_off, off, next_off;
487         int entry_size, key_size;
488
489         spin_lock(&tree->hash_lock);
490         node = hfs_bnode_findhash(tree, num);
491         if (node) {
492                 hfs_bnode_get(node);
493                 spin_unlock(&tree->hash_lock);
494                 wait_event(node->lock_wq,
495                         !test_bit(HFS_BNODE_NEW, &node->flags));
496                 if (test_bit(HFS_BNODE_ERROR, &node->flags))
497                         goto node_error;
498                 return node;
499         }
500         spin_unlock(&tree->hash_lock);
501         node = __hfs_bnode_create(tree, num);
502         if (!node)
503                 return ERR_PTR(-ENOMEM);
504         if (test_bit(HFS_BNODE_ERROR, &node->flags))
505                 goto node_error;
506         if (!test_bit(HFS_BNODE_NEW, &node->flags))
507                 return node;
508
509         desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) +
510                         node->page_offset);
511         node->prev = be32_to_cpu(desc->prev);
512         node->next = be32_to_cpu(desc->next);
513         node->num_recs = be16_to_cpu(desc->num_recs);
514         node->type = desc->type;
515         node->height = desc->height;
516         kunmap(node->page[0]);
517
518         switch (node->type) {
519         case HFS_NODE_HEADER:
520         case HFS_NODE_MAP:
521                 if (node->height != 0)
522                         goto node_error;
523                 break;
524         case HFS_NODE_LEAF:
525                 if (node->height != 1)
526                         goto node_error;
527                 break;
528         case HFS_NODE_INDEX:
529                 if (node->height <= 1 || node->height > tree->depth)
530                         goto node_error;
531                 break;
532         default:
533                 goto node_error;
534         }
535
536         rec_off = tree->node_size - 2;
537         off = hfs_bnode_read_u16(node, rec_off);
538         if (off != sizeof(struct hfs_bnode_desc))
539                 goto node_error;
540         for (i = 1; i <= node->num_recs; off = next_off, i++) {
541                 rec_off -= 2;
542                 next_off = hfs_bnode_read_u16(node, rec_off);
543                 if (next_off <= off ||
544                     next_off > tree->node_size ||
545                     next_off & 1)
546                         goto node_error;
547                 entry_size = next_off - off;
548                 if (node->type != HFS_NODE_INDEX &&
549                     node->type != HFS_NODE_LEAF)
550                         continue;
551                 key_size = hfs_bnode_read_u16(node, off) + 2;
552                 if (key_size >= entry_size || key_size & 1)
553                         goto node_error;
554         }
555         clear_bit(HFS_BNODE_NEW, &node->flags);
556         wake_up(&node->lock_wq);
557         return node;
558
559 node_error:
560         set_bit(HFS_BNODE_ERROR, &node->flags);
561         clear_bit(HFS_BNODE_NEW, &node->flags);
562         wake_up(&node->lock_wq);
563         hfs_bnode_put(node);
564         return ERR_PTR(-EIO);
565 }
566
567 void hfs_bnode_free(struct hfs_bnode *node)
568 {
569         int i;
570
571         for (i = 0; i < node->tree->pages_per_bnode; i++)
572                 if (node->page[i])
573                         put_page(node->page[i]);
574         kfree(node);
575 }
576
577 struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)
578 {
579         struct hfs_bnode *node;
580         struct page **pagep;
581         int i;
582
583         spin_lock(&tree->hash_lock);
584         node = hfs_bnode_findhash(tree, num);
585         spin_unlock(&tree->hash_lock);
586         if (node) {
587                 pr_crit("new node %u already hashed?\n", num);
588                 WARN_ON(1);
589                 return node;
590         }
591         node = __hfs_bnode_create(tree, num);
592         if (!node)
593                 return ERR_PTR(-ENOMEM);
594         if (test_bit(HFS_BNODE_ERROR, &node->flags)) {
595                 hfs_bnode_put(node);
596                 return ERR_PTR(-EIO);
597         }
598
599         pagep = node->page;
600         memset(kmap(*pagep) + node->page_offset, 0,
601                min_t(int, PAGE_SIZE, tree->node_size));
602         set_page_dirty(*pagep);
603         kunmap(*pagep);
604         for (i = 1; i < tree->pages_per_bnode; i++) {
605                 memset(kmap(*++pagep), 0, PAGE_SIZE);
606                 set_page_dirty(*pagep);
607                 kunmap(*pagep);
608         }
609         clear_bit(HFS_BNODE_NEW, &node->flags);
610         wake_up(&node->lock_wq);
611
612         return node;
613 }
614
615 void hfs_bnode_get(struct hfs_bnode *node)
616 {
617         if (node) {
618                 atomic_inc(&node->refcnt);
619                 hfs_dbg(BNODE_REFS, "get_node(%d:%d): %d\n",
620                         node->tree->cnid, node->this,
621                         atomic_read(&node->refcnt));
622         }
623 }
624
625 /* Dispose of resources used by a node */
626 void hfs_bnode_put(struct hfs_bnode *node)
627 {
628         if (node) {
629                 struct hfs_btree *tree = node->tree;
630                 int i;
631
632                 hfs_dbg(BNODE_REFS, "put_node(%d:%d): %d\n",
633                         node->tree->cnid, node->this,
634                         atomic_read(&node->refcnt));
635                 BUG_ON(!atomic_read(&node->refcnt));
636                 if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock))
637                         return;
638                 for (i = 0; i < tree->pages_per_bnode; i++) {
639                         if (!node->page[i])
640                                 continue;
641                         mark_page_accessed(node->page[i]);
642                 }
643
644                 if (test_bit(HFS_BNODE_DELETED, &node->flags)) {
645                         hfs_bnode_unhash(node);
646                         spin_unlock(&tree->hash_lock);
647                         if (hfs_bnode_need_zeroout(tree))
648                                 hfs_bnode_clear(node, 0, tree->node_size);
649                         hfs_bmap_free(node);
650                         hfs_bnode_free(node);
651                         return;
652                 }
653                 spin_unlock(&tree->hash_lock);
654         }
655 }
656
657 /*
658  * Unused nodes have to be zeroed if this is the catalog tree and
659  * a corresponding flag in the volume header is set.
660  */
661 bool hfs_bnode_need_zeroout(struct hfs_btree *tree)
662 {
663         struct super_block *sb = tree->inode->i_sb;
664         struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
665         const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes);
666
667         return tree->cnid == HFSPLUS_CAT_CNID &&
668                 volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX;
669 }