| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
|---|
| 3 | 4 | * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This copyrighted material is made available to anyone wishing to use, |
|---|
| 6 | | - * modify, copy, or redistribute it subject to the terms and conditions |
|---|
| 7 | | - * of the GNU General Public License version 2. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 20 | 17 | #include <linux/crc32.h> |
|---|
| 21 | 18 | #include <linux/iomap.h> |
|---|
| 22 | 19 | #include <linux/security.h> |
|---|
| 20 | +#include <linux/fiemap.h> |
|---|
| 23 | 21 | #include <linux/uaccess.h> |
|---|
| 24 | 22 | |
|---|
| 25 | 23 | #include "gfs2.h" |
|---|
| .. | .. |
|---|
| 117 | 115 | * placeholder because it doesn't otherwise make sense), the on-disk block type |
|---|
| 118 | 116 | * is verified to be @blktype. |
|---|
| 119 | 117 | * |
|---|
| 118 | + * When @no_formal_ino is non-zero, this function will return ERR_PTR(-ESTALE) |
|---|
| 119 | + * if it detects that @no_formal_ino doesn't match the actual inode generation |
|---|
| 120 | + * number. However, it doesn't always know unless @type is DT_UNKNOWN. |
|---|
| 121 | + * |
|---|
| 120 | 122 | * Returns: A VFS inode, or an error |
|---|
| 121 | 123 | */ |
|---|
| 122 | 124 | |
|---|
| .. | .. |
|---|
| 139 | 141 | |
|---|
| 140 | 142 | if (inode->i_state & I_NEW) { |
|---|
| 141 | 143 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
|---|
| 142 | | - ip->i_no_formal_ino = no_formal_ino; |
|---|
| 143 | 144 | |
|---|
| 144 | 145 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
|---|
| 145 | 146 | if (unlikely(error)) |
|---|
| .. | .. |
|---|
| 148 | 149 | |
|---|
| 149 | 150 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
|---|
| 150 | 151 | if (unlikely(error)) |
|---|
| 151 | | - goto fail_put; |
|---|
| 152 | + goto fail; |
|---|
| 153 | + if (blktype != GFS2_BLKST_UNLINKED) |
|---|
| 154 | + gfs2_cancel_delete_work(io_gl); |
|---|
| 152 | 155 | |
|---|
| 153 | 156 | if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) { |
|---|
| 154 | 157 | /* |
|---|
| .. | .. |
|---|
| 159 | 162 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, |
|---|
| 160 | 163 | GL_SKIP, &i_gh); |
|---|
| 161 | 164 | if (error) |
|---|
| 162 | | - goto fail_put; |
|---|
| 165 | + goto fail; |
|---|
| 166 | + |
|---|
| 167 | + error = -ESTALE; |
|---|
| 168 | + if (no_formal_ino && |
|---|
| 169 | + gfs2_inode_already_deleted(ip->i_gl, no_formal_ino)) |
|---|
| 170 | + goto fail; |
|---|
| 163 | 171 | |
|---|
| 164 | 172 | if (blktype != GFS2_BLKST_FREE) { |
|---|
| 165 | 173 | error = gfs2_check_blk_type(sdp, no_addr, |
|---|
| 166 | 174 | blktype); |
|---|
| 167 | 175 | if (error) |
|---|
| 168 | | - goto fail_put; |
|---|
| 176 | + goto fail; |
|---|
| 169 | 177 | } |
|---|
| 170 | 178 | } |
|---|
| 171 | 179 | |
|---|
| .. | .. |
|---|
| 173 | 181 | set_bit(GIF_INVALID, &ip->i_flags); |
|---|
| 174 | 182 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
|---|
| 175 | 183 | if (unlikely(error)) |
|---|
| 176 | | - goto fail_put; |
|---|
| 184 | + goto fail; |
|---|
| 177 | 185 | glock_set_object(ip->i_iopen_gh.gh_gl, ip); |
|---|
| 178 | 186 | gfs2_glock_put(io_gl); |
|---|
| 179 | 187 | io_gl = NULL; |
|---|
| 180 | | - |
|---|
| 181 | | - if (type == DT_UNKNOWN) { |
|---|
| 182 | | - /* Inode glock must be locked already */ |
|---|
| 183 | | - error = gfs2_inode_refresh(GFS2_I(inode)); |
|---|
| 184 | | - if (error) |
|---|
| 185 | | - goto fail_refresh; |
|---|
| 186 | | - } else { |
|---|
| 187 | | - inode->i_mode = DT2IF(type); |
|---|
| 188 | | - } |
|---|
| 189 | | - |
|---|
| 190 | | - gfs2_set_iop(inode); |
|---|
| 191 | 188 | |
|---|
| 192 | 189 | /* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */ |
|---|
| 193 | 190 | inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1); |
|---|
| 194 | 191 | inode->i_atime.tv_nsec = 0; |
|---|
| 195 | 192 | |
|---|
| 196 | | - unlock_new_inode(inode); |
|---|
| 193 | + if (type == DT_UNKNOWN) { |
|---|
| 194 | + /* Inode glock must be locked already */ |
|---|
| 195 | + error = gfs2_inode_refresh(GFS2_I(inode)); |
|---|
| 196 | + if (error) |
|---|
| 197 | + goto fail; |
|---|
| 198 | + } else { |
|---|
| 199 | + ip->i_no_formal_ino = no_formal_ino; |
|---|
| 200 | + inode->i_mode = DT2IF(type); |
|---|
| 201 | + } |
|---|
| 202 | + |
|---|
| 203 | + if (gfs2_holder_initialized(&i_gh)) |
|---|
| 204 | + gfs2_glock_dq_uninit(&i_gh); |
|---|
| 205 | + |
|---|
| 206 | + gfs2_set_iop(inode); |
|---|
| 197 | 207 | } |
|---|
| 198 | 208 | |
|---|
| 199 | | - if (gfs2_holder_initialized(&i_gh)) |
|---|
| 200 | | - gfs2_glock_dq_uninit(&i_gh); |
|---|
| 209 | + if (no_formal_ino && ip->i_no_formal_ino && |
|---|
| 210 | + no_formal_ino != ip->i_no_formal_ino) { |
|---|
| 211 | + error = -ESTALE; |
|---|
| 212 | + if (inode->i_state & I_NEW) |
|---|
| 213 | + goto fail; |
|---|
| 214 | + iput(inode); |
|---|
| 215 | + return ERR_PTR(error); |
|---|
| 216 | + } |
|---|
| 217 | + |
|---|
| 218 | + if (inode->i_state & I_NEW) |
|---|
| 219 | + unlock_new_inode(inode); |
|---|
| 220 | + |
|---|
| 201 | 221 | return inode; |
|---|
| 202 | 222 | |
|---|
| 203 | | -fail_refresh: |
|---|
| 204 | | - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
|---|
| 205 | | - glock_clear_object(ip->i_iopen_gh.gh_gl, ip); |
|---|
| 206 | | - gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
|---|
| 207 | | -fail_put: |
|---|
| 223 | +fail: |
|---|
| 208 | 224 | if (io_gl) |
|---|
| 209 | 225 | gfs2_glock_put(io_gl); |
|---|
| 210 | | - glock_clear_object(ip->i_gl, ip); |
|---|
| 211 | 226 | if (gfs2_holder_initialized(&i_gh)) |
|---|
| 212 | 227 | gfs2_glock_dq_uninit(&i_gh); |
|---|
| 213 | | -fail: |
|---|
| 214 | 228 | iget_failed(inode); |
|---|
| 215 | 229 | return ERR_PTR(error); |
|---|
| 216 | 230 | } |
|---|
| 217 | 231 | |
|---|
| 232 | +/** |
|---|
| 233 | + * gfs2_lookup_by_inum - look up an inode by inode number |
|---|
| 234 | + * @sdp: The super block |
|---|
| 235 | + * @no_addr: The inode number |
|---|
| 236 | + * @no_formal_ino: The inode generation number (0 for any) |
|---|
| 237 | + * @blktype: Requested block type (see gfs2_inode_lookup) |
|---|
| 238 | + */ |
|---|
| 218 | 239 | struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, |
|---|
| 219 | | - u64 *no_formal_ino, unsigned int blktype) |
|---|
| 240 | + u64 no_formal_ino, unsigned int blktype) |
|---|
| 220 | 241 | { |
|---|
| 221 | 242 | struct super_block *sb = sdp->sd_vfs; |
|---|
| 222 | 243 | struct inode *inode; |
|---|
| 223 | 244 | int error; |
|---|
| 224 | 245 | |
|---|
| 225 | | - inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0, blktype); |
|---|
| 246 | + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, no_formal_ino, |
|---|
| 247 | + blktype); |
|---|
| 226 | 248 | if (IS_ERR(inode)) |
|---|
| 227 | 249 | return inode; |
|---|
| 228 | 250 | |
|---|
| 229 | | - /* Two extra checks for NFS only */ |
|---|
| 230 | 251 | if (no_formal_ino) { |
|---|
| 231 | | - error = -ESTALE; |
|---|
| 232 | | - if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino) |
|---|
| 233 | | - goto fail_iput; |
|---|
| 234 | | - |
|---|
| 235 | 252 | error = -EIO; |
|---|
| 236 | 253 | if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) |
|---|
| 237 | 254 | goto fail_iput; |
|---|
| .. | .. |
|---|
| 597 | 614 | if (!name->len || name->len > GFS2_FNAMESIZE) |
|---|
| 598 | 615 | return -ENAMETOOLONG; |
|---|
| 599 | 616 | |
|---|
| 600 | | - error = gfs2_rsqa_alloc(dip); |
|---|
| 617 | + error = gfs2_qa_get(dip); |
|---|
| 601 | 618 | if (error) |
|---|
| 602 | 619 | return error; |
|---|
| 603 | 620 | |
|---|
| 604 | 621 | error = gfs2_rindex_update(sdp); |
|---|
| 605 | 622 | if (error) |
|---|
| 606 | | - return error; |
|---|
| 623 | + goto fail; |
|---|
| 607 | 624 | |
|---|
| 608 | 625 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
|---|
| 609 | 626 | if (error) |
|---|
| .. | .. |
|---|
| 631 | 648 | error = finish_no_open(file, NULL); |
|---|
| 632 | 649 | } |
|---|
| 633 | 650 | gfs2_glock_dq_uninit(ghs); |
|---|
| 634 | | - return error; |
|---|
| 651 | + goto fail; |
|---|
| 635 | 652 | } else if (error != -ENOENT) { |
|---|
| 636 | 653 | goto fail_gunlock; |
|---|
| 637 | 654 | } |
|---|
| .. | .. |
|---|
| 650 | 667 | goto fail_gunlock; |
|---|
| 651 | 668 | |
|---|
| 652 | 669 | ip = GFS2_I(inode); |
|---|
| 653 | | - error = gfs2_rsqa_alloc(ip); |
|---|
| 670 | + error = gfs2_qa_get(ip); |
|---|
| 654 | 671 | if (error) |
|---|
| 655 | 672 | goto fail_free_acls; |
|---|
| 656 | 673 | |
|---|
| .. | .. |
|---|
| 659 | 676 | inode->i_rdev = dev; |
|---|
| 660 | 677 | inode->i_size = size; |
|---|
| 661 | 678 | inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); |
|---|
| 662 | | - gfs2_set_inode_blocks(inode, 1); |
|---|
| 663 | 679 | munge_mode_uid_gid(dip, inode); |
|---|
| 664 | 680 | check_and_update_goal(dip); |
|---|
| 665 | 681 | ip->i_goal = dip->i_goal; |
|---|
| .. | .. |
|---|
| 709 | 725 | flush_delayed_work(&ip->i_gl->gl_work); |
|---|
| 710 | 726 | glock_set_object(ip->i_gl, ip); |
|---|
| 711 | 727 | |
|---|
| 712 | | - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
|---|
| 728 | + error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
|---|
| 713 | 729 | if (error) |
|---|
| 714 | 730 | goto fail_free_inode; |
|---|
| 731 | + gfs2_cancel_delete_work(io_gl); |
|---|
| 732 | + glock_set_object(io_gl, ip); |
|---|
| 733 | + |
|---|
| 734 | + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
|---|
| 735 | + if (error) |
|---|
| 736 | + goto fail_gunlock2; |
|---|
| 715 | 737 | |
|---|
| 716 | 738 | error = gfs2_trans_begin(sdp, blocks, 0); |
|---|
| 717 | 739 | if (error) |
|---|
| 718 | | - goto fail_free_inode; |
|---|
| 740 | + goto fail_gunlock2; |
|---|
| 719 | 741 | |
|---|
| 720 | 742 | if (blocks > 1) { |
|---|
| 721 | 743 | ip->i_eattr = ip->i_no_addr + 1; |
|---|
| .. | .. |
|---|
| 724 | 746 | init_dinode(dip, ip, symname); |
|---|
| 725 | 747 | gfs2_trans_end(sdp); |
|---|
| 726 | 748 | |
|---|
| 727 | | - error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
|---|
| 728 | | - if (error) |
|---|
| 729 | | - goto fail_free_inode; |
|---|
| 730 | | - |
|---|
| 731 | 749 | BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags)); |
|---|
| 732 | 750 | |
|---|
| 733 | 751 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
|---|
| 734 | 752 | if (error) |
|---|
| 735 | 753 | goto fail_gunlock2; |
|---|
| 736 | 754 | |
|---|
| 737 | | - glock_set_object(ip->i_iopen_gh.gh_gl, ip); |
|---|
| 738 | 755 | gfs2_set_iop(inode); |
|---|
| 739 | 756 | insert_inode_hash(inode); |
|---|
| 740 | 757 | |
|---|
| .. | .. |
|---|
| 774 | 791 | error = finish_open(file, dentry, gfs2_open_common); |
|---|
| 775 | 792 | } |
|---|
| 776 | 793 | gfs2_glock_dq_uninit(ghs); |
|---|
| 794 | + gfs2_qa_put(ip); |
|---|
| 777 | 795 | gfs2_glock_dq_uninit(ghs + 1); |
|---|
| 778 | 796 | clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); |
|---|
| 779 | 797 | gfs2_glock_put(io_gl); |
|---|
| 798 | + gfs2_qa_put(dip); |
|---|
| 780 | 799 | return error; |
|---|
| 781 | 800 | |
|---|
| 782 | 801 | fail_gunlock3: |
|---|
| .. | .. |
|---|
| 784 | 803 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
|---|
| 785 | 804 | fail_gunlock2: |
|---|
| 786 | 805 | clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); |
|---|
| 806 | + glock_clear_object(io_gl, ip); |
|---|
| 787 | 807 | gfs2_glock_put(io_gl); |
|---|
| 788 | 808 | fail_free_inode: |
|---|
| 789 | 809 | if (ip->i_gl) { |
|---|
| 790 | 810 | glock_clear_object(ip->i_gl, ip); |
|---|
| 791 | | - gfs2_glock_put(ip->i_gl); |
|---|
| 811 | + if (free_vfs_inode) /* else evict will do the put for us */ |
|---|
| 812 | + gfs2_glock_put(ip->i_gl); |
|---|
| 792 | 813 | } |
|---|
| 793 | | - gfs2_rsqa_delete(ip, NULL); |
|---|
| 814 | + gfs2_rs_deltree(&ip->i_res); |
|---|
| 815 | + gfs2_qa_put(ip); |
|---|
| 794 | 816 | fail_free_acls: |
|---|
| 795 | 817 | posix_acl_release(default_acl); |
|---|
| 796 | 818 | posix_acl_release(acl); |
|---|
| 797 | 819 | fail_gunlock: |
|---|
| 798 | 820 | gfs2_dir_no_add(&da); |
|---|
| 799 | 821 | gfs2_glock_dq_uninit(ghs); |
|---|
| 800 | | - if (inode && !IS_ERR(inode)) { |
|---|
| 822 | + if (!IS_ERR_OR_NULL(inode)) { |
|---|
| 801 | 823 | clear_nlink(inode); |
|---|
| 802 | 824 | if (!free_vfs_inode) |
|---|
| 803 | 825 | mark_inode_dirty(inode); |
|---|
| .. | .. |
|---|
| 808 | 830 | if (gfs2_holder_initialized(ghs + 1)) |
|---|
| 809 | 831 | gfs2_glock_dq_uninit(ghs + 1); |
|---|
| 810 | 832 | fail: |
|---|
| 833 | + gfs2_qa_put(dip); |
|---|
| 811 | 834 | return error; |
|---|
| 812 | 835 | } |
|---|
| 813 | 836 | |
|---|
| .. | .. |
|---|
| 909 | 932 | if (S_ISDIR(inode->i_mode)) |
|---|
| 910 | 933 | return -EPERM; |
|---|
| 911 | 934 | |
|---|
| 912 | | - error = gfs2_rsqa_alloc(dip); |
|---|
| 935 | + error = gfs2_qa_get(dip); |
|---|
| 913 | 936 | if (error) |
|---|
| 914 | 937 | return error; |
|---|
| 915 | 938 | |
|---|
| .. | .. |
|---|
| 1012 | 1035 | out_child: |
|---|
| 1013 | 1036 | gfs2_glock_dq(ghs); |
|---|
| 1014 | 1037 | out_parent: |
|---|
| 1038 | + gfs2_qa_put(dip); |
|---|
| 1015 | 1039 | gfs2_holder_uninit(ghs); |
|---|
| 1016 | 1040 | gfs2_holder_uninit(ghs + 1); |
|---|
| 1017 | 1041 | return error; |
|---|
| .. | .. |
|---|
| 1352 | 1376 | struct gfs2_inode *ip = GFS2_I(d_inode(odentry)); |
|---|
| 1353 | 1377 | struct gfs2_inode *nip = NULL; |
|---|
| 1354 | 1378 | struct gfs2_sbd *sdp = GFS2_SB(odir); |
|---|
| 1355 | | - struct gfs2_holder ghs[5], r_gh; |
|---|
| 1379 | + struct gfs2_holder ghs[4], r_gh, rd_gh; |
|---|
| 1356 | 1380 | struct gfs2_rgrpd *nrgd; |
|---|
| 1357 | 1381 | unsigned int num_gh; |
|---|
| 1358 | 1382 | int dir_rename = 0; |
|---|
| .. | .. |
|---|
| 1361 | 1385 | int error; |
|---|
| 1362 | 1386 | |
|---|
| 1363 | 1387 | gfs2_holder_mark_uninitialized(&r_gh); |
|---|
| 1388 | + gfs2_holder_mark_uninitialized(&rd_gh); |
|---|
| 1364 | 1389 | if (d_really_is_positive(ndentry)) { |
|---|
| 1365 | 1390 | nip = GFS2_I(d_inode(ndentry)); |
|---|
| 1366 | 1391 | if (ip == nip) |
|---|
| .. | .. |
|---|
| 1371 | 1396 | if (error) |
|---|
| 1372 | 1397 | return error; |
|---|
| 1373 | 1398 | |
|---|
| 1374 | | - error = gfs2_rsqa_alloc(ndip); |
|---|
| 1399 | + error = gfs2_qa_get(ndip); |
|---|
| 1375 | 1400 | if (error) |
|---|
| 1376 | 1401 | return error; |
|---|
| 1377 | 1402 | |
|---|
| .. | .. |
|---|
| 1391 | 1416 | } |
|---|
| 1392 | 1417 | |
|---|
| 1393 | 1418 | num_gh = 1; |
|---|
| 1394 | | - gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
|---|
| 1419 | + gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs); |
|---|
| 1395 | 1420 | if (odip != ndip) { |
|---|
| 1396 | | - gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1421 | + gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE,GL_ASYNC, |
|---|
| 1422 | + ghs + num_gh); |
|---|
| 1397 | 1423 | num_gh++; |
|---|
| 1398 | 1424 | } |
|---|
| 1399 | | - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1425 | + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh); |
|---|
| 1400 | 1426 | num_gh++; |
|---|
| 1401 | 1427 | |
|---|
| 1402 | 1428 | if (nip) { |
|---|
| 1403 | | - gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1429 | + gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, |
|---|
| 1430 | + ghs + num_gh); |
|---|
| 1404 | 1431 | num_gh++; |
|---|
| 1405 | | - /* grab the resource lock for unlink flag twiddling |
|---|
| 1406 | | - * this is the case of the target file already existing |
|---|
| 1407 | | - * so we unlink before doing the rename |
|---|
| 1408 | | - */ |
|---|
| 1409 | | - nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr, 1); |
|---|
| 1410 | | - if (nrgd) |
|---|
| 1411 | | - gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); |
|---|
| 1412 | 1432 | } |
|---|
| 1413 | 1433 | |
|---|
| 1414 | 1434 | for (x = 0; x < num_gh; x++) { |
|---|
| 1415 | 1435 | error = gfs2_glock_nq(ghs + x); |
|---|
| 1436 | + if (error) |
|---|
| 1437 | + goto out_gunlock; |
|---|
| 1438 | + } |
|---|
| 1439 | + error = gfs2_glock_async_wait(num_gh, ghs); |
|---|
| 1440 | + if (error) |
|---|
| 1441 | + goto out_gunlock; |
|---|
| 1442 | + |
|---|
| 1443 | + if (nip) { |
|---|
| 1444 | + /* Grab the resource group glock for unlink flag twiddling. |
|---|
| 1445 | + * This is the case where the target dinode already exists |
|---|
| 1446 | + * so we unlink before doing the rename. |
|---|
| 1447 | + */ |
|---|
| 1448 | + nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr, 1); |
|---|
| 1449 | + if (!nrgd) { |
|---|
| 1450 | + error = -ENOENT; |
|---|
| 1451 | + goto out_gunlock; |
|---|
| 1452 | + } |
|---|
| 1453 | + error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, |
|---|
| 1454 | + &rd_gh); |
|---|
| 1416 | 1455 | if (error) |
|---|
| 1417 | 1456 | goto out_gunlock; |
|---|
| 1418 | 1457 | } |
|---|
| .. | .. |
|---|
| 1464 | 1503 | error = -EEXIST; |
|---|
| 1465 | 1504 | default: |
|---|
| 1466 | 1505 | goto out_gunlock; |
|---|
| 1467 | | - }; |
|---|
| 1506 | + } |
|---|
| 1468 | 1507 | |
|---|
| 1469 | 1508 | if (odip != ndip) { |
|---|
| 1470 | 1509 | if (!ndip->i_inode.i_nlink) { |
|---|
| .. | .. |
|---|
| 1545 | 1584 | gfs2_quota_unlock(ndip); |
|---|
| 1546 | 1585 | out_gunlock: |
|---|
| 1547 | 1586 | gfs2_dir_no_add(&da); |
|---|
| 1587 | + if (gfs2_holder_initialized(&rd_gh)) |
|---|
| 1588 | + gfs2_glock_dq_uninit(&rd_gh); |
|---|
| 1589 | + |
|---|
| 1548 | 1590 | while (x--) { |
|---|
| 1549 | | - gfs2_glock_dq(ghs + x); |
|---|
| 1591 | + if (gfs2_holder_queued(ghs + x)) |
|---|
| 1592 | + gfs2_glock_dq(ghs + x); |
|---|
| 1550 | 1593 | gfs2_holder_uninit(ghs + x); |
|---|
| 1551 | 1594 | } |
|---|
| 1552 | 1595 | out_gunlock_r: |
|---|
| 1553 | 1596 | if (gfs2_holder_initialized(&r_gh)) |
|---|
| 1554 | 1597 | gfs2_glock_dq_uninit(&r_gh); |
|---|
| 1555 | 1598 | out: |
|---|
| 1599 | + gfs2_qa_put(ndip); |
|---|
| 1556 | 1600 | return error; |
|---|
| 1557 | 1601 | } |
|---|
| 1558 | 1602 | |
|---|
| .. | .. |
|---|
| 1576 | 1620 | struct gfs2_inode *oip = GFS2_I(odentry->d_inode); |
|---|
| 1577 | 1621 | struct gfs2_inode *nip = GFS2_I(ndentry->d_inode); |
|---|
| 1578 | 1622 | struct gfs2_sbd *sdp = GFS2_SB(odir); |
|---|
| 1579 | | - struct gfs2_holder ghs[5], r_gh; |
|---|
| 1623 | + struct gfs2_holder ghs[4], r_gh; |
|---|
| 1580 | 1624 | unsigned int num_gh; |
|---|
| 1581 | 1625 | unsigned int x; |
|---|
| 1582 | 1626 | umode_t old_mode = oip->i_inode.i_mode; |
|---|
| .. | .. |
|---|
| 1610 | 1654 | } |
|---|
| 1611 | 1655 | |
|---|
| 1612 | 1656 | num_gh = 1; |
|---|
| 1613 | | - gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
|---|
| 1657 | + gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs); |
|---|
| 1614 | 1658 | if (odip != ndip) { |
|---|
| 1615 | | - gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1659 | + gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, |
|---|
| 1660 | + ghs + num_gh); |
|---|
| 1616 | 1661 | num_gh++; |
|---|
| 1617 | 1662 | } |
|---|
| 1618 | | - gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1663 | + gfs2_holder_init(oip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh); |
|---|
| 1619 | 1664 | num_gh++; |
|---|
| 1620 | 1665 | |
|---|
| 1621 | | - gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); |
|---|
| 1666 | + gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, GL_ASYNC, ghs + num_gh); |
|---|
| 1622 | 1667 | num_gh++; |
|---|
| 1623 | 1668 | |
|---|
| 1624 | 1669 | for (x = 0; x < num_gh; x++) { |
|---|
| .. | .. |
|---|
| 1626 | 1671 | if (error) |
|---|
| 1627 | 1672 | goto out_gunlock; |
|---|
| 1628 | 1673 | } |
|---|
| 1674 | + |
|---|
| 1675 | + error = gfs2_glock_async_wait(num_gh, ghs); |
|---|
| 1676 | + if (error) |
|---|
| 1677 | + goto out_gunlock; |
|---|
| 1629 | 1678 | |
|---|
| 1630 | 1679 | error = -ENOENT; |
|---|
| 1631 | 1680 | if (oip->i_inode.i_nlink == 0 || nip->i_inode.i_nlink == 0) |
|---|
| .. | .. |
|---|
| 1687 | 1736 | gfs2_trans_end(sdp); |
|---|
| 1688 | 1737 | out_gunlock: |
|---|
| 1689 | 1738 | while (x--) { |
|---|
| 1690 | | - gfs2_glock_dq(ghs + x); |
|---|
| 1739 | + if (gfs2_holder_queued(ghs + x)) |
|---|
| 1740 | + gfs2_glock_dq(ghs + x); |
|---|
| 1691 | 1741 | gfs2_holder_uninit(ghs + x); |
|---|
| 1692 | 1742 | } |
|---|
| 1693 | 1743 | out_gunlock_r: |
|---|
| .. | .. |
|---|
| 1858 | 1908 | ouid = nuid = NO_UID_QUOTA_CHANGE; |
|---|
| 1859 | 1909 | if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid)) |
|---|
| 1860 | 1910 | ogid = ngid = NO_GID_QUOTA_CHANGE; |
|---|
| 1861 | | - |
|---|
| 1862 | | - error = gfs2_rsqa_alloc(ip); |
|---|
| 1911 | + error = gfs2_qa_get(ip); |
|---|
| 1863 | 1912 | if (error) |
|---|
| 1864 | | - goto out; |
|---|
| 1913 | + return error; |
|---|
| 1865 | 1914 | |
|---|
| 1866 | 1915 | error = gfs2_rindex_update(sdp); |
|---|
| 1867 | 1916 | if (error) |
|---|
| .. | .. |
|---|
| 1899 | 1948 | out_gunlock_q: |
|---|
| 1900 | 1949 | gfs2_quota_unlock(ip); |
|---|
| 1901 | 1950 | out: |
|---|
| 1951 | + gfs2_qa_put(ip); |
|---|
| 1902 | 1952 | return error; |
|---|
| 1903 | 1953 | } |
|---|
| 1904 | 1954 | |
|---|
| .. | .. |
|---|
| 1920 | 1970 | struct gfs2_holder i_gh; |
|---|
| 1921 | 1971 | int error; |
|---|
| 1922 | 1972 | |
|---|
| 1923 | | - error = gfs2_rsqa_alloc(ip); |
|---|
| 1973 | + error = gfs2_qa_get(ip); |
|---|
| 1924 | 1974 | if (error) |
|---|
| 1925 | 1975 | return error; |
|---|
| 1926 | 1976 | |
|---|
| 1927 | 1977 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); |
|---|
| 1928 | 1978 | if (error) |
|---|
| 1929 | | - return error; |
|---|
| 1979 | + goto out; |
|---|
| 1930 | 1980 | |
|---|
| 1931 | 1981 | error = -EPERM; |
|---|
| 1932 | 1982 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
|---|
| 1933 | | - goto out; |
|---|
| 1983 | + goto error; |
|---|
| 1934 | 1984 | |
|---|
| 1935 | 1985 | error = setattr_prepare(dentry, attr); |
|---|
| 1936 | 1986 | if (error) |
|---|
| 1937 | | - goto out; |
|---|
| 1987 | + goto error; |
|---|
| 1938 | 1988 | |
|---|
| 1939 | 1989 | if (attr->ia_valid & ATTR_SIZE) |
|---|
| 1940 | 1990 | error = gfs2_setattr_size(inode, attr->ia_size); |
|---|
| .. | .. |
|---|
| 1946 | 1996 | error = posix_acl_chmod(inode, inode->i_mode); |
|---|
| 1947 | 1997 | } |
|---|
| 1948 | 1998 | |
|---|
| 1949 | | -out: |
|---|
| 1999 | +error: |
|---|
| 1950 | 2000 | if (!error) |
|---|
| 1951 | 2001 | mark_inode_dirty(inode); |
|---|
| 1952 | 2002 | gfs2_glock_dq_uninit(&i_gh); |
|---|
| 2003 | +out: |
|---|
| 2004 | + gfs2_qa_put(ip); |
|---|
| 1953 | 2005 | return error; |
|---|
| 1954 | 2006 | } |
|---|
| 1955 | 2007 | |
|---|
| .. | .. |
|---|
| 2065 | 2117 | return vfs_setpos(file, ret, inode->i_sb->s_maxbytes); |
|---|
| 2066 | 2118 | } |
|---|
| 2067 | 2119 | |
|---|
| 2120 | +static int gfs2_update_time(struct inode *inode, struct timespec64 *time, |
|---|
| 2121 | + int flags) |
|---|
| 2122 | +{ |
|---|
| 2123 | + struct gfs2_inode *ip = GFS2_I(inode); |
|---|
| 2124 | + struct gfs2_glock *gl = ip->i_gl; |
|---|
| 2125 | + struct gfs2_holder *gh; |
|---|
| 2126 | + int error; |
|---|
| 2127 | + |
|---|
| 2128 | + gh = gfs2_glock_is_locked_by_me(gl); |
|---|
| 2129 | + if (gh && !gfs2_glock_is_held_excl(gl)) { |
|---|
| 2130 | + gfs2_glock_dq(gh); |
|---|
| 2131 | + gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, gh); |
|---|
| 2132 | + error = gfs2_glock_nq(gh); |
|---|
| 2133 | + if (error) |
|---|
| 2134 | + return error; |
|---|
| 2135 | + } |
|---|
| 2136 | + return generic_update_time(inode, time, flags); |
|---|
| 2137 | +} |
|---|
| 2138 | + |
|---|
| 2068 | 2139 | const struct inode_operations gfs2_file_iops = { |
|---|
| 2069 | 2140 | .permission = gfs2_permission, |
|---|
| 2070 | 2141 | .setattr = gfs2_setattr, |
|---|
| .. | .. |
|---|
| 2073 | 2144 | .fiemap = gfs2_fiemap, |
|---|
| 2074 | 2145 | .get_acl = gfs2_get_acl, |
|---|
| 2075 | 2146 | .set_acl = gfs2_set_acl, |
|---|
| 2147 | + .update_time = gfs2_update_time, |
|---|
| 2076 | 2148 | }; |
|---|
| 2077 | 2149 | |
|---|
| 2078 | 2150 | const struct inode_operations gfs2_dir_iops = { |
|---|
| .. | .. |
|---|
| 2092 | 2164 | .fiemap = gfs2_fiemap, |
|---|
| 2093 | 2165 | .get_acl = gfs2_get_acl, |
|---|
| 2094 | 2166 | .set_acl = gfs2_set_acl, |
|---|
| 2167 | + .update_time = gfs2_update_time, |
|---|
| 2095 | 2168 | .atomic_open = gfs2_atomic_open, |
|---|
| 2096 | 2169 | }; |
|---|
| 2097 | 2170 | |
|---|