diff options
Diffstat (limited to 'fs/nilfs2/inode.c')
-rw-r--r-- | fs/nilfs2/inode.c | 167 |
1 files changed, 134 insertions, 33 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index eccb2f2e2315..71d4bc8464e0 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -34,6 +34,12 @@ | |||
34 | #include "cpfile.h" | 34 | #include "cpfile.h" |
35 | #include "ifile.h" | 35 | #include "ifile.h" |
36 | 36 | ||
37 | struct nilfs_iget_args { | ||
38 | u64 ino; | ||
39 | __u64 cno; | ||
40 | struct nilfs_root *root; | ||
41 | int for_gc; | ||
42 | }; | ||
37 | 43 | ||
38 | /** | 44 | /** |
39 | * nilfs_get_block() - get a file block on the filesystem (callback function) | 45 | * nilfs_get_block() - get a file block on the filesystem (callback function) |
@@ -279,6 +285,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
279 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 285 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
280 | struct inode *inode; | 286 | struct inode *inode; |
281 | struct nilfs_inode_info *ii; | 287 | struct nilfs_inode_info *ii; |
288 | struct nilfs_root *root; | ||
282 | int err = -ENOMEM; | 289 | int err = -ENOMEM; |
283 | ino_t ino; | 290 | ino_t ino; |
284 | 291 | ||
@@ -289,15 +296,17 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
289 | mapping_set_gfp_mask(inode->i_mapping, | 296 | mapping_set_gfp_mask(inode->i_mapping, |
290 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 297 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
291 | 298 | ||
299 | root = NILFS_I(dir)->i_root; | ||
292 | ii = NILFS_I(inode); | 300 | ii = NILFS_I(inode); |
293 | ii->i_state = 1 << NILFS_I_NEW; | 301 | ii->i_state = 1 << NILFS_I_NEW; |
302 | ii->i_root = root; | ||
294 | 303 | ||
295 | err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); | 304 | err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh); |
296 | if (unlikely(err)) | 305 | if (unlikely(err)) |
297 | goto failed_ifile_create_inode; | 306 | goto failed_ifile_create_inode; |
298 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ | 307 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ |
299 | 308 | ||
300 | atomic_inc(&sbi->s_inodes_count); | 309 | atomic_inc(&root->inodes_count); |
301 | inode_init_owner(inode, dir, mode); | 310 | inode_init_owner(inode, dir, mode); |
302 | inode->i_ino = ino; | 311 | inode->i_ino = ino; |
303 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 312 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
@@ -320,7 +329,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
320 | /* ii->i_file_acl = 0; */ | 329 | /* ii->i_file_acl = 0; */ |
321 | /* ii->i_dir_acl = 0; */ | 330 | /* ii->i_dir_acl = 0; */ |
322 | ii->i_dir_start_lookup = 0; | 331 | ii->i_dir_start_lookup = 0; |
323 | ii->i_cno = 0; | ||
324 | nilfs_set_inode_flags(inode); | 332 | nilfs_set_inode_flags(inode); |
325 | spin_lock(&sbi->s_next_gen_lock); | 333 | spin_lock(&sbi->s_next_gen_lock); |
326 | inode->i_generation = sbi->s_next_generation++; | 334 | inode->i_generation = sbi->s_next_generation++; |
@@ -350,16 +358,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
350 | return ERR_PTR(err); | 358 | return ERR_PTR(err); |
351 | } | 359 | } |
352 | 360 | ||
353 | void nilfs_free_inode(struct inode *inode) | ||
354 | { | ||
355 | struct super_block *sb = inode->i_sb; | ||
356 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
357 | |||
358 | /* XXX: check error code? Is there any thing I can do? */ | ||
359 | (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino); | ||
360 | atomic_dec(&sbi->s_inodes_count); | ||
361 | } | ||
362 | |||
363 | void nilfs_set_inode_flags(struct inode *inode) | 361 | void nilfs_set_inode_flags(struct inode *inode) |
364 | { | 362 | { |
365 | unsigned int flags = NILFS_I(inode)->i_flags; | 363 | unsigned int flags = NILFS_I(inode)->i_flags; |
@@ -410,7 +408,6 @@ int nilfs_read_inode_common(struct inode *inode, | |||
410 | 0 : le32_to_cpu(raw_inode->i_dir_acl); | 408 | 0 : le32_to_cpu(raw_inode->i_dir_acl); |
411 | #endif | 409 | #endif |
412 | ii->i_dir_start_lookup = 0; | 410 | ii->i_dir_start_lookup = 0; |
413 | ii->i_cno = 0; | ||
414 | inode->i_generation = le32_to_cpu(raw_inode->i_generation); | 411 | inode->i_generation = le32_to_cpu(raw_inode->i_generation); |
415 | 412 | ||
416 | if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 413 | if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
@@ -424,7 +421,8 @@ int nilfs_read_inode_common(struct inode *inode, | |||
424 | return 0; | 421 | return 0; |
425 | } | 422 | } |
426 | 423 | ||
427 | static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | 424 | static int __nilfs_read_inode(struct super_block *sb, |
425 | struct nilfs_root *root, unsigned long ino, | ||
428 | struct inode *inode) | 426 | struct inode *inode) |
429 | { | 427 | { |
430 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 428 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
@@ -434,11 +432,11 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
434 | int err; | 432 | int err; |
435 | 433 | ||
436 | down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 434 | down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ |
437 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, ino, &bh); | 435 | err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh); |
438 | if (unlikely(err)) | 436 | if (unlikely(err)) |
439 | goto bad_inode; | 437 | goto bad_inode; |
440 | 438 | ||
441 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); | 439 | raw_inode = nilfs_ifile_map_inode(root->ifile, ino, bh); |
442 | 440 | ||
443 | err = nilfs_read_inode_common(inode, raw_inode); | 441 | err = nilfs_read_inode_common(inode, raw_inode); |
444 | if (err) | 442 | if (err) |
@@ -461,14 +459,14 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
461 | inode, inode->i_mode, | 459 | inode, inode->i_mode, |
462 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); | 460 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); |
463 | } | 461 | } |
464 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 462 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
465 | brelse(bh); | 463 | brelse(bh); |
466 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 464 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ |
467 | nilfs_set_inode_flags(inode); | 465 | nilfs_set_inode_flags(inode); |
468 | return 0; | 466 | return 0; |
469 | 467 | ||
470 | failed_unmap: | 468 | failed_unmap: |
471 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 469 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
472 | brelse(bh); | 470 | brelse(bh); |
473 | 471 | ||
474 | bad_inode: | 472 | bad_inode: |
@@ -476,18 +474,95 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
476 | return err; | 474 | return err; |
477 | } | 475 | } |
478 | 476 | ||
479 | struct inode *nilfs_iget(struct super_block *sb, unsigned long ino) | 477 | static int nilfs_iget_test(struct inode *inode, void *opaque) |
478 | { | ||
479 | struct nilfs_iget_args *args = opaque; | ||
480 | struct nilfs_inode_info *ii; | ||
481 | |||
482 | if (args->ino != inode->i_ino || args->root != NILFS_I(inode)->i_root) | ||
483 | return 0; | ||
484 | |||
485 | ii = NILFS_I(inode); | ||
486 | if (!test_bit(NILFS_I_GCINODE, &ii->i_state)) | ||
487 | return !args->for_gc; | ||
488 | |||
489 | return args->for_gc && args->cno == ii->i_cno; | ||
490 | } | ||
491 | |||
492 | static int nilfs_iget_set(struct inode *inode, void *opaque) | ||
493 | { | ||
494 | struct nilfs_iget_args *args = opaque; | ||
495 | |||
496 | inode->i_ino = args->ino; | ||
497 | if (args->for_gc) { | ||
498 | NILFS_I(inode)->i_state = 1 << NILFS_I_GCINODE; | ||
499 | NILFS_I(inode)->i_cno = args->cno; | ||
500 | NILFS_I(inode)->i_root = NULL; | ||
501 | } else { | ||
502 | if (args->root && args->ino == NILFS_ROOT_INO) | ||
503 | nilfs_get_root(args->root); | ||
504 | NILFS_I(inode)->i_root = args->root; | ||
505 | } | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | struct inode *nilfs_ilookup(struct super_block *sb, struct nilfs_root *root, | ||
510 | unsigned long ino) | ||
511 | { | ||
512 | struct nilfs_iget_args args = { | ||
513 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
514 | }; | ||
515 | |||
516 | return ilookup5(sb, ino, nilfs_iget_test, &args); | ||
517 | } | ||
518 | |||
519 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, | ||
520 | unsigned long ino) | ||
521 | { | ||
522 | struct nilfs_iget_args args = { | ||
523 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
524 | }; | ||
525 | |||
526 | return iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); | ||
527 | } | ||
528 | |||
529 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | ||
530 | unsigned long ino) | ||
480 | { | 531 | { |
481 | struct inode *inode; | 532 | struct inode *inode; |
482 | int err; | 533 | int err; |
483 | 534 | ||
484 | inode = iget_locked(sb, ino); | 535 | inode = nilfs_iget_locked(sb, root, ino); |
485 | if (unlikely(!inode)) | 536 | if (unlikely(!inode)) |
486 | return ERR_PTR(-ENOMEM); | 537 | return ERR_PTR(-ENOMEM); |
487 | if (!(inode->i_state & I_NEW)) | 538 | if (!(inode->i_state & I_NEW)) |
488 | return inode; | 539 | return inode; |
489 | 540 | ||
490 | err = __nilfs_read_inode(sb, ino, inode); | 541 | err = __nilfs_read_inode(sb, root, ino, inode); |
542 | if (unlikely(err)) { | ||
543 | iget_failed(inode); | ||
544 | return ERR_PTR(err); | ||
545 | } | ||
546 | unlock_new_inode(inode); | ||
547 | return inode; | ||
548 | } | ||
549 | |||
550 | struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, | ||
551 | __u64 cno) | ||
552 | { | ||
553 | struct nilfs_iget_args args = { | ||
554 | .ino = ino, .root = NULL, .cno = cno, .for_gc = 1 | ||
555 | }; | ||
556 | struct inode *inode; | ||
557 | int err; | ||
558 | |||
559 | inode = iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); | ||
560 | if (unlikely(!inode)) | ||
561 | return ERR_PTR(-ENOMEM); | ||
562 | if (!(inode->i_state & I_NEW)) | ||
563 | return inode; | ||
564 | |||
565 | err = nilfs_init_gcinode(inode); | ||
491 | if (unlikely(err)) { | 566 | if (unlikely(err)) { |
492 | iget_failed(inode); | 567 | iget_failed(inode); |
493 | return ERR_PTR(err); | 568 | return ERR_PTR(err); |
@@ -528,21 +603,20 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) | |||
528 | { | 603 | { |
529 | ino_t ino = inode->i_ino; | 604 | ino_t ino = inode->i_ino; |
530 | struct nilfs_inode_info *ii = NILFS_I(inode); | 605 | struct nilfs_inode_info *ii = NILFS_I(inode); |
531 | struct super_block *sb = inode->i_sb; | 606 | struct inode *ifile = ii->i_root->ifile; |
532 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
533 | struct nilfs_inode *raw_inode; | 607 | struct nilfs_inode *raw_inode; |
534 | 608 | ||
535 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); | 609 | raw_inode = nilfs_ifile_map_inode(ifile, ino, ibh); |
536 | 610 | ||
537 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) | 611 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) |
538 | memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); | 612 | memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); |
539 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); | 613 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); |
540 | 614 | ||
541 | nilfs_write_inode_common(inode, raw_inode, 0); | 615 | nilfs_write_inode_common(inode, raw_inode, 0); |
542 | /* XXX: call with has_bmap = 0 is a workaround to avoid | 616 | /* XXX: call with has_bmap = 0 is a workaround to avoid |
543 | deadlock of bmap. This delays update of i_bmap to just | 617 | deadlock of bmap. This delays update of i_bmap to just |
544 | before writing */ | 618 | before writing */ |
545 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, ibh); | 619 | nilfs_ifile_unmap_inode(ifile, ino, ibh); |
546 | } | 620 | } |
547 | 621 | ||
548 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ | 622 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ |
@@ -617,6 +691,7 @@ void nilfs_truncate(struct inode *inode) | |||
617 | static void nilfs_clear_inode(struct inode *inode) | 691 | static void nilfs_clear_inode(struct inode *inode) |
618 | { | 692 | { |
619 | struct nilfs_inode_info *ii = NILFS_I(inode); | 693 | struct nilfs_inode_info *ii = NILFS_I(inode); |
694 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
620 | 695 | ||
621 | /* | 696 | /* |
622 | * Free resources allocated in nilfs_read_inode(), here. | 697 | * Free resources allocated in nilfs_read_inode(), here. |
@@ -625,10 +700,16 @@ static void nilfs_clear_inode(struct inode *inode) | |||
625 | brelse(ii->i_bh); | 700 | brelse(ii->i_bh); |
626 | ii->i_bh = NULL; | 701 | ii->i_bh = NULL; |
627 | 702 | ||
703 | if (mdi && mdi->mi_palloc_cache) | ||
704 | nilfs_palloc_destroy_cache(inode); | ||
705 | |||
628 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) | 706 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) |
629 | nilfs_bmap_clear(ii->i_bmap); | 707 | nilfs_bmap_clear(ii->i_bmap); |
630 | 708 | ||
631 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); | 709 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); |
710 | |||
711 | if (ii->i_root && inode->i_ino == NILFS_ROOT_INO) | ||
712 | nilfs_put_root(ii->i_root); | ||
632 | } | 713 | } |
633 | 714 | ||
634 | void nilfs_evict_inode(struct inode *inode) | 715 | void nilfs_evict_inode(struct inode *inode) |
@@ -637,7 +718,7 @@ void nilfs_evict_inode(struct inode *inode) | |||
637 | struct super_block *sb = inode->i_sb; | 718 | struct super_block *sb = inode->i_sb; |
638 | struct nilfs_inode_info *ii = NILFS_I(inode); | 719 | struct nilfs_inode_info *ii = NILFS_I(inode); |
639 | 720 | ||
640 | if (inode->i_nlink || unlikely(is_bad_inode(inode))) { | 721 | if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { |
641 | if (inode->i_data.nrpages) | 722 | if (inode->i_data.nrpages) |
642 | truncate_inode_pages(&inode->i_data, 0); | 723 | truncate_inode_pages(&inode->i_data, 0); |
643 | end_writeback(inode); | 724 | end_writeback(inode); |
@@ -649,12 +730,16 @@ void nilfs_evict_inode(struct inode *inode) | |||
649 | if (inode->i_data.nrpages) | 730 | if (inode->i_data.nrpages) |
650 | truncate_inode_pages(&inode->i_data, 0); | 731 | truncate_inode_pages(&inode->i_data, 0); |
651 | 732 | ||
733 | /* TODO: some of the following operations may fail. */ | ||
652 | nilfs_truncate_bmap(ii, 0); | 734 | nilfs_truncate_bmap(ii, 0); |
653 | nilfs_mark_inode_dirty(inode); | 735 | nilfs_mark_inode_dirty(inode); |
654 | end_writeback(inode); | 736 | end_writeback(inode); |
737 | |||
738 | nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino); | ||
739 | atomic_dec(&ii->i_root->inodes_count); | ||
740 | |||
655 | nilfs_clear_inode(inode); | 741 | nilfs_clear_inode(inode); |
656 | nilfs_free_inode(inode); | 742 | |
657 | /* nilfs_free_inode() marks inode buffer dirty */ | ||
658 | if (IS_SYNC(inode)) | 743 | if (IS_SYNC(inode)) |
659 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 744 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
660 | nilfs_transaction_commit(sb); | 745 | nilfs_transaction_commit(sb); |
@@ -700,6 +785,17 @@ out_err: | |||
700 | return err; | 785 | return err; |
701 | } | 786 | } |
702 | 787 | ||
788 | int nilfs_permission(struct inode *inode, int mask) | ||
789 | { | ||
790 | struct nilfs_root *root = NILFS_I(inode)->i_root; | ||
791 | |||
792 | if ((mask & MAY_WRITE) && root && | ||
793 | root->cno != NILFS_CPTREE_CURRENT_CNO) | ||
794 | return -EROFS; /* snapshot is not writable */ | ||
795 | |||
796 | return generic_permission(inode, mask, NULL); | ||
797 | } | ||
798 | |||
703 | int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | 799 | int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, |
704 | struct buffer_head **pbh) | 800 | struct buffer_head **pbh) |
705 | { | 801 | { |
@@ -709,8 +805,8 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | |||
709 | spin_lock(&sbi->s_inode_lock); | 805 | spin_lock(&sbi->s_inode_lock); |
710 | if (ii->i_bh == NULL) { | 806 | if (ii->i_bh == NULL) { |
711 | spin_unlock(&sbi->s_inode_lock); | 807 | spin_unlock(&sbi->s_inode_lock); |
712 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino, | 808 | err = nilfs_ifile_get_inode_block(ii->i_root->ifile, |
713 | pbh); | 809 | inode->i_ino, pbh); |
714 | if (unlikely(err)) | 810 | if (unlikely(err)) |
715 | return err; | 811 | return err; |
716 | spin_lock(&sbi->s_inode_lock); | 812 | spin_lock(&sbi->s_inode_lock); |
@@ -790,7 +886,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
790 | } | 886 | } |
791 | nilfs_update_inode(inode, ibh); | 887 | nilfs_update_inode(inode, ibh); |
792 | nilfs_mdt_mark_buffer_dirty(ibh); | 888 | nilfs_mdt_mark_buffer_dirty(ibh); |
793 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 889 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); |
794 | brelse(ibh); | 890 | brelse(ibh); |
795 | return 0; | 891 | return 0; |
796 | } | 892 | } |
@@ -808,6 +904,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
808 | void nilfs_dirty_inode(struct inode *inode) | 904 | void nilfs_dirty_inode(struct inode *inode) |
809 | { | 905 | { |
810 | struct nilfs_transaction_info ti; | 906 | struct nilfs_transaction_info ti; |
907 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
811 | 908 | ||
812 | if (is_bad_inode(inode)) { | 909 | if (is_bad_inode(inode)) { |
813 | nilfs_warning(inode->i_sb, __func__, | 910 | nilfs_warning(inode->i_sb, __func__, |
@@ -815,6 +912,10 @@ void nilfs_dirty_inode(struct inode *inode) | |||
815 | dump_stack(); | 912 | dump_stack(); |
816 | return; | 913 | return; |
817 | } | 914 | } |
915 | if (mdi) { | ||
916 | nilfs_mdt_mark_dirty(inode); | ||
917 | return; | ||
918 | } | ||
818 | nilfs_transaction_begin(inode->i_sb, &ti, 0); | 919 | nilfs_transaction_begin(inode->i_sb, &ti, 0); |
819 | nilfs_mark_inode_dirty(inode); | 920 | nilfs_mark_inode_dirty(inode); |
820 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | 921 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |