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
...@@ -55,15 +55,23 @@ ...@@ -55,15 +55,23 @@
typedef unsigned long xfs_pflags_t; typedef unsigned long xfs_pflags_t;
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS) #define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
/* these could be nested, so we save state */
#define PFLAGS_SET_FSTRANS(STATEP) do { \ #define PFLAGS_SET_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \ *(STATEP) = current->flags; \
current->flags |= PF_FSTRANS; \ current->flags |= PF_FSTRANS; \
} while (0) } while (0)
#define PFLAGS_RESTORE(STATEP) do { \ #define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
current->flags = *(STATEP); \ *(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) } while (0)
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \ #define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
......
...@@ -88,6 +88,7 @@ static inline void mrdemote(mrlock_t *mrp) ...@@ -88,6 +88,7 @@ static inline void mrdemote(mrlock_t *mrp)
downgrade_write(&mrp->mr_lock); downgrade_write(&mrp->mr_lock);
} }
#ifdef DEBUG
/* /*
* Debug-only routine, without some platform-specific asm code, we can * Debug-only routine, without some platform-specific asm code, we can
* now only answer requests regarding whether we hold the lock for write * now only answer requests regarding whether we hold the lock for write
...@@ -96,9 +97,10 @@ static inline void mrdemote(mrlock_t *mrp) ...@@ -96,9 +97,10 @@ static inline void mrdemote(mrlock_t *mrp)
*/ */
static inline int ismrlocked(mrlock_t *mrp, int type) static inline int ismrlocked(mrlock_t *mrp, int type)
{ {
if (type == MR_UPDATE) if (mrp && type == MR_UPDATE)
return mrp->mr_writer; return mrp->mr_writer;
return 1; return 1;
} }
#endif
#endif /* __XFS_SUPPORT_MRLOCK_H__ */ #endif /* __XFS_SUPPORT_MRLOCK_H__ */
...@@ -717,7 +717,8 @@ xfs_page_state_convert( ...@@ -717,7 +717,8 @@ xfs_page_state_convert(
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
xfs_iomap_t *iomp, iomap; xfs_iomap_t *iomp, iomap;
unsigned long p_offset = 0, end_index; 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 len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAPI_TRYLOCK; int flags = startio ? 0 : BMAPI_TRYLOCK;
int page_dirty = 1; int page_dirty = 1;
...@@ -734,9 +735,8 @@ xfs_page_state_convert( ...@@ -734,9 +735,8 @@ xfs_page_state_convert(
} }
offset = (loff_t)page->index << PAGE_CACHE_SHIFT; offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
end_offset = offset + PAGE_CACHE_SIZE; end_offset = min_t(unsigned long long,
if (end_offset > i_size_read(inode)) offset + PAGE_CACHE_SIZE, i_size_read(inode));
end_offset = i_size_read(inode);
bh = head = page_buffers(page); bh = head = page_buffers(page);
iomp = NULL; iomp = NULL;
......
...@@ -68,16 +68,15 @@ __linvfs_read( ...@@ -68,16 +68,15 @@ __linvfs_read(
{ {
struct iovec iov = {buf, count}; struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
vnode_t *vp; vnode_t *vp = LINVFS_GET_VP(file->f_dentry->d_inode);
int error; ssize_t rval;
BUG_ON(iocb->ki_pos != pos); BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT)) if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT; ioflags |= IO_ISDIRECT;
vp = LINVFS_GET_VP(file->f_dentry->d_inode); VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, error); return rval;
return error;
} }
...@@ -114,20 +113,21 @@ __linvfs_write( ...@@ -114,20 +113,21 @@ __linvfs_write(
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode); vnode_t *vp = LINVFS_GET_VP(inode);
int error; ssize_t rval;
BUG_ON(iocb->ki_pos != pos); BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT)) { if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT; ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error); ioflags, NULL, rval);
} else { } else {
down(&inode->i_sem); down(&inode->i_sem);
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, error); ioflags, NULL, rval);
up(&inode->i_sem); up(&inode->i_sem);
} }
return error;
return rval;
} }
...@@ -163,19 +163,19 @@ __linvfs_readv( ...@@ -163,19 +163,19 @@ __linvfs_readv(
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode); vnode_t *vp = LINVFS_GET_VP(inode);
struct kiocb kiocb; struct kiocb kiocb;
int error; ssize_t rval;
init_sync_kiocb(&kiocb, file); init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos; kiocb.ki_pos = *ppos;
if (unlikely(file->f_flags & O_DIRECT)) if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT; ioflags |= IO_ISDIRECT;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, error); VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
if (-EIOCBQUEUED == error) if (rval == -EIOCBQUEUED)
error = wait_on_sync_kiocb(&kiocb); rval = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return error; *ppos = kiocb.ki_pos;
return rval;
} }
STATIC ssize_t STATIC ssize_t
...@@ -210,25 +210,26 @@ __linvfs_writev( ...@@ -210,25 +210,26 @@ __linvfs_writev(
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
vnode_t *vp = LINVFS_GET_VP(inode); vnode_t *vp = LINVFS_GET_VP(inode);
struct kiocb kiocb; struct kiocb kiocb;
int error; ssize_t rval;
init_sync_kiocb(&kiocb, file); init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos; kiocb.ki_pos = *ppos;
if (unlikely(file->f_flags & O_DIRECT)) { if (unlikely(file->f_flags & O_DIRECT)) {
ioflags |= IO_ISDIRECT; ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error); ioflags, NULL, rval);
} else { } else {
down(&inode->i_sem); down(&inode->i_sem);
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, error); ioflags, NULL, rval);
up(&inode->i_sem); 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( ...@@ -850,6 +850,9 @@ xfs_ioctl(
case XFS_IOC_ERROR_INJECTION: { case XFS_IOC_ERROR_INJECTION: {
xfs_error_injection_t in; xfs_error_injection_t in;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (copy_from_user(&in, (char *)arg, sizeof(in))) if (copy_from_user(&in, (char *)arg, sizeof(in)))
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
...@@ -858,6 +861,9 @@ xfs_ioctl( ...@@ -858,6 +861,9 @@ xfs_ioctl(
} }
case XFS_IOC_ERROR_CLEARALL: case XFS_IOC_ERROR_CLEARALL:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
error = xfs_errortag_clearall(mp); error = xfs_errortag_clearall(mp);
return -error; return -error;
...@@ -882,7 +888,7 @@ xfs_ioc_space( ...@@ -882,7 +888,7 @@ xfs_ioc_space(
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
return -XFS_ERROR(EPERM); return -XFS_ERROR(EPERM);
if (filp->f_flags & O_RDONLY) if (!(filp->f_flags & FMODE_WRITE))
return -XFS_ERROR(EBADF); return -XFS_ERROR(EBADF);
if (vp->v_type != VREG) if (vp->v_type != VREG)
......
...@@ -536,6 +536,10 @@ linvfs_setattr( ...@@ -536,6 +536,10 @@ linvfs_setattr(
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET))
flags = ATTR_UTIME; flags = ATTR_UTIME;
#ifdef ATTR_NO_BLOCK
if ((ia_valid & ATTR_NO_BLOCK))
flags |= ATTR_NONBLOCK;
#endif
VOP_SETATTR(vp, &vattr, flags, NULL, error); VOP_SETATTR(vp, &vattr, flags, NULL, error);
if (error) if (error)
......
...@@ -575,8 +575,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -575,8 +575,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
for ( ; i < nsbuf; i++, sbp++) { for ( ; i < nsbuf; i++, sbp++) {
attrnames_t *namesp; attrnames_t *namesp;
namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure : namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user); &attr_user);
if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) { if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) {
...@@ -587,8 +587,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) ...@@ -587,8 +587,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
ASSERT(context->flags & ATTR_KERNAMELS); ASSERT(context->flags & ATTR_KERNAMELS);
context->count += namesp->attr_namelen + context->count += namesp->attr_namelen +
sbp->namelen + 1; sbp->namelen + 1;
} } else {
else {
if (xfs_attr_put_listent(context, namesp, if (xfs_attr_put_listent(context, namesp,
sbp->name, sbp->namelen, sbp->name, sbp->namelen,
INT_GET(sbp->valuelen, ARCH_CONVERT))) INT_GET(sbp->valuelen, ARCH_CONVERT)))
......
...@@ -119,6 +119,11 @@ xfs_swapext( ...@@ -119,6 +119,11 @@ xfs_swapext(
tip = XFS_BHVTOI(tbdp); tip = XFS_BHVTOI(tbdp);
} }
if (ip->i_mount != tip->i_mount) {
error = XFS_ERROR(EINVAL);
goto error0;
}
if (ip->i_ino == tip->i_ino) { if (ip->i_ino == tip->i_ino) {
error = XFS_ERROR(EINVAL); error = XFS_ERROR(EINVAL);
goto error0; goto error0;
...@@ -147,20 +152,17 @@ xfs_swapext( ...@@ -147,20 +152,17 @@ xfs_swapext(
xfs_lock_inodes(ips, 2, 0, lock_flags); xfs_lock_inodes(ips, 2, 0, lock_flags);
/* Check permissions */ /* Check permissions */
if ((error = _MAC_XFS_IACCESS(ip, MACWRITE, NULL))) { error = xfs_iaccess(ip, S_IWUSR, NULL);
goto error0; if (error)
}
if ((error = _MAC_XFS_IACCESS(tip, MACWRITE, NULL))) {
goto error0; goto error0;
}
if ((current_fsuid(cred) != ip->i_d.di_uid) && error = xfs_iaccess(tip, S_IWUSR, NULL);
(error = xfs_iaccess(ip, S_IWUSR, NULL)) && if (error)
!capable_cred(NULL, CAP_FOWNER)) {
goto error0; goto error0;
}
if ((current_fsuid(cred) != tip->i_d.di_uid) && /* Verify that both files have the same format */
(error = xfs_iaccess(tip, S_IWUSR, NULL)) && if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
!capable_cred(NULL, CAP_FOWNER)) { error = XFS_ERROR(EINVAL);
goto error0; goto error0;
} }
......
...@@ -3707,14 +3707,13 @@ xfs_iaccess( ...@@ -3707,14 +3707,13 @@ xfs_iaccess(
* Read/write DACs are always overridable. * Read/write DACs are always overridable.
* Executable DACs are overridable if at least one exec bit is set. * Executable DACs are overridable if at least one exec bit is set.
*/ */
if (!(orgmode & S_IXUSR) || (inode->i_mode & S_IXUGO) || if (!(orgmode & S_IXUSR) ||
(ip->i_d.di_mode & S_IFMT) == S_IFDIR) (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
if (capable_cred(cr, CAP_DAC_OVERRIDE)) if (capable_cred(cr, CAP_DAC_OVERRIDE))
return 0; return 0;
if ((orgmode == S_IRUSR) || if ((orgmode == S_IRUSR) ||
(((ip->i_d.di_mode & S_IFMT) == S_IFDIR) && (S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) {
(!(orgmode & ~(S_IWUSR|S_IXUSR))))) {
if (capable_cred(cr, CAP_DAC_READ_SEARCH)) if (capable_cred(cr, CAP_DAC_READ_SEARCH))
return 0; return 0;
#ifdef NOISE #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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -940,7 +940,8 @@ xlog_space_left(xlog_t *log, int cycle, int bytes) ...@@ -940,7 +940,8 @@ xlog_space_left(xlog_t *log, int cycle, int bytes)
void void
xlog_iodone(xfs_buf_t *bp) xlog_iodone(xfs_buf_t *bp)
{ {
xlog_in_core_t *iclog; xlog_in_core_t *iclog;
xlog_t *l;
int aborted; int aborted;
iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *); iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
...@@ -948,19 +949,20 @@ xlog_iodone(xfs_buf_t *bp) ...@@ -948,19 +949,20 @@ xlog_iodone(xfs_buf_t *bp)
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
aborted = 0; aborted = 0;
/*
* 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 broken cpp.
*/
l = iclog->ic_log;
/* /*
* Race to shutdown the filesystem if we see an error. * Race to shutdown the filesystem if we see an error.
*/ */
if (XFS_BUF_GETERROR(bp)) { if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
/* Some versions of cpp barf on the recursive definition of XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
* ic_log -> hic_fields.ic_log and expand ic_log twice when xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
* it is passed through two macros. Workaround for broken cpp
*/
struct log *l;
xfs_ioerror_alert("xlog_iodone",
iclog->ic_log->l_mp, bp, XFS_BUF_ADDR(bp));
XFS_BUF_STALE(bp); XFS_BUF_STALE(bp);
l = iclog->ic_log;
xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR); xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
/* /*
* This flag will be propagated to the trans-committed * This flag will be propagated to the trans-committed
...@@ -3158,6 +3160,7 @@ xlog_ticket_get(xlog_t *log, ...@@ -3158,6 +3160,7 @@ xlog_ticket_get(xlog_t *log,
uint xflags) uint xflags)
{ {
xlog_ticket_t *tic; xlog_ticket_t *tic;
uint num_headers;
SPLDECL(s); SPLDECL(s);
alloc: alloc:
...@@ -3181,21 +3184,30 @@ xlog_ticket_get(xlog_t *log, ...@@ -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 * 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 * of these log operations. Normal reservations have a cnt of 1
* and their unit amount is the total amount of space required. * 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 * The following lines of code account for non-transaction data
* round off errors when syncing a LR to disk. The bytes are * which occupy space in the on-disk log.
* 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.
*/ */
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_unit_res = unit_bytes;
tic->t_curr_res = unit_bytes; tic->t_curr_res = unit_bytes;
......
...@@ -57,12 +57,6 @@ struct xfs_mount; ...@@ -57,12 +57,6 @@ struct xfs_mount;
#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ #define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ #define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ #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) / \ #define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
(log)->l_mp->m_sb.sb_logsunit) (log)->l_mp->m_sb.sb_logsunit)
#define XLOG_LSUNITTOB(log, su) ((su) * (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 *); ...@@ -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 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 *); 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_GRAB_FLUSH 1
#define XLOG_TRACE_REL_FLUSH 2 #define XLOG_TRACE_REL_FLUSH 2
#define XLOG_TRACE_SLEEP_FLUSH 3 #define XLOG_TRACE_SLEEP_FLUSH 3
......
...@@ -2219,14 +2219,6 @@ xfs_sb_version_toold(unsigned v) ...@@ -2219,14 +2219,6 @@ xfs_sb_version_toold(unsigned v)
} }
#endif #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) #if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XLOG_GRANT_ADD_SPACE)
void void
xlog_grant_add_space(xlog_t *log, int bytes, int type) 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) ...@@ -2242,3 +2234,12 @@ xlog_grant_sub_space(xlog_t *log, int bytes, int type)
XLOG_GRANT_SUB_SPACE(log, bytes, type); XLOG_GRANT_SUB_SPACE(log, bytes, type);
} }
#endif #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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -117,6 +117,7 @@ static struct { ...@@ -117,6 +117,7 @@ static struct {
{ offsetof(xfs_sb_t, sb_logsectlog), 0 }, { offsetof(xfs_sb_t, sb_logsectlog), 0 },
{ offsetof(xfs_sb_t, sb_logsectsize),0 }, { offsetof(xfs_sb_t, sb_logsectsize),0 },
{ offsetof(xfs_sb_t, sb_logsunit), 0 }, { offsetof(xfs_sb_t, sb_logsunit), 0 },
{ offsetof(xfs_sb_t, sb_features2), 0 },
{ sizeof(xfs_sb_t), 0 } { sizeof(xfs_sb_t), 0 }
}; };
......
...@@ -60,6 +60,7 @@ struct xfs_mount; ...@@ -60,6 +60,7 @@ struct xfs_mount;
#define XFS_SB_VERSION_SECTORBIT 0x0800 #define XFS_SB_VERSION_SECTORBIT 0x0800
#define XFS_SB_VERSION_EXTFLGBIT 0x1000 #define XFS_SB_VERSION_EXTFLGBIT 0x1000
#define XFS_SB_VERSION_DIRV2BIT 0x2000 #define XFS_SB_VERSION_DIRV2BIT 0x2000
#define XFS_SB_VERSION_MOREBITSBIT 0x8000
#define XFS_SB_VERSION_OKSASHFBITS \ #define XFS_SB_VERSION_OKSASHFBITS \
(XFS_SB_VERSION_EXTFLGBIT | \ (XFS_SB_VERSION_EXTFLGBIT | \
XFS_SB_VERSION_DIRV2BIT) XFS_SB_VERSION_DIRV2BIT)
...@@ -80,17 +81,46 @@ struct xfs_mount; ...@@ -80,17 +81,46 @@ struct xfs_mount;
(XFS_SB_VERSION_NUMBITS | \ (XFS_SB_VERSION_NUMBITS | \
XFS_SB_VERSION_OKREALFBITS | \ XFS_SB_VERSION_OKREALFBITS | \
XFS_SB_VERSION_OKSASHFBITS) XFS_SB_VERSION_OKSASHFBITS)
#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag) \ #define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag,morebits) \
(((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag)) ? \ (((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag) || \
(morebits)) ? \
(XFS_SB_VERSION_4 | \ (XFS_SB_VERSION_4 | \
((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \ ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \
((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \ ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \
((extflag) ? XFS_SB_VERSION_EXTFLGBIT : 0) | \ ((extflag) ? XFS_SB_VERSION_EXTFLGBIT : 0) | \
((dirv2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \ ((dirv2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \
((na) ? XFS_SB_VERSION_LOGV2BIT : 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) 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 typedef struct xfs_sb
{ {
__uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
...@@ -146,6 +176,7 @@ typedef struct xfs_sb ...@@ -146,6 +176,7 @@ typedef struct xfs_sb
__uint8_t sb_logsectlog; /* log2 of the log sector size */ __uint8_t sb_logsectlog; /* log2 of the log sector size */
__uint16_t sb_logsectsize; /* sector size for the log, bytes */ __uint16_t sb_logsectsize; /* sector size for the log, bytes */
__uint32_t sb_logsunit; /* stripe unit size for the log */ __uint32_t sb_logsunit; /* stripe unit size for the log */
__uint32_t sb_features2; /* additonal feature bits */
} xfs_sb_t; } xfs_sb_t;
/* /*
...@@ -164,6 +195,7 @@ typedef enum { ...@@ -164,6 +195,7 @@ typedef enum {
XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, 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_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
XFS_SBS_FEATURES2,
XFS_SBS_FIELDCOUNT XFS_SBS_FIELDCOUNT
} xfs_sb_field_t; } xfs_sb_field_t;
...@@ -217,8 +249,11 @@ int xfs_sb_good_version(xfs_sb_t *sbp); ...@@ -217,8 +249,11 @@ int xfs_sb_good_version(xfs_sb_t *sbp);
#define XFS_SB_GOOD_VERSION_INT(sbp) \ #define XFS_SB_GOOD_VERSION_INT(sbp) \
((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \ ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \ ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ ((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__ #ifdef __KERNEL__
#define XFS_SB_GOOD_VERSION(sbp) \ #define XFS_SB_GOOD_VERSION(sbp) \
(XFS_SB_GOOD_VERSION_INT(sbp) && \ (XFS_SB_GOOD_VERSION_INT(sbp) && \
...@@ -453,6 +488,25 @@ int xfs_sb_version_hassector(xfs_sb_t *sbp); ...@@ -453,6 +488,25 @@ int xfs_sb_version_hassector(xfs_sb_t *sbp);
((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT)) ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT))
#endif #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 * end of superblock version macros
*/ */
......
...@@ -250,7 +250,7 @@ xfs_trans_reserve( ...@@ -250,7 +250,7 @@ xfs_trans_reserve(
error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
-blocks, rsvd); -blocks, rsvd);
if (error != 0) { if (error != 0) {
PFLAGS_RESTORE(&tp->t_pflags); PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
return (XFS_ERROR(ENOSPC)); return (XFS_ERROR(ENOSPC));
} }
tp->t_blk_res += blocks; tp->t_blk_res += blocks;
...@@ -323,7 +323,7 @@ xfs_trans_reserve( ...@@ -323,7 +323,7 @@ xfs_trans_reserve(
tp->t_blk_res = 0; tp->t_blk_res = 0;
} }
PFLAGS_RESTORE(&tp->t_pflags); PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
return (error); return (error);
} }
...@@ -734,7 +734,7 @@ xfs_trans_commit( ...@@ -734,7 +734,7 @@ xfs_trans_commit(
if (commit_lsn == -1 && !shutdown) if (commit_lsn == -1 && !shutdown)
shutdown = XFS_ERROR(EIO); 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_items(tp, shutdown? XFS_TRANS_ABORT : 0);
xfs_trans_free_busy(tp); xfs_trans_free_busy(tp);
xfs_trans_free(tp); xfs_trans_free(tp);
...@@ -823,7 +823,7 @@ xfs_trans_commit( ...@@ -823,7 +823,7 @@ xfs_trans_commit(
* had pinned, clean up, free trans structure, and return error. * had pinned, clean up, free trans structure, and return error.
*/ */
if (error || commit_lsn == -1) { if (error || commit_lsn == -1) {
PFLAGS_RESTORE(&tp->t_pflags); PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
...@@ -862,7 +862,7 @@ xfs_trans_commit( ...@@ -862,7 +862,7 @@ xfs_trans_commit(
error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
/* mark this thread as no longer being in a transaction */ /* 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 * Once all the items of the transaction have been copied
...@@ -1100,7 +1100,7 @@ xfs_trans_cancel( ...@@ -1100,7 +1100,7 @@ xfs_trans_cancel(
} }
/* mark this thread as no longer being in a transaction */ /* 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_items(tp, flags);
xfs_trans_free_busy(tp); xfs_trans_free_busy(tp);
......
...@@ -535,6 +535,8 @@ typedef struct xfs_trans { ...@@ -535,6 +535,8 @@ typedef struct xfs_trans {
* the super block to reflect the freed blocks: sector size * the super block to reflect the freed blocks: sector size
* worst case split in allocation btrees per extent assuming 4 extents: * worst case split in allocation btrees per extent assuming 4 extents:
* 4 exts * 2 trees * (2 * max depth - 1) * block size * 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) \ #define XFS_CALC_ITRUNCATE_LOG_RES(mp) \
(MAX( \ (MAX( \
...@@ -545,7 +547,11 @@ typedef struct xfs_trans { ...@@ -545,7 +547,11 @@ typedef struct xfs_trans {
(4 * (mp)->m_sb.sb_sectsize) + \ (4 * (mp)->m_sb.sb_sectsize) + \
(mp)->m_sb.sb_sectsize + \ (mp)->m_sb.sb_sectsize + \
XFS_ALLOCFREE_LOG_RES(mp, 4) + \ 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) #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
...@@ -713,6 +719,7 @@ typedef struct xfs_trans { ...@@ -713,6 +719,7 @@ typedef struct xfs_trans {
XFS_FSB_TO_B((mp), 1) + \ XFS_FSB_TO_B((mp), 1) + \
MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
(128 * 5) + \ (128 * 5) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
(128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
......
/* /*
* XFS filesystem operations. * 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 * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -229,7 +229,10 @@ xfs_start_flags( ...@@ -229,7 +229,10 @@ xfs_start_flags(
mp->m_swidth = ap->swidth; 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_MIN_ICLOGS ||
ap->logbufs > XLOG_MAX_ICLOGS)) { ap->logbufs > XLOG_MAX_ICLOGS)) {
cmn_err(CE_WARN, cmn_err(CE_WARN,
...@@ -1484,8 +1487,10 @@ xfs_syncsub( ...@@ -1484,8 +1487,10 @@ xfs_syncsub(
*/ */
if (XFS_BUF_ISPINNED(bp)) if (XFS_BUF_ISPINNED(bp))
xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
if (!(flags & SYNC_WAIT)) if (flags & SYNC_WAIT)
XFS_BUF_BFLAGS(bp) |= XFS_B_ASYNC; XFS_BUF_UNASYNC(bp);
else
XFS_BUF_ASYNC(bp);
error = xfs_bwrite(mp, bp); error = xfs_bwrite(mp, bp);
} }
if (error) { if (error) {
......
...@@ -1106,14 +1106,11 @@ xfs_fsync( ...@@ -1106,14 +1106,11 @@ xfs_fsync(
xfs_off_t stop) xfs_off_t stop)
{ {
xfs_inode_t *ip; xfs_inode_t *ip;
int error;
int error2;
int syncall;
vnode_t *vp;
xfs_trans_t *tp; xfs_trans_t *tp;
int error;
vp = BHV_TO_VNODE(bdp); vn_trace_entry(BHV_TO_VNODE(bdp),
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); __FUNCTION__, (inst_t *)__return_address);
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
...@@ -1122,44 +1119,6 @@ xfs_fsync( ...@@ -1122,44 +1119,6 @@ xfs_fsync(
if (XFS_FORCED_SHUTDOWN(ip->i_mount)) if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return XFS_ERROR(EIO); 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 * We always need to make sure that the required inode state
* is safe on disk. The vnode might be clean but because * is safe on disk. The vnode might be clean but because
...@@ -1199,7 +1158,7 @@ xfs_fsync( ...@@ -1199,7 +1158,7 @@ xfs_fsync(
* be pinned. If it is, force the log. * 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)) { if (xfs_ipincount(ip)) {
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, xfs_log_force(ip->i_mount, (xfs_lsn_t)0,
...@@ -1222,7 +1181,6 @@ xfs_fsync( ...@@ -1222,7 +1181,6 @@ xfs_fsync(
XFS_FSYNC_TS_LOG_RES(ip->i_mount), XFS_FSYNC_TS_LOG_RES(ip->i_mount),
0, 0, 0))) { 0, 0, 0))) {
xfs_trans_cancel(tp, 0); xfs_trans_cancel(tp, 0);
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error; return error;
} }
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
...@@ -1237,68 +1195,18 @@ xfs_fsync( ...@@ -1237,68 +1195,18 @@ xfs_fsync(
* inode in another recent transaction. So we * inode in another recent transaction. So we
* play it safe and fire off the transaction anyway. * 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_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
if (flag & FSYNC_WAIT) if (flag & FSYNC_WAIT)
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL); error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
} }
return error; 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, * This is called by xfs_inactive to free any blocks beyond eof,
* when the link count isn't zero. * 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