.. | .. |
---|
| 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> |
---|
.. | .. |
---|
212 | 198 | * callers. */ |
---|
213 | 199 | if (S_ISDIR(mode)) |
---|
214 | 200 | set_nlink(inode, 2); |
---|
| 201 | + mode = mode_strip_sgid(dir, mode); |
---|
215 | 202 | inode_init_owner(inode, dir, mode); |
---|
216 | 203 | status = dquot_initialize(inode); |
---|
217 | 204 | if (status) |
---|
.. | .. |
---|
245 | 232 | handle_t *handle = NULL; |
---|
246 | 233 | struct ocfs2_super *osb; |
---|
247 | 234 | struct ocfs2_dinode *dirfe; |
---|
| 235 | + struct ocfs2_dinode *fe = NULL; |
---|
248 | 236 | struct buffer_head *new_fe_bh = NULL; |
---|
249 | 237 | struct inode *inode = NULL; |
---|
250 | 238 | struct ocfs2_alloc_context *inode_ac = NULL; |
---|
.. | .. |
---|
254 | 242 | int want_meta = 0; |
---|
255 | 243 | int xattr_credits = 0; |
---|
256 | 244 | struct ocfs2_security_xattr_info si = { |
---|
| 245 | + .name = NULL, |
---|
257 | 246 | .enable = 1, |
---|
258 | 247 | }; |
---|
259 | 248 | int did_quota_inode = 0; |
---|
.. | .. |
---|
395 | 384 | goto leave; |
---|
396 | 385 | } |
---|
397 | 386 | |
---|
| 387 | + fe = (struct ocfs2_dinode *) new_fe_bh->b_data; |
---|
398 | 388 | if (S_ISDIR(mode)) { |
---|
399 | 389 | status = ocfs2_fill_new_dir(osb, handle, dir, inode, |
---|
400 | 390 | new_fe_bh, data_ac, meta_ac); |
---|
.. | .. |
---|
420 | 410 | |
---|
421 | 411 | if (status < 0) { |
---|
422 | 412 | mlog_errno(status); |
---|
423 | | - goto leave; |
---|
| 413 | + goto roll_back; |
---|
424 | 414 | } |
---|
425 | 415 | |
---|
426 | 416 | if (si.enable) { |
---|
.. | .. |
---|
428 | 418 | meta_ac, data_ac); |
---|
429 | 419 | if (status < 0) { |
---|
430 | 420 | mlog_errno(status); |
---|
431 | | - goto leave; |
---|
| 421 | + goto roll_back; |
---|
432 | 422 | } |
---|
433 | 423 | } |
---|
434 | 424 | |
---|
.. | .. |
---|
441 | 431 | OCFS2_I(dir)->ip_blkno); |
---|
442 | 432 | if (status) { |
---|
443 | 433 | mlog_errno(status); |
---|
444 | | - goto leave; |
---|
| 434 | + goto roll_back; |
---|
445 | 435 | } |
---|
446 | 436 | |
---|
447 | 437 | dl = dentry->d_fsdata; |
---|
.. | .. |
---|
451 | 441 | &lookup); |
---|
452 | 442 | if (status < 0) { |
---|
453 | 443 | mlog_errno(status); |
---|
454 | | - goto leave; |
---|
| 444 | + goto roll_back; |
---|
455 | 445 | } |
---|
456 | 446 | |
---|
457 | 447 | insert_inode_hash(inode); |
---|
458 | 448 | d_instantiate(dentry, inode); |
---|
459 | 449 | status = 0; |
---|
| 450 | + |
---|
| 451 | +roll_back: |
---|
| 452 | + if (status < 0 && S_ISDIR(mode)) { |
---|
| 453 | + ocfs2_add_links_count(dirfe, -1); |
---|
| 454 | + drop_nlink(dir); |
---|
| 455 | + } |
---|
| 456 | + |
---|
460 | 457 | leave: |
---|
461 | 458 | if (status < 0 && did_quota_inode) |
---|
462 | 459 | dquot_free_inode(inode); |
---|
463 | | - if (handle) |
---|
| 460 | + if (handle) { |
---|
| 461 | + if (status < 0 && fe) |
---|
| 462 | + ocfs2_set_links_count(fe, 0); |
---|
464 | 463 | ocfs2_commit_trans(osb, handle); |
---|
| 464 | + } |
---|
465 | 465 | |
---|
466 | 466 | ocfs2_inode_unlock(dir, 1); |
---|
467 | 467 | if (did_block_signals) |
---|
.. | .. |
---|
600 | 600 | mlog_errno(status); |
---|
601 | 601 | } |
---|
602 | 602 | |
---|
603 | | - oi->i_sync_tid = handle->h_transaction->t_tid; |
---|
604 | | - oi->i_datasync_tid = handle->h_transaction->t_tid; |
---|
| 603 | + ocfs2_update_inode_fsync_trans(handle, inode, 1); |
---|
605 | 604 | |
---|
606 | 605 | leave: |
---|
607 | 606 | if (status < 0) { |
---|
.. | .. |
---|
639 | 638 | return status; |
---|
640 | 639 | } |
---|
641 | 640 | |
---|
642 | | - status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
---|
| 641 | + return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, |
---|
643 | 642 | parent_fe_bh, handle, inode_ac, |
---|
644 | 643 | 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 | 644 | } |
---|
655 | 645 | |
---|
656 | 646 | static int ocfs2_mkdir(struct inode *dir, |
---|
.. | .. |
---|
1542 | 1532 | status = ocfs2_add_entry(handle, new_dentry, old_inode, |
---|
1543 | 1533 | OCFS2_I(old_inode)->ip_blkno, |
---|
1544 | 1534 | new_dir_bh, &target_insert); |
---|
| 1535 | + if (status < 0) { |
---|
| 1536 | + mlog_errno(status); |
---|
| 1537 | + goto bail; |
---|
| 1538 | + } |
---|
1545 | 1539 | } |
---|
1546 | 1540 | |
---|
1547 | 1541 | old_inode->i_ctime = current_time(old_inode); |
---|
.. | .. |
---|
1812 | 1806 | int want_clusters = 0; |
---|
1813 | 1807 | int xattr_credits = 0; |
---|
1814 | 1808 | struct ocfs2_security_xattr_info si = { |
---|
| 1809 | + .name = NULL, |
---|
1815 | 1810 | .enable = 1, |
---|
1816 | 1811 | }; |
---|
1817 | 1812 | int did_quota = 0, did_quota_inode = 0; |
---|
.. | .. |
---|
2031 | 2026 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
---|
2032 | 2027 | if (status < 0 && did_quota_inode) |
---|
2033 | 2028 | dquot_free_inode(inode); |
---|
2034 | | - if (handle) |
---|
| 2029 | + if (handle) { |
---|
| 2030 | + if (status < 0 && fe) |
---|
| 2031 | + ocfs2_set_links_count(fe, 0); |
---|
2035 | 2032 | ocfs2_commit_trans(osb, handle); |
---|
| 2033 | + } |
---|
2036 | 2034 | |
---|
2037 | 2035 | ocfs2_inode_unlock(dir, 1); |
---|
2038 | 2036 | if (did_block_signals) |
---|
.. | .. |
---|
2500 | 2498 | struct inode *inode = NULL; |
---|
2501 | 2499 | struct inode *orphan_dir = NULL; |
---|
2502 | 2500 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
---|
2503 | | - struct ocfs2_dinode *di = NULL; |
---|
2504 | 2501 | handle_t *handle = NULL; |
---|
2505 | 2502 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
---|
2506 | 2503 | struct buffer_head *parent_di_bh = NULL; |
---|
2507 | 2504 | struct buffer_head *new_di_bh = NULL; |
---|
2508 | 2505 | struct ocfs2_alloc_context *inode_ac = NULL; |
---|
2509 | 2506 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
---|
2510 | | - u64 uninitialized_var(di_blkno), suballoc_loc; |
---|
| 2507 | + u64 di_blkno, suballoc_loc; |
---|
2511 | 2508 | u16 suballoc_bit; |
---|
2512 | 2509 | |
---|
2513 | 2510 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); |
---|
.. | .. |
---|
2566 | 2563 | goto leave; |
---|
2567 | 2564 | } |
---|
2568 | 2565 | |
---|
2569 | | - di = (struct ocfs2_dinode *)new_di_bh->b_data; |
---|
2570 | 2566 | status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name, |
---|
2571 | 2567 | &orphan_insert, orphan_dir, false); |
---|
2572 | 2568 | if (status < 0) { |
---|