.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* -*- mode: c; c-basic-offset: 8; -*- |
---|
2 | 3 | * vim: noexpandtab sw=8 ts=8 sts=0: |
---|
3 | 4 | * |
---|
.. | .. |
---|
19 | 20 | * linux/fs/minix/dir.c |
---|
20 | 21 | * |
---|
21 | 22 | * Copyright (C) 1991, 1992 Linux Torvalds |
---|
22 | | - * |
---|
23 | | - * This program is free software; you can redistribute it and/or |
---|
24 | | - * modify it under the terms of the GNU General Public |
---|
25 | | - * License as published by the Free Software Foundation; either |
---|
26 | | - * version 2 of the License, or (at your option) any later version. |
---|
27 | | - * |
---|
28 | | - * This program is distributed in the hope that it will be useful, |
---|
29 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
30 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
31 | | - * General Public License for more details. |
---|
32 | | - * |
---|
33 | | - * You should have received a copy of the GNU General Public |
---|
34 | | - * License along with this program; if not, write to the |
---|
35 | | - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
36 | | - * Boston, MA 021110-1307, USA. |
---|
37 | 23 | */ |
---|
38 | 24 | |
---|
39 | 25 | #include <linux/fs.h> |
---|
.. | .. |
---|
245 | 231 | handle_t *handle = NULL; |
---|
246 | 232 | struct ocfs2_super *osb; |
---|
247 | 233 | struct ocfs2_dinode *dirfe; |
---|
| 234 | + struct ocfs2_dinode *fe = NULL; |
---|
248 | 235 | struct buffer_head *new_fe_bh = NULL; |
---|
249 | 236 | struct inode *inode = NULL; |
---|
250 | 237 | struct ocfs2_alloc_context *inode_ac = NULL; |
---|
.. | .. |
---|
395 | 382 | goto leave; |
---|
396 | 383 | } |
---|
397 | 384 | |
---|
| 385 | + fe = (struct ocfs2_dinode *) new_fe_bh->b_data; |
---|
398 | 386 | if (S_ISDIR(mode)) { |
---|
399 | 387 | status = ocfs2_fill_new_dir(osb, handle, dir, inode, |
---|
400 | 388 | new_fe_bh, data_ac, meta_ac); |
---|
.. | .. |
---|
420 | 408 | |
---|
421 | 409 | if (status < 0) { |
---|
422 | 410 | mlog_errno(status); |
---|
423 | | - goto leave; |
---|
| 411 | + goto roll_back; |
---|
424 | 412 | } |
---|
425 | 413 | |
---|
426 | 414 | if (si.enable) { |
---|
.. | .. |
---|
428 | 416 | meta_ac, data_ac); |
---|
429 | 417 | if (status < 0) { |
---|
430 | 418 | mlog_errno(status); |
---|
431 | | - goto leave; |
---|
| 419 | + goto roll_back; |
---|
432 | 420 | } |
---|
433 | 421 | } |
---|
434 | 422 | |
---|
.. | .. |
---|
441 | 429 | OCFS2_I(dir)->ip_blkno); |
---|
442 | 430 | if (status) { |
---|
443 | 431 | mlog_errno(status); |
---|
444 | | - goto leave; |
---|
| 432 | + goto roll_back; |
---|
445 | 433 | } |
---|
446 | 434 | |
---|
447 | 435 | dl = dentry->d_fsdata; |
---|
.. | .. |
---|
451 | 439 | &lookup); |
---|
452 | 440 | if (status < 0) { |
---|
453 | 441 | mlog_errno(status); |
---|
454 | | - goto leave; |
---|
| 442 | + goto roll_back; |
---|
455 | 443 | } |
---|
456 | 444 | |
---|
457 | 445 | insert_inode_hash(inode); |
---|
458 | 446 | d_instantiate(dentry, inode); |
---|
459 | 447 | status = 0; |
---|
| 448 | + |
---|
| 449 | +roll_back: |
---|
| 450 | + if (status < 0 && S_ISDIR(mode)) { |
---|
| 451 | + ocfs2_add_links_count(dirfe, -1); |
---|
| 452 | + drop_nlink(dir); |
---|
| 453 | + } |
---|
| 454 | + |
---|
460 | 455 | leave: |
---|
461 | 456 | if (status < 0 && did_quota_inode) |
---|
462 | 457 | dquot_free_inode(inode); |
---|
463 | | - if (handle) |
---|
| 458 | + if (handle) { |
---|
| 459 | + if (status < 0 && fe) |
---|
| 460 | + ocfs2_set_links_count(fe, 0); |
---|
464 | 461 | ocfs2_commit_trans(osb, handle); |
---|
| 462 | + } |
---|
465 | 463 | |
---|
466 | 464 | ocfs2_inode_unlock(dir, 1); |
---|
467 | 465 | if (did_block_signals) |
---|
.. | .. |
---|
600 | 598 | mlog_errno(status); |
---|
601 | 599 | } |
---|
602 | 600 | |
---|
603 | | - oi->i_sync_tid = handle->h_transaction->t_tid; |
---|
604 | | - oi->i_datasync_tid = handle->h_transaction->t_tid; |
---|
| 601 | + ocfs2_update_inode_fsync_trans(handle, inode, 1); |
---|
605 | 602 | |
---|
606 | 603 | leave: |
---|
607 | 604 | if (status < 0) { |
---|
.. | .. |
---|
639 | 636 | return status; |
---|
640 | 637 | } |
---|
641 | 638 | |
---|
642 | | - status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
---|
| 639 | + return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
---|
643 | 640 | parent_fe_bh, handle, inode_ac, |
---|
644 | 641 | fe_blkno, suballoc_loc, suballoc_bit); |
---|
645 | | - if (status < 0) { |
---|
646 | | - u64 bg_blkno = ocfs2_which_suballoc_group(fe_blkno, suballoc_bit); |
---|
647 | | - int tmp = ocfs2_free_suballoc_bits(handle, inode_ac->ac_inode, |
---|
648 | | - inode_ac->ac_bh, suballoc_bit, bg_blkno, 1); |
---|
649 | | - if (tmp) |
---|
650 | | - mlog_errno(tmp); |
---|
651 | | - } |
---|
652 | | - |
---|
653 | | - return status; |
---|
654 | 642 | } |
---|
655 | 643 | |
---|
656 | 644 | static int ocfs2_mkdir(struct inode *dir, |
---|
.. | .. |
---|
2031 | 2019 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
---|
2032 | 2020 | if (status < 0 && did_quota_inode) |
---|
2033 | 2021 | dquot_free_inode(inode); |
---|
2034 | | - if (handle) |
---|
| 2022 | + if (handle) { |
---|
| 2023 | + if (status < 0 && fe) |
---|
| 2024 | + ocfs2_set_links_count(fe, 0); |
---|
2035 | 2025 | ocfs2_commit_trans(osb, handle); |
---|
| 2026 | + } |
---|
2036 | 2027 | |
---|
2037 | 2028 | ocfs2_inode_unlock(dir, 1); |
---|
2038 | 2029 | if (did_block_signals) |
---|
.. | .. |
---|
2500 | 2491 | struct inode *inode = NULL; |
---|
2501 | 2492 | struct inode *orphan_dir = NULL; |
---|
2502 | 2493 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
---|
2503 | | - struct ocfs2_dinode *di = NULL; |
---|
2504 | 2494 | handle_t *handle = NULL; |
---|
2505 | 2495 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
---|
2506 | 2496 | struct buffer_head *parent_di_bh = NULL; |
---|
2507 | 2497 | struct buffer_head *new_di_bh = NULL; |
---|
2508 | 2498 | struct ocfs2_alloc_context *inode_ac = NULL; |
---|
2509 | 2499 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
---|
2510 | | - u64 uninitialized_var(di_blkno), suballoc_loc; |
---|
| 2500 | + u64 di_blkno, suballoc_loc; |
---|
2511 | 2501 | u16 suballoc_bit; |
---|
2512 | 2502 | |
---|
2513 | 2503 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); |
---|
.. | .. |
---|
2566 | 2556 | goto leave; |
---|
2567 | 2557 | } |
---|
2568 | 2558 | |
---|
2569 | | - di = (struct ocfs2_dinode *)new_di_bh->b_data; |
---|
2570 | 2559 | status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name, |
---|
2571 | 2560 | &orphan_insert, orphan_dir, false); |
---|
2572 | 2561 | if (status < 0) { |
---|