Commit 6f20514e authored by Linus Torvalds's avatar Linus Torvalds

Merge http://xfs.org:8090/xfs-linux-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 9cc17134 1e747215
......@@ -57,13 +57,21 @@ typedef unsigned long xfs_pflags_t;
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
/* these could be nested, so we save state */
#define PFLAGS_SET_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
current->flags |= PF_FSTRANS; \
} while (0)
#define PFLAGS_RESTORE(STATEP) do { \
current->flags = *(STATEP); \
#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
current->flags &= ~PF_FSTRANS; \
} while (0)
/* Restore the PF_FSTRANS state to what was saved in STATEP */
#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
current->flags = ((current->flags & ~PF_FSTRANS) | \
(*(STATEP) & PF_FSTRANS)); \
} while (0)
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
......
......@@ -88,6 +88,7 @@ static inline void mrdemote(mrlock_t *mrp)
downgrade_write(&mrp->mr_lock);
}
#ifdef DEBUG
/*
* Debug-only routine, without some platform-specific asm code, we can
* now only answer requests regarding whether we hold the lock for write
......@@ -96,9 +97,10 @@ static inline void mrdemote(mrlock_t *mrp)
*/
static inline int ismrlocked(mrlock_t *mrp, int type)
{
if (type == MR_UPDATE)
if (mrp && type == MR_UPDATE)
return mrp->mr_writer;
return 1;
}
#endif
#endif /* __XFS_SUPPORT_MRLOCK_H__ */
......@@ -717,7 +717,8 @@ xfs_page_state_convert(
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
xfs_iomap_t *iomp, iomap;
unsigned long p_offset = 0, end_index;
loff_t offset, end_offset;
loff_t offset;
unsigned long long end_offset;
int len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAPI_TRYLOCK;
int page_dirty = 1;
......@@ -734,9 +735,8 @@ xfs_page_state_convert(
}
offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
end_offset = offset + PAGE_CACHE_SIZE;
if (end_offset > i_size_read(inode))
end_offset = i_size_read(inode);
end_offset = min_t(unsigned long long,
offset + PAGE_CACHE_SIZE, i_size_read(inode));
bh = head = page_buffers(page);
iomp = NULL;
......
......@@ -68,16 +68,15 @@ __linvfs_read(
{
struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp;
vnode_t *vp;
int error;
vnode_t *vp = LINVFS_GET_VP(file->f_dentry->d_inode);
ssize_t rval;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
vp = LINVFS_GET_VP(file->f_dentry->d_inode);
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, error);
return error;
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
}
......@@ -114,20 +113,21 @@ __linvfs_write(
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
ssize_t rval;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error);
ioflags, NULL, rval);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error);
ioflags, NULL, rval);
up(&inode->i_sem);
}
return error;
return rval;
}
......@@ -163,19 +163,19 @@ __linvfs_readv(
struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
struct kiocb kiocb;
int error;
ssize_t rval;
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, error);
if (-EIOCBQUEUED == error)
error = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
if (rval == -EIOCBQUEUED)
rval = wait_on_sync_kiocb(&kiocb);
return error;
*ppos = kiocb.ki_pos;
return rval;
}
STATIC ssize_t
......@@ -210,25 +210,26 @@ __linvfs_writev(
struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode);
struct kiocb kiocb;
int error;
ssize_t rval;
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error);
ioflags, NULL, rval);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error);
ioflags, NULL, rval);
up(&inode->i_sem);
}
if (-EIOCBQUEUED == error)
error = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return error;
if (rval == -EIOCBQUEUED)
rval = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return rval;
}
......
......@@ -850,6 +850,9 @@ xfs_ioctl(
case XFS_IOC_ERROR_INJECTION: {
xfs_error_injection_t in;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (copy_from_user(&in, (char *)arg, sizeof(in)))
return -XFS_ERROR(EFAULT);
......@@ -858,6 +861,9 @@ xfs_ioctl(
}
case XFS_IOC_ERROR_CLEARALL:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
error = xfs_errortag_clearall(mp);
return -error;
......@@ -882,7 +888,7 @@ xfs_ioc_space(
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
return -XFS_ERROR(EPERM);
if (filp->f_flags & O_RDONLY)
if (!(filp->f_flags & FMODE_WRITE))
return -XFS_ERROR(EBADF);
if (vp->v_type != VREG)
......
......@@ -536,6 +536,10 @@ linvfs_setattr(
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
flags = ATTR_UTIME;
#ifdef ATTR_NO_BLOCK
if ((ia_valid & ATTR_NO_BLOCK))
flags |= ATTR_NONBLOCK;
#endif
VOP_SETATTR(vp, &vattr, flags, NULL, error);
if (error)
......
......@@ -575,8 +575,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
for ( ; i < nsbuf; i++, sbp++) {
attrnames_t *namesp;
namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure :
((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user);
if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) {
......@@ -587,8 +587,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
ASSERT(context->flags & ATTR_KERNAMELS);
context->count += namesp->attr_namelen +
sbp->namelen + 1;
}
else {
} else {
if (xfs_attr_put_listent(context, namesp,
sbp->name, sbp->namelen,
INT_GET(sbp->valuelen, ARCH_CONVERT)))
......
......@@ -119,6 +119,11 @@ xfs_swapext(
tip = XFS_BHVTOI(tbdp);
}
if (ip->i_mount != tip->i_mount) {
error = XFS_ERROR(EINVAL);
goto error0;
}
if (ip->i_ino == tip->i_ino) {
error = XFS_ERROR(EINVAL);
goto error0;
......@@ -147,20 +152,17 @@ xfs_swapext(
xfs_lock_inodes(ips, 2, 0, lock_flags);
/* Check permissions */
if ((error = _MAC_XFS_IACCESS(ip, MACWRITE, NULL))) {
goto error0;
}
if ((error = _MAC_XFS_IACCESS(tip, MACWRITE, NULL))) {
error = xfs_iaccess(ip, S_IWUSR, NULL);
if (error)
goto error0;
}
if ((current_fsuid(cred) != ip->i_d.di_uid) &&
(error = xfs_iaccess(ip, S_IWUSR, NULL)) &&
!capable_cred(NULL, CAP_FOWNER)) {
error = xfs_iaccess(tip, S_IWUSR, NULL);
if (error)
goto error0;
}
if ((current_fsuid(cred) != tip->i_d.di_uid) &&
(error = xfs_iaccess(tip, S_IWUSR, NULL)) &&
!capable_cred(NULL, CAP_FOWNER)) {
/* Verify that both files have the same format */
if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
error = XFS_ERROR(EINVAL);
goto error0;
}
......
......@@ -3707,14 +3707,13 @@ xfs_iaccess(
* Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set.
*/
if (!(orgmode & S_IXUSR) || (inode->i_mode & S_IXUGO) ||
(ip->i_d.di_mode & S_IFMT) == S_IFDIR)
if (!(orgmode & S_IXUSR) ||
(inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable_cred(cr, CAP_DAC_OVERRIDE))
return 0;
if ((orgmode == S_IRUSR) ||
(((ip->i_d.di_mode & S_IFMT) == S_IFDIR) &&
(!(orgmode & ~(S_IWUSR|S_IXUSR))))) {
(S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) {
if (capable_cred(cr, CAP_DAC_READ_SEARCH))
return 0;
#ifdef NOISE
......
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......@@ -941,6 +941,7 @@ void
xlog_iodone(xfs_buf_t *bp)
{
xlog_in_core_t *iclog;
xlog_t *l;
int aborted;
iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
......@@ -949,18 +950,19 @@ xlog_iodone(xfs_buf_t *bp)
aborted = 0;
/*
* Race to shutdown the filesystem if we see an error.
*/
if (XFS_BUF_GETERROR(bp)) {
/* Some versions of cpp barf on the recursive definition of
* Some versions of cpp barf on the recursive definition of
* ic_log -> hic_fields.ic_log and expand ic_log twice when
* it is passed through two macros. Workaround for broken cpp
* it is passed through two macros. Workaround broken cpp.
*/
struct log *l;
xfs_ioerror_alert("xlog_iodone",
iclog->ic_log->l_mp, bp, XFS_BUF_ADDR(bp));
XFS_BUF_STALE(bp);
l = iclog->ic_log;
/*
* Race to shutdown the filesystem if we see an error.
*/
if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
XFS_BUF_STALE(bp);
xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
/*
* This flag will be propagated to the trans-committed
......@@ -3158,6 +3160,7 @@ xlog_ticket_get(xlog_t *log,
uint xflags)
{
xlog_ticket_t *tic;
uint num_headers;
SPLDECL(s);
alloc:
......@@ -3181,21 +3184,30 @@ xlog_ticket_get(xlog_t *log,
* in the log. A unit in this case is the amount of space for one
* of these log operations. Normal reservations have a cnt of 1
* and their unit amount is the total amount of space required.
* The following line of code adds one log record header length
* for each part of an operation which may fall on a different
* log record.
*
* One more XLOG_HEADER_SIZE is added to account for possible
* round off errors when syncing a LR to disk. The bytes are
* subtracted if the thread using this ticket is the first writer
* to a new LR.
*
* We add an extra log header for the possibility that the commit
* record is the first data written to a new log record. In this
* case it is separate from the rest of the transaction data and
* will be charged for the log record header.
* The following lines of code account for non-transaction data
* which occupy space in the on-disk log.
*/
unit_bytes += log->l_iclog_hsize * (XLOG_BTOLRBB(unit_bytes) + 2);
/* for start-rec */
unit_bytes += sizeof(xlog_op_header_t);
/* for padding */
if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
log->l_mp->m_sb.sb_logsunit > 1) {
/* log su roundoff */
unit_bytes += log->l_mp->m_sb.sb_logsunit;
} else {
/* BB roundoff */
unit_bytes += BBSIZE;
}
/* for commit-rec */
unit_bytes += sizeof(xlog_op_header_t);
/* for LR headers */
num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
unit_bytes += log->l_iclog_hsize * num_headers;
tic->t_unit_res = unit_bytes;
tic->t_curr_res = unit_bytes;
......
......@@ -57,12 +57,6 @@ struct xfs_mount;
#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XLOG_BTOLRBB)
int xlog_btolrbb(int b);
#define XLOG_BTOLRBB(b) xlog_btolrbb(b)
#else
#define XLOG_BTOLRBB(b) (((b)+XLOG_RECORD_BSIZE-1) >> XLOG_RECORD_BSHIFT)
#endif
#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
(log)->l_mp->m_sb.sb_logsunit)
#define XLOG_LSUNITTOB(log, su) ((su) * (log)->l_mp->m_sb.sb_logsunit)
......@@ -560,6 +554,7 @@ extern void xlog_put_bp(struct xfs_buf *);
extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
/* iclog tracing */
#define XLOG_TRACE_GRAB_FLUSH 1
#define XLOG_TRACE_REL_FLUSH 2
#define XLOG_TRACE_SLEEP_FLUSH 3
......
......@@ -2219,14 +2219,6 @@ xfs_sb_version_toold(unsigned v)
}
#endif
#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XLOG_BTOLRBB)
int
xlog_btolrbb(int b)
{
return XLOG_BTOLRBB(b);
}
#endif
#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XLOG_GRANT_ADD_SPACE)
void
xlog_grant_add_space(xlog_t *log, int bytes, int type)
......@@ -2242,3 +2234,12 @@ xlog_grant_sub_space(xlog_t *log, int bytes, int type)
XLOG_GRANT_SUB_SPACE(log, bytes, type);
}
#endif
#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASMOREBITS)
int
xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
{
return XFS_SB_VERSION_HASMOREBITS(sbp);
}
#endif
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......@@ -117,6 +117,7 @@ static struct {
{ offsetof(xfs_sb_t, sb_logsectlog), 0 },
{ offsetof(xfs_sb_t, sb_logsectsize),0 },
{ offsetof(xfs_sb_t, sb_logsunit), 0 },
{ offsetof(xfs_sb_t, sb_features2), 0 },
{ sizeof(xfs_sb_t), 0 }
};
......
......@@ -60,6 +60,7 @@ struct xfs_mount;
#define XFS_SB_VERSION_SECTORBIT 0x0800
#define XFS_SB_VERSION_EXTFLGBIT 0x1000
#define XFS_SB_VERSION_DIRV2BIT 0x2000
#define XFS_SB_VERSION_MOREBITSBIT 0x8000
#define XFS_SB_VERSION_OKSASHFBITS \
(XFS_SB_VERSION_EXTFLGBIT | \
XFS_SB_VERSION_DIRV2BIT)
......@@ -80,17 +81,46 @@ struct xfs_mount;
(XFS_SB_VERSION_NUMBITS | \
XFS_SB_VERSION_OKREALFBITS | \
XFS_SB_VERSION_OKSASHFBITS)
#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag) \
(((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag)) ? \
#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag,morebits) \
(((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag) || \
(morebits)) ? \
(XFS_SB_VERSION_4 | \
((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \
((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \
((extflag) ? XFS_SB_VERSION_EXTFLGBIT : 0) | \
((dirv2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \
((na) ? XFS_SB_VERSION_LOGV2BIT : 0) | \
((sflag) ? XFS_SB_VERSION_SECTORBIT : 0)) : \
((sflag) ? XFS_SB_VERSION_SECTORBIT : 0) | \
((morebits) ? XFS_SB_VERSION_MOREBITSBIT : 0)) : \
XFS_SB_VERSION_1)
/*
* There are two words to hold XFS "feature" bits: the original
* word, sb_versionnum, and sb_features2. Whenever a bit is set in
* sb_features2, the feature bit XFS_SB_VERSION_MOREBITSBIT must be set.
*
* These defines represent bits in sb_features2.
*/
#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */
#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001
#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
require changing
PROM and SASH */
#define XFS_SB_VERSION2_OKREALFBITS \
(0)
#define XFS_SB_VERSION2_OKSASHFBITS \
(0)
#define XFS_SB_VERSION2_OKREALBITS \
(XFS_SB_VERSION2_OKREALFBITS | \
XFS_SB_VERSION2_OKSASHFBITS )
/*
* mkfs macro to set up sb_features2 word
*/
#define XFS_SB_VERSION2_MKFS(xyz) \
((xyz) ? 0 : 0)
typedef struct xfs_sb
{
__uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
......@@ -146,6 +176,7 @@ typedef struct xfs_sb
__uint8_t sb_logsectlog; /* log2 of the log sector size */
__uint16_t sb_logsectsize; /* sector size for the log, bytes */
__uint32_t sb_logsunit; /* stripe unit size for the log */
__uint32_t sb_features2; /* additonal feature bits */
} xfs_sb_t;
/*
......@@ -164,6 +195,7 @@ typedef enum {
XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
XFS_SBS_FEATURES2,
XFS_SBS_FIELDCOUNT
} xfs_sb_field_t;
......@@ -218,7 +250,10 @@ int xfs_sb_good_version(xfs_sb_t *sbp);
((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
!((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS)
!(((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) && \
((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) && \
((sbp)->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS))
#ifdef __KERNEL__
#define XFS_SB_GOOD_VERSION(sbp) \
(XFS_SB_GOOD_VERSION_INT(sbp) && \
......@@ -453,6 +488,25 @@ int xfs_sb_version_hassector(xfs_sb_t *sbp);
((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT))
#endif
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASMOREBITSBIT)
int xfs_sb_version_hasmorebits(xfs_sb_t *sbp);
#define XFS_SB_VERSION_HASMOREBITS(sbp) xfs_sb_version_hasmorebits(sbp)
#else
#define XFS_SB_VERSION_HASMOREBITS(sbp) \
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
((sbp)->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT))
#endif
/*
* sb_features2 bit version macros.
*
* For example, for a bit defined as XFS_SB_VERSION2_YBIT, has a macro:
*
* SB_VERSION_HASYBIT(xfs_sb_t *sbp)
* ((XFS_SB_VERSION_HASMOREBITS(sbp) &&
* ((sbp)->sb_versionnum & XFS_SB_VERSION2_YBIT)
*/
/*
* end of superblock version macros
*/
......
......@@ -250,7 +250,7 @@ xfs_trans_reserve(
error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
-blocks, rsvd);
if (error != 0) {
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
return (XFS_ERROR(ENOSPC));
}
tp->t_blk_res += blocks;
......@@ -323,7 +323,7 @@ xfs_trans_reserve(
tp->t_blk_res = 0;
}
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
return (error);
}
......@@ -734,7 +734,7 @@ xfs_trans_commit(
if (commit_lsn == -1 && !shutdown)
shutdown = XFS_ERROR(EIO);
}
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
xfs_trans_free_busy(tp);
xfs_trans_free(tp);
......@@ -823,7 +823,7 @@ xfs_trans_commit(
* had pinned, clean up, free trans structure, and return error.
*/
if (error || commit_lsn == -1) {
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
return XFS_ERROR(EIO);
}
......@@ -862,7 +862,7 @@ xfs_trans_commit(
error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
/* mark this thread as no longer being in a transaction */
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
/*
* Once all the items of the transaction have been copied
......@@ -1100,7 +1100,7 @@ xfs_trans_cancel(
}
/* mark this thread as no longer being in a transaction */
PFLAGS_RESTORE(&tp->t_pflags);
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp);
......
......@@ -535,6 +535,8 @@ typedef struct xfs_trans {
* the super block to reflect the freed blocks: sector size
* worst case split in allocation btrees per extent assuming 4 extents:
* 4 exts * 2 trees * (2 * max depth - 1) * block size
* the inode btree: max depth * blocksize
* the allocation btrees: 2 trees * (max depth - 1) * block size
*/
#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \
(MAX( \
......@@ -545,7 +547,11 @@ typedef struct xfs_trans {
(4 * (mp)->m_sb.sb_sectsize) + \
(mp)->m_sb.sb_sectsize + \
XFS_ALLOCFREE_LOG_RES(mp, 4) + \
(128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))))))
(128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
(128 * 5) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
(128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
......@@ -713,6 +719,7 @@ typedef struct xfs_trans {
XFS_FSB_TO_B((mp), 1) + \
MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
(128 * 5) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
(128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
......
/*
* XFS filesystem operations.
*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......@@ -229,7 +229,10 @@ xfs_start_flags(
mp->m_swidth = ap->swidth;
}
if (ap->logbufs != 0 && ap->logbufs != -1 &&
if (ap->logbufs != -1 &&
#if defined(DEBUG) || defined(XLOG_NOLOG)
ap->logbufs != 0 &&
#endif
(ap->logbufs < XLOG_MIN_ICLOGS ||
ap->logbufs > XLOG_MAX_ICLOGS)) {
cmn_err(CE_WARN,
......@@ -1484,8 +1487,10 @@ xfs_syncsub(
*/
if (XFS_BUF_ISPINNED(bp))
xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
if (!(flags & SYNC_WAIT))
XFS_BUF_BFLAGS(bp) |= XFS_B_ASYNC;
if (flags & SYNC_WAIT)
XFS_BUF_UNASYNC(bp);
else
XFS_BUF_ASYNC(bp);
error = xfs_bwrite(mp, bp);
}
if (error) {
......
......@@ -1106,14 +1106,11 @@ xfs_fsync(
xfs_off_t stop)
{
xfs_inode_t *ip;
int error;
int error2;
int syncall;
vnode_t *vp;
xfs_trans_t *tp;
int error;
vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
vn_trace_entry(BHV_TO_VNODE(bdp),
__FUNCTION__, (inst_t *)__return_address);
ip = XFS_BHVTOI(bdp);
......@@ -1122,44 +1119,6 @@ xfs_fsync(
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return XFS_ERROR(EIO);
xfs_ilock(ip, XFS_IOLOCK_EXCL);
syncall = error = error2 = 0;
if (stop == -1) {
ASSERT(start >= 0);
if (start == 0)
syncall = 1;
stop = xfs_file_last_byte(ip);
}
/*
* If we're invalidating, always flush since we want to
* tear things down. Otherwise, don't flush anything if
* we're not dirty.
*/
if (flag & FSYNC_INVAL) {
if (ip->i_df.if_flags & XFS_IFEXTENTS &&
ip->i_df.if_bytes > 0) {
VOP_FLUSHINVAL_PAGES(vp, start, -1, FI_REMAPF_LOCKED);
}
ASSERT(syncall == 0 || (VN_CACHED(vp) == 0));
} else {
/*
* In the non-invalidating case, calls to fsync() do not
* flush all the dirty mmap'd pages. That requires a
* call to msync().
*/
VOP_FLUSH_PAGES(vp, start, -1,
(flag & FSYNC_WAIT) ? 0 : XFS_B_ASYNC,
FI_NONE, error2);
}
if (error2) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return XFS_ERROR(error2);
}
/*
* We always need to make sure that the required inode state
* is safe on disk. The vnode might be clean but because
......@@ -1199,7 +1158,7 @@ xfs_fsync(
* be pinned. If it is, force the log.
*/
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (xfs_ipincount(ip)) {
xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
......@@ -1222,7 +1181,6 @@ xfs_fsync(
XFS_FSYNC_TS_LOG_RES(ip->i_mount),
0, 0, 0))) {
xfs_trans_cancel(tp, 0);
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
......@@ -1237,68 +1195,18 @@ xfs_fsync(
* inode in another recent transaction. So we
* play it safe and fire off the transaction anyway.
*/
xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
if (flag & FSYNC_WAIT)
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
return error;
}
#if 0
/*
* This is a utility routine for xfs_inactive. It is called when a
* transaction attempting to free up the disk space for a file encounters
* an error. It cancels the old transaction and starts up a new one
* to be used to free up the inode. It also sets the inode size and extent
* counts to 0 and frees up any memory being used to store inline data,
* extents, or btree roots.
*/
STATIC void
xfs_itruncate_cleanup(
xfs_trans_t **tpp,
xfs_inode_t *ip,
int commit_flags,
int fork)
{
xfs_mount_t *mp;
/* REFERENCED */
int error;
mp = ip->i_mount;
if (*tpp) {
xfs_trans_cancel(*tpp, commit_flags | XFS_TRANS_ABORT);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
*tpp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
error = xfs_trans_reserve(*tpp, 0, XFS_IFREE_LOG_RES(mp), 0, 0,
XFS_DEFAULT_LOG_COUNT);
if (error) {
return;
}
xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ijoin(*tpp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
xfs_trans_ihold(*tpp, ip);
xfs_idestroy_fork(ip, fork);
if (fork == XFS_DATA_FORK) {
ip->i_d.di_nblocks = 0;
ip->i_d.di_nextents = 0;
ip->i_d.di_size = 0;
} else {
ip->i_d.di_anextents = 0;
}
xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
}
#endif
/*
* This is called by xfs_inactive to free any blocks beyond eof,
* when the link count isn't zero.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment