| .. | .. |
|---|
| 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) { |
|---|