| .. | .. |
|---|
| 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-2008 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/spinlock.h> |
|---|
| .. | .. |
|---|
| 28 | 25 | #include "util.h" |
|---|
| 29 | 26 | #include "trans.h" |
|---|
| 30 | 27 | #include "dir.h" |
|---|
| 28 | +#include "lops.h" |
|---|
| 31 | 29 | |
|---|
| 32 | 30 | struct workqueue_struct *gfs2_freeze_wq; |
|---|
| 31 | + |
|---|
| 32 | +extern struct workqueue_struct *gfs2_control_wq; |
|---|
| 33 | 33 | |
|---|
| 34 | 34 | static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) |
|---|
| 35 | 35 | { |
|---|
| .. | .. |
|---|
| 41 | 41 | fs_err(gl->gl_name.ln_sbd, "AIL glock %u:%llu mapping %p\n", |
|---|
| 42 | 42 | gl->gl_name.ln_type, gl->gl_name.ln_number, |
|---|
| 43 | 43 | gfs2_glock2aspace(gl)); |
|---|
| 44 | | - gfs2_lm_withdraw(gl->gl_name.ln_sbd, "AIL error\n"); |
|---|
| 44 | + gfs2_lm(gl->gl_name.ln_sbd, "AIL error\n"); |
|---|
| 45 | + gfs2_withdraw(gl->gl_name.ln_sbd); |
|---|
| 45 | 46 | } |
|---|
| 46 | 47 | |
|---|
| 47 | 48 | /** |
|---|
| .. | .. |
|---|
| 81 | 82 | } |
|---|
| 82 | 83 | |
|---|
| 83 | 84 | |
|---|
| 84 | | -static void gfs2_ail_empty_gl(struct gfs2_glock *gl) |
|---|
| 85 | +static int gfs2_ail_empty_gl(struct gfs2_glock *gl) |
|---|
| 85 | 86 | { |
|---|
| 86 | 87 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 87 | 88 | struct gfs2_trans tr; |
|---|
| 89 | + int ret; |
|---|
| 88 | 90 | |
|---|
| 89 | 91 | memset(&tr, 0, sizeof(tr)); |
|---|
| 90 | 92 | INIT_LIST_HEAD(&tr.tr_buf); |
|---|
| .. | .. |
|---|
| 93 | 95 | INIT_LIST_HEAD(&tr.tr_ail2_list); |
|---|
| 94 | 96 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); |
|---|
| 95 | 97 | |
|---|
| 96 | | - if (!tr.tr_revokes) |
|---|
| 97 | | - return; |
|---|
| 98 | + if (!tr.tr_revokes) { |
|---|
| 99 | + bool have_revokes; |
|---|
| 100 | + bool log_in_flight; |
|---|
| 101 | + |
|---|
| 102 | + /* |
|---|
| 103 | + * We have nothing on the ail, but there could be revokes on |
|---|
| 104 | + * the sdp revoke queue, in which case, we still want to flush |
|---|
| 105 | + * the log and wait for it to finish. |
|---|
| 106 | + * |
|---|
| 107 | + * If the sdp revoke list is empty too, we might still have an |
|---|
| 108 | + * io outstanding for writing revokes, so we should wait for |
|---|
| 109 | + * it before returning. |
|---|
| 110 | + * |
|---|
| 111 | + * If none of these conditions are true, our revokes are all |
|---|
| 112 | + * flushed and we can return. |
|---|
| 113 | + */ |
|---|
| 114 | + gfs2_log_lock(sdp); |
|---|
| 115 | + have_revokes = !list_empty(&sdp->sd_log_revokes); |
|---|
| 116 | + log_in_flight = atomic_read(&sdp->sd_log_in_flight); |
|---|
| 117 | + gfs2_log_unlock(sdp); |
|---|
| 118 | + if (have_revokes) |
|---|
| 119 | + goto flush; |
|---|
| 120 | + if (log_in_flight) |
|---|
| 121 | + log_flush_wait(sdp); |
|---|
| 122 | + return 0; |
|---|
| 123 | + } |
|---|
| 98 | 124 | |
|---|
| 99 | 125 | /* A shortened, inline version of gfs2_trans_begin() |
|---|
| 100 | 126 | * tr->alloced is not set since the transaction structure is |
|---|
| 101 | 127 | * on the stack */ |
|---|
| 102 | | - tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); |
|---|
| 128 | + tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes); |
|---|
| 103 | 129 | tr.tr_ip = _RET_IP_; |
|---|
| 104 | | - if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) |
|---|
| 105 | | - return; |
|---|
| 130 | + ret = gfs2_log_reserve(sdp, tr.tr_reserved); |
|---|
| 131 | + if (ret < 0) |
|---|
| 132 | + return ret; |
|---|
| 106 | 133 | WARN_ON_ONCE(current->journal_info); |
|---|
| 107 | 134 | current->journal_info = &tr; |
|---|
| 108 | 135 | |
|---|
| 109 | 136 | __gfs2_ail_flush(gl, 0, tr.tr_revokes); |
|---|
| 110 | 137 | |
|---|
| 111 | 138 | gfs2_trans_end(sdp); |
|---|
| 139 | +flush: |
|---|
| 112 | 140 | gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | |
|---|
| 113 | 141 | GFS2_LFC_AIL_EMPTY_GL); |
|---|
| 142 | + return 0; |
|---|
| 114 | 143 | } |
|---|
| 115 | 144 | |
|---|
| 116 | 145 | void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) |
|---|
| .. | .. |
|---|
| 136 | 165 | } |
|---|
| 137 | 166 | |
|---|
| 138 | 167 | /** |
|---|
| 168 | + * gfs2_rgrp_metasync - sync out the metadata of a resource group |
|---|
| 169 | + * @gl: the glock protecting the resource group |
|---|
| 170 | + * |
|---|
| 171 | + */ |
|---|
| 172 | + |
|---|
| 173 | +static int gfs2_rgrp_metasync(struct gfs2_glock *gl) |
|---|
| 174 | +{ |
|---|
| 175 | + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 176 | + struct address_space *metamapping = &sdp->sd_aspace; |
|---|
| 177 | + struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); |
|---|
| 178 | + const unsigned bsize = sdp->sd_sb.sb_bsize; |
|---|
| 179 | + loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK; |
|---|
| 180 | + loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1; |
|---|
| 181 | + int error; |
|---|
| 182 | + |
|---|
| 183 | + filemap_fdatawrite_range(metamapping, start, end); |
|---|
| 184 | + error = filemap_fdatawait_range(metamapping, start, end); |
|---|
| 185 | + WARN_ON_ONCE(error && !gfs2_withdrawn(sdp)); |
|---|
| 186 | + mapping_set_error(metamapping, error); |
|---|
| 187 | + if (error) |
|---|
| 188 | + gfs2_io_error(sdp); |
|---|
| 189 | + return error; |
|---|
| 190 | +} |
|---|
| 191 | + |
|---|
| 192 | +/** |
|---|
| 139 | 193 | * rgrp_go_sync - sync out the metadata for this glock |
|---|
| 140 | 194 | * @gl: the glock |
|---|
| 141 | 195 | * |
|---|
| .. | .. |
|---|
| 144 | 198 | * return to caller to demote/unlock the glock until I/O is complete. |
|---|
| 145 | 199 | */ |
|---|
| 146 | 200 | |
|---|
| 147 | | -static void rgrp_go_sync(struct gfs2_glock *gl) |
|---|
| 201 | +static int rgrp_go_sync(struct gfs2_glock *gl) |
|---|
| 148 | 202 | { |
|---|
| 149 | 203 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 150 | | - struct address_space *mapping = &sdp->sd_aspace; |
|---|
| 151 | | - struct gfs2_rgrpd *rgd; |
|---|
| 204 | + struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); |
|---|
| 152 | 205 | int error; |
|---|
| 153 | 206 | |
|---|
| 154 | | - spin_lock(&gl->gl_lockref.lock); |
|---|
| 155 | | - rgd = gl->gl_object; |
|---|
| 156 | | - if (rgd) |
|---|
| 157 | | - gfs2_rgrp_brelse(rgd); |
|---|
| 158 | | - spin_unlock(&gl->gl_lockref.lock); |
|---|
| 159 | | - |
|---|
| 160 | 207 | if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) |
|---|
| 161 | | - return; |
|---|
| 208 | + return 0; |
|---|
| 162 | 209 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); |
|---|
| 163 | 210 | |
|---|
| 164 | 211 | gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL | |
|---|
| 165 | 212 | GFS2_LFC_RGRP_GO_SYNC); |
|---|
| 166 | | - filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
|---|
| 167 | | - error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
|---|
| 168 | | - mapping_set_error(mapping, error); |
|---|
| 169 | | - gfs2_ail_empty_gl(gl); |
|---|
| 170 | | - |
|---|
| 171 | | - spin_lock(&gl->gl_lockref.lock); |
|---|
| 172 | | - rgd = gl->gl_object; |
|---|
| 173 | | - if (rgd) |
|---|
| 174 | | - gfs2_free_clones(rgd); |
|---|
| 175 | | - spin_unlock(&gl->gl_lockref.lock); |
|---|
| 213 | + error = gfs2_rgrp_metasync(gl); |
|---|
| 214 | + if (!error) |
|---|
| 215 | + error = gfs2_ail_empty_gl(gl); |
|---|
| 216 | + gfs2_free_clones(rgd); |
|---|
| 217 | + return error; |
|---|
| 176 | 218 | } |
|---|
| 177 | 219 | |
|---|
| 178 | 220 | /** |
|---|
| .. | .. |
|---|
| 190 | 232 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 191 | 233 | struct address_space *mapping = &sdp->sd_aspace; |
|---|
| 192 | 234 | struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); |
|---|
| 235 | + const unsigned bsize = sdp->sd_sb.sb_bsize; |
|---|
| 236 | + loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK; |
|---|
| 237 | + loff_t end = PAGE_ALIGN((rgd->rd_addr + rgd->rd_length) * bsize) - 1; |
|---|
| 193 | 238 | |
|---|
| 194 | | - if (rgd) |
|---|
| 195 | | - gfs2_rgrp_brelse(rgd); |
|---|
| 196 | | - |
|---|
| 239 | + gfs2_rgrp_brelse(rgd); |
|---|
| 197 | 240 | WARN_ON_ONCE(!(flags & DIO_METADATA)); |
|---|
| 198 | | - gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
|---|
| 199 | | - truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
|---|
| 241 | + truncate_inode_pages_range(mapping, start, end); |
|---|
| 242 | + rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
|---|
| 243 | +} |
|---|
| 244 | + |
|---|
| 245 | +static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl, |
|---|
| 246 | + const char *fs_id_buf) |
|---|
| 247 | +{ |
|---|
| 248 | + struct gfs2_rgrpd *rgd = gl->gl_object; |
|---|
| 200 | 249 | |
|---|
| 201 | 250 | if (rgd) |
|---|
| 202 | | - rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
|---|
| 251 | + gfs2_rgrp_dump(seq, rgd, fs_id_buf); |
|---|
| 203 | 252 | } |
|---|
| 204 | 253 | |
|---|
| 205 | 254 | static struct gfs2_inode *gfs2_glock2inode(struct gfs2_glock *gl) |
|---|
| .. | .. |
|---|
| 235 | 284 | } |
|---|
| 236 | 285 | |
|---|
| 237 | 286 | /** |
|---|
| 238 | | - * inode_go_sync - Sync the dirty data and/or metadata for an inode glock |
|---|
| 287 | + * gfs2_inode_metasync - sync out the metadata of an inode |
|---|
| 288 | + * @gl: the glock protecting the inode |
|---|
| 289 | + * |
|---|
| 290 | + */ |
|---|
| 291 | +int gfs2_inode_metasync(struct gfs2_glock *gl) |
|---|
| 292 | +{ |
|---|
| 293 | + struct address_space *metamapping = gfs2_glock2aspace(gl); |
|---|
| 294 | + int error; |
|---|
| 295 | + |
|---|
| 296 | + filemap_fdatawrite(metamapping); |
|---|
| 297 | + error = filemap_fdatawait(metamapping); |
|---|
| 298 | + if (error) |
|---|
| 299 | + gfs2_io_error(gl->gl_name.ln_sbd); |
|---|
| 300 | + return error; |
|---|
| 301 | +} |
|---|
| 302 | + |
|---|
| 303 | +/** |
|---|
| 304 | + * inode_go_sync - Sync the dirty metadata of an inode |
|---|
| 239 | 305 | * @gl: the glock protecting the inode |
|---|
| 240 | 306 | * |
|---|
| 241 | 307 | */ |
|---|
| 242 | 308 | |
|---|
| 243 | | -static void inode_go_sync(struct gfs2_glock *gl) |
|---|
| 309 | +static int inode_go_sync(struct gfs2_glock *gl) |
|---|
| 244 | 310 | { |
|---|
| 245 | 311 | struct gfs2_inode *ip = gfs2_glock2inode(gl); |
|---|
| 246 | 312 | int isreg = ip && S_ISREG(ip->i_inode.i_mode); |
|---|
| 247 | 313 | struct address_space *metamapping = gfs2_glock2aspace(gl); |
|---|
| 248 | | - int error; |
|---|
| 314 | + int error = 0, ret; |
|---|
| 249 | 315 | |
|---|
| 250 | 316 | if (isreg) { |
|---|
| 251 | 317 | if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags)) |
|---|
| .. | .. |
|---|
| 266 | 332 | error = filemap_fdatawait(mapping); |
|---|
| 267 | 333 | mapping_set_error(mapping, error); |
|---|
| 268 | 334 | } |
|---|
| 269 | | - error = filemap_fdatawait(metamapping); |
|---|
| 270 | | - mapping_set_error(metamapping, error); |
|---|
| 335 | + ret = gfs2_inode_metasync(gl); |
|---|
| 336 | + if (!error) |
|---|
| 337 | + error = ret; |
|---|
| 271 | 338 | gfs2_ail_empty_gl(gl); |
|---|
| 272 | 339 | /* |
|---|
| 273 | 340 | * Writeback of the data mapping may cause the dirty flag to be set |
|---|
| .. | .. |
|---|
| 278 | 345 | |
|---|
| 279 | 346 | out: |
|---|
| 280 | 347 | gfs2_clear_glop_pending(ip); |
|---|
| 348 | + return error; |
|---|
| 281 | 349 | } |
|---|
| 282 | 350 | |
|---|
| 283 | 351 | /** |
|---|
| .. | .. |
|---|
| 294 | 362 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
|---|
| 295 | 363 | { |
|---|
| 296 | 364 | struct gfs2_inode *ip = gfs2_glock2inode(gl); |
|---|
| 297 | | - |
|---|
| 298 | | - gfs2_assert_withdraw(gl->gl_name.ln_sbd, !atomic_read(&gl->gl_ail_count)); |
|---|
| 299 | 365 | |
|---|
| 300 | 366 | if (flags & DIO_METADATA) { |
|---|
| 301 | 367 | struct address_space *mapping = gfs2_glock2aspace(gl); |
|---|
| .. | .. |
|---|
| 354 | 420 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), |
|---|
| 355 | 421 | be32_to_cpu(str->di_minor)); |
|---|
| 356 | 422 | break; |
|---|
| 357 | | - }; |
|---|
| 423 | + } |
|---|
| 358 | 424 | |
|---|
| 359 | 425 | i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); |
|---|
| 360 | 426 | i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); |
|---|
| .. | .. |
|---|
| 465 | 531 | * inode_go_dump - print information about an inode |
|---|
| 466 | 532 | * @seq: The iterator |
|---|
| 467 | 533 | * @ip: the inode |
|---|
| 534 | + * @fs_id_buf: file system id (may be empty) |
|---|
| 468 | 535 | * |
|---|
| 469 | 536 | */ |
|---|
| 470 | 537 | |
|---|
| 471 | | -static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) |
|---|
| 538 | +static void inode_go_dump(struct seq_file *seq, struct gfs2_glock *gl, |
|---|
| 539 | + const char *fs_id_buf) |
|---|
| 472 | 540 | { |
|---|
| 473 | | - const struct gfs2_inode *ip = gl->gl_object; |
|---|
| 541 | + struct gfs2_inode *ip = gl->gl_object; |
|---|
| 542 | + struct inode *inode = &ip->i_inode; |
|---|
| 543 | + unsigned long nrpages; |
|---|
| 544 | + |
|---|
| 474 | 545 | if (ip == NULL) |
|---|
| 475 | 546 | return; |
|---|
| 476 | | - gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n", |
|---|
| 547 | + |
|---|
| 548 | + xa_lock_irq(&inode->i_data.i_pages); |
|---|
| 549 | + nrpages = inode->i_data.nrpages; |
|---|
| 550 | + xa_unlock_irq(&inode->i_data.i_pages); |
|---|
| 551 | + |
|---|
| 552 | + gfs2_print_dbg(seq, "%s I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu " |
|---|
| 553 | + "p:%lu\n", fs_id_buf, |
|---|
| 477 | 554 | (unsigned long long)ip->i_no_formal_ino, |
|---|
| 478 | 555 | (unsigned long long)ip->i_no_addr, |
|---|
| 479 | 556 | IF2DT(ip->i_inode.i_mode), ip->i_flags, |
|---|
| 480 | 557 | (unsigned int)ip->i_diskflags, |
|---|
| 481 | | - (unsigned long long)i_size_read(&ip->i_inode)); |
|---|
| 558 | + (unsigned long long)i_size_read(inode), nrpages); |
|---|
| 482 | 559 | } |
|---|
| 483 | 560 | |
|---|
| 484 | 561 | /** |
|---|
| .. | .. |
|---|
| 489 | 566 | * |
|---|
| 490 | 567 | */ |
|---|
| 491 | 568 | |
|---|
| 492 | | -static void freeze_go_sync(struct gfs2_glock *gl) |
|---|
| 569 | +static int freeze_go_sync(struct gfs2_glock *gl) |
|---|
| 493 | 570 | { |
|---|
| 494 | 571 | int error = 0; |
|---|
| 495 | 572 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 496 | 573 | |
|---|
| 497 | | - if (gl->gl_state == LM_ST_SHARED && |
|---|
| 498 | | - test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
|---|
| 574 | + /* |
|---|
| 575 | + * We need to check gl_state == LM_ST_SHARED here and not gl_req == |
|---|
| 576 | + * LM_ST_EXCLUSIVE. That's because when any node does a freeze, |
|---|
| 577 | + * all the nodes should have the freeze glock in SH mode and they all |
|---|
| 578 | + * call do_xmote: One for EX and the others for UN. They ALL must |
|---|
| 579 | + * freeze locally, and they ALL must queue freeze work. The freeze_work |
|---|
| 580 | + * calls freeze_func, which tries to reacquire the freeze glock in SH, |
|---|
| 581 | + * effectively waiting for the thaw on the node who holds it in EX. |
|---|
| 582 | + * Once thawed, the work func acquires the freeze glock in |
|---|
| 583 | + * SH and everybody goes back to thawed. |
|---|
| 584 | + */ |
|---|
| 585 | + if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) && |
|---|
| 586 | + !test_bit(SDF_NORECOVERY, &sdp->sd_flags)) { |
|---|
| 499 | 587 | atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); |
|---|
| 500 | 588 | error = freeze_super(sdp->sd_vfs); |
|---|
| 501 | 589 | if (error) { |
|---|
| 502 | | - printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error); |
|---|
| 590 | + fs_info(sdp, "GFS2: couldn't freeze filesystem: %d\n", |
|---|
| 591 | + error); |
|---|
| 592 | + if (gfs2_withdrawn(sdp)) { |
|---|
| 593 | + atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN); |
|---|
| 594 | + return 0; |
|---|
| 595 | + } |
|---|
| 503 | 596 | gfs2_assert_withdraw(sdp, 0); |
|---|
| 504 | 597 | } |
|---|
| 505 | 598 | queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); |
|---|
| 506 | | - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | |
|---|
| 507 | | - GFS2_LFC_FREEZE_GO_SYNC); |
|---|
| 599 | + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) |
|---|
| 600 | + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | |
|---|
| 601 | + GFS2_LFC_FREEZE_GO_SYNC); |
|---|
| 602 | + else /* read-only mounts */ |
|---|
| 603 | + atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); |
|---|
| 508 | 604 | } |
|---|
| 605 | + return 0; |
|---|
| 509 | 606 | } |
|---|
| 510 | 607 | |
|---|
| 511 | 608 | /** |
|---|
| .. | .. |
|---|
| 525 | 622 | if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
|---|
| 526 | 623 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
|---|
| 527 | 624 | |
|---|
| 528 | | - error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
|---|
| 529 | | - if (error) |
|---|
| 530 | | - gfs2_consist(sdp); |
|---|
| 531 | | - if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) |
|---|
| 532 | | - gfs2_consist(sdp); |
|---|
| 533 | | - |
|---|
| 534 | | - /* Initialize some head of the log stuff */ |
|---|
| 535 | | - if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { |
|---|
| 536 | | - sdp->sd_log_sequence = head.lh_sequence + 1; |
|---|
| 537 | | - gfs2_log_pointers_init(sdp, head.lh_blkno); |
|---|
| 538 | | - } |
|---|
| 625 | + error = gfs2_find_jhead(sdp->sd_jdesc, &head, false); |
|---|
| 626 | + if (gfs2_assert_withdraw_delayed(sdp, !error)) |
|---|
| 627 | + return error; |
|---|
| 628 | + if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags & |
|---|
| 629 | + GFS2_LOG_HEAD_UNMOUNT)) |
|---|
| 630 | + return -EIO; |
|---|
| 631 | + sdp->sd_log_sequence = head.lh_sequence + 1; |
|---|
| 632 | + gfs2_log_pointers_init(sdp, head.lh_blkno); |
|---|
| 539 | 633 | } |
|---|
| 540 | 634 | return 0; |
|---|
| 541 | 635 | } |
|---|
| .. | .. |
|---|
| 569 | 663 | if (gl->gl_demote_state == LM_ST_UNLOCKED && |
|---|
| 570 | 664 | gl->gl_state == LM_ST_SHARED && ip) { |
|---|
| 571 | 665 | gl->gl_lockref.count++; |
|---|
| 572 | | - if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) |
|---|
| 666 | + if (!queue_delayed_work(gfs2_delete_workqueue, |
|---|
| 667 | + &gl->gl_delete, 0)) |
|---|
| 573 | 668 | gl->gl_lockref.count--; |
|---|
| 574 | 669 | } |
|---|
| 575 | 670 | } |
|---|
| 576 | 671 | |
|---|
| 672 | +static int iopen_go_demote_ok(const struct gfs2_glock *gl) |
|---|
| 673 | +{ |
|---|
| 674 | + return !gfs2_delete_work_queued(gl); |
|---|
| 675 | +} |
|---|
| 676 | + |
|---|
| 677 | +/** |
|---|
| 678 | + * inode_go_free - wake up anyone waiting for dlm's unlock ast to free it |
|---|
| 679 | + * @gl: glock being freed |
|---|
| 680 | + * |
|---|
| 681 | + * For now, this is only used for the journal inode glock. In withdraw |
|---|
| 682 | + * situations, we need to wait for the glock to be freed so that we know |
|---|
| 683 | + * other nodes may proceed with recovery / journal replay. |
|---|
| 684 | + */ |
|---|
| 685 | +static void inode_go_free(struct gfs2_glock *gl) |
|---|
| 686 | +{ |
|---|
| 687 | + /* Note that we cannot reference gl_object because it's already set |
|---|
| 688 | + * to NULL by this point in its lifecycle. */ |
|---|
| 689 | + if (!test_bit(GLF_FREEING, &gl->gl_flags)) |
|---|
| 690 | + return; |
|---|
| 691 | + clear_bit_unlock(GLF_FREEING, &gl->gl_flags); |
|---|
| 692 | + wake_up_bit(&gl->gl_flags, GLF_FREEING); |
|---|
| 693 | +} |
|---|
| 694 | + |
|---|
| 695 | +/** |
|---|
| 696 | + * nondisk_go_callback - used to signal when a node did a withdraw |
|---|
| 697 | + * @gl: the nondisk glock |
|---|
| 698 | + * @remote: true if this came from a different cluster node |
|---|
| 699 | + * |
|---|
| 700 | + */ |
|---|
| 701 | +static void nondisk_go_callback(struct gfs2_glock *gl, bool remote) |
|---|
| 702 | +{ |
|---|
| 703 | + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
|---|
| 704 | + |
|---|
| 705 | + /* Ignore the callback unless it's from another node, and it's the |
|---|
| 706 | + live lock. */ |
|---|
| 707 | + if (!remote || gl->gl_name.ln_number != GFS2_LIVE_LOCK) |
|---|
| 708 | + return; |
|---|
| 709 | + |
|---|
| 710 | + /* First order of business is to cancel the demote request. We don't |
|---|
| 711 | + * really want to demote a nondisk glock. At best it's just to inform |
|---|
| 712 | + * us of another node's withdraw. We'll keep it in SH mode. */ |
|---|
| 713 | + clear_bit(GLF_DEMOTE, &gl->gl_flags); |
|---|
| 714 | + clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags); |
|---|
| 715 | + |
|---|
| 716 | + /* Ignore the unlock if we're withdrawn, unmounting, or in recovery. */ |
|---|
| 717 | + if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || |
|---|
| 718 | + test_bit(SDF_WITHDRAWN, &sdp->sd_flags) || |
|---|
| 719 | + test_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags)) |
|---|
| 720 | + return; |
|---|
| 721 | + |
|---|
| 722 | + /* We only care when a node wants us to unlock, because that means |
|---|
| 723 | + * they want a journal recovered. */ |
|---|
| 724 | + if (gl->gl_demote_state != LM_ST_UNLOCKED) |
|---|
| 725 | + return; |
|---|
| 726 | + |
|---|
| 727 | + if (sdp->sd_args.ar_spectator) { |
|---|
| 728 | + fs_warn(sdp, "Spectator node cannot recover journals.\n"); |
|---|
| 729 | + return; |
|---|
| 730 | + } |
|---|
| 731 | + |
|---|
| 732 | + fs_warn(sdp, "Some node has withdrawn; checking for recovery.\n"); |
|---|
| 733 | + set_bit(SDF_REMOTE_WITHDRAW, &sdp->sd_flags); |
|---|
| 734 | + /* |
|---|
| 735 | + * We can't call remote_withdraw directly here or gfs2_recover_journal |
|---|
| 736 | + * because this is called from the glock unlock function and the |
|---|
| 737 | + * remote_withdraw needs to enqueue and dequeue the same "live" glock |
|---|
| 738 | + * we were called from. So we queue it to the control work queue in |
|---|
| 739 | + * lock_dlm. |
|---|
| 740 | + */ |
|---|
| 741 | + queue_delayed_work(gfs2_control_wq, &sdp->sd_control_work, 0); |
|---|
| 742 | +} |
|---|
| 743 | + |
|---|
| 577 | 744 | const struct gfs2_glock_operations gfs2_meta_glops = { |
|---|
| 578 | 745 | .go_type = LM_TYPE_META, |
|---|
| 746 | + .go_flags = GLOF_NONDISK, |
|---|
| 579 | 747 | }; |
|---|
| 580 | 748 | |
|---|
| 581 | 749 | const struct gfs2_glock_operations gfs2_inode_glops = { |
|---|
| .. | .. |
|---|
| 585 | 753 | .go_lock = inode_go_lock, |
|---|
| 586 | 754 | .go_dump = inode_go_dump, |
|---|
| 587 | 755 | .go_type = LM_TYPE_INODE, |
|---|
| 588 | | - .go_flags = GLOF_ASPACE | GLOF_LRU, |
|---|
| 756 | + .go_flags = GLOF_ASPACE | GLOF_LRU | GLOF_LVB, |
|---|
| 757 | + .go_free = inode_go_free, |
|---|
| 589 | 758 | }; |
|---|
| 590 | 759 | |
|---|
| 591 | 760 | const struct gfs2_glock_operations gfs2_rgrp_glops = { |
|---|
| 592 | 761 | .go_sync = rgrp_go_sync, |
|---|
| 593 | 762 | .go_inval = rgrp_go_inval, |
|---|
| 594 | 763 | .go_lock = gfs2_rgrp_go_lock, |
|---|
| 595 | | - .go_unlock = gfs2_rgrp_go_unlock, |
|---|
| 596 | | - .go_dump = gfs2_rgrp_dump, |
|---|
| 764 | + .go_dump = gfs2_rgrp_go_dump, |
|---|
| 597 | 765 | .go_type = LM_TYPE_RGRP, |
|---|
| 598 | 766 | .go_flags = GLOF_LVB, |
|---|
| 599 | 767 | }; |
|---|
| .. | .. |
|---|
| 603 | 771 | .go_xmote_bh = freeze_go_xmote_bh, |
|---|
| 604 | 772 | .go_demote_ok = freeze_go_demote_ok, |
|---|
| 605 | 773 | .go_type = LM_TYPE_NONDISK, |
|---|
| 774 | + .go_flags = GLOF_NONDISK, |
|---|
| 606 | 775 | }; |
|---|
| 607 | 776 | |
|---|
| 608 | 777 | const struct gfs2_glock_operations gfs2_iopen_glops = { |
|---|
| 609 | 778 | .go_type = LM_TYPE_IOPEN, |
|---|
| 610 | 779 | .go_callback = iopen_go_callback, |
|---|
| 611 | | - .go_flags = GLOF_LRU, |
|---|
| 780 | + .go_demote_ok = iopen_go_demote_ok, |
|---|
| 781 | + .go_flags = GLOF_LRU | GLOF_NONDISK, |
|---|
| 782 | + .go_subclass = 1, |
|---|
| 612 | 783 | }; |
|---|
| 613 | 784 | |
|---|
| 614 | 785 | const struct gfs2_glock_operations gfs2_flock_glops = { |
|---|
| 615 | 786 | .go_type = LM_TYPE_FLOCK, |
|---|
| 616 | | - .go_flags = GLOF_LRU, |
|---|
| 787 | + .go_flags = GLOF_LRU | GLOF_NONDISK, |
|---|
| 617 | 788 | }; |
|---|
| 618 | 789 | |
|---|
| 619 | 790 | const struct gfs2_glock_operations gfs2_nondisk_glops = { |
|---|
| 620 | 791 | .go_type = LM_TYPE_NONDISK, |
|---|
| 792 | + .go_flags = GLOF_NONDISK, |
|---|
| 793 | + .go_callback = nondisk_go_callback, |
|---|
| 621 | 794 | }; |
|---|
| 622 | 795 | |
|---|
| 623 | 796 | const struct gfs2_glock_operations gfs2_quota_glops = { |
|---|
| 624 | 797 | .go_type = LM_TYPE_QUOTA, |
|---|
| 625 | | - .go_flags = GLOF_LVB | GLOF_LRU, |
|---|
| 798 | + .go_flags = GLOF_LVB | GLOF_LRU | GLOF_NONDISK, |
|---|
| 626 | 799 | }; |
|---|
| 627 | 800 | |
|---|
| 628 | 801 | const struct gfs2_glock_operations gfs2_journal_glops = { |
|---|
| 629 | 802 | .go_type = LM_TYPE_JOURNAL, |
|---|
| 803 | + .go_flags = GLOF_NONDISK, |
|---|
| 630 | 804 | }; |
|---|
| 631 | 805 | |
|---|
| 632 | 806 | const struct gfs2_glock_operations *gfs2_glops_list[] = { |
|---|