~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/gfs2/util.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
  4  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
  5  */
  6 
  7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  8 
  9 #include <linux/spinlock.h>
 10 #include <linux/completion.h>
 11 #include <linux/buffer_head.h>
 12 #include <linux/kthread.h>
 13 #include <linux/crc32.h>
 14 #include <linux/gfs2_ondisk.h>
 15 #include <linux/delay.h>
 16 #include <linux/uaccess.h>
 17 
 18 #include "gfs2.h"
 19 #include "incore.h"
 20 #include "glock.h"
 21 #include "glops.h"
 22 #include "log.h"
 23 #include "lops.h"
 24 #include "recovery.h"
 25 #include "rgrp.h"
 26 #include "super.h"
 27 #include "util.h"
 28 
 29 struct kmem_cache *gfs2_glock_cachep __read_mostly;
 30 struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly;
 31 struct kmem_cache *gfs2_inode_cachep __read_mostly;
 32 struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
 33 struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
 34 struct kmem_cache *gfs2_quotad_cachep __read_mostly;
 35 struct kmem_cache *gfs2_qadata_cachep __read_mostly;
 36 struct kmem_cache *gfs2_trans_cachep __read_mostly;
 37 mempool_t *gfs2_page_pool __read_mostly;
 38 
 39 void gfs2_assert_i(struct gfs2_sbd *sdp)
 40 {
 41         fs_emerg(sdp, "fatal assertion failed\n");
 42 }
 43 
 44 /**
 45  * check_journal_clean - Make sure a journal is clean for a spectator mount
 46  * @sdp: The GFS2 superblock
 47  * @jd: The journal descriptor
 48  * @verbose: Show more prints in the log
 49  *
 50  * Returns: 0 if the journal is clean or locked, else an error
 51  */
 52 int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
 53                         bool verbose)
 54 {
 55         int error;
 56         struct gfs2_holder j_gh;
 57         struct gfs2_log_header_host head;
 58         struct gfs2_inode *ip;
 59 
 60         ip = GFS2_I(jd->jd_inode);
 61         error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP |
 62                                    GL_EXACT | GL_NOCACHE, &j_gh);
 63         if (error) {
 64                 if (verbose)
 65                         fs_err(sdp, "Error %d locking journal for spectator "
 66                                "mount.\n", error);
 67                 return -EPERM;
 68         }
 69         error = gfs2_jdesc_check(jd);
 70         if (error) {
 71                 if (verbose)
 72                         fs_err(sdp, "Error checking journal for spectator "
 73                                "mount.\n");
 74                 goto out_unlock;
 75         }
 76         error = gfs2_find_jhead(jd, &head, false);
 77         if (error) {
 78                 if (verbose)
 79                         fs_err(sdp, "Error parsing journal for spectator "
 80                                "mount.\n");
 81                 goto out_unlock;
 82         }
 83         if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
 84                 error = -EPERM;
 85                 if (verbose)
 86                         fs_err(sdp, "jid=%u: Journal is dirty, so the first "
 87                                "mounter must not be a spectator.\n",
 88                                jd->jd_jid);
 89         }
 90 
 91 out_unlock:
 92         gfs2_glock_dq_uninit(&j_gh);
 93         return error;
 94 }
 95 
 96 /**
 97  * gfs2_freeze_lock_shared - hold the freeze glock
 98  * @sdp: the superblock
 99  */
100 int gfs2_freeze_lock_shared(struct gfs2_sbd *sdp)
101 {
102         int flags = LM_FLAG_NOEXP | GL_EXACT;
103         int error;
104 
105         error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, flags,
106                                    &sdp->sd_freeze_gh);
107         if (error && error != GLR_TRYFAILED)
108                 fs_err(sdp, "can't lock the freeze glock: %d\n", error);
109         return error;
110 }
111 
112 void gfs2_freeze_unlock(struct gfs2_sbd *sdp)
113 {
114         if (gfs2_holder_initialized(&sdp->sd_freeze_gh))
115                 gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
116 }
117 
118 static void signal_our_withdraw(struct gfs2_sbd *sdp)
119 {
120         struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl;
121         struct inode *inode;
122         struct gfs2_inode *ip;
123         struct gfs2_glock *i_gl;
124         u64 no_formal_ino;
125         int ret = 0;
126         int tries;
127 
128         if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc)
129                 return;
130 
131         gfs2_ail_drain(sdp); /* frees all transactions */
132         inode = sdp->sd_jdesc->jd_inode;
133         ip = GFS2_I(inode);
134         i_gl = ip->i_gl;
135         no_formal_ino = ip->i_no_formal_ino;
136 
137         /* Prevent any glock dq until withdraw recovery is complete */
138         set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
139         /*
140          * Don't tell dlm we're bailing until we have no more buffers in the
141          * wind. If journal had an IO error, the log code should just purge
142          * the outstanding buffers rather than submitting new IO. Making the
143          * file system read-only will flush the journal, etc.
144          *
145          * During a normal unmount, gfs2_make_fs_ro calls gfs2_log_shutdown
146          * which clears SDF_JOURNAL_LIVE. In a withdraw, we must not write
147          * any UNMOUNT log header, so we can't call gfs2_log_shutdown, and
148          * therefore we need to clear SDF_JOURNAL_LIVE manually.
149          */
150         clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
151         if (!sb_rdonly(sdp->sd_vfs)) {
152                 bool locked = mutex_trylock(&sdp->sd_freeze_mutex);
153 
154                 wake_up(&sdp->sd_logd_waitq);
155                 wake_up(&sdp->sd_quota_wait);
156 
157                 wait_event_timeout(sdp->sd_log_waitq,
158                                    gfs2_log_is_empty(sdp),
159                                    HZ * 5);
160 
161                 sdp->sd_vfs->s_flags |= SB_RDONLY;
162 
163                 if (locked)
164                         mutex_unlock(&sdp->sd_freeze_mutex);
165 
166                 /*
167                  * Dequeue any pending non-system glock holders that can no
168                  * longer be granted because the file system is withdrawn.
169                  */
170                 gfs2_gl_dq_holders(sdp);
171         }
172 
173         if (sdp->sd_lockstruct.ls_ops->lm_lock == NULL) { /* lock_nolock */
174                 if (!ret)
175                         ret = -EIO;
176                 clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
177                 goto skip_recovery;
178         }
179         /*
180          * Drop the glock for our journal so another node can recover it.
181          */
182         if (gfs2_holder_initialized(&sdp->sd_journal_gh)) {
183                 gfs2_glock_dq_wait(&sdp->sd_journal_gh);
184                 gfs2_holder_uninit(&sdp->sd_journal_gh);
185         }
186         sdp->sd_jinode_gh.gh_flags |= GL_NOCACHE;
187         gfs2_glock_dq(&sdp->sd_jinode_gh);
188         gfs2_thaw_freeze_initiator(sdp->sd_vfs);
189         wait_on_bit(&i_gl->gl_flags, GLF_DEMOTE, TASK_UNINTERRUPTIBLE);
190 
191         /*
192          * holder_uninit to force glock_put, to force dlm to let go
193          */
194         gfs2_holder_uninit(&sdp->sd_jinode_gh);
195 
196         /*
197          * Note: We need to be careful here:
198          * Our iput of jd_inode will evict it. The evict will dequeue its
199          * glock, but the glock dq will wait for the withdraw unless we have
200          * exception code in glock_dq.
201          */
202         iput(inode);
203         sdp->sd_jdesc->jd_inode = NULL;
204         /*
205          * Wait until the journal inode's glock is freed. This allows try locks
206          * on other nodes to be successful, otherwise we remain the owner of
207          * the glock as far as dlm is concerned.
208          */
209         if (i_gl->gl_ops->go_unlocked) {
210                 set_bit(GLF_UNLOCKED, &i_gl->gl_flags);
211                 wait_on_bit(&i_gl->gl_flags, GLF_UNLOCKED, TASK_UNINTERRUPTIBLE);
212         }
213 
214         /*
215          * Dequeue the "live" glock, but keep a reference so it's never freed.
216          */
217         gfs2_glock_hold(live_gl);
218         gfs2_glock_dq_wait(&sdp->sd_live_gh);
219         /*
220          * We enqueue the "live" glock in EX so that all other nodes
221          * get a demote request and act on it. We don't really want the
222          * lock in EX, so we send a "try" lock with 1CB to produce a callback.
223          */
224         fs_warn(sdp, "Requesting recovery of jid %d.\n",
225                 sdp->sd_lockstruct.ls_jid);
226         gfs2_holder_reinit(LM_ST_EXCLUSIVE,
227                            LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | GL_NOPID,
228                            &sdp->sd_live_gh);
229         msleep(GL_GLOCK_MAX_HOLD);
230         /*
231          * This will likely fail in a cluster, but succeed standalone:
232          */
233         ret = gfs2_glock_nq(&sdp->sd_live_gh);
234 
235         /*
236          * If we actually got the "live" lock in EX mode, there are no other
237          * nodes available to replay our journal. So we try to replay it
238          * ourselves. We hold the "live" glock to prevent other mounters
239          * during recovery, then just dequeue it and reacquire it in our
240          * normal SH mode. Just in case the problem that caused us to
241          * withdraw prevents us from recovering our journal (e.g. io errors
242          * and such) we still check if the journal is clean before proceeding
243          * but we may wait forever until another mounter does the recovery.
244          */
245         if (ret == 0) {
246                 fs_warn(sdp, "No other mounters found. Trying to recover our "
247                         "own journal jid %d.\n", sdp->sd_lockstruct.ls_jid);
248                 if (gfs2_recover_journal(sdp->sd_jdesc, 1))
249                         fs_warn(sdp, "Unable to recover our journal jid %d.\n",
250                                 sdp->sd_lockstruct.ls_jid);
251                 gfs2_glock_dq_wait(&sdp->sd_live_gh);
252                 gfs2_holder_reinit(LM_ST_SHARED,
253                                    LM_FLAG_NOEXP | GL_EXACT | GL_NOPID,
254                                    &sdp->sd_live_gh);
255                 gfs2_glock_nq(&sdp->sd_live_gh);
256         }
257 
258         gfs2_glock_put(live_gl); /* drop extra reference we acquired */
259         clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
260 
261         /*
262          * At this point our journal is evicted, so we need to get a new inode
263          * for it. Once done, we need to call gfs2_find_jhead which
264          * calls gfs2_map_journal_extents to map it for us again.
265          *
266          * Note that we don't really want it to look up a FREE block. The
267          * GFS2_BLKST_FREE simply overrides a block check in gfs2_inode_lookup
268          * which would otherwise fail because it requires grabbing an rgrp
269          * glock, which would fail with -EIO because we're withdrawing.
270          */
271         inode = gfs2_inode_lookup(sdp->sd_vfs, DT_UNKNOWN,
272                                   sdp->sd_jdesc->jd_no_addr, no_formal_ino,
273                                   GFS2_BLKST_FREE);
274         if (IS_ERR(inode)) {
275                 fs_warn(sdp, "Reprocessing of jid %d failed with %ld.\n",
276                         sdp->sd_lockstruct.ls_jid, PTR_ERR(inode));
277                 goto skip_recovery;
278         }
279         sdp->sd_jdesc->jd_inode = inode;
280         d_mark_dontcache(inode);
281 
282         /*
283          * Now wait until recovery is complete.
284          */
285         for (tries = 0; tries < 10; tries++) {
286                 ret = check_journal_clean(sdp, sdp->sd_jdesc, false);
287                 if (!ret)
288                         break;
289                 msleep(HZ);
290                 fs_warn(sdp, "Waiting for journal recovery jid %d.\n",
291                         sdp->sd_lockstruct.ls_jid);
292         }
293 skip_recovery:
294         if (!ret)
295                 fs_warn(sdp, "Journal recovery complete for jid %d.\n",
296                         sdp->sd_lockstruct.ls_jid);
297         else
298                 fs_warn(sdp, "Journal recovery skipped for jid %d until next "
299                         "mount.\n", sdp->sd_lockstruct.ls_jid);
300         fs_warn(sdp, "Glock dequeues delayed: %lu\n", sdp->sd_glock_dqs_held);
301         sdp->sd_glock_dqs_held = 0;
302         wake_up_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY);
303 }
304 
305 void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...)
306 {
307         struct va_format vaf;
308         va_list args;
309 
310         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
311             test_bit(SDF_WITHDRAWN, &sdp->sd_flags))
312                 return;
313 
314         va_start(args, fmt);
315         vaf.fmt = fmt;
316         vaf.va = &args;
317         fs_err(sdp, "%pV", &vaf);
318         va_end(args);
319 }
320 
321 int gfs2_withdraw(struct gfs2_sbd *sdp)
322 {
323         struct lm_lockstruct *ls = &sdp->sd_lockstruct;
324         const struct lm_lockops *lm = ls->ls_ops;
325 
326         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
327                 unsigned long old = READ_ONCE(sdp->sd_flags), new;
328 
329                 do {
330                         if (old & BIT(SDF_WITHDRAWN)) {
331                                 wait_on_bit(&sdp->sd_flags,
332                                             SDF_WITHDRAW_IN_PROG,
333                                             TASK_UNINTERRUPTIBLE);
334                                 return -1;
335                         }
336                         new = old | BIT(SDF_WITHDRAWN) | BIT(SDF_WITHDRAW_IN_PROG);
337                 } while (unlikely(!try_cmpxchg(&sdp->sd_flags, &old, new)));
338 
339                 fs_err(sdp, "about to withdraw this file system\n");
340                 BUG_ON(sdp->sd_args.ar_debug);
341 
342                 signal_our_withdraw(sdp);
343 
344                 kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
345 
346                 if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
347                         wait_for_completion(&sdp->sd_wdack);
348 
349                 if (lm->lm_unmount) {
350                         fs_err(sdp, "telling LM to unmount\n");
351                         lm->lm_unmount(sdp);
352                 }
353                 fs_err(sdp, "File system withdrawn\n");
354                 dump_stack();
355                 clear_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags);
356                 smp_mb__after_atomic();
357                 wake_up_bit(&sdp->sd_flags, SDF_WITHDRAW_IN_PROG);
358         }
359 
360         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
361                 panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname);
362 
363         return -1;
364 }
365 
366 /*
367  * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false
368  */
369 
370 void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
371                             const char *function, char *file, unsigned int line,
372                             bool delayed)
373 {
374         if (gfs2_withdrawing_or_withdrawn(sdp))
375                 return;
376 
377         fs_err(sdp,
378                "fatal: assertion \"%s\" failed - "
379                "function = %s, file = %s, line = %u\n",
380                assertion, function, file, line);
381 
382         /*
383          * If errors=panic was specified on mount, it won't help to delay the
384          * withdraw.
385          */
386         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
387                 delayed = false;
388 
389         if (delayed)
390                 gfs2_withdraw_delayed(sdp);
391         else
392                 gfs2_withdraw(sdp);
393         dump_stack();
394 }
395 
396 /*
397  * gfs2_assert_warn_i - Print a message to the console if @assertion is false
398  */
399 
400 void gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
401                         const char *function, char *file, unsigned int line)
402 {
403         if (time_before(jiffies,
404                         sdp->sd_last_warning +
405                         gfs2_tune_get(sdp, gt_complain_secs) * HZ))
406                 return;
407 
408         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
409                 fs_warn(sdp, "warning: assertion \"%s\" failed - "
410                         "function = %s, file = %s, line = %u\n",
411                         assertion, function, file, line);
412 
413         if (sdp->sd_args.ar_debug)
414                 BUG();
415         else
416                 dump_stack();
417 
418         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
419                 panic("GFS2: fsid=%s: warning: assertion \"%s\" failed - "
420                       "function = %s, file = %s, line = %u\n",
421                       sdp->sd_fsname, assertion,
422                       function, file, line);
423 
424         sdp->sd_last_warning = jiffies;
425 }
426 
427 /*
428  * gfs2_consist_i - Flag a filesystem consistency error and withdraw
429  */
430 
431 void gfs2_consist_i(struct gfs2_sbd *sdp, const char *function,
432                     char *file, unsigned int line)
433 {
434         gfs2_lm(sdp,
435                 "fatal: filesystem consistency error - "
436                 "function = %s, file = %s, line = %u\n",
437                 function, file, line);
438         gfs2_withdraw(sdp);
439 }
440 
441 /*
442  * gfs2_consist_inode_i - Flag an inode consistency error and withdraw
443  */
444 
445 void gfs2_consist_inode_i(struct gfs2_inode *ip,
446                           const char *function, char *file, unsigned int line)
447 {
448         struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
449 
450         gfs2_lm(sdp,
451                 "fatal: filesystem consistency error - "
452                 "inode = %llu %llu, "
453                 "function = %s, file = %s, line = %u\n",
454                 (unsigned long long)ip->i_no_formal_ino,
455                 (unsigned long long)ip->i_no_addr,
456                 function, file, line);
457         gfs2_dump_glock(NULL, ip->i_gl, 1);
458         gfs2_withdraw(sdp);
459 }
460 
461 /*
462  * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw
463  */
464 
465 void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd,
466                           const char *function, char *file, unsigned int line)
467 {
468         struct gfs2_sbd *sdp = rgd->rd_sbd;
469         char fs_id_buf[sizeof(sdp->sd_fsname) + 7];
470 
471         sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname);
472         gfs2_rgrp_dump(NULL, rgd, fs_id_buf);
473         gfs2_lm(sdp,
474                 "fatal: filesystem consistency error - "
475                 "RG = %llu, "
476                 "function = %s, file = %s, line = %u\n",
477                 (unsigned long long)rgd->rd_addr,
478                 function, file, line);
479         gfs2_dump_glock(NULL, rgd->rd_gl, 1);
480         gfs2_withdraw(sdp);
481 }
482 
483 /*
484  * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw
485  * Returns: -1 if this call withdrew the machine,
486  *          -2 if it was already withdrawn
487  */
488 
489 int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
490                        const char *function, char *file,
491                        unsigned int line)
492 {
493         int me;
494 
495         gfs2_lm(sdp,
496                 "fatal: invalid metadata block - "
497                 "bh = %llu (bad magic number), "
498                 "function = %s, file = %s, line = %u\n",
499                 (unsigned long long)bh->b_blocknr,
500                 function, file, line);
501         me = gfs2_withdraw(sdp);
502         return (me) ? -1 : -2;
503 }
504 
505 /*
506  * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw
507  * Returns: -1 if this call withdrew the machine,
508  *          -2 if it was already withdrawn
509  */
510 
511 int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
512                            u16 type, u16 t, const char *function,
513                            char *file, unsigned int line)
514 {
515         int me;
516 
517         gfs2_lm(sdp,
518                 "fatal: invalid metadata block - "
519                 "bh = %llu (type: exp=%u, found=%u), "
520                 "function = %s, file = %s, line = %u\n",
521                 (unsigned long long)bh->b_blocknr, type, t,
522                 function, file, line);
523         me = gfs2_withdraw(sdp);
524         return (me) ? -1 : -2;
525 }
526 
527 /*
528  * gfs2_io_error_i - Flag an I/O error and withdraw
529  * Returns: -1 if this call withdrew the machine,
530  *          0 if it was already withdrawn
531  */
532 
533 int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
534                     unsigned int line)
535 {
536         gfs2_lm(sdp,
537                 "fatal: I/O error - "
538                 "function = %s, file = %s, line = %u\n",
539                 function, file, line);
540         return gfs2_withdraw(sdp);
541 }
542 
543 /*
544  * gfs2_io_error_bh_i - Flag a buffer I/O error
545  * @withdraw: withdraw the filesystem
546  */
547 
548 void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
549                         const char *function, char *file, unsigned int line,
550                         bool withdraw)
551 {
552         if (gfs2_withdrawing_or_withdrawn(sdp))
553                 return;
554 
555         fs_err(sdp, "fatal: I/O error - "
556                "block = %llu, "
557                "function = %s, file = %s, line = %u\n",
558                (unsigned long long)bh->b_blocknr, function, file, line);
559         if (withdraw)
560                 gfs2_withdraw(sdp);
561 }
562 
563 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php