diff options
| -rw-r--r-- | fs/gfs2/bmap.c | 11 | ||||
| -rw-r--r-- | fs/gfs2/glock.c | 71 | ||||
| -rw-r--r-- | fs/gfs2/glock.h | 28 | ||||
| -rw-r--r-- | fs/gfs2/glops.c | 1 | ||||
| -rw-r--r-- | fs/gfs2/incore.h | 12 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 9 | ||||
| -rw-r--r-- | fs/gfs2/lock_dlm.c | 15 | ||||
| -rw-r--r-- | fs/gfs2/ops_inode.c | 18 | ||||
| -rw-r--r-- | fs/gfs2/quota.c | 13 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 57 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.h | 1 | ||||
| -rw-r--r-- | fs/gfs2/xattr.c | 23 |
12 files changed, 86 insertions, 173 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 5476c066d4e..3c4039d5eef 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
| @@ -763,7 +763,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
| 763 | int metadata; | 763 | int metadata; |
| 764 | unsigned int revokes = 0; | 764 | unsigned int revokes = 0; |
| 765 | int x; | 765 | int x; |
| 766 | int error; | 766 | int error = 0; |
| 767 | 767 | ||
| 768 | if (!*top) | 768 | if (!*top) |
| 769 | sm->sm_first = 0; | 769 | sm->sm_first = 0; |
| @@ -780,7 +780,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
| 780 | if (metadata) | 780 | if (metadata) |
| 781 | revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; | 781 | revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; |
| 782 | 782 | ||
| 783 | error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); | 783 | if (ip != GFS2_I(sdp->sd_rindex)) |
| 784 | error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); | ||
| 785 | else if (!sdp->sd_rgrps) | ||
| 786 | error = gfs2_ri_update(ip); | ||
| 787 | |||
| 784 | if (error) | 788 | if (error) |
| 785 | return error; | 789 | return error; |
| 786 | 790 | ||
| @@ -879,7 +883,8 @@ out_rg_gunlock: | |||
| 879 | out_rlist: | 883 | out_rlist: |
| 880 | gfs2_rlist_free(&rlist); | 884 | gfs2_rlist_free(&rlist); |
| 881 | out: | 885 | out: |
| 882 | gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); | 886 | if (ip != GFS2_I(sdp->sd_rindex)) |
| 887 | gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); | ||
| 883 | return error; | 888 | return error; |
| 884 | } | 889 | } |
| 885 | 890 | ||
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f92c1770416..08a8beb152e 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -541,21 +541,6 @@ out_locked: | |||
| 541 | spin_unlock(&gl->gl_spin); | 541 | spin_unlock(&gl->gl_spin); |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock, | ||
| 545 | unsigned int req_state, | ||
| 546 | unsigned int flags) | ||
| 547 | { | ||
| 548 | int ret = LM_OUT_ERROR; | ||
| 549 | |||
| 550 | if (!sdp->sd_lockstruct.ls_ops->lm_lock) | ||
| 551 | return req_state == LM_ST_UNLOCKED ? 0 : req_state; | ||
| 552 | |||
| 553 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
| 554 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, | ||
| 555 | req_state, flags); | ||
| 556 | return ret; | ||
| 557 | } | ||
| 558 | |||
| 559 | /** | 544 | /** |
| 560 | * do_xmote - Calls the DLM to change the state of a lock | 545 | * do_xmote - Calls the DLM to change the state of a lock |
| 561 | * @gl: The lock state | 546 | * @gl: The lock state |
| @@ -575,13 +560,14 @@ __acquires(&gl->gl_spin) | |||
| 575 | 560 | ||
| 576 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | | 561 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | |
| 577 | LM_FLAG_PRIORITY); | 562 | LM_FLAG_PRIORITY); |
| 578 | BUG_ON(gl->gl_state == target); | 563 | GLOCK_BUG_ON(gl, gl->gl_state == target); |
| 579 | BUG_ON(gl->gl_state == gl->gl_target); | 564 | GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target); |
| 580 | if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) && | 565 | if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) && |
| 581 | glops->go_inval) { | 566 | glops->go_inval) { |
| 582 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); | 567 | set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); |
| 583 | do_error(gl, 0); /* Fail queued try locks */ | 568 | do_error(gl, 0); /* Fail queued try locks */ |
| 584 | } | 569 | } |
| 570 | gl->gl_req = target; | ||
| 585 | spin_unlock(&gl->gl_spin); | 571 | spin_unlock(&gl->gl_spin); |
| 586 | if (glops->go_xmote_th) | 572 | if (glops->go_xmote_th) |
| 587 | glops->go_xmote_th(gl); | 573 | glops->go_xmote_th(gl); |
| @@ -594,15 +580,17 @@ __acquires(&gl->gl_spin) | |||
| 594 | gl->gl_state == LM_ST_DEFERRED) && | 580 | gl->gl_state == LM_ST_DEFERRED) && |
| 595 | !(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) | 581 | !(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) |
| 596 | lck_flags |= LM_FLAG_TRY_1CB; | 582 | lck_flags |= LM_FLAG_TRY_1CB; |
| 597 | ret = gfs2_lm_lock(sdp, gl, target, lck_flags); | ||
| 598 | 583 | ||
| 599 | if (!(ret & LM_OUT_ASYNC)) { | 584 | if (sdp->sd_lockstruct.ls_ops->lm_lock) { |
| 600 | finish_xmote(gl, ret); | 585 | /* lock_dlm */ |
| 586 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags); | ||
| 587 | GLOCK_BUG_ON(gl, ret); | ||
| 588 | } else { /* lock_nolock */ | ||
| 589 | finish_xmote(gl, target); | ||
| 601 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 590 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 602 | gfs2_glock_put(gl); | 591 | gfs2_glock_put(gl); |
| 603 | } else { | ||
| 604 | GLOCK_BUG_ON(gl, ret != LM_OUT_ASYNC); | ||
| 605 | } | 592 | } |
| 593 | |||
| 606 | spin_lock(&gl->gl_spin); | 594 | spin_lock(&gl->gl_spin); |
| 607 | } | 595 | } |
| 608 | 596 | ||
| @@ -951,17 +939,22 @@ int gfs2_glock_wait(struct gfs2_holder *gh) | |||
| 951 | 939 | ||
| 952 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | 940 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) |
| 953 | { | 941 | { |
| 942 | struct va_format vaf; | ||
| 954 | va_list args; | 943 | va_list args; |
| 955 | 944 | ||
| 956 | va_start(args, fmt); | 945 | va_start(args, fmt); |
| 946 | |||
| 957 | if (seq) { | 947 | if (seq) { |
| 958 | struct gfs2_glock_iter *gi = seq->private; | 948 | struct gfs2_glock_iter *gi = seq->private; |
| 959 | vsprintf(gi->string, fmt, args); | 949 | vsprintf(gi->string, fmt, args); |
| 960 | seq_printf(seq, gi->string); | 950 | seq_printf(seq, gi->string); |
| 961 | } else { | 951 | } else { |
| 962 | printk(KERN_ERR " "); | 952 | vaf.fmt = fmt; |
| 963 | vprintk(fmt, args); | 953 | vaf.va = &args; |
| 954 | |||
| 955 | printk(KERN_ERR " %pV", &vaf); | ||
| 964 | } | 956 | } |
| 957 | |||
| 965 | va_end(args); | 958 | va_end(args); |
| 966 | } | 959 | } |
| 967 | 960 | ||
| @@ -1361,24 +1354,28 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl) | |||
| 1361 | * @gl: Pointer to the glock | 1354 | * @gl: Pointer to the glock |
| 1362 | * @ret: The return value from the dlm | 1355 | * @ret: The return value from the dlm |
| 1363 | * | 1356 | * |
| 1357 | * The gl_reply field is under the gl_spin lock so that it is ok | ||
| 1358 | * to use a bitfield shared with other glock state fields. | ||
| 1364 | */ | 1359 | */ |
| 1365 | 1360 | ||
| 1366 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) | 1361 | void gfs2_glock_complete(struct gfs2_glock *gl, int ret) |
| 1367 | { | 1362 | { |
| 1368 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; | 1363 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; |
| 1369 | 1364 | ||
| 1365 | spin_lock(&gl->gl_spin); | ||
| 1370 | gl->gl_reply = ret; | 1366 | gl->gl_reply = ret; |
| 1371 | 1367 | ||
| 1372 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { | 1368 | if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) { |
| 1373 | spin_lock(&gl->gl_spin); | ||
| 1374 | if (gfs2_should_freeze(gl)) { | 1369 | if (gfs2_should_freeze(gl)) { |
| 1375 | set_bit(GLF_FROZEN, &gl->gl_flags); | 1370 | set_bit(GLF_FROZEN, &gl->gl_flags); |
| 1376 | spin_unlock(&gl->gl_spin); | 1371 | spin_unlock(&gl->gl_spin); |
| 1377 | return; | 1372 | return; |
| 1378 | } | 1373 | } |
| 1379 | spin_unlock(&gl->gl_spin); | ||
| 1380 | } | 1374 | } |
| 1375 | |||
| 1376 | spin_unlock(&gl->gl_spin); | ||
| 1381 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); | 1377 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); |
| 1378 | smp_wmb(); | ||
| 1382 | gfs2_glock_hold(gl); | 1379 | gfs2_glock_hold(gl); |
| 1383 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1380 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
| 1384 | gfs2_glock_put(gl); | 1381 | gfs2_glock_put(gl); |
| @@ -1626,18 +1623,17 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags) | |||
| 1626 | static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) | 1623 | static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) |
| 1627 | { | 1624 | { |
| 1628 | struct task_struct *gh_owner = NULL; | 1625 | struct task_struct *gh_owner = NULL; |
| 1629 | char buffer[KSYM_SYMBOL_LEN]; | ||
| 1630 | char flags_buf[32]; | 1626 | char flags_buf[32]; |
| 1631 | 1627 | ||
| 1632 | sprint_symbol(buffer, gh->gh_ip); | ||
| 1633 | if (gh->gh_owner_pid) | 1628 | if (gh->gh_owner_pid) |
| 1634 | gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); | 1629 | gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); |
| 1635 | gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %s\n", | 1630 | gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %pS\n", |
| 1636 | state2str(gh->gh_state), | 1631 | state2str(gh->gh_state), |
| 1637 | hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), | 1632 | hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), |
| 1638 | gh->gh_error, | 1633 | gh->gh_error, |
| 1639 | gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, | 1634 | gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, |
| 1640 | gh_owner ? gh_owner->comm : "(ended)", buffer); | 1635 | gh_owner ? gh_owner->comm : "(ended)", |
| 1636 | (void *)gh->gh_ip); | ||
| 1641 | return 0; | 1637 | return 0; |
| 1642 | } | 1638 | } |
| 1643 | 1639 | ||
| @@ -1782,12 +1778,13 @@ int __init gfs2_glock_init(void) | |||
| 1782 | } | 1778 | } |
| 1783 | #endif | 1779 | #endif |
| 1784 | 1780 | ||
| 1785 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_RESCUER | | 1781 | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | |
| 1786 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); | 1782 | WQ_HIGHPRI | WQ_FREEZEABLE, 0); |
| 1787 | if (IS_ERR(glock_workqueue)) | 1783 | if (IS_ERR(glock_workqueue)) |
| 1788 | return PTR_ERR(glock_workqueue); | 1784 | return PTR_ERR(glock_workqueue); |
| 1789 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", WQ_RESCUER | | 1785 | gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", |
| 1790 | WQ_FREEZEABLE, 0); | 1786 | WQ_MEM_RECLAIM | WQ_FREEZEABLE, |
| 1787 | 0); | ||
| 1791 | if (IS_ERR(gfs2_delete_workqueue)) { | 1788 | if (IS_ERR(gfs2_delete_workqueue)) { |
| 1792 | destroy_workqueue(glock_workqueue); | 1789 | destroy_workqueue(glock_workqueue); |
| 1793 | return PTR_ERR(gfs2_delete_workqueue); | 1790 | return PTR_ERR(gfs2_delete_workqueue); |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index db1c26d6d22..691851ceb61 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
| @@ -87,11 +87,10 @@ enum { | |||
| 87 | #define GL_ASYNC 0x00000040 | 87 | #define GL_ASYNC 0x00000040 |
| 88 | #define GL_EXACT 0x00000080 | 88 | #define GL_EXACT 0x00000080 |
| 89 | #define GL_SKIP 0x00000100 | 89 | #define GL_SKIP 0x00000100 |
| 90 | #define GL_ATIME 0x00000200 | ||
| 91 | #define GL_NOCACHE 0x00000400 | 90 | #define GL_NOCACHE 0x00000400 |
| 92 | 91 | ||
| 93 | /* | 92 | /* |
| 94 | * lm_lock() and lm_async_cb return flags | 93 | * lm_async_cb return flags |
| 95 | * | 94 | * |
| 96 | * LM_OUT_ST_MASK | 95 | * LM_OUT_ST_MASK |
| 97 | * Masks the lower two bits of lock state in the returned value. | 96 | * Masks the lower two bits of lock state in the returned value. |
| @@ -99,15 +98,11 @@ enum { | |||
| 99 | * LM_OUT_CANCELED | 98 | * LM_OUT_CANCELED |
| 100 | * The lock request was canceled. | 99 | * The lock request was canceled. |
| 101 | * | 100 | * |
| 102 | * LM_OUT_ASYNC | ||
| 103 | * The result of the request will be returned in an LM_CB_ASYNC callback. | ||
| 104 | * | ||
| 105 | */ | 101 | */ |
| 106 | 102 | ||
| 107 | #define LM_OUT_ST_MASK 0x00000003 | 103 | #define LM_OUT_ST_MASK 0x00000003 |
| 108 | #define LM_OUT_CANCELED 0x00000008 | 104 | #define LM_OUT_CANCELED 0x00000008 |
| 109 | #define LM_OUT_ASYNC 0x00000080 | 105 | #define LM_OUT_ERROR 0x00000004 |
| 110 | #define LM_OUT_ERROR 0x00000100 | ||
| 111 | 106 | ||
| 112 | /* | 107 | /* |
| 113 | * lm_recovery_done() messages | 108 | * lm_recovery_done() messages |
| @@ -124,25 +119,12 @@ struct lm_lockops { | |||
| 124 | void (*lm_unmount) (struct gfs2_sbd *sdp); | 119 | void (*lm_unmount) (struct gfs2_sbd *sdp); |
| 125 | void (*lm_withdraw) (struct gfs2_sbd *sdp); | 120 | void (*lm_withdraw) (struct gfs2_sbd *sdp); |
| 126 | void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl); | 121 | void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl); |
| 127 | unsigned int (*lm_lock) (struct gfs2_glock *gl, | 122 | int (*lm_lock) (struct gfs2_glock *gl, unsigned int req_state, |
| 128 | unsigned int req_state, unsigned int flags); | 123 | unsigned int flags); |
| 129 | void (*lm_cancel) (struct gfs2_glock *gl); | 124 | void (*lm_cancel) (struct gfs2_glock *gl); |
| 130 | const match_table_t *lm_tokens; | 125 | const match_table_t *lm_tokens; |
| 131 | }; | 126 | }; |
| 132 | 127 | ||
| 133 | #define LM_FLAG_TRY 0x00000001 | ||
| 134 | #define LM_FLAG_TRY_1CB 0x00000002 | ||
| 135 | #define LM_FLAG_NOEXP 0x00000004 | ||
| 136 | #define LM_FLAG_ANY 0x00000008 | ||
| 137 | #define LM_FLAG_PRIORITY 0x00000010 | ||
| 138 | |||
| 139 | #define GL_ASYNC 0x00000040 | ||
| 140 | #define GL_EXACT 0x00000080 | ||
| 141 | #define GL_SKIP 0x00000100 | ||
| 142 | #define GL_NOCACHE 0x00000400 | ||
| 143 | |||
| 144 | #define GLR_TRYFAILED 13 | ||
| 145 | |||
| 146 | extern struct workqueue_struct *gfs2_delete_workqueue; | 128 | extern struct workqueue_struct *gfs2_delete_workqueue; |
| 147 | static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) | 129 | static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) |
| 148 | { | 130 | { |
| @@ -212,6 +194,8 @@ int gfs2_glock_nq_num(struct gfs2_sbd *sdp, | |||
| 212 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 194 | int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
| 213 | void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 195 | void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
| 214 | void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); | 196 | void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); |
| 197 | |||
| 198 | __attribute__ ((format(printf, 2, 3))) | ||
| 215 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); | 199 | void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); |
| 216 | 200 | ||
| 217 | /** | 201 | /** |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 0d149dcc04e..263561bf1a5 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
| @@ -325,7 +325,6 @@ static void trans_go_sync(struct gfs2_glock *gl) | |||
| 325 | 325 | ||
| 326 | if (gl->gl_state != LM_ST_UNLOCKED && | 326 | if (gl->gl_state != LM_ST_UNLOCKED && |
| 327 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 327 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
| 328 | flush_workqueue(gfs2_delete_workqueue); | ||
| 329 | gfs2_meta_syncfs(sdp); | 328 | gfs2_meta_syncfs(sdp); |
| 330 | gfs2_log_shutdown(sdp); | 329 | gfs2_log_shutdown(sdp); |
| 331 | } | 330 | } |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 764fbb49efc..8d3d2b4a0a7 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
| @@ -207,12 +207,14 @@ struct gfs2_glock { | |||
| 207 | 207 | ||
| 208 | spinlock_t gl_spin; | 208 | spinlock_t gl_spin; |
| 209 | 209 | ||
| 210 | unsigned int gl_state; | 210 | /* State fields protected by gl_spin */ |
| 211 | unsigned int gl_target; | 211 | unsigned int gl_state:2, /* Current state */ |
| 212 | unsigned int gl_reply; | 212 | gl_target:2, /* Target state */ |
| 213 | gl_demote_state:2, /* State requested by remote node */ | ||
| 214 | gl_req:2, /* State in last dlm request */ | ||
| 215 | gl_reply:8; /* Last reply from the dlm */ | ||
| 216 | |||
| 213 | unsigned int gl_hash; | 217 | unsigned int gl_hash; |
| 214 | unsigned int gl_req; | ||
| 215 | unsigned int gl_demote_state; /* state requested by remote node */ | ||
| 216 | unsigned long gl_demote_time; /* time of first demote request */ | 218 | unsigned long gl_demote_time; /* time of first demote request */ |
| 217 | struct list_head gl_holders; | 219 | struct list_head gl_holders; |
| 218 | 220 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index e1213f7f921..14e682dbe8b 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -916,17 +916,8 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
| 916 | if (error) | 916 | if (error) |
| 917 | return error; | 917 | return error; |
| 918 | 918 | ||
| 919 | if ((attr->ia_valid & ATTR_SIZE) && | ||
| 920 | attr->ia_size != i_size_read(inode)) { | ||
| 921 | error = vmtruncate(inode, attr->ia_size); | ||
| 922 | if (error) | ||
| 923 | return error; | ||
| 924 | } | ||
| 925 | |||
| 926 | setattr_copy(inode, attr); | 919 | setattr_copy(inode, attr); |
| 927 | mark_inode_dirty(inode); | 920 | mark_inode_dirty(inode); |
| 928 | |||
| 929 | gfs2_assert_warn(GFS2_SB(inode), !error); | ||
| 930 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 921 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
| 931 | gfs2_dinode_out(ip, dibh->b_data); | 922 | gfs2_dinode_out(ip, dibh->b_data); |
| 932 | brelse(dibh); | 923 | brelse(dibh); |
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 1c09425b45f..6e493aee28f 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c | |||
| @@ -146,15 +146,13 @@ static u32 make_flags(const u32 lkid, const unsigned int gfs_flags, | |||
| 146 | return lkf; | 146 | return lkf; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static unsigned int gdlm_lock(struct gfs2_glock *gl, | 149 | static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state, |
| 150 | unsigned int req_state, unsigned int flags) | 150 | unsigned int flags) |
| 151 | { | 151 | { |
| 152 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; | 152 | struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; |
| 153 | int error; | ||
| 154 | int req; | 153 | int req; |
| 155 | u32 lkf; | 154 | u32 lkf; |
| 156 | 155 | ||
| 157 | gl->gl_req = req_state; | ||
| 158 | req = make_mode(req_state); | 156 | req = make_mode(req_state); |
| 159 | lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); | 157 | lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); |
| 160 | 158 | ||
| @@ -162,13 +160,8 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl, | |||
| 162 | * Submit the actual lock request. | 160 | * Submit the actual lock request. |
| 163 | */ | 161 | */ |
| 164 | 162 | ||
| 165 | error = dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname, | 163 | return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname, |
| 166 | GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast); | 164 | GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast); |
| 167 | if (error == -EAGAIN) | ||
| 168 | return 0; | ||
| 169 | if (error) | ||
| 170 | return LM_OUT_ERROR; | ||
| 171 | return LM_OUT_ASYNC; | ||
| 172 | } | 165 | } |
| 173 | 166 | ||
| 174 | static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl) | 167 | static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl) |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 12cbea7502c..1db6b734322 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
| @@ -1069,7 +1069,6 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
| 1069 | { | 1069 | { |
| 1070 | struct gfs2_inode *ip = GFS2_I(inode); | 1070 | struct gfs2_inode *ip = GFS2_I(inode); |
| 1071 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1071 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| 1072 | struct buffer_head *dibh; | ||
| 1073 | u32 ouid, ogid, nuid, ngid; | 1072 | u32 ouid, ogid, nuid, ngid; |
| 1074 | int error; | 1073 | int error; |
| 1075 | 1074 | ||
| @@ -1100,25 +1099,10 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
| 1100 | if (error) | 1099 | if (error) |
| 1101 | goto out_gunlock_q; | 1100 | goto out_gunlock_q; |
| 1102 | 1101 | ||
| 1103 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1102 | error = gfs2_setattr_simple(ip, attr); |
| 1104 | if (error) | 1103 | if (error) |
| 1105 | goto out_end_trans; | 1104 | goto out_end_trans; |
| 1106 | 1105 | ||
| 1107 | if ((attr->ia_valid & ATTR_SIZE) && | ||
| 1108 | attr->ia_size != i_size_read(inode)) { | ||
| 1109 | int error; | ||
| 1110 | |||
| 1111 | error = vmtruncate(inode, attr->ia_size); | ||
| 1112 | gfs2_assert_warn(sdp, !error); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | setattr_copy(inode, attr); | ||
| 1116 | mark_inode_dirty(inode); | ||
| 1117 | |||
| 1118 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
| 1119 | gfs2_dinode_out(ip, dibh->b_data); | ||
| 1120 | brelse(dibh); | ||
| 1121 | |||
| 1122 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 1106 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
| 1123 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); | 1107 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); |
| 1124 | gfs2_quota_change(ip, -blocks, ouid, ogid); | 1108 | gfs2_quota_change(ip, -blocks, ouid, ogid); |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index f606baf9ba7..a689901963d 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
| @@ -666,6 +666,10 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
| 666 | qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift); | 666 | qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift); |
| 667 | qd->qd_qb.qb_limit = qp->qu_limit; | 667 | qd->qd_qb.qb_limit = qp->qu_limit; |
| 668 | } | 668 | } |
| 669 | if (fdq->d_fieldmask & FS_DQ_BCOUNT) { | ||
| 670 | qp->qu_value = cpu_to_be64(fdq->d_bcount >> sdp->sd_fsb2bb_shift); | ||
| 671 | qd->qd_qb.qb_value = qp->qu_value; | ||
| 672 | } | ||
| 669 | } | 673 | } |
| 670 | 674 | ||
| 671 | /* Write the quota into the quota file on disk */ | 675 | /* Write the quota into the quota file on disk */ |
| @@ -1509,7 +1513,7 @@ out: | |||
| 1509 | } | 1513 | } |
| 1510 | 1514 | ||
| 1511 | /* GFS2 only supports a subset of the XFS fields */ | 1515 | /* GFS2 only supports a subset of the XFS fields */ |
| 1512 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD) | 1516 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) |
| 1513 | 1517 | ||
| 1514 | static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | 1518 | static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, |
| 1515 | struct fs_disk_quota *fdq) | 1519 | struct fs_disk_quota *fdq) |
| @@ -1569,9 +1573,15 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
| 1569 | if ((fdq->d_fieldmask & FS_DQ_BSOFT) && | 1573 | if ((fdq->d_fieldmask & FS_DQ_BSOFT) && |
| 1570 | ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) | 1574 | ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) |
| 1571 | fdq->d_fieldmask ^= FS_DQ_BSOFT; | 1575 | fdq->d_fieldmask ^= FS_DQ_BSOFT; |
| 1576 | |||
| 1572 | if ((fdq->d_fieldmask & FS_DQ_BHARD) && | 1577 | if ((fdq->d_fieldmask & FS_DQ_BHARD) && |
| 1573 | ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) | 1578 | ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) |
| 1574 | fdq->d_fieldmask ^= FS_DQ_BHARD; | 1579 | fdq->d_fieldmask ^= FS_DQ_BHARD; |
| 1580 | |||
| 1581 | if ((fdq->d_fieldmask & FS_DQ_BCOUNT) && | ||
| 1582 | ((fdq->d_bcount >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_value))) | ||
| 1583 | fdq->d_fieldmask ^= FS_DQ_BCOUNT; | ||
| 1584 | |||
| 1575 | if (fdq->d_fieldmask == 0) | 1585 | if (fdq->d_fieldmask == 0) |
| 1576 | goto out_i; | 1586 | goto out_i; |
| 1577 | 1587 | ||
| @@ -1620,4 +1630,3 @@ const struct quotactl_ops gfs2_quotactl_ops = { | |||
| 1620 | .get_dqblk = gfs2_get_dqblk, | 1630 | .get_dqblk = gfs2_get_dqblk, |
| 1621 | .set_dqblk = gfs2_set_dqblk, | 1631 | .set_dqblk = gfs2_set_dqblk, |
| 1622 | }; | 1632 | }; |
| 1623 | |||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 33c8407b876..7293ea27020 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -500,7 +500,7 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) | |||
| 500 | for (rgrps = 0;; rgrps++) { | 500 | for (rgrps = 0;; rgrps++) { |
| 501 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); | 501 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); |
| 502 | 502 | ||
| 503 | if (pos + sizeof(struct gfs2_rindex) >= i_size_read(inode)) | 503 | if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode)) |
| 504 | break; | 504 | break; |
| 505 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | 505 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, |
| 506 | sizeof(struct gfs2_rindex)); | 506 | sizeof(struct gfs2_rindex)); |
| @@ -583,7 +583,7 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
| 583 | * Returns: 0 on successful update, error code otherwise | 583 | * Returns: 0 on successful update, error code otherwise |
| 584 | */ | 584 | */ |
| 585 | 585 | ||
| 586 | static int gfs2_ri_update(struct gfs2_inode *ip) | 586 | int gfs2_ri_update(struct gfs2_inode *ip) |
| 587 | { | 587 | { |
| 588 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 588 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
| 589 | struct inode *inode = &ip->i_inode; | 589 | struct inode *inode = &ip->i_inode; |
| @@ -614,46 +614,6 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | /** | 616 | /** |
| 617 | * gfs2_ri_update_special - Pull in a new resource index from the disk | ||
| 618 | * | ||
| 619 | * This is a special version that's safe to call from gfs2_inplace_reserve_i. | ||
| 620 | * In this case we know that we don't have any resource groups in memory yet. | ||
| 621 | * | ||
| 622 | * @ip: pointer to the rindex inode | ||
| 623 | * | ||
| 624 | * Returns: 0 on successful update, error code otherwise | ||
| 625 | */ | ||
| 626 | static int gfs2_ri_update_special(struct gfs2_inode *ip) | ||
| 627 | { | ||
| 628 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 629 | struct inode *inode = &ip->i_inode; | ||
| 630 | struct file_ra_state ra_state; | ||
| 631 | struct gfs2_rgrpd *rgd; | ||
| 632 | unsigned int max_data = 0; | ||
| 633 | int error; | ||
| 634 | |||
| 635 | file_ra_state_init(&ra_state, inode->i_mapping); | ||
| 636 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { | ||
| 637 | /* Ignore partials */ | ||
| 638 | if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > | ||
| 639 | i_size_read(inode)) | ||
| 640 | break; | ||
| 641 | error = read_rindex_entry(ip, &ra_state); | ||
| 642 | if (error) { | ||
| 643 | clear_rgrpdi(sdp); | ||
| 644 | return error; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | list_for_each_entry(rgd, &sdp->sd_rindex_list, rd_list) | ||
| 648 | if (rgd->rd_data > max_data) | ||
| 649 | max_data = rgd->rd_data; | ||
| 650 | sdp->sd_max_rg_data = max_data; | ||
| 651 | |||
| 652 | sdp->sd_rindex_uptodate = 1; | ||
| 653 | return 0; | ||
| 654 | } | ||
| 655 | |||
| 656 | /** | ||
| 657 | * gfs2_rindex_hold - Grab a lock on the rindex | 617 | * gfs2_rindex_hold - Grab a lock on the rindex |
| 658 | * @sdp: The GFS2 superblock | 618 | * @sdp: The GFS2 superblock |
| 659 | * @ri_gh: the glock holder | 619 | * @ri_gh: the glock holder |
| @@ -1226,16 +1186,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | |||
| 1226 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | 1186 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); |
| 1227 | else if (!sdp->sd_rgrps) /* We may not have the rindex read | 1187 | else if (!sdp->sd_rgrps) /* We may not have the rindex read |
| 1228 | in, so: */ | 1188 | in, so: */ |
| 1229 | error = gfs2_ri_update_special(ip); | 1189 | error = gfs2_ri_update(ip); |
| 1230 | if (error) | 1190 | if (error) |
| 1231 | return error; | 1191 | return error; |
| 1232 | } | 1192 | } |
| 1233 | 1193 | ||
| 1194 | try_again: | ||
| 1234 | do { | 1195 | do { |
| 1235 | error = get_local_rgrp(ip, &last_unlinked); | 1196 | error = get_local_rgrp(ip, &last_unlinked); |
| 1236 | /* If there is no space, flushing the log may release some */ | 1197 | /* If there is no space, flushing the log may release some */ |
| 1237 | if (error) | 1198 | if (error) { |
| 1199 | if (ip == GFS2_I(sdp->sd_rindex) && | ||
| 1200 | !sdp->sd_rindex_uptodate) { | ||
| 1201 | error = gfs2_ri_update(ip); | ||
| 1202 | if (error) | ||
| 1203 | return error; | ||
| 1204 | goto try_again; | ||
| 1205 | } | ||
| 1238 | gfs2_log_flush(sdp, NULL); | 1206 | gfs2_log_flush(sdp, NULL); |
| 1207 | } | ||
| 1239 | } while (error && tries++ < 3); | 1208 | } while (error && tries++ < 3); |
| 1240 | 1209 | ||
| 1241 | if (error) { | 1210 | if (error) { |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 0e35c0466f9..50c2bb04369 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
| @@ -48,6 +48,7 @@ extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | |||
| 48 | 48 | ||
| 49 | extern void gfs2_inplace_release(struct gfs2_inode *ip); | 49 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
| 50 | 50 | ||
| 51 | extern int gfs2_ri_update(struct gfs2_inode *ip); | ||
| 51 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); | 52 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); |
| 52 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); | 53 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); |
| 53 | 54 | ||
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 30b58f07c8a..439b61c0326 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
| @@ -1296,10 +1296,8 @@ fail: | |||
| 1296 | 1296 | ||
| 1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | 1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) |
| 1298 | { | 1298 | { |
| 1299 | struct inode *inode = &ip->i_inode; | ||
| 1300 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1299 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
| 1301 | struct gfs2_ea_location el; | 1300 | struct gfs2_ea_location el; |
| 1302 | struct buffer_head *dibh; | ||
| 1303 | int error; | 1301 | int error; |
| 1304 | 1302 | ||
| 1305 | error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el); | 1303 | error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el); |
| @@ -1321,26 +1319,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | |||
| 1321 | if (error) | 1319 | if (error) |
| 1322 | return error; | 1320 | return error; |
| 1323 | 1321 | ||
| 1324 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1322 | error = gfs2_setattr_simple(ip, attr); |
| 1325 | if (error) | ||
| 1326 | goto out_trans_end; | ||
| 1327 | |||
| 1328 | if ((attr->ia_valid & ATTR_SIZE) && | ||
| 1329 | attr->ia_size != i_size_read(inode)) { | ||
| 1330 | int error; | ||
| 1331 | |||
| 1332 | error = vmtruncate(inode, attr->ia_size); | ||
| 1333 | gfs2_assert_warn(GFS2_SB(inode), !error); | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | setattr_copy(inode, attr); | ||
| 1337 | mark_inode_dirty(inode); | ||
| 1338 | |||
| 1339 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
| 1340 | gfs2_dinode_out(ip, dibh->b_data); | ||
| 1341 | brelse(dibh); | ||
| 1342 | |||
| 1343 | out_trans_end: | ||
| 1344 | gfs2_trans_end(sdp); | 1323 | gfs2_trans_end(sdp); |
| 1345 | return error; | 1324 | return error; |
| 1346 | } | 1325 | } |
