Commit 74a6c1d3 authored by Stephen Lord's avatar Stephen Lord

Merge kernel.bkbits.net:/home/repos/linux-2.5

into kernel.bkbits.net:/home/lord/xfs-2.5
parents 5d6a2114 acdb4ea9
......@@ -93,6 +93,7 @@ linvfs_unwritten_conv(
XFS_BUF_SET_FSPRIVATE(bp, NULL);
XFS_BUF_CLR_IODONE_FUNC(bp);
XFS_BUF_UNDATAIO(bp);
iput(LINVFS_GET_IP(vp));
pagebuf_iodone(bp, 0, 0);
}
......@@ -384,7 +385,16 @@ map_unwritten(
pb = pagebuf_lookup(mp->pbm_target,
mp->pbm_offset, mp->pbm_bsize, 0);
if (!pb)
return -ENOMEM;
return -EAGAIN;
/* Take a reference to the inode to prevent it from
* being reclaimed while we have outstanding unwritten
* extent IO on it.
*/
if ((igrab(inode)) != inode) {
pagebuf_free(pb);
return -EAGAIN;
}
/* Set the count to 1 initially, this will stop an I/O
* completion callout which happens before we have started
......@@ -442,8 +452,7 @@ map_unwritten(
if (page) {
nblocks += bs;
atomic_add(bs, &pb->pb_io_remaining);
convert_page(inode, page,
mp, pb, 1, all_bh);
convert_page(inode, page, mp, pb, 1, all_bh);
}
}
}
......@@ -617,11 +626,11 @@ cluster_write(
STATIC int
page_state_convert(
struct inode *inode,
struct page *page,
int startio,
int unmapped) /* also implies page uptodate */
{
struct inode *inode = page->mapping->host;
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
page_buf_bmap_t *mp, map;
unsigned long p_offset = 0, end_index;
......@@ -1021,7 +1030,6 @@ count_page_state(
* the page, we have to check the process flags first, if we
* are already in a transaction or disk I/O during allocations
* is off, we need to fail the writepage and redirty the page.
* We also need to set PF_NOIO ourselves.
*/
STATIC int
......@@ -1057,7 +1065,7 @@ linvfs_writepage(
* then mark the page dirty again and leave the page
* as is.
*/
if ((current->flags & (PF_FSTRANS)) && need_trans)
if (PFLAGS_TEST_FSTRANS() && need_trans)
goto out_fail;
/*
......@@ -1071,7 +1079,7 @@ linvfs_writepage(
* Convert delayed allocate, unwritten or unmapped space
* to real space and flush out to disk.
*/
error = page_state_convert(page, 1, unmapped);
error = page_state_convert(inode, page, 1, unmapped);
if (error == -EAGAIN)
goto out_fail;
if (unlikely(error < 0))
......@@ -1112,6 +1120,7 @@ linvfs_release_page(
struct page *page,
int gfp_mask)
{
struct inode *inode = page->mapping->host;
int delalloc, unmapped, unwritten;
count_page_state(page, &delalloc, &unmapped, &unwritten);
......@@ -1127,7 +1136,7 @@ linvfs_release_page(
* Never need to allocate space here - we will always
* come back to writepage in that case.
*/
if (page_state_convert(page, 0, 0) == 0)
if (page_state_convert(inode, page, 0, 0) == 0)
goto free_buffers;
return 0;
......
......@@ -51,15 +51,14 @@ unsigned long xfs_physmem;
*/
xfs_param_t xfs_params = {
/* MIN DFLT MAX */
restrict_chown: { 0, 1, 1 },
sgid_inherit: { 0, 0, 1 },
symlink_mode: { 0, 0, 1 },
panic_mask: { 0, 0, 127 },
error_level: { 0, 3, 11 },
sync_interval: { HZ, 30*HZ, 60*HZ },
stats_clear: { 0, 0, 1 },
/* MIN DFLT MAX */
.restrict_chown = { 0, 1, 1 },
.sgid_inherit = { 0, 0, 1 },
.symlink_mode = { 0, 0, 1 },
.panic_mask = { 0, 0, 127 },
.error_level = { 0, 3, 11 },
.sync_interval = { HZ, 30*HZ, 60*HZ },
.stats_clear = { 0, 0, 1 },
};
/*
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2003 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
......@@ -172,8 +172,11 @@ xfs_iomap(
BUG();
}
ASSERT(offset <= mp->m_maxioffset);
if ((xfs_fsize_t)offset + count > mp->m_maxioffset)
count = mp->m_maxioffset - offset;
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
offset_fsb = XFS_B_TO_FSBT(mp, offset);
end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
error = XFS_BMAPI(mp, NULL, io, offset_fsb,
(xfs_filblks_t)(end_fsb - offset_fsb) ,
......
......@@ -642,7 +642,7 @@ linvfs_setxattr(
}
STATIC ssize_t
__linvfs_getxattr(
linvfs_getxattr(
struct dentry *dentry,
const char *name,
void *data,
......@@ -698,23 +698,7 @@ __linvfs_getxattr(
}
STATIC ssize_t
linvfs_getxattr(
struct dentry *dentry,
const char *name,
void *data,
size_t size)
{
int error;
down(&dentry->d_inode->i_sem);
error = __linvfs_getxattr(dentry, name, data, size);
up(&dentry->d_inode->i_sem);
return error;
}
STATIC ssize_t
__linvfs_listxattr(
linvfs_listxattr(
struct dentry *dentry,
char *data,
size_t size)
......@@ -756,21 +740,6 @@ __linvfs_listxattr(
return result;
}
STATIC ssize_t
linvfs_listxattr(
struct dentry *dentry,
char *data,
size_t size)
{
int error;
down(&dentry->d_inode->i_sem);
error = __linvfs_listxattr(dentry, data, size);
up(&dentry->d_inode->i_sem);
return error;
}
STATIC int
linvfs_removexattr(
struct dentry *dentry,
......
......@@ -205,7 +205,7 @@ xfs_read(
}
}
n = XFS_MAX_FILE_OFFSET - *offp;
n = XFS_MAXIOFFSET(mp) - *offp;
if ((n <= 0) || (size == 0))
return 0;
......@@ -265,7 +265,7 @@ xfs_sendfile(
XFS_STATS_INC(xfsstats.xs_read_calls);
n = XFS_MAX_FILE_OFFSET - *offp;
n = XFS_MAXIOFFSET(mp) - *offp;
if ((n <= 0) || (count == 0))
return 0;
......@@ -454,7 +454,8 @@ xfs_zero_eof(
}
ASSERT(nimaps > 0);
if (imap.br_startblock == HOLESTARTBLOCK) {
if (imap.br_state == XFS_EXT_UNWRITTEN ||
imap.br_startblock == HOLESTARTBLOCK) {
/*
* This loop handles initializing pages that were
* partially initialized by the code below this
......@@ -527,7 +528,7 @@ xfs_write(
ssize_t ret;
int error = 0;
xfs_fsize_t isize, new_size;
xfs_fsize_t n, limit = XFS_MAX_FILE_OFFSET;
xfs_fsize_t n, limit;
xfs_iocore_t *io;
vnode_t *vp;
unsigned long seg;
......@@ -593,6 +594,7 @@ xfs_write(
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
isize = xip->i_d.di_size;
limit = XFS_MAXIOFFSET(mp);
if (file->f_flags & O_APPEND)
*offset = isize;
......
......@@ -79,7 +79,7 @@ STATIC struct export_operations linvfs_export_ops;
STATIC kmem_cache_t * linvfs_inode_cachep;
STATIC struct xfs_mount_args *
args_allocate(
xfs_args_allocate(
struct super_block *sb)
{
struct xfs_mount_args *args;
......@@ -98,6 +98,40 @@ args_allocate(
return args;
}
__uint64_t
xfs_max_file_offset(
unsigned int blockshift)
{
unsigned int pagefactor = 1;
unsigned int bitshift = BITS_PER_LONG - 1;
/* Figure out maximum filesize, on Linux this can depend on
* the filesystem blocksize (on 32 bit platforms).
* __block_prepare_write does this in an [unsigned] long...
* page->index << (PAGE_CACHE_SHIFT - bbits)
* So, for page sized blocks (4K on 32 bit platforms),
* this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
* (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
* but for smaller blocksizes it is less (bbits = log2 bsize).
* Note1: get_block_t takes a long (implicit cast from above)
* Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
* can optionally convert the [unsigned] long from above into
* an [unsigned] long long.
*/
#if BITS_PER_LONG == 32
# if defined(HAVE_SECTOR_T)
ASSERT(sizeof(sector_t) == 8);
pagefactor = PAGE_CACHE_SIZE;
bitshift = BITS_PER_LONG;
# else
pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
# endif
#endif
return (((__uint64_t)pagefactor) << bitshift) - 1;
}
STATIC __inline__ void
xfs_set_inodeops(
struct inode *inode)
......@@ -287,20 +321,14 @@ xfs_alloc_buftarg(
return btp;
}
STATIC __inline__ unsigned int gfp_mask(void)
{
/* If we're not in a transaction, FS activity is ok */
if (current->flags & PF_FSTRANS) return GFP_NOFS;
return GFP_KERNEL;
}
STATIC struct inode *
linvfs_alloc_inode(
struct super_block *sb)
{
vnode_t *vp;
vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep, gfp_mask());
vp = (vnode_t *)kmem_cache_alloc(linvfs_inode_cachep,
kmem_flags_convert(KM_SLEEP));
if (!vp)
return NULL;
return LINVFS_GET_IP(vp);
......@@ -497,7 +525,7 @@ linvfs_remount(
char *options)
{
vfs_t *vfsp = LINVFS_GET_VFS(sb);
struct xfs_mount_args *args = args_allocate(sb);
struct xfs_mount_args *args = xfs_args_allocate(sb);
int error;
VFS_PARSEARGS(vfsp, options, args, 1, error);
......@@ -676,7 +704,7 @@ linvfs_fill_super(
{
vnode_t *rootvp;
struct vfs *vfsp = vfs_allocate();
struct xfs_mount_args *args = args_allocate(sb);
struct xfs_mount_args *args = xfs_args_allocate(sb);
struct kstatfs statvfs;
int error;
......@@ -693,7 +721,6 @@ linvfs_fill_super(
}
sb_min_blocksize(sb, BBSIZE);
sb->s_maxbytes = XFS_MAX_FILE_OFFSET;
sb->s_export_op = &linvfs_export_ops;
sb->s_qcop = &linvfs_qops;
sb->s_op = &linvfs_sops;
......@@ -709,9 +736,10 @@ linvfs_fill_super(
goto fail_unmount;
sb->s_dirt = 1;
sb->s_magic = XFS_SB_MAGIC;
sb->s_magic = statvfs.f_type;
sb->s_blocksize = statvfs.f_bsize;
sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
set_posix_acl_flag(sb);
VFS_ROOT(vfsp, &rootvp, error);
......
......@@ -66,6 +66,12 @@
# define XFS_REALTIME_STRING
#endif
#if XFS_BIG_FILESYSTEMS
# define XFS_BIGFS_STRING "big filesystems, "
#else
# define XFS_BIGFS_STRING
#endif
#ifdef CONFIG_XFS_VNODE_TRACING
# define XFS_VNTRACE_STRING "VN-trace, "
#else
......@@ -80,6 +86,7 @@
#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
XFS_REALTIME_STRING \
XFS_BIGFS_STRING \
XFS_VNTRACE_STRING \
XFS_DBG_STRING /* DBG must be last */
......@@ -92,6 +99,8 @@ struct xfs_mount;
struct pb_target;
struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern int xfs_blkdev_get(struct xfs_mount *, const char *,
......
......@@ -39,8 +39,6 @@
#ifndef __XFS_VERSION_H__
#define __XFS_VERSION_H__
#include <linux/version.h>
#define XFS_VERSION_STRING "for Linux " UTS_RELEASE
#define XFS_VERSION_STRING "for Linux"
#endif /* __XFS_VERSION_H__ */
......@@ -130,11 +130,11 @@ STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
*/
pagebuf_param_t pb_params = {
/* MIN DFLT MAX */
flush_interval: { HZ/2, HZ, 30*HZ },
age_buffer: { 1*HZ, 15*HZ, 300*HZ },
stats_clear: { 0, 0, 1 },
debug: { 0, 0, 1 },
/* MIN DFLT MAX */
.flush_interval = { HZ/2, HZ, 30*HZ },
.age_buffer = { 1*HZ, 15*HZ, 300*HZ },
.stats_clear = { 0, 0, 1 },
.debug = { 0, 0, 1 },
};
/*
......@@ -834,13 +834,14 @@ pagebuf_readahead(
page_buf_t *
pagebuf_get_empty(
size_t len,
pb_target_t *target)
{
page_buf_t *pb;
pb = pagebuf_allocate(_PBF_LOCKABLE);
if (pb)
_pagebuf_initialize(pb, target, 0, 0, _PBF_LOCKABLE);
_pagebuf_initialize(pb, target, 0, len, _PBF_LOCKABLE);
return pb;
}
......
......@@ -267,6 +267,7 @@ extern page_buf_t *pagebuf_lookup(
extern page_buf_t *pagebuf_get_empty( /* allocate pagebuf struct with */
/* no memory or disk address */
size_t len,
struct pb_target *); /* mount point "fake" inode */
extern page_buf_t *pagebuf_get_no_daddr(/* allocate pagebuf struct */
......
......@@ -1612,7 +1612,7 @@ xfs_qm_dqiterate(
map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP);
lblkno = 0;
maxlblkcnt = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAX_FILE_OFFSET);
maxlblkcnt = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
do {
nmaps = XFS_DQITER_MAP_SIZE;
/*
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2003 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
......@@ -53,14 +53,32 @@
#define KM_NOSLEEP 0x0002
#define KM_NOFS 0x0004
typedef unsigned long xfs_pflags_t;
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
#define PFLAGS_SET_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
current->flags |= PF_FSTRANS; \
} while (0)
#define PFLAGS_RESTORE(STATEP) do { \
current->flags = *(STATEP); \
} while (0)
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
*(NSTATEP) = *(OSTATEP); \
} while (0)
/*
* XXX get rid of the unconditional __GFP_NOFAIL by adding
* a KM_FAIL flag and using it where we're allowed to fail.
*/
static __inline unsigned int
flag_convert(int flags)
kmem_flags_convert(int flags)
{
int lflags;
#if DEBUG
if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS))) {
printk(KERN_WARNING
......@@ -69,12 +87,13 @@ flag_convert(int flags)
}
#endif
if (flags & KM_NOSLEEP)
return GFP_ATOMIC;
/* If we're in a transaction, FS activity is not ok */
else if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
return GFP_NOFS | __GFP_NOFAIL;
return GFP_KERNEL | __GFP_NOFAIL;
lflags = (flags & KM_NOSLEEP) ? GFP_ATOMIC : (GFP_KERNEL|__GFP_NOFAIL);
/* avoid recusive callbacks to filesystem during transactions */
if (PFLAGS_TEST_FSTRANS())
lflags &= ~__GFP_FS;
return lflags;
}
static __inline void *
......@@ -82,8 +101,8 @@ kmem_alloc(size_t size, int flags)
{
if (unlikely(MAX_SLAB_SIZE < size))
/* Avoid doing filesystem sensitive stuff to get this */
return __vmalloc(size, flag_convert(flags), PAGE_KERNEL);
return kmalloc(size, flag_convert(flags));
return __vmalloc(size, kmem_flags_convert(flags), PAGE_KERNEL);
return kmalloc(size, kmem_flags_convert(flags));
}
static __inline void *
......@@ -128,7 +147,7 @@ kmem_zone_init(int size, char *zone_name)
static __inline void *
kmem_zone_alloc(kmem_zone_t *zone, int flags)
{
return kmem_cache_alloc(zone, flag_convert(flags));
return kmem_cache_alloc(zone, kmem_flags_convert(flags));
}
static __inline void *
......
......@@ -43,6 +43,8 @@
* We don't need to worry about SMP or not here.
*/
#define SPLDECL(s) unsigned long s
typedef spinlock_t lock_t;
#define spinlock_init(lock, name) spin_lock_init(lock)
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2003 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
......@@ -5579,7 +5579,7 @@ xfs_getbmap(
if (whichfork == XFS_DATA_FORK) {
if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {
prealloced = 1;
fixlen = XFS_MAX_FILE_OFFSET;
fixlen = XFS_MAXIOFFSET(mp);
} else {
prealloced = 0;
fixlen = ip->i_d.di_size;
......
......@@ -316,11 +316,8 @@ static inline int xfs_bdwrite(void *mp, page_buf_t *bp)
#define xfs_baread(target, rablkno, ralen) \
pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)
#define XFS_getrbuf(sleep,mp) \
pagebuf_get_empty((mp)->m_ddev_targp)
#define XFS_ngetrbuf(len,mp) \
pagebuf_get_no_daddr(len,(mp)->m_ddev_targp)
#define XFS_freerbuf(bp) pagebuf_free(bp)
#define XFS_nfreerbuf(bp) pagebuf_free(bp)
#define xfs_buf_get_empty(len, target) pagebuf_get_empty((len), (target))
#define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target))
#define xfs_buf_free(bp) pagebuf_free(bp)
#endif
......@@ -1265,7 +1265,7 @@ xfs_isize_check(
*/
if (xfs_bmapi(NULL, ip, map_first,
(XFS_B_TO_FSB(mp,
(xfs_ufsize_t)XFS_MAX_FILE_OFFSET) -
(xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
map_first),
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
NULL))
......@@ -1319,11 +1319,11 @@ xfs_file_last_byte(
last_byte = XFS_FSB_TO_B(mp, last_block);
if (last_byte < 0) {
return XFS_MAX_FILE_OFFSET;
return XFS_MAXIOFFSET(mp);
}
last_byte += (1 << mp->m_writeio_log);
if (last_byte < 0) {
return XFS_MAX_FILE_OFFSET;
return XFS_MAXIOFFSET(mp);
}
return last_byte;
}
......@@ -1613,7 +1613,7 @@ xfs_itruncate_finish(
* beyond the maximum file size (ie it is the same as last_block),
* then there is nothing to do.
*/
last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAX_FILE_OFFSET);
last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
ASSERT(first_unmap_block <= last_block);
done = 0;
if (last_block == first_unmap_block) {
......
......@@ -406,14 +406,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
#define XFS_ITRUNC_DEFINITE 0x1
#define XFS_ITRUNC_MAYBE 0x2
/*
* max file offset is 2^(31+PAGE_SHIFT) - 1 (due to linux page cache)
*
* NOTE: XFS itself can handle 2^63 - 1 (largest positive value of xfs_fsize_t)
* but this is the Linux limit.
*/
#define XFS_MAX_FILE_OFFSET MAX_LFS_FILESIZE
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV)
struct vnode *xfs_itov(xfs_inode_t *ip);
#define XFS_ITOV(ip) xfs_itov(ip)
......
......@@ -1219,15 +1219,14 @@ xlog_alloc_log(xfs_mount_t *mp,
xlog_get_iclog_buffer_size(mp, log);
bp = log->l_xbuf = XFS_getrbuf(0,mp); /* get my locked buffer */ /* mp needed for pagebuf/linux only */
XFS_BUF_SET_TARGET(bp, mp->m_logdev_targp);
XFS_BUF_SET_SIZE(bp, log->l_iclog_size);
bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
ASSERT(XFS_BUF_ISBUSY(log->l_xbuf));
ASSERT(XFS_BUF_VALUSEMA(log->l_xbuf) <= 0);
ASSERT(XFS_BUF_ISBUSY(bp));
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
log->l_xbuf = bp;
spinlock_init(&log->l_icloglock, "iclog");
spinlock_init(&log->l_grant_lock, "grhead_iclog");
initnsema(&log->l_flushsema, 0, "ic-flush");
......@@ -1267,12 +1266,11 @@ xlog_alloc_log(xfs_mount_t *mp,
INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
bp = iclog->ic_bp = XFS_getrbuf(0,mp); /* my locked buffer */ /* mp need for pagebuf/linux only */
XFS_BUF_SET_TARGET(bp, mp->m_logdev_targp);
XFS_BUF_SET_SIZE(bp, log->l_iclog_size);
bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
iclog->ic_bp = bp;
iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize;
iclog->ic_state = XLOG_STATE_ACTIVE;
......@@ -1572,7 +1570,7 @@ xlog_unalloc_log(xlog_t *log)
for (i=0; i<log->l_iclog_bufs; i++) {
sv_destroy(&iclog->ic_forcesema);
sv_destroy(&iclog->ic_writesema);
XFS_freerbuf(iclog->ic_bp);
xfs_buf_free(iclog->ic_bp);
#ifdef DEBUG
if (iclog->ic_trace != NULL) {
ktrace_free(iclog->ic_trace);
......@@ -1603,7 +1601,7 @@ xlog_unalloc_log(xlog_t *log)
tic = next_tic;
}
}
XFS_freerbuf(log->l_xbuf);
xfs_buf_free(log->l_xbuf);
#ifdef DEBUG
if (log->l_trace != NULL) {
ktrace_free(log->l_trace);
......@@ -3375,6 +3373,7 @@ xlog_verify_iclog(xlog_t *log,
{
xlog_op_header_t *ophead;
xlog_in_core_t *icptr;
xlog_in_core_2_t *xhdr;
xfs_caddr_t ptr;
xfs_caddr_t base_ptr;
__psint_t field_offset;
......@@ -3383,11 +3382,6 @@ xlog_verify_iclog(xlog_t *log,
int idx;
SPLDECL(s);
union ich {
xlog_rec_ext_header_t hic_xheader;
char hic_sector[XLOG_HEADER_SIZE];
}*xhdr;
/* check validity of iclog pointers */
s = LOG_LOCK(log);
icptr = log->l_iclog;
......@@ -3416,7 +3410,7 @@ xlog_verify_iclog(xlog_t *log,
ptr = iclog->ic_datap;
base_ptr = ptr;
ophead = (xlog_op_header_t *)ptr;
xhdr = (union ich*)&iclog->ic_header;
xhdr = (xlog_in_core_2_t *)&iclog->ic_header;
for (i = 0; i < len; i++) {
ophead = (xlog_op_header_t *)ptr;
......
......@@ -484,59 +484,65 @@ typedef struct xlog_in_core {
* that round off problems won't occur when releasing partial reservations.
*/
typedef struct log {
/* The following block of fields are changed while holding icloglock */
sema_t l_flushsema; /* iclog flushing semaphore */
int l_flushcnt; /* # of procs waiting on this sema */
int l_ticket_cnt; /* free ticket count */
int l_ticket_tcnt; /* total ticket count */
int l_covered_state;/* state of "covering disk log entries" */
xlog_ticket_t *l_freelist; /* free list of tickets */
xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */
xlog_ticket_t *l_tail; /* free list of tickets */
xlog_in_core_t *l_iclog; /* head log queue */
lock_t l_icloglock; /* grab to change iclog state */
xfs_lsn_t l_tail_lsn; /* lsn of 1st LR w/ unflush buffers */
xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */
struct xfs_mount *l_mp; /* mount point */
struct xfs_buf *l_xbuf; /* extra buffer for log wrapping */
dev_t l_dev; /* dev_t of log */
xfs_daddr_t l_logBBstart; /* start block of log */
int l_logsize; /* size of log in bytes */
int l_logBBsize; /* size of log in 512 byte chunks */
int l_roundoff; /* round off error of all iclogs */
int l_curr_cycle; /* Cycle number of log writes */
int l_prev_cycle; /* Cycle # b4 last block increment */
int l_curr_block; /* current logical block of log */
int l_prev_block; /* previous logical block of log */
int l_iclog_size; /* size of log in bytes */
int l_iclog_size_log;/* log power size of log */
int l_iclog_bufs; /* number of iclog buffers */
/* The following field are used for debugging; need to hold icloglock */
char *l_iclog_bak[XLOG_MAX_ICLOGS];
/* The following block of fields are changed while holding grant_lock */
lock_t l_grant_lock; /* protects below fields */
xlog_ticket_t *l_reserve_headq; /* */
xlog_ticket_t *l_write_headq; /* */
int l_grant_reserve_cycle; /* */
int l_grant_reserve_bytes; /* */
int l_grant_write_cycle; /* */
int l_grant_write_bytes; /* */
/* The following fields don't need locking */
/* The following block of fields are changed while holding icloglock */
sema_t l_flushsema; /* iclog flushing semaphore */
int l_flushcnt; /* # of procs waiting on this
* sema */
int l_ticket_cnt; /* free ticket count */
int l_ticket_tcnt; /* total ticket count */
int l_covered_state;/* state of "covering disk
* log entries" */
xlog_ticket_t *l_freelist; /* free list of tickets */
xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */
xlog_ticket_t *l_tail; /* free list of tickets */
xlog_in_core_t *l_iclog; /* head log queue */
lock_t l_icloglock; /* grab to change iclog state */
xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed
* buffers */
xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */
struct xfs_mount *l_mp; /* mount point */
struct xfs_buf *l_xbuf; /* extra buffer for log
* wrapping */
dev_t l_dev; /* dev_t of log */
xfs_daddr_t l_logBBstart; /* start block of log */
int l_logsize; /* size of log in bytes */
int l_logBBsize; /* size of log in BB chunks */
int l_roundoff; /* round off error of iclogs */
int l_curr_cycle; /* Cycle number of log writes */
int l_prev_cycle; /* Cycle number before last
* block increment */
int l_curr_block; /* current logical log block */
int l_prev_block; /* previous logical log block */
int l_iclog_size; /* size of log in bytes */
int l_iclog_size_log; /* log power size of log */
int l_iclog_bufs; /* number of iclog buffers */
/* The following field are used for debugging; need to hold icloglock */
char *l_iclog_bak[XLOG_MAX_ICLOGS];
/* The following block of fields are changed while holding grant_lock */
lock_t l_grant_lock;
xlog_ticket_t *l_reserve_headq;
xlog_ticket_t *l_write_headq;
int l_grant_reserve_cycle;
int l_grant_reserve_bytes;
int l_grant_write_cycle;
int l_grant_write_bytes;
/* The following fields don't need locking */
#ifdef DEBUG
struct ktrace *l_trace;
struct ktrace *l_grant_trace;
struct ktrace *l_trace;
struct ktrace *l_grant_trace;
#endif
uint l_flags;
uint l_quotaoffs_flag;/* XFS_DQ_*, if QUOTAOFFs found */
struct xfs_buf_cancel **l_buf_cancel_table;
int l_stripemask; /* log stripe mask */
int l_iclog_hsize; /* size of iclog header */
int l_iclog_heads; /* number of iclog header sectors */
uint l_sectbb_log; /* log2 of sector size in bbs */
uint l_sectbb_mask; /* sector size in bbs alignment mask */
uint l_flags;
uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
struct xfs_buf_cancel **l_buf_cancel_table;
int l_stripemask; /* log stripe mask */
int l_iclog_hsize; /* size of iclog header */
int l_iclog_heads; /* # of iclog header sectors */
uint l_sectbb_log; /* log2 of sector size in BBs */
uint l_sectbb_mask; /* sector size (in BBs)
* alignment mask */
} xlog_t;
......
......@@ -99,14 +99,14 @@ xlog_get_bp(
num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
}
return XFS_ngetrbuf(BBTOB(num_bblks), log->l_mp);
return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
}
void
xlog_put_bp(
xfs_buf_t *bp)
{
XFS_nfreerbuf(bp);
xfs_buf_free(bp);
}
......
......@@ -728,6 +728,8 @@ xfs_mountfs(
} else
mp->m_maxicount = 0;
mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
/*
* XFS uses the uuid from the superblock as the unique
* identifier for fsid. We can not use the uuid from the volume
......
......@@ -80,7 +80,6 @@ struct xfs_iocore;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
#define SPLDECL(s) unsigned long s
#define AIL_LOCK_T lock_t
#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
#define AIL_LOCK_DESTROY(x) spinlock_destroy(x)
......@@ -352,6 +351,7 @@ typedef struct xfs_mount {
uint m_qflags; /* quota status flags */
xfs_trans_reservations_t m_reservations;/* precomputed res values */
__uint64_t m_maxicount; /* maximum inode count */
__uint64_t m_maxioffset; /* maximum inode offset */
__uint64_t m_resblks; /* total reserved blocks */
__uint64_t m_resblks_avail;/* available reserved blocks */
#if XFS_BIG_FILESYSTEMS
......@@ -418,8 +418,6 @@ typedef struct xfs_mount {
* 32 bits in size */
#define XFS_MOUNT_NOLOGFLUSH 0x00010000
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
/*
* Default minimum read and write sizes.
*/
......@@ -444,6 +442,9 @@ typedef struct xfs_mount {
#define XFS_WSYNC_READIO_LOG 15 /* 32K */
#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */
#define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset)
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
#define xfs_force_shutdown(m,f) \
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
......
......@@ -200,6 +200,7 @@ xfs_trans_dup(
tp->t_blk_res = tp->t_blk_res_used;
ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
tp->t_rtx_res = tp->t_rtx_res_used;
PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags);
XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
......@@ -238,7 +239,7 @@ xfs_trans_reserve(
rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
/* Mark this thread as being in a transaction */
current->flags |= PF_FSTRANS;
PFLAGS_SET_FSTRANS(&tp->t_pflags);
/*
* Attempt to reserve the needed disk blocks by decrementing
......@@ -249,7 +250,7 @@ xfs_trans_reserve(
error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
-blocks, rsvd);
if (error != 0) {
current->flags &= ~PF_FSTRANS;
PFLAGS_RESTORE(&tp->t_pflags);
return (XFS_ERROR(ENOSPC));
}
tp->t_blk_res += blocks;
......@@ -322,7 +323,7 @@ xfs_trans_reserve(
tp->t_blk_res = 0;
}
current->flags &= ~PF_FSTRANS;
PFLAGS_RESTORE(&tp->t_pflags);
return (error);
}
......@@ -734,13 +735,13 @@ xfs_trans_commit(
if (commit_lsn == -1 && !shutdown)
shutdown = XFS_ERROR(EIO);
}
PFLAGS_RESTORE(&tp->t_pflags);
xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
xfs_trans_free_busy(tp);
xfs_trans_free(tp);
XFS_STATS_INC(xfsstats.xs_trans_empty);
if (commit_lsn_p)
*commit_lsn_p = commit_lsn;
current->flags &= ~PF_FSTRANS;
return (shutdown);
}
#if defined(XLOG_NOLOG) || defined(DEBUG)
......@@ -823,8 +824,8 @@ xfs_trans_commit(
* had pinned, clean up, free trans structure, and return error.
*/
if (error || commit_lsn == -1) {
PFLAGS_RESTORE(&tp->t_pflags);
xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
current->flags &= ~PF_FSTRANS;
return XFS_ERROR(EIO);
}
......@@ -861,6 +862,9 @@ 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);
/*
* Once all the items of the transaction have been copied
* to the in core log and the callback is attached, the
......@@ -896,9 +900,6 @@ xfs_trans_commit(
XFS_STATS_INC(xfsstats.xs_trans_async);
}
/* mark this thread as no longer being in a transaction */
current->flags &= ~PF_FSTRANS;
return (error);
}
......@@ -1098,12 +1099,13 @@ xfs_trans_cancel(
}
xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
}
/* mark this thread as no longer being in a transaction */
PFLAGS_RESTORE(&tp->t_pflags);
xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp);
xfs_trans_free(tp);
/* mark this thread as no longer being in a transaction */
current->flags &= ~PF_FSTRANS;
}
......
......@@ -409,6 +409,7 @@ typedef struct xfs_trans {
xfs_trans_header_t t_header; /* header for in-log trans */
unsigned int t_busy_free; /* busy descs free */
xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */
xfs_pflags_t t_pflags; /* saved pflags state */
} xfs_trans_t;
#endif /* __KERNEL__ */
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2003 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
......@@ -1287,7 +1287,7 @@ xfs_inactive_free_eofblocks(
* of the file. If not, then there is nothing to do.
*/
end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size));
last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAX_FILE_OFFSET);
last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
map_len = last_fsb - end_fsb;
if (map_len <= 0)
return (0);
......@@ -4282,24 +4282,18 @@ xfs_zero_remaining_bytes(
xfs_off_t startoff,
xfs_off_t endoff)
{
xfs_buf_t *bp;
int error=0;
xfs_bmbt_irec_t imap;
xfs_fileoff_t offset_fsb;
xfs_off_t lastoffset;
xfs_mount_t *mp;
int nimap;
xfs_off_t offset;
xfs_fileoff_t offset_fsb;
mp = ip->i_mount;
bp = XFS_ngetrbuf(mp->m_sb.sb_blocksize,mp);
ASSERT(!XFS_BUF_GETERROR(bp));
xfs_buf_t *bp;
xfs_mount_t *mp = ip->i_mount;
int nimap;
int error = 0;
if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
XFS_BUF_SET_TARGET(bp, mp->m_rtdev_targp);
} else {
XFS_BUF_SET_TARGET(bp, mp->m_ddev_targp);
}
bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
ip->i_d.di_flags & XFS_DIFLAG_REALTIME ?
mp->m_rtdev_targp : mp->m_ddev_targp);
for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
offset_fsb = XFS_B_TO_FSBT(mp, offset);
......@@ -4341,7 +4335,7 @@ xfs_zero_remaining_bytes(
break;
}
}
XFS_nfreerbuf(bp);
xfs_buf_free(bp);
return error;
}
......@@ -4612,9 +4606,9 @@ xfs_change_file_space(
llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len;
if ( (bf->l_start < 0)
|| (bf->l_start > XFS_MAX_FILE_OFFSET)
|| (bf->l_start > XFS_MAXIOFFSET(mp))
|| (bf->l_start + llen < 0)
|| (bf->l_start + llen > XFS_MAX_FILE_OFFSET))
|| (bf->l_start + llen > XFS_MAXIOFFSET(mp)))
return XFS_ERROR(EINVAL);
bf->l_whence = 0;
......
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