Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  3 * All Rights Reserved.
  4 *
  5 * This program is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU General Public License as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it would be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write the Free Software Foundation,
 16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 17 */
 18#include "xfs.h"
 19#include "xfs_fs.h"
 20#include "xfs_types.h"
 21#include "xfs_bit.h"
 22#include "xfs_log.h"
 23#include "xfs_inum.h"
 24#include "xfs_trans.h"
 25#include "xfs_sb.h"
 26#include "xfs_ag.h"
 27#include "xfs_mount.h"
 28#include "xfs_bmap_btree.h"
 29#include "xfs_dinode.h"
 30#include "xfs_inode.h"
 31#include "xfs_error.h"
 32#include "xfs_rw.h"
 33
 34/*
 35 * Force a shutdown of the filesystem instantly while keeping
 36 * the filesystem consistent. We don't do an unmount here; just shutdown
 37 * the shop, make sure that absolutely nothing persistent happens to
 38 * this filesystem after this point.
 39 */
 40void
 41xfs_do_force_shutdown(
 42	xfs_mount_t	*mp,
 43	int		flags,
 44	char		*fname,
 45	int		lnnum)
 46{
 47	int		logerror;
 48
 49	logerror = flags & SHUTDOWN_LOG_IO_ERROR;
 50
 51	if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
 52		xfs_notice(mp,
 53	"%s(0x%x) called from line %d of file %s.  Return address = 0x%p",
 54			__func__, flags, lnnum, fname, __return_address);
 55	}
 56	/*
 57	 * No need to duplicate efforts.
 58	 */
 59	if (XFS_FORCED_SHUTDOWN(mp) && !logerror)
 60		return;
 61
 62	/*
 63	 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
 64	 * queue up anybody new on the log reservations, and wakes up
 65	 * everybody who's sleeping on log reservations to tell them
 66	 * the bad news.
 67	 */
 68	if (xfs_log_force_umount(mp, logerror))
 69		return;
 70
 71	if (flags & SHUTDOWN_CORRUPT_INCORE) {
 72		xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_CORRUPT,
 73    "Corruption of in-memory data detected.  Shutting down filesystem");
 74		if (XFS_ERRLEVEL_HIGH <= xfs_error_level)
 75			xfs_stack_trace();
 76	} else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
 77		if (logerror) {
 78			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_LOGERROR,
 79		"Log I/O Error Detected.  Shutting down filesystem");
 80		} else if (flags & SHUTDOWN_DEVICE_REQ) {
 81			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
 82		"All device paths lost.  Shutting down filesystem");
 83		} else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
 84			xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_IOERROR,
 85		"I/O Error Detected. Shutting down filesystem");
 86		}
 87	}
 88	if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
 89		xfs_alert(mp,
 90	"Please umount the filesystem and rectify the problem(s)");
 91	}
 92}
 93
 94/*
 95 * Prints out an ALERT message about I/O error.
 96 */
 97void
 98xfs_ioerror_alert(
 99	char			*func,
100	struct xfs_mount	*mp,
101	xfs_buf_t		*bp,
102	xfs_daddr_t		blkno)
103{
104	xfs_alert(mp,
105		 "I/O error occurred: meta-data dev %s block 0x%llx"
106		 "       (\"%s\") error %d buf count %zd",
107		xfs_buf_target_name(bp->b_target),
108		(__uint64_t)blkno, func,
109		bp->b_error, XFS_BUF_COUNT(bp));
110}
111
112/*
113 * This isn't an absolute requirement, but it is
114 * just a good idea to call xfs_read_buf instead of
115 * directly doing a read_buf call. For one, we shouldn't
116 * be doing this disk read if we are in SHUTDOWN state anyway,
117 * so this stops that from happening. Secondly, this does all
118 * the error checking stuff and the brelse if appropriate for
119 * the caller, so the code can be a little leaner.
120 */
121
122int
123xfs_read_buf(
124	struct xfs_mount *mp,
125	xfs_buftarg_t	 *target,
126	xfs_daddr_t	 blkno,
127	int              len,
128	uint             flags,
129	xfs_buf_t	 **bpp)
130{
131	xfs_buf_t	 *bp;
132	int		 error;
133
134	if (!flags)
135		flags = XBF_LOCK | XBF_MAPPED;
136
137	bp = xfs_buf_read(target, blkno, len, flags);
138	if (!bp)
139		return XFS_ERROR(EIO);
140	error = bp->b_error;
141	if (!error && !XFS_FORCED_SHUTDOWN(mp)) {
142		*bpp = bp;
143	} else {
144		*bpp = NULL;
145		if (error) {
146			xfs_ioerror_alert("xfs_read_buf", mp, bp, XFS_BUF_ADDR(bp));
147		} else {
148			error = XFS_ERROR(EIO);
149		}
150		if (bp) {
151			XFS_BUF_UNDONE(bp);
152			XFS_BUF_UNDELAYWRITE(bp);
153			XFS_BUF_STALE(bp);
154			/*
155			 * brelse clears B_ERROR and b_error
156			 */
157			xfs_buf_relse(bp);
158		}
159	}
160	return (error);
161}
162
163/*
164 * helper function to extract extent size hint from inode
165 */
166xfs_extlen_t
167xfs_get_extsz_hint(
168	struct xfs_inode	*ip)
169{
170	if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize)
171		return ip->i_d.di_extsize;
172	if (XFS_IS_REALTIME_INODE(ip))
173		return ip->i_mount->m_sb.sb_rextsize;
174	return 0;
175}