/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
#include "xfs_trans_priv.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
+#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
xfs_daddr_t bno,
uint imap_flags)
{
- xfs_imap_t imap;
xfs_buf_t *bp;
int error;
+ xfs_imap_t imap;
+#ifdef __KERNEL__
int i;
int ni;
+#endif
if (ip->i_blkno == (xfs_daddr_t)0) {
/*
*/
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
(int)imap.im_len, XFS_BUF_LOCK, &bp);
+
if (error) {
#ifdef DEBUG
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
#endif /* DEBUG */
return error;
}
-
+#ifdef __KERNEL__
/*
* Validate the magic number and version of every inode in the buffer
* (if DEBUG kernel) or the first inode in the buffer, otherwise.
- * No validation is done here in userspace (xfs_repair).
*/
-#if !defined(__KERNEL__)
- ni = 0;
-#elif defined(DEBUG)
- ni = BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog;
-#else /* usual case */
- ni = 1;
+#ifdef DEBUG
+ ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
+ (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
+#else
+ ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
#endif
-
for (i = 0; i < ni; i++) {
int di_ok;
xfs_dinode_t *dip;
(i << mp->m_sb.sb_inodelog));
di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
- if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
- XFS_ERRTAG_ITOBP_INOTOBP,
- XFS_RANDOM_ITOBP_INOTOBP))) {
- if (imap_flags & XFS_IMAP_BULKSTAT) {
- xfs_trans_brelse(tp, bp);
- return XFS_ERROR(EINVAL);
- }
+ if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
+ XFS_RANDOM_ITOBP_INOTOBP))) {
#ifdef DEBUG
- cmn_err(CE_ALERT,
- "Device %s - bad inode magic/vsn "
- "daddr %lld #%d (magic=%x)",
- XFS_BUFTARG_NAME(mp->m_ddev_targp),
+ prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
+ mp->m_ddev_targp,
(unsigned long long)imap.im_blkno, i,
INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
#endif
return XFS_ERROR(EFSCORRUPTED);
}
}
+#endif /* __KERNEL__ */
xfs_inobp_check(mp, bp);
STATIC uint
_xfs_dic2xflags(
+ xfs_dinode_core_t *dic,
__uint16_t di_flags)
{
uint flags = 0;
flags |= XFS_XFLAG_EXTSIZE;
if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
flags |= XFS_XFLAG_EXTSZINHERIT;
- if (di_flags & XFS_DIFLAG_NODEFRAG)
- flags |= XFS_XFLAG_NODEFRAG;
}
return flags;
{
xfs_dinode_core_t *dic = &ip->i_d;
- return _xfs_dic2xflags(dic->di_flags) |
- (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
+ return _xfs_dic2xflags(dic, dic->di_flags) |
+ (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
}
uint
xfs_dic2xflags(
xfs_dinode_core_t *dic)
{
- return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
- (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
+ return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) |
+ (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
}
/*
{
xfs_ino_t ino;
xfs_inode_t *ip;
- bhv_vnode_t *vp;
+ vnode_t *vp;
uint flags;
int error;
di_flags |= XFS_DIFLAG_NOSYMLINKS;
if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
di_flags |= XFS_DIFLAG_PROJINHERIT;
- if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
- xfs_inherit_nodefrag)
- di_flags |= XFS_DIFLAG_NODEFRAG;
ip->i_d.di_flags |= di_flags;
}
/* FALLTHROUGH */
*/
xfs_trans_log_inode(tp, ip, flags);
- /* now that we have an i_mode we can setup inode ops and unlock */
- bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
+ /* now that we have an i_mode we can set Linux inode ops (& unlock) */
+ VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
*ipp = ip;
return 0;
(xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
map_first),
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
- NULL, NULL))
+ NULL))
return;
ASSERT(nimaps == 1);
ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
xfs_fsize_t last_byte;
xfs_off_t toss_start;
xfs_mount_t *mp;
- bhv_vnode_t *vp;
+ vnode_t *vp;
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
vn_iowait(vp); /* wait for the completion of any pending DIOs */
/*
- * Call toss_pages or flushinval_pages to get rid of pages
+ * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers
* overlapping the region being removed. We have to use
- * the less efficient flushinval_pages in the case that the
+ * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the
* caller may not be able to finish the truncate without
* dropping the inode's I/O lock. Make sure
* to catch any pages brought in by buffers overlapping
* so that we don't toss things on the same block as
* new_size but before it.
*
- * Before calling toss_page or flushinval_pages, make sure to
+ * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to
* call remapf() over the same region if the file is mapped.
* This frees up mapped file references to the pages in the
- * given range and for the flushinval_pages case it ensures
+ * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures
* that we get the latest mapped changes flushed out.
*/
toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
last_byte);
if (last_byte > toss_start) {
if (flags & XFS_ITRUNC_DEFINITE) {
- bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
+ VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
} else {
- bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
+ VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
}
}
* runs.
*/
XFS_BMAP_INIT(&free_list, &first_block);
- error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
- first_unmap_block, unmap_len,
+ error = xfs_bunmapi(ntp, ip, first_unmap_block,
+ unmap_len,
XFS_BMAPI_AFLAG(fork) |
(sync ? 0 : XFS_BMAPI_ASYNC),
XFS_ITRUNC_MAX_EXTENTS,
- &first_block, &free_list,
- NULL, &done);
+ &first_block, &free_list, &done);
if (error) {
/*
* If the bunmapi call encounters an error,
xfs_agino_t agino;
xfs_agino_t next_agino;
xfs_buf_t *last_ibp;
- xfs_dinode_t *last_dip = NULL;
+ xfs_dinode_t *last_dip;
short bucket_index;
- int offset, last_offset = 0;
+ int offset, last_offset;
int error;
int agi_ok;
* the inode to become unpinned.
*/
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
- bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
+ vnode_t *vp = XFS_ITOV_NULL(ip);
/* make sync come back and flush this inode */
if (vp) {
struct inode *inode = vn_to_inode(vp);
- if (!(inode->i_state &
- (I_NEW|I_FREEING|I_CLEAR)))
+ if (!(inode->i_state & I_NEW))
mark_inode_dirty_sync(inode);
}
}
ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
}
+ if (whichfork == XFS_DATA_FORK) {
+ if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
+ XFS_ERROR_REPORT("xfs_iflush_fork",
+ XFS_ERRLEVEL_LOW, mp);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ }
break;
case XFS_DINODE_FMT_EXTENTS:
XFS_STATS_INC(xs_iflush_count);
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
- ASSERT(issemalocked(&(ip->i_flock)));
+ ASSERT(valusema(&ip->i_flock) <= 0);
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
corrupt_out:
xfs_buf_relse(bp);
- xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_iflush_abort(ip);
/*
* Unlocks the flush lock
xfs_buf_relse(bp);
}
- xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
if(!bufwasdelwri) {
/*
SPLDECL(s);
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
- ASSERT(issemalocked(&(ip->i_flock)));
+ ASSERT(valusema(&ip->i_flock) <= 0);
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
xfs_mount_t *mp)
{
xfs_inode_t *ip;
- bhv_vnode_t *vp;
+ vnode_t *vp;
again:
XFS_MOUNT_ILOCK(mp);
*/
memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
nextents * sizeof(xfs_bmbt_rec_t));
- kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
+ kmem_free(ifp->if_u1.if_extents, KM_SLEEP);
ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
ifp->if_real_bytes = 0;
}