Commit 668d7c5d authored by Stephen Lord's avatar Stephen Lord

Merge bk://kernel.bkbits.net/lord/xfs-2.5

into jen.americas.sgi.com:/src/lord/bitkeeper/xfs-2.5
parents 0c37bbab 21aea9c9
/* /*
* 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 * 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
...@@ -172,8 +172,11 @@ xfs_iomap( ...@@ -172,8 +172,11 @@ xfs_iomap(
BUG(); 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); 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, error = XFS_BMAPI(mp, NULL, io, offset_fsb,
(xfs_filblks_t)(end_fsb - offset_fsb) , (xfs_filblks_t)(end_fsb - offset_fsb) ,
......
...@@ -205,7 +205,7 @@ xfs_read( ...@@ -205,7 +205,7 @@ xfs_read(
} }
} }
n = XFS_MAX_FILE_OFFSET - *offp; n = XFS_MAXIOFFSET(mp) - *offp;
if ((n <= 0) || (size == 0)) if ((n <= 0) || (size == 0))
return 0; return 0;
...@@ -265,7 +265,7 @@ xfs_sendfile( ...@@ -265,7 +265,7 @@ xfs_sendfile(
XFS_STATS_INC(xfsstats.xs_read_calls); XFS_STATS_INC(xfsstats.xs_read_calls);
n = XFS_MAX_FILE_OFFSET - *offp; n = XFS_MAXIOFFSET(mp) - *offp;
if ((n <= 0) || (count == 0)) if ((n <= 0) || (count == 0))
return 0; return 0;
...@@ -527,7 +527,7 @@ xfs_write( ...@@ -527,7 +527,7 @@ xfs_write(
ssize_t ret; ssize_t ret;
int error = 0; int error = 0;
xfs_fsize_t isize, new_size; xfs_fsize_t isize, new_size;
xfs_fsize_t n, limit = XFS_MAX_FILE_OFFSET; xfs_fsize_t n, limit;
xfs_iocore_t *io; xfs_iocore_t *io;
vnode_t *vp; vnode_t *vp;
unsigned long seg; unsigned long seg;
...@@ -593,6 +593,7 @@ xfs_write( ...@@ -593,6 +593,7 @@ xfs_write(
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
isize = xip->i_d.di_size; isize = xip->i_d.di_size;
limit = XFS_MAXIOFFSET(mp);
if (file->f_flags & O_APPEND) if (file->f_flags & O_APPEND)
*offset = isize; *offset = isize;
......
...@@ -79,7 +79,7 @@ STATIC struct export_operations linvfs_export_ops; ...@@ -79,7 +79,7 @@ STATIC struct export_operations linvfs_export_ops;
STATIC kmem_cache_t * linvfs_inode_cachep; STATIC kmem_cache_t * linvfs_inode_cachep;
STATIC struct xfs_mount_args * STATIC struct xfs_mount_args *
args_allocate( xfs_args_allocate(
struct super_block *sb) struct super_block *sb)
{ {
struct xfs_mount_args *args; struct xfs_mount_args *args;
...@@ -98,6 +98,34 @@ args_allocate( ...@@ -98,6 +98,34 @@ args_allocate(
return args; return args;
} }
__uint64_t
xfs_max_file_offset(
unsigned int blockshift)
{
unsigned int pageshift = 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 fropm above into
* an unsigned long long.
*/
#if defined(HAVE_SECTOR_T)
ASSERT(sizeof(sector_t) == 8);
#elif BITS_PER_LONG == 32
pageshift = PAGE_CACHE_SHIFT >> (PAGE_CACHE_SHIFT - blockshift);
#endif
return (((__uint64_t)pageshift) << (BITS_PER_LONG - 1)) - 1;
}
STATIC __inline__ void STATIC __inline__ void
xfs_set_inodeops( xfs_set_inodeops(
struct inode *inode) struct inode *inode)
...@@ -497,7 +525,7 @@ linvfs_remount( ...@@ -497,7 +525,7 @@ linvfs_remount(
char *options) char *options)
{ {
vfs_t *vfsp = LINVFS_GET_VFS(sb); 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; int error;
VFS_PARSEARGS(vfsp, options, args, 1, error); VFS_PARSEARGS(vfsp, options, args, 1, error);
...@@ -676,7 +704,7 @@ linvfs_fill_super( ...@@ -676,7 +704,7 @@ linvfs_fill_super(
{ {
vnode_t *rootvp; vnode_t *rootvp;
struct vfs *vfsp = vfs_allocate(); 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; struct kstatfs statvfs;
int error; int error;
...@@ -693,7 +721,6 @@ linvfs_fill_super( ...@@ -693,7 +721,6 @@ linvfs_fill_super(
} }
sb_min_blocksize(sb, BBSIZE); sb_min_blocksize(sb, BBSIZE);
sb->s_maxbytes = XFS_MAX_FILE_OFFSET;
sb->s_export_op = &linvfs_export_ops; sb->s_export_op = &linvfs_export_ops;
sb->s_qcop = &linvfs_qops; sb->s_qcop = &linvfs_qops;
sb->s_op = &linvfs_sops; sb->s_op = &linvfs_sops;
...@@ -709,9 +736,10 @@ linvfs_fill_super( ...@@ -709,9 +736,10 @@ linvfs_fill_super(
goto fail_unmount; goto fail_unmount;
sb->s_dirt = 1; 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 = statvfs.f_bsize;
sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1; 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); set_posix_acl_flag(sb);
VFS_ROOT(vfsp, &rootvp, error); VFS_ROOT(vfsp, &rootvp, error);
......
...@@ -92,6 +92,8 @@ struct xfs_mount; ...@@ -92,6 +92,8 @@ struct xfs_mount;
struct pb_target; struct pb_target;
struct block_device; 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 void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern int xfs_blkdev_get(struct xfs_mount *, const char *, extern int xfs_blkdev_get(struct xfs_mount *, const char *,
......
...@@ -1612,7 +1612,7 @@ xfs_qm_dqiterate( ...@@ -1612,7 +1612,7 @@ xfs_qm_dqiterate(
map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP); map = kmem_alloc(XFS_DQITER_MAP_SIZE * sizeof(*map), KM_SLEEP);
lblkno = 0; 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 { do {
nmaps = XFS_DQITER_MAP_SIZE; 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 * 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
...@@ -5579,7 +5579,7 @@ xfs_getbmap( ...@@ -5579,7 +5579,7 @@ xfs_getbmap(
if (whichfork == XFS_DATA_FORK) { if (whichfork == XFS_DATA_FORK) {
if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) { if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {
prealloced = 1; prealloced = 1;
fixlen = XFS_MAX_FILE_OFFSET; fixlen = XFS_MAXIOFFSET(mp);
} else { } else {
prealloced = 0; prealloced = 0;
fixlen = ip->i_d.di_size; fixlen = ip->i_d.di_size;
......
...@@ -1265,7 +1265,7 @@ xfs_isize_check( ...@@ -1265,7 +1265,7 @@ xfs_isize_check(
*/ */
if (xfs_bmapi(NULL, ip, map_first, if (xfs_bmapi(NULL, ip, map_first,
(XFS_B_TO_FSB(mp, (XFS_B_TO_FSB(mp,
(xfs_ufsize_t)XFS_MAX_FILE_OFFSET) - (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
map_first), map_first),
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
NULL)) NULL))
...@@ -1319,11 +1319,11 @@ xfs_file_last_byte( ...@@ -1319,11 +1319,11 @@ xfs_file_last_byte(
last_byte = XFS_FSB_TO_B(mp, last_block); last_byte = XFS_FSB_TO_B(mp, last_block);
if (last_byte < 0) { if (last_byte < 0) {
return XFS_MAX_FILE_OFFSET; return XFS_MAXIOFFSET(mp);
} }
last_byte += (1 << mp->m_writeio_log); last_byte += (1 << mp->m_writeio_log);
if (last_byte < 0) { if (last_byte < 0) {
return XFS_MAX_FILE_OFFSET; return XFS_MAXIOFFSET(mp);
} }
return last_byte; return last_byte;
} }
...@@ -1613,7 +1613,7 @@ xfs_itruncate_finish( ...@@ -1613,7 +1613,7 @@ xfs_itruncate_finish(
* beyond the maximum file size (ie it is the same as last_block), * beyond the maximum file size (ie it is the same as last_block),
* then there is nothing to do. * 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); ASSERT(first_unmap_block <= last_block);
done = 0; done = 0;
if (last_block == first_unmap_block) { if (last_block == first_unmap_block) {
......
...@@ -406,14 +406,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n); ...@@ -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_DEFINITE 0x1
#define XFS_ITRUNC_MAYBE 0x2 #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) #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV)
struct vnode *xfs_itov(xfs_inode_t *ip); struct vnode *xfs_itov(xfs_inode_t *ip);
#define XFS_ITOV(ip) xfs_itov(ip) #define XFS_ITOV(ip) xfs_itov(ip)
......
...@@ -728,6 +728,8 @@ xfs_mountfs( ...@@ -728,6 +728,8 @@ xfs_mountfs(
} else } else
mp->m_maxicount = 0; mp->m_maxicount = 0;
mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
/* /*
* XFS uses the uuid from the superblock as the unique * XFS uses the uuid from the superblock as the unique
* identifier for fsid. We can not use the uuid from the volume * identifier for fsid. We can not use the uuid from the volume
......
...@@ -352,6 +352,7 @@ typedef struct xfs_mount { ...@@ -352,6 +352,7 @@ typedef struct xfs_mount {
uint m_qflags; /* quota status flags */ uint m_qflags; /* quota status flags */
xfs_trans_reservations_t m_reservations;/* precomputed res values */ xfs_trans_reservations_t m_reservations;/* precomputed res values */
__uint64_t m_maxicount; /* maximum inode count */ __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; /* total reserved blocks */
__uint64_t m_resblks_avail;/* available reserved blocks */ __uint64_t m_resblks_avail;/* available reserved blocks */
#if XFS_BIG_FILESYSTEMS #if XFS_BIG_FILESYSTEMS
...@@ -418,8 +419,6 @@ typedef struct xfs_mount { ...@@ -418,8 +419,6 @@ typedef struct xfs_mount {
* 32 bits in size */ * 32 bits in size */
#define XFS_MOUNT_NOLOGFLUSH 0x00010000 #define XFS_MOUNT_NOLOGFLUSH 0x00010000
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
/* /*
* Default minimum read and write sizes. * Default minimum read and write sizes.
*/ */
...@@ -444,6 +443,9 @@ typedef struct xfs_mount { ...@@ -444,6 +443,9 @@ typedef struct xfs_mount {
#define XFS_WSYNC_READIO_LOG 15 /* 32K */ #define XFS_WSYNC_READIO_LOG 15 /* 32K */
#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */ #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) \ #define xfs_force_shutdown(m,f) \
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
......
/* /*
* 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 * 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
...@@ -1287,7 +1287,7 @@ xfs_inactive_free_eofblocks( ...@@ -1287,7 +1287,7 @@ xfs_inactive_free_eofblocks(
* of the file. If not, then there is nothing to do. * 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)); 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; map_len = last_fsb - end_fsb;
if (map_len <= 0) if (map_len <= 0)
return (0); return (0);
...@@ -4612,9 +4612,9 @@ xfs_change_file_space( ...@@ -4612,9 +4612,9 @@ xfs_change_file_space(
llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len;
if ( (bf->l_start < 0) 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 < 0)
|| (bf->l_start + llen > XFS_MAX_FILE_OFFSET)) || (bf->l_start + llen > XFS_MAXIOFFSET(mp)))
return XFS_ERROR(EINVAL); return XFS_ERROR(EINVAL);
bf->l_whence = 0; 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