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