diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-22 05:11:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-22 05:11:54 -0700 |
commit | 786501bbcef901e24a6648fe59017392df3ed1bf (patch) | |
tree | 34ec10333fb6cbe50eea526f4166f99e6f63bc31 /fs | |
parent | b1dcc3d1f1f15a242e2f8c7c521bc5bf009d9888 (diff) | |
parent | 4ee6c244e947c7bbb38b41ded0bd3a2dc12a61b2 (diff) | |
download | history-786501bbcef901e24a6648fe59017392df3ed1bf.tar.gz |
Merge http://xfs.org:8090/xfs-linux-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'fs')
55 files changed, 775 insertions, 396 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 09f81b3793e12e..6db9fb85a4b63a 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -71,6 +71,7 @@ xfs-$(CONFIG_XFS_POSIX_CAP) += xfs_cap.o xfs-$(CONFIG_XFS_POSIX_MAC) += xfs_mac.o xfs-$(CONFIG_PROC_FS) += linux-2.6/xfs_stats.o xfs-$(CONFIG_SYSCTL) += linux-2.6/xfs_sysctl.o +xfs-$(CONFIG_COMPAT) += linux-2.6/xfs_ioctl32.o xfs-y += xfs_alloc.o \ diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 7122efdba49160..ef8bd10688fc04 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -234,6 +234,7 @@ xfs_map_at_offset( sector_shift = block_bits - BBSHIFT; bn = iomapp->iomap_bn >> sector_shift; bn += delta; + BUG_ON(!bn && !(iomapp->iomap_flags & IOMAP_REALTIME)); ASSERT((bn << sector_shift) >= iomapp->iomap_bn); lock_buffer(bh); @@ -264,7 +265,7 @@ xfs_probe_unwritten_page( page = find_trylock_page(mapping, index); if (!page) - return 0; + return NULL; if (PageWriteback(page)) goto out; @@ -938,9 +939,8 @@ linvfs_get_block_core( bn = iomap.iomap_bn >> (inode->i_blkbits - BBSHIFT); bn += delta; - + BUG_ON(!bn && !(iomap.iomap_flags & IOMAP_REALTIME)); bh_result->b_blocknr = bn; - bh_result->b_bdev = iomap.iomap_target->pbr_bdev; set_buffer_mapped(bh_result); } if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) { @@ -965,21 +965,18 @@ linvfs_get_block_core( } if (iomap.iomap_flags & IOMAP_DELAY) { - if (unlikely(direct)) - BUG(); + BUG_ON(direct); if (create) { set_buffer_mapped(bh_result); set_buffer_uptodate(bh_result); } - bh_result->b_bdev = iomap.iomap_target->pbr_bdev; set_buffer_delay(bh_result); } if (blocks) { - loff_t iosize; - iosize = (iomap.iomap_bsize - iomap.iomap_delta); - bh_result->b_size = - (ssize_t)min(iosize, (loff_t)(blocks << inode->i_blkbits)); + bh_result->b_size = (ssize_t)min( + (loff_t)(iomap.iomap_bsize - iomap.iomap_delta), + (loff_t)(blocks << inode->i_blkbits)); } return 0; @@ -997,17 +994,6 @@ linvfs_get_block( } STATIC int -linvfs_get_block_sync( - struct inode *inode, - sector_t iblock, - struct buffer_head *bh_result, - int create) -{ - return linvfs_get_block_core(inode, iblock, 0, bh_result, - create, 0, BMAPI_SYNC|BMAPI_WRITE); -} - -STATIC int linvfs_get_blocks_direct( struct inode *inode, sector_t iblock, @@ -1261,13 +1247,7 @@ linvfs_prepare_write( unsigned int from, unsigned int to) { - if (file && (file->f_flags & O_SYNC)) { - return block_prepare_write(page, from, to, - linvfs_get_block_sync); - } else { - return block_prepare_write(page, from, to, - linvfs_get_block); - } + return block_prepare_write(page, from, to, linvfs_get_block); } struct address_space_operations linvfs_aops = { diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index ed8abf22dac92b..77c1ccaf37da5f 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1484,6 +1484,7 @@ xfs_free_buftarg( xfs_flush_buftarg(btp, 1); if (external) xfs_blkdev_put(btp->pbr_bdev); + iput(btp->pbr_mapping->host); kmem_free(btp, sizeof(*btp)); } @@ -1497,7 +1498,7 @@ xfs_incore_relse( truncate_inode_pages(btp->pbr_mapping, 0LL); } -void +int xfs_setsize_buftarg( xfs_buftarg_t *btp, unsigned int blocksize, @@ -1511,7 +1512,42 @@ xfs_setsize_buftarg( printk(KERN_WARNING "XFS: Cannot set_blocksize to %u on device %s\n", sectorsize, XFS_BUFTARG_NAME(btp)); + return EINVAL; + } + return 0; +} + +STATIC int +xfs_mapping_buftarg( + xfs_buftarg_t *btp, + struct block_device *bdev) +{ + struct backing_dev_info *bdi; + struct inode *inode; + struct address_space *mapping; + static struct address_space_operations mapping_aops = { + .sync_page = block_sync_page, + }; + + inode = new_inode(bdev->bd_inode->i_sb); + if (!inode) { + printk(KERN_WARNING + "XFS: Cannot allocate mapping inode for device %s\n", + XFS_BUFTARG_NAME(btp)); + return ENOMEM; } + inode->i_mode = S_IFBLK; + inode->i_bdev = bdev; + inode->i_rdev = bdev->bd_dev; + bdi = blk_get_backing_dev_info(bdev); + if (!bdi) + bdi = &default_backing_dev_info; + mapping = &inode->i_data; + mapping->a_ops = &mapping_aops; + mapping->backing_dev_info = bdi; + mapping_set_gfp_mask(mapping, GFP_KERNEL); + btp->pbr_mapping = mapping; + return 0; } xfs_buftarg_t * @@ -1524,10 +1560,15 @@ xfs_alloc_buftarg( btp->pbr_dev = bdev->bd_dev; btp->pbr_bdev = bdev; - btp->pbr_mapping = bdev->bd_inode->i_mapping; - xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev)); - + if (xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev))) + goto error; + if (xfs_mapping_buftarg(btp, bdev)) + goto error; return btp; + +error: + kmem_free(btp, sizeof(*btp)); + return NULL; } diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 7bebfd65a7fca0..242ba07d6168b9 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -566,7 +566,7 @@ static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *); extern void xfs_free_buftarg(xfs_buftarg_t *, int); -extern void xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); +extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); extern void xfs_incore_relse(xfs_buftarg_t *, int, int); extern int xfs_flush_buftarg(xfs_buftarg_t *, int); diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index e8e02f501013fd..eca2c32f8be8a4 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -61,7 +61,7 @@ static struct vm_operations_struct linvfs_file_vm_ops; STATIC inline ssize_t __linvfs_read( struct kiocb *iocb, - char __user *buf, + char __user *buf, int ioflags, size_t count, loff_t pos) @@ -83,7 +83,7 @@ __linvfs_read( STATIC ssize_t linvfs_read( struct kiocb *iocb, - char __user *buf, + char __user *buf, size_t count, loff_t pos) { @@ -93,7 +93,7 @@ linvfs_read( STATIC ssize_t linvfs_read_invis( struct kiocb *iocb, - char __user *buf, + char __user *buf, size_t count, loff_t pos) { @@ -104,12 +104,12 @@ linvfs_read_invis( STATIC inline ssize_t __linvfs_write( struct kiocb *iocb, - const char *buf, + const char __user *buf, int ioflags, size_t count, loff_t pos) { - struct iovec iov = {(void *)buf, count}; + struct iovec iov = {(void __user *)buf, count}; struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; vnode_t *vp = LINVFS_GET_VP(inode); @@ -134,7 +134,7 @@ __linvfs_write( STATIC ssize_t linvfs_write( struct kiocb *iocb, - const char __user *buf, + const char __user *buf, size_t count, loff_t pos) { @@ -144,7 +144,7 @@ linvfs_write( STATIC ssize_t linvfs_write_invis( struct kiocb *iocb, - const char __user *buf, + const char __user *buf, size_t count, loff_t pos) { @@ -259,7 +259,7 @@ linvfs_sendfile( loff_t *ppos, size_t count, read_actor_t actor, - void *target) + void __user *target) { vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode); ssize_t rval; @@ -442,7 +442,7 @@ linvfs_ioctl( vnode_t *vp = LINVFS_GET_VP(inode); unlock_kernel(); - VOP_IOCTL(vp, inode, filp, 0, cmd, arg, error); + VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); VMODIFY(vp); lock_kernel(); @@ -467,7 +467,7 @@ linvfs_ioctl_invis( unlock_kernel(); ASSERT(vp); - VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, arg, error); + VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); VMODIFY(vp); lock_kernel(); diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index e348ef84944a90..ef764054fcdf4b 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -73,14 +73,6 @@ #include <linux/pagemap.h> /* - * ioctl commands that are used by Linux filesystems - */ -#define XFS_IOC_GETXFLAGS _IOR('f', 1, long) -#define XFS_IOC_SETXFLAGS _IOW('f', 2, long) -#define XFS_IOC_GETVERSION _IOR('v', 1, long) - - -/* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to * a file or fs handle. * @@ -94,7 +86,7 @@ STATIC int xfs_find_handle( unsigned int cmd, - unsigned long arg) + void __user *arg) { int hsize; xfs_handle_t handle; @@ -102,7 +94,7 @@ xfs_find_handle( struct inode *inode; struct vnode *vp; - if (copy_from_user(&hreq, (xfs_fsop_handlereq_t *)arg, sizeof(hreq))) + if (copy_from_user(&hreq, arg, sizeof(hreq))) return -XFS_ERROR(EFAULT); memset((char *)&handle, 0, sizeof(handle)); @@ -113,7 +105,7 @@ xfs_find_handle( struct nameidata nd; int error; - error = user_path_walk_link(hreq.path, &nd); + error = user_path_walk_link((const char __user *)hreq.path, &nd); if (error) return error; @@ -185,7 +177,7 @@ xfs_find_handle( } /* now copy our handle into the user buffer & write out the size */ - if (copy_to_user((xfs_handle_t *)hreq.ohandle, &handle, hsize) || + if (copy_to_user(hreq.ohandle, &handle, hsize) || copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) { iput(inode); return -XFS_ERROR(EFAULT); @@ -211,14 +203,14 @@ xfs_vget_fsop_handlereq( xfs_mount_t *mp, struct inode *parinode, /* parent inode pointer */ int cap, /* capability level for op */ - unsigned long arg, /* userspace data pointer */ + void __user *arg, /* userspace data pointer */ unsigned long size, /* size of expected struct */ /* output arguments */ xfs_fsop_handlereq_t *hreq, vnode_t **vp, struct inode **inode) { - void *hanp; + void __user *hanp; size_t hlen; xfs_fid_t *xfid; xfs_handle_t *handlep; @@ -243,7 +235,7 @@ xfs_vget_fsop_handlereq( * Copy the handle down from the user and validate * that it looks to be in the correct format. */ - if (copy_from_user(hreq, (struct xfs_fsop_handlereq *)arg, size)) + if (copy_from_user(hreq, arg, size)) return XFS_ERROR(EFAULT); hanp = hreq->ihandle; @@ -300,7 +292,7 @@ xfs_vget_fsop_handlereq( STATIC int xfs_open_by_handle( xfs_mount_t *mp, - unsigned long arg, + void __user *arg, struct file *parfilp, struct inode *parinode) { @@ -383,7 +375,7 @@ xfs_open_by_handle( STATIC int xfs_readlink_by_handle( xfs_mount_t *mp, - unsigned long arg, + void __user *arg, struct file *parfilp, struct inode *parinode) { @@ -429,7 +421,7 @@ xfs_readlink_by_handle( STATIC int xfs_fssetdm_by_handle( xfs_mount_t *mp, - unsigned long arg, + void __user *arg, struct file *parfilp, struct inode *parinode) { @@ -469,7 +461,7 @@ xfs_fssetdm_by_handle( STATIC int xfs_attrlist_by_handle( xfs_mount_t *mp, - unsigned long arg, + void __user *arg, struct file *parfilp, struct inode *parinode) { @@ -498,7 +490,7 @@ xfs_attrlist_by_handle( STATIC int xfs_attrmulti_by_handle( xfs_mount_t *mp, - unsigned long arg, + void __user *arg, struct file *parfilp, struct inode *parinode) { @@ -577,23 +569,23 @@ xfs_ioc_space( struct file *filp, int flags, unsigned int cmd, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_bulkstat( xfs_mount_t *mp, unsigned int cmd, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_fsgeometry_v1( xfs_mount_t *mp, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_fsgeometry( xfs_mount_t *mp, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_xattr( @@ -601,7 +593,7 @@ xfs_ioc_xattr( xfs_inode_t *ip, struct file *filp, unsigned int cmd, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_getbmap( @@ -609,12 +601,12 @@ xfs_ioc_getbmap( struct file *filp, int flags, unsigned int cmd, - unsigned long arg); + void __user *arg); STATIC int xfs_ioc_getbmapx( bhv_desc_t *bdp, - unsigned long arg); + void __user *arg); int xfs_ioctl( @@ -623,7 +615,7 @@ xfs_ioctl( struct file *filp, int ioflags, unsigned int cmd, - unsigned long arg) + void __user *arg) { int error; vnode_t *vp; @@ -667,7 +659,7 @@ xfs_ioctl( /* The size dio will do in one go */ da.d_maxiosz = 64 * PAGE_CACHE_SIZE; - if (copy_to_user((struct dioattr *)arg, &da, sizeof(da))) + if (copy_to_user(arg, &da, sizeof(da))) return -XFS_ERROR(EFAULT); return 0; } @@ -694,7 +686,7 @@ xfs_ioctl( case XFS_IOC_FSSETDM: { struct fsdmidata dmi; - if (copy_from_user(&dmi, (struct fsdmidata *)arg, sizeof(dmi))) + if (copy_from_user(&dmi, arg, sizeof(dmi))) return -XFS_ERROR(EFAULT); error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate, @@ -730,7 +722,7 @@ xfs_ioctl( return xfs_attrmulti_by_handle(mp, arg, filp, inode); case XFS_IOC_SWAPEXT: { - error = xfs_swapext((struct xfs_swapext *)arg); + error = xfs_swapext((struct xfs_swapext __user *)arg); return -error; } @@ -741,7 +733,7 @@ xfs_ioctl( if (error) return -error; - if (copy_to_user((char *)arg, &out, sizeof(out))) + if (copy_to_user(arg, &out, sizeof(out))) return -XFS_ERROR(EFAULT); return 0; } @@ -753,7 +745,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user(&inout, (char *)arg, sizeof(inout))) + if (copy_from_user(&inout, arg, sizeof(inout))) return -XFS_ERROR(EFAULT); /* input parameter is passed in resblks field of structure */ @@ -762,7 +754,7 @@ xfs_ioctl( if (error) return -error; - if (copy_to_user((char *)arg, &inout, sizeof(inout))) + if (copy_to_user(arg, &inout, sizeof(inout))) return -XFS_ERROR(EFAULT); return 0; } @@ -777,7 +769,7 @@ xfs_ioctl( if (error) return -error; - if (copy_to_user((char *)arg, &out, sizeof(out))) + if (copy_to_user(arg, &out, sizeof(out))) return -XFS_ERROR(EFAULT); return 0; @@ -789,7 +781,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user(&in, (char *)arg, sizeof(in))) + if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_data(mp, &in); @@ -802,7 +794,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user(&in, (char *)arg, sizeof(in))) + if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_log(mp, &in); @@ -815,7 +807,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user(&in, (char *)arg, sizeof(in))) + if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_growfs_rt(mp, &in); @@ -841,7 +833,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (get_user(in, (__uint32_t *)arg)) + if (get_user(in, (__uint32_t __user *)arg)) return -XFS_ERROR(EFAULT); error = xfs_fs_goingdown(mp, in); @@ -854,7 +846,7 @@ xfs_ioctl( if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (copy_from_user(&in, (char *)arg, sizeof(in))) + if (copy_from_user(&in, arg, sizeof(in))) return -XFS_ERROR(EFAULT); error = xfs_errortag_add(in.errtag, mp); @@ -880,7 +872,7 @@ xfs_ioc_space( struct file *filp, int ioflags, unsigned int cmd, - unsigned long arg) + void __user *arg) { xfs_flock64_t bf; int attr_flags = 0; @@ -895,7 +887,7 @@ xfs_ioc_space( if (vp->v_type != VREG) return -XFS_ERROR(EINVAL); - if (copy_from_user(&bf, (xfs_flock64_t *)arg, sizeof(bf))) + if (copy_from_user(&bf, arg, sizeof(bf))) return -XFS_ERROR(EFAULT); if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) @@ -912,7 +904,7 @@ STATIC int xfs_ioc_bulkstat( xfs_mount_t *mp, unsigned int cmd, - unsigned long arg) + void __user *arg) { xfs_fsop_bulkreq_t bulkreq; int count; /* # of records returned */ @@ -929,12 +921,10 @@ xfs_ioc_bulkstat( if (XFS_FORCED_SHUTDOWN(mp)) return -XFS_ERROR(EIO); - if (copy_from_user(&bulkreq, (xfs_fsop_bulkreq_t *)arg, - sizeof(xfs_fsop_bulkreq_t))) + if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t))) return -XFS_ERROR(EFAULT); - if (copy_from_user(&inlast, (__s64 *)bulkreq.lastip, - sizeof(__s64))) + if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) return -XFS_ERROR(EFAULT); if ((count = bulkreq.icount) <= 0) @@ -963,12 +953,11 @@ xfs_ioc_bulkstat( return -error; if (bulkreq.ocount != NULL) { - if (copy_to_user((xfs_ino_t *)bulkreq.lastip, &inlast, + if (copy_to_user(bulkreq.lastip, &inlast, sizeof(xfs_ino_t))) return -XFS_ERROR(EFAULT); - if (copy_to_user((__s32 *)bulkreq.ocount, &count, - sizeof(count))) + if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) return -XFS_ERROR(EFAULT); } @@ -978,7 +967,7 @@ xfs_ioc_bulkstat( STATIC int xfs_ioc_fsgeometry_v1( xfs_mount_t *mp, - unsigned long arg) + void __user *arg) { xfs_fsop_geom_v1_t fsgeo; int error; @@ -987,7 +976,7 @@ xfs_ioc_fsgeometry_v1( if (error) return -error; - if (copy_to_user((xfs_fsop_geom_t *)arg, &fsgeo, sizeof(fsgeo))) + if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) return -XFS_ERROR(EFAULT); return 0; } @@ -995,7 +984,7 @@ xfs_ioc_fsgeometry_v1( STATIC int xfs_ioc_fsgeometry( xfs_mount_t *mp, - unsigned long arg) + void __user *arg) { xfs_fsop_geom_t fsgeo; int error; @@ -1004,7 +993,7 @@ xfs_ioc_fsgeometry( if (error) return -error; - if (copy_to_user((xfs_fsop_geom_t *)arg, &fsgeo, sizeof(fsgeo))) + if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) return -XFS_ERROR(EFAULT); return 0; } @@ -1074,7 +1063,7 @@ xfs_ioc_xattr( xfs_inode_t *ip, struct file *filp, unsigned int cmd, - unsigned long arg) + void __user *arg) { struct fsxattr fa; vattr_t va; @@ -1093,13 +1082,13 @@ xfs_ioc_xattr( fa.fsx_extsize = va.va_extsize; fa.fsx_nextents = va.va_nextents; - if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa))) + if (copy_to_user(arg, &fa, sizeof(fa))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_FSSETXATTR: { - if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa))) + if (copy_from_user(&fa, arg, sizeof(fa))) return -XFS_ERROR(EFAULT); attr_flags = 0; @@ -1126,20 +1115,20 @@ xfs_ioc_xattr( fa.fsx_extsize = va.va_extsize; fa.fsx_nextents = va.va_anextents; - if (copy_to_user((struct fsxattr *)arg, &fa, sizeof(fa))) + if (copy_to_user(arg, &fa, sizeof(fa))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_GETXFLAGS: { flags = xfs_di2lxflags(ip->i_d.di_flags); - if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags))) + if (copy_to_user(arg, &flags, sizeof(flags))) return -XFS_ERROR(EFAULT); return 0; } case XFS_IOC_SETXFLAGS: { - if (copy_from_user(&flags, (unsigned int *)arg, sizeof(flags))) + if (copy_from_user(&flags, arg, sizeof(flags))) return -XFS_ERROR(EFAULT); if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \ @@ -1163,7 +1152,7 @@ xfs_ioc_xattr( case XFS_IOC_GETVERSION: { flags = LINVFS_GET_IP(vp)->i_generation; - if (copy_to_user((unsigned int *)arg, &flags, sizeof(flags))) + if (copy_to_user(arg, &flags, sizeof(flags))) return -XFS_ERROR(EFAULT); return 0; } @@ -1179,13 +1168,13 @@ xfs_ioc_getbmap( struct file *filp, int ioflags, unsigned int cmd, - unsigned long arg) + void __user *arg) { struct getbmap bm; int iflags; int error; - if (copy_from_user(&bm, (struct getbmap *)arg, sizeof(bm))) + if (copy_from_user(&bm, arg, sizeof(bm))) return -XFS_ERROR(EFAULT); if (bm.bmv_count < 2) @@ -1195,11 +1184,11 @@ xfs_ioc_getbmap( if (ioflags & IO_INVIS) iflags |= BMV_IF_NO_DMAPI_READ; - error = xfs_getbmap(bdp, &bm, (struct getbmap *)arg+1, iflags); + error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags); if (error) return -error; - if (copy_to_user((struct getbmap *)arg, &bm, sizeof(bm))) + if (copy_to_user(arg, &bm, sizeof(bm))) return -XFS_ERROR(EFAULT); return 0; } @@ -1207,14 +1196,14 @@ xfs_ioc_getbmap( STATIC int xfs_ioc_getbmapx( bhv_desc_t *bdp, - unsigned long arg) + void __user *arg) { struct getbmapx bmx; struct getbmap bm; int iflags; int error; - if (copy_from_user(&bmx, (struct getbmapx *)arg, sizeof(bmx))) + if (copy_from_user(&bmx, arg, sizeof(bmx))) return -XFS_ERROR(EFAULT); if (bmx.bmv_count < 2) @@ -1233,13 +1222,13 @@ xfs_ioc_getbmapx( iflags |= BMV_IF_EXTENDED; - error = xfs_getbmap(bdp, &bm, (struct getbmapx *)arg+1, iflags); + error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags); if (error) return -error; GETBMAP_CONVERT(bm, bmx); - if (copy_to_user((struct getbmapx *)arg, &bmx, sizeof(bmx))) + if (copy_to_user(arg, &bmx, sizeof(bmx))) return -XFS_ERROR(EFAULT); return 0; diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c new file mode 100644 index 00000000000000..1df29c130bce70 --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include <linux/config.h> +#include <linux/compat.h> +#include <linux/init.h> +#include <linux/ioctl.h> +#include <linux/ioctl32.h> +#include <linux/syscalls.h> +#include <linux/types.h> +#include <asm/uaccess.h> + +#include "xfs_types.h" +#include "xfs_fs.h" +#include "xfs_dfrag.h" + +#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) +#define BROKEN_X86_ALIGNMENT +#endif + + +typedef struct xfs_fsop_bulkreq32 { + compat_uptr_t lastip; /* last inode # pointer */ + __s32 icount; /* count of entries in buffer */ + compat_uptr_t ubuffer; /* user buffer for inode desc. */ + __s32 ocount; /* output count pointer */ +} xfs_fsop_bulkreq32_t; + +static int +xfs_ioctl32_bulkstat( + unsigned int fd, + unsigned int cmd, + unsigned long arg, + struct file * file) +{ + xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; + xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); + u32 addr; + + if (get_user(addr, &p32->lastip) || + put_user(compat_ptr(addr), &p->lastip) || + copy_in_user(&p->icount, &p32->icount, sizeof(s32)) || + get_user(addr, &p32->ubuffer) || + put_user(compat_ptr(addr), &p->ubuffer) || + get_user(addr, &p32->ocount) || + put_user(compat_ptr(addr), &p->ocount)) + return -EFAULT; + + return sys_ioctl(fd, cmd, (unsigned long)p); +} + +struct ioctl_trans xfs_ioctl32_trans[] = { + { XFS_IOC_DIOINFO, }, + { XFS_IOC_FSGEOMETRY_V1, }, + { XFS_IOC_FSGEOMETRY, }, + { XFS_IOC_GETVERSION, }, + { XFS_IOC_GETXFLAGS, }, + { XFS_IOC_SETXFLAGS, }, + { XFS_IOC_FSGETXATTR, }, + { XFS_IOC_FSSETXATTR, }, + { XFS_IOC_FSGETXATTRA, }, + { XFS_IOC_FSSETDM, }, + { XFS_IOC_GETBMAP, }, + { XFS_IOC_GETBMAPA, }, + { XFS_IOC_GETBMAPX, }, +/* not handled + { XFS_IOC_FD_TO_HANDLE, }, + { XFS_IOC_PATH_TO_HANDLE, }, + { XFS_IOC_PATH_TO_HANDLE, }, + { XFS_IOC_PATH_TO_FSHANDLE, }, + { XFS_IOC_OPEN_BY_HANDLE, }, + { XFS_IOC_FSSETDM_BY_HANDLE, }, + { XFS_IOC_READLINK_BY_HANDLE, }, + { XFS_IOC_ATTRLIST_BY_HANDLE, }, + { XFS_IOC_ATTRMULTI_BY_HANDLE, }, +*/ + { XFS_IOC_FSCOUNTS, NULL, }, + { XFS_IOC_SET_RESBLKS, NULL, }, + { XFS_IOC_GET_RESBLKS, NULL, }, + { XFS_IOC_FSGROWFSDATA, NULL, }, + { XFS_IOC_FSGROWFSLOG, NULL, }, + { XFS_IOC_FSGROWFSRT, NULL, }, + { XFS_IOC_FREEZE, NULL, }, + { XFS_IOC_THAW, NULL, }, + { XFS_IOC_GOINGDOWN, NULL, }, + { XFS_IOC_ERROR_INJECTION, NULL, }, + { XFS_IOC_ERROR_CLEARALL, NULL, }, +#ifndef BROKEN_X86_ALIGNMENT + /* xfs_flock_t and xfs_bstat_t have wrong u32 vs u64 alignment */ + { XFS_IOC_ALLOCSP, }, + { XFS_IOC_FREESP, }, + { XFS_IOC_RESVSP, }, + { XFS_IOC_UNRESVSP, }, + { XFS_IOC_ALLOCSP64, }, + { XFS_IOC_FREESP64, }, + { XFS_IOC_RESVSP64, }, + { XFS_IOC_UNRESVSP64, }, + { XFS_IOC_SWAPEXT, }, + { XFS_IOC_FSBULKSTAT_SINGLE, xfs_ioctl32_bulkstat }, + { XFS_IOC_FSBULKSTAT, xfs_ioctl32_bulkstat}, + { XFS_IOC_FSINUMBERS, xfs_ioctl32_bulkstat}, +#endif + { 0, }, +}; + +int __init +xfs_ioctl32_init(void) +{ + int error, i; + + for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++) { + error = register_ioctl32_conversion(xfs_ioctl32_trans[i].cmd, + xfs_ioctl32_trans[i].handler); + if (error) + goto fail; + } + + return 0; + + fail: + while (--i) + unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd); + return error; +} + +void +xfs_ioctl32_exit(void) +{ + int i; + + for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++) + unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd); +} diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h new file mode 100644 index 00000000000000..0e24f08a9105ca --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_ioctl32.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include <linux/config.h> + +#ifdef CONFIG_COMPAT +extern int xfs_ioctl32_init(void); +extern void xfs_ioctl32_exit(void); +#else +static inline int xfs_ioctl32_init(void) { return 0; } +static inline void xfs_ioctl32_exit(void) { } +#endif diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index a76f59645b64ec..e9136b50e94d92 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -376,7 +376,7 @@ linvfs_rename( STATIC int linvfs_readlink( struct dentry *dentry, - char *buf, + char __user *buf, int size) { vnode_t *vp = LINVFS_GET_VP(dentry->d_inode); diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h index f0f5c870f1a8d1..6a69a62c36b033 100644 --- a/fs/xfs/linux-2.6/xfs_iops.h +++ b/fs/xfs/linux-2.6/xfs_iops.h @@ -46,6 +46,6 @@ extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int) extern void linvfs_unwritten_done(struct buffer_head *, int); extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *, - int, unsigned int, unsigned long); + int, unsigned int, void __user *); #endif /* __XFS_IOPS_H__ */ diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index c45e9639ca28d5..ae16c6f959c08c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -81,7 +81,7 @@ void xfs_rw_enter_trace( int tag, xfs_iocore_t *io, - const struct iovec *iovp, + void *data, size_t segs, loff_t offset, int ioflags) @@ -95,7 +95,7 @@ xfs_rw_enter_trace( (void *)ip, (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), - (void *)(__psint_t)iovp, + (void *)data, (void *)((unsigned long)segs), (void *)((unsigned long)((offset >> 32) & 0xffffffff)), (void *)((unsigned long)(offset & 0xffffffff)), @@ -345,7 +345,7 @@ xfs_read( } xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, - iovp, segs, *offset, ioflags); + (void *)iovp, segs, *offset, ioflags); ret = __generic_file_aio_read(iocb, iovp, segs, offset); xfs_iunlock(ip, XFS_IOLOCK_SHARED); @@ -366,7 +366,7 @@ xfs_sendfile( int ioflags, size_t count, read_actor_t actor, - void *target, + void __user *target, cred_t *credp) { ssize_t ret; @@ -406,7 +406,7 @@ xfs_sendfile( } } xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore, - target, count, *offset, ioflags); + (void*)(unsigned long)target, count, *offset, ioflags); ret = generic_file_sendfile(filp, offset, count, actor, target); xfs_iunlock(ip, XFS_IOLOCK_SHARED); @@ -805,10 +805,10 @@ retry: if (ioflags & IO_ISDIRECT) { xfs_inval_cached_pages(vp, io, *offset, 1, 1); xfs_rw_enter_trace(XFS_DIOWR_ENTER, - io, iovp, segs, *offset, ioflags); + io, (void *)iovp, segs, *offset, ioflags); } else { xfs_rw_enter_trace(XFS_WRITE_ENTER, - io, iovp, segs, *offset, ioflags); + io, (void *)iovp, segs, *offset, ioflags); } ret = generic_file_aio_write_nolock(iocb, iovp, segs, offset); diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index faf0afc7026065..d33af13308e593 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h @@ -74,11 +74,11 @@ struct xfs_iomap; #define XFS_IOMAP_ALLOC_MAP 25 #define XFS_IOMAP_UNWRITTEN 26 extern void xfs_rw_enter_trace(int, struct xfs_iocore *, - const struct iovec *, size_t, loff_t, int); + void *, size_t, loff_t, int); extern void xfs_inval_cached_trace(struct xfs_iocore *, - xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t); + xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t); #else -#define xfs_rw_enter_trace(tag, io, iovec, segs, offset, ioflags) +#define xfs_rw_enter_trace(tag, io, data, size, offset, ioflags) #define xfs_inval_cached_trace(io, offset, len, first, last) #endif @@ -104,7 +104,7 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, loff_t *, int, struct cred *); extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, loff_t *, int, size_t, read_actor_t, - void *, struct cred *); + void __user *, struct cred *); extern int xfs_dev_is_read_only(struct xfs_mount *, char *); diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c index 86b633e7a20a36..aaf5ddba47f300 100644 --- a/fs/xfs/linux-2.6/xfs_stats.c +++ b/fs/xfs/linux-2.6/xfs_stats.c @@ -119,9 +119,9 @@ xfs_read_xfsstats( void xfs_init_procfs(void) { - if (!proc_mkdir("fs/xfs", 0)) + if (!proc_mkdir("fs/xfs", NULL)) return; - create_proc_read_entry("fs/xfs/stat", 0, 0, xfs_read_xfsstats, NULL); + create_proc_read_entry("fs/xfs/stat", 0, NULL, xfs_read_xfsstats, NULL); } void diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 00818cd70e7ddc..fc7d4ce32f0887 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -66,6 +66,7 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_version.h" +#include "xfs_ioctl32.h" #include <linux/namei.h> #include <linux/init.h> @@ -573,7 +574,7 @@ linvfs_get_parent( dotdot.d_name.name = ".."; dotdot.d_name.len = 2; - dotdot.d_inode = 0; + dotdot.d_inode = NULL; cvp = NULL; vp = LINVFS_GET_VP(child->d_inode); @@ -857,6 +858,10 @@ init_xfs_fs( void ) goto undo_shaker; } + error = xfs_ioctl32_init(); + if (error) + goto undo_ioctl32; + error = register_filesystem(&xfs_fs_type); if (error) goto undo_register; @@ -864,6 +869,9 @@ init_xfs_fs( void ) return 0; undo_register: + xfs_ioctl32_exit(); + +undo_ioctl32: kmem_shake_deregister(xfs_inode_shaker); undo_shaker: @@ -882,6 +890,7 @@ exit_xfs_fs( void ) vfs_exitquota(); XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); + xfs_ioctl32_exit(); kmem_shake_deregister(xfs_inode_shaker); xfs_cleanup(); pagebuf_terminate(); diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c index 4a173d3d8916bd..670422a10378fd 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.c +++ b/fs/xfs/linux-2.6/xfs_sysctl.c @@ -45,7 +45,7 @@ xfs_stats_clear_proc_handler( ctl_table *ctl, int write, struct file *filp, - void *buffer, + void __user *buffer, size_t *lenp, loff_t *ppos) { diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 9240efb2b86249..d85452f9c04f21 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c @@ -188,13 +188,51 @@ vn_get( } /* + * Revalidate the Linux inode from the vattr. + * Note: i_size _not_ updated; we must hold the inode + * semaphore when doing that - callers responsibility. + */ +void +vn_revalidate_core( + struct vnode *vp, + vattr_t *vap) +{ + struct inode *inode = LINVFS_GET_IP(vp); + + inode = LINVFS_GET_IP(vp); + inode->i_mode = VTTOIF(vap->va_type) | vap->va_mode; + inode->i_nlink = vap->va_nlink; + inode->i_uid = vap->va_uid; + inode->i_gid = vap->va_gid; + inode->i_blocks = vap->va_nblocks; + inode->i_mtime = vap->va_mtime; + inode->i_ctime = vap->va_ctime; + inode->i_atime = vap->va_atime; + if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) + inode->i_flags |= S_IMMUTABLE; + else + inode->i_flags &= ~S_IMMUTABLE; + if (vap->va_xflags & XFS_XFLAG_APPEND) + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; + if (vap->va_xflags & XFS_XFLAG_SYNC) + inode->i_flags |= S_SYNC; + else + inode->i_flags &= ~S_SYNC; + if (vap->va_xflags & XFS_XFLAG_NOATIME) + inode->i_flags |= S_NOATIME; + else + inode->i_flags &= ~S_NOATIME; +} + +/* * Revalidate the Linux inode from the vnode. */ int vn_revalidate( struct vnode *vp) { - struct inode *inode; vattr_t va; int error; @@ -204,31 +242,7 @@ vn_revalidate( va.va_mask = XFS_AT_STAT|XFS_AT_XFLAGS; VOP_GETATTR(vp, &va, 0, NULL, error); if (!error) { - inode = LINVFS_GET_IP(vp); - inode->i_mode = VTTOIF(va.va_type) | va.va_mode; - inode->i_nlink = va.va_nlink; - inode->i_uid = va.va_uid; - inode->i_gid = va.va_gid; - inode->i_blocks = va.va_nblocks; - inode->i_mtime = va.va_mtime; - inode->i_ctime = va.va_ctime; - inode->i_atime = va.va_atime; - if (va.va_xflags & XFS_XFLAG_IMMUTABLE) - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; - if (va.va_xflags & XFS_XFLAG_APPEND) - inode->i_flags |= S_APPEND; - else - inode->i_flags &= ~S_APPEND; - if (va.va_xflags & XFS_XFLAG_SYNC) - inode->i_flags |= S_SYNC; - else - inode->i_flags &= ~S_SYNC; - if (va.va_xflags & XFS_XFLAG_NOATIME) - inode->i_flags |= S_NOATIME; - else - inode->i_flags &= ~S_NOATIME; + vn_revalidate_core(vp, &va); VUNMODIFY(vp); } return -error; diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index af0b65fe5136e5..33c89a6e638817 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -192,9 +192,9 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, loff_t *, int, struct cred *); typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, loff_t *, int, size_t, read_actor_t, - void *, struct cred *); + void __user *, struct cred *); typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, - int, unsigned int, unsigned long); + int, unsigned int, void __user *); typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, struct cred *); typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, @@ -532,6 +532,7 @@ typedef struct vnode_map { extern void vn_purge(struct vnode *, vmap_t *); extern vnode_t *vn_get(struct vnode *, vmap_t *); extern int vn_revalidate(struct vnode *); +extern void vn_revalidate_core(struct vnode *, vattr_t *); extern void vn_remove(struct vnode *); static inline int vn_count(struct vnode *vp) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index d1368c92dc31a1..9a26a60419e981 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -145,7 +145,7 @@ xfs_qm_dqinit( dqp->q_res_icount = 0; dqp->q_res_rtbcount = 0; dqp->q_pincount = 0; - dqp->q_hash = 0; + dqp->q_hash = NULL; ASSERT(dqp->dq_flnext == dqp->dq_flprev); #ifdef XFS_DQUOT_TRACE diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 0088d7de4afd42..0138929b5fd5c5 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -229,11 +229,8 @@ xfs_qm_hold_quotafs_ref( */ XFS_QM_LOCK(xfs_Gqm); - if (xfs_Gqm == NULL) { - if ((xfs_Gqm = xfs_Gqm_init()) == NULL) { - return (XFS_ERROR(EINVAL)); - } - } + if (xfs_Gqm == NULL) + xfs_Gqm = xfs_Gqm_init(); /* * We can keep a list of all filesystems with quotas mounted for * debugging and statistical purposes, but ... @@ -1735,7 +1732,7 @@ STATIC int xfs_qm_dqusage_adjust( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode number to get data for */ - void *buffer, /* not used */ + void __user *buffer, /* not used */ int ubsize, /* not used */ void *private_data, /* not used */ xfs_daddr_t bno, /* starting block of inode cluster */ diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index d3553ea4a74ee6..29978e037fee49 100644 --- a/fs/xfs/quota/xfs_qm_stats.c +++ b/fs/xfs/quota/xfs_qm_stats.c @@ -137,8 +137,8 @@ xfs_qm_read_stats( void xfs_qm_init_procfs(void) { - create_proc_read_entry("fs/xfs/xqmstat", 0, 0, xfs_qm_read_stats, NULL); - create_proc_read_entry("fs/xfs/xqm", 0, 0, xfs_qm_read_xfsquota, NULL); + create_proc_read_entry("fs/xfs/xqmstat", 0, NULL, xfs_qm_read_stats, NULL); + create_proc_read_entry("fs/xfs/xqm", 0, NULL, xfs_qm_read_xfsquota, NULL); } void diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 5a0f1ad941e9a6..5a6046b5d3df02 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -1114,7 +1114,7 @@ mutex_t qcheck_lock; cmn_err(CE_DEBUG, "%s (#%d)", title, (int) (l)->qh_nelems); \ for (dqp = (xfs_dqtest_t *)(l)->qh_next; dqp != NULL; \ dqp = (xfs_dqtest_t *)dqp->NXT) { \ - cmn_err(CE_DEBUG, " %d\. \"%d (%s)\" bcnt = %d, icnt = %d", \ + cmn_err(CE_DEBUG, " %d. \"%d (%s)\" bcnt = %d, icnt = %d", \ ++i, dqp->d_id, DQFLAGTO_TYPESTR(dqp), \ dqp->d_bcount, dqp->d_icount); } \ } @@ -1299,7 +1299,7 @@ STATIC int xfs_qm_internalqcheck_adjust( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode number to get data for */ - void *buffer, /* not used */ + void __user *buffer, /* not used */ int ubsize, /* not used */ void *private_data, /* not used */ xfs_daddr_t bno, /* starting block of inode cluster */ diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c index 852a92dc0a958b..3dae14c8c55a14 100644 --- a/fs/xfs/support/ktrace.c +++ b/fs/xfs/support/ktrace.c @@ -30,14 +30,7 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include <linux/types.h> -#include <linux/slab.h> - -#include <xfs_types.h> -#include "kmem.h" -#include "spin.h" -#include "debug.h" -#include "ktrace.h" +#include <xfs.h> static kmem_zone_t *ktrace_hdr_zone; static kmem_zone_t *ktrace_ent_zone; diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c index 9f3d2ebb13bfe9..15b5194f16b29d 100644 --- a/fs/xfs/support/move.c +++ b/fs/xfs/support/move.c @@ -30,13 +30,7 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include <linux/string.h> -#include <linux/errno.h> -#include <asm/uaccess.h> - -#include <xfs_types.h> -#include "debug.h" -#include "move.h" +#include <xfs.h> /* Read from kernel buffer at src to user/kernel buffer defined * by the uio structure. Advance the pointer in the uio struct diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 35e56b7f00abb7..90a8a5e196ca9c 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -95,7 +95,7 @@ extern int xfs_acl_vremove(struct vnode *vp, int); #define _ACL_XFS_IACCESS(i,m,c) (XFS_IFORK_Q(i) ? xfs_acl_iaccess(i,m,c) : -1) #define _ACL_ALLOC(a) ((a) = kmem_zone_alloc(xfs_acl_zone, KM_SLEEP)) -#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)) : 0) +#define _ACL_FREE(a) ((a)? kmem_zone_free(xfs_acl_zone, (a)):(void)0) #else #define xfs_acl_zone_init(zone,name) diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 74cad985b0032f..02337c2a4caad0 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -665,7 +665,7 @@ xfs_alloc_ag_vextent_exact( * Allocate/initialize a cursor for the by-number freespace btree. */ bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_BNO, 0, 0); + args->agno, XFS_BTNUM_BNO, NULL, 0); /* * Lookup bno and minlen in the btree (minlen is irrelevant, really). * Look for the closest free block <= bno, it must contain bno @@ -721,7 +721,7 @@ xfs_alloc_ag_vextent_exact( * Allocate/initialize a cursor for the by-size btree. */ cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_CNT, 0, 0); + args->agno, XFS_BTNUM_CNT, NULL, 0); ASSERT(args->agbno + args->len <= INT_GET(XFS_BUF_TO_AGF(args->agbp)->agf_length, ARCH_CONVERT)); @@ -788,7 +788,7 @@ xfs_alloc_ag_vextent_near( * Get a cursor for the by-size btree. */ cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_CNT, 0, 0); + args->agno, XFS_BTNUM_CNT, NULL, 0); ltlen = 0; bno_cur_lt = bno_cur_gt = NULL; /* @@ -916,7 +916,7 @@ xfs_alloc_ag_vextent_near( * Set up a cursor for the by-bno tree. */ bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, - args->agbp, args->agno, XFS_BTNUM_BNO, 0, 0); + args->agbp, args->agno, XFS_BTNUM_BNO, NULL, 0); /* * Fix up the btree entries. */ @@ -944,7 +944,7 @@ xfs_alloc_ag_vextent_near( * Allocate and initialize the cursor for the leftward search. */ bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_BNO, 0, 0); + args->agno, XFS_BTNUM_BNO, NULL, 0); /* * Lookup <= bno to find the leftward search's starting point. */ @@ -956,7 +956,7 @@ xfs_alloc_ag_vextent_near( * search. */ bno_cur_gt = bno_cur_lt; - bno_cur_lt = 0; + bno_cur_lt = NULL; } /* * Found something. Duplicate the cursor for the rightward search. @@ -1301,7 +1301,7 @@ xfs_alloc_ag_vextent_size( * Allocate and initialize a cursor for the by-size btree. */ cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_CNT, 0, 0); + args->agno, XFS_BTNUM_CNT, NULL, 0); bno_cur = NULL; /* * Look for an entry >= maxlen+alignment-1 blocks. @@ -1406,7 +1406,7 @@ xfs_alloc_ag_vextent_size( * Allocate and initialize a cursor for the by-block tree. */ bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_BNO, 0, 0); + args->agno, XFS_BTNUM_BNO, NULL, 0); if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, rbno, rlen, XFSA_FIXUP_CNT_OK))) goto error0; @@ -1553,7 +1553,7 @@ xfs_free_ag_extent( /* * Allocate and initialize a cursor for the by-block btree. */ - bno_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO, 0, + bno_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO, NULL, 0); cnt_cur = NULL; /* @@ -1613,7 +1613,7 @@ xfs_free_ag_extent( /* * Now allocate and initialize a cursor for the by-size tree. */ - cnt_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT, 0, + cnt_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT, NULL, 0); /* * Have both left and right contiguous neighbors. diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 55c405cc560977..6b5de3a284e3f0 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -263,7 +263,7 @@ xfs_alloc_delrec( /* * Update the cursor so there's one fewer level. */ - xfs_btree_setbuf(cur, level, 0); + xfs_btree_setbuf(cur, level, NULL); cur->bc_nlevels--; } else if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index f1ccb5890665db..e101b3205555c5 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -104,7 +104,6 @@ STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ -#define ATTR_RMTVALUE_TRANSBLKS 8 /* max # of blks in a transaction */ #if defined(XFS_ATTR_TRACE) ktrace_t *xfs_attr_trace_buf; diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index d797f406e9f122..a99ab0428f3c0d 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -1,5 +1,5 @@ /* - * 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 @@ -203,8 +203,6 @@ STATIC void xfs_bmap_check_extents( xfs_inode_t *ip, /* incore inode pointer */ int whichfork); /* data or attr fork */ -#else -#define xfs_bmap_check_extents(ip,w) #endif /* @@ -3429,6 +3427,19 @@ xfs_bmap_do_search_extents( int high; /* high index of binary search */ int low; /* low index of binary search */ + /* Initialize the extent entry structure to catch access to + * uninitialized br_startblock field. + */ + + got.br_startoff = 0xffa5a5a5a5a5a5a5; + got.br_blockcount = 0xa55a5a5a5a5a5a5a; + got.br_state = XFS_EXT_INVALID; + + #if XFS_BIG_BLKNOS + got.br_startblock = 0xffffa5a5a5a5a5a5; + #else + got.br_startblock = 0xffffa5a5; + #endif if (lastx != NULLEXTNUM && lastx < nextents) ep = base + lastx; else @@ -3527,6 +3538,8 @@ xfs_bmap_search_extents( xfs_bmbt_rec_t *base; /* base of extent list */ xfs_extnum_t lastx; /* last extent index used */ xfs_extnum_t nextents; /* extent list size */ + xfs_bmbt_rec_t *ep; /* extent list entry pointer */ + int rt; /* realtime flag */ XFS_STATS_INC(xs_look_exlist); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -3534,8 +3547,18 @@ xfs_bmap_search_extents( nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); base = &ifp->if_u1.if_extents[0]; - return xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, + ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, lastxp, gotp, prevp); + rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME; + if(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM)) { + cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " + "start_block : %llx start_off : %llx blkcnt : %llx " + "extent-state : %x \n", + (ip->i_mount)->m_fsname,(long long)ip->i_ino, + gotp->br_startblock, gotp->br_startoff, + gotp->br_blockcount,gotp->br_state); + } + return ep; } @@ -4689,8 +4712,41 @@ xfs_bmapi( } break; } + + /* + * Split changing sb for alen and indlen since + * they could be coming from different places. + */ + if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { + xfs_extlen_t extsz; + xfs_extlen_t ralen; + if (!(extsz = ip->i_d.di_extsize)) + extsz = mp->m_sb.sb_rextsize; + ralen = roundup(alen, extsz); + ralen = ralen / mp->m_sb.sb_rextsize; + if (xfs_mod_incore_sb(mp, + XFS_SBS_FREXTENTS, + -(ralen), rsvd)) { + if (XFS_IS_QUOTA_ON(ip->i_mount)) + XFS_TRANS_UNRESERVE_BLKQUOTA( + mp, NULL, ip, + (long)alen); + break; + } + } else { + if (xfs_mod_incore_sb(mp, + XFS_SBS_FDBLOCKS, + -(alen), rsvd)) { + if (XFS_IS_QUOTA_ON(ip->i_mount)) + XFS_TRANS_UNRESERVE_BLKQUOTA( + mp, NULL, ip, + (long)alen); + break; + } + } + if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(alen + indlen), rsvd)) { + -(indlen), rsvd)) { XFS_TRANS_UNRESERVE_BLKQUOTA( mp, NULL, ip, (long)alen); break; @@ -5445,7 +5501,7 @@ int /* error code */ xfs_getbmap( bhv_desc_t *bdp, /* XFS behavior descriptor*/ struct getbmap *bmv, /* user bmap structure */ - void *ap, /* pointer to user's array */ + void __user *ap, /* pointer to user's array */ int interface) /* interface flags */ { __int64_t bmvend; /* last block requested */ @@ -5634,8 +5690,10 @@ xfs_getbmap( (__int64_t)(bmvend - bmv->bmv_offset)); bmv->bmv_entries++; ap = (interface & BMV_IF_EXTENDED) ? - (void *)((struct getbmapx *)ap + 1) : - (void *)((struct getbmap *)ap + 1); + (void __user *) + ((struct getbmapx __user *)ap + 1) : + (void __user *) + ((struct getbmap __user *)ap + 1); } } } while (nmap && nexleft && bmv->bmv_length); diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 479e0d5598b4f1..f1bc22fb26aec4 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -328,7 +328,7 @@ int /* error code */ xfs_getbmap( bhv_desc_t *bdp, /* XFS behavior descriptor*/ struct getbmap *bmv, /* user bmap structure */ - void *ap, /* pointer to user's array */ + void __user *ap, /* pointer to user's array */ int iflags); /* interface flags */ /* diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index ed83f855df3455..0ed189102257d0 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -1953,7 +1953,7 @@ xfs_bmbt_get_block( *bpp = cur->bc_bufs[level]; rval = XFS_BUF_TO_BMBT_BLOCK(*bpp); } else { - *bpp = 0; + *bpp = NULL; ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); rval = ifp->if_broot; diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index e2150f70318318..a4a666a7c3a0f9 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000,2002-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 @@ -153,7 +153,7 @@ typedef enum { */ typedef enum { XFS_EXT_NORM, XFS_EXT_UNWRITTEN, - XFS_EXT_DMAPI_OFFLINE + XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID } xfs_exntst_t; /* diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index d550aa03012957..9ab0039f07df21 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -55,8 +55,6 @@ #include "xfs_error.h" -#define ROUNDUPNBWORD(x) (((x) + (NBWORD - 1)) & ~(NBWORD - 1)) - kmem_zone_t *xfs_buf_item_zone; #ifdef XFS_TRANS_DEBUG diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index f0431b7e625316..bbe00dc550d656 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -2092,7 +2092,7 @@ xfs_da_do_buf( int caller, inst_t *ra) { - xfs_buf_t *bp = 0; + xfs_buf_t *bp = NULL; xfs_buf_t **bplist; int error=0; int i; diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index f3bc48fe0c5ee6..08d551a173478d 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -65,7 +65,7 @@ */ int xfs_swapext( - xfs_swapext_t *sxp) + xfs_swapext_t __user *sxp) { xfs_swapext_t sx; xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h index 0e1c26fba89354..904860594b8f1f 100644 --- a/fs/xfs/xfs_dfrag.h +++ b/fs/xfs/xfs_dfrag.h @@ -60,7 +60,7 @@ typedef struct xfs_swapext /* * Syscall interface for xfs_swapext */ -int xfs_swapext(struct xfs_swapext *sx); +int xfs_swapext(struct xfs_swapext __user *sx); #endif /* __KERNEL__ */ diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index e0b529b337d926..a8f9b42dfd0504 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h @@ -456,6 +456,7 @@ xfs_dinode_t *xfs_buf_to_dinode(struct xfs_buf *bp); #define XFS_DIFLAG_SYNC_BIT 5 /* inode is written synchronously */ #define XFS_DIFLAG_NOATIME_BIT 6 /* do not update atime */ #define XFS_DIFLAG_NODUMP_BIT 7 /* do not dump */ +#define XFS_DIFLAG_RTINHERIT_BIT 8 /* create with realtime bit set */ #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) @@ -464,5 +465,11 @@ xfs_dinode_t *xfs_buf_to_dinode(struct xfs_buf *bp); #define XFS_DIFLAG_SYNC (1 << XFS_DIFLAG_SYNC_BIT) #define XFS_DIFLAG_NOATIME (1 << XFS_DIFLAG_NOATIME_BIT) #define XFS_DIFLAG_NODUMP (1 << XFS_DIFLAG_NODUMP_BIT) +#define XFS_DIFLAG_RTINHERIT (1 << XFS_DIFLAG_RTINHERIT_BIT) + +#define XFS_DIFLAG_ANY \ + (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ + XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ + XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT) #endif /* __XFS_DINODE_H__ */ diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c index c6747162f25183..9d64173931408d 100644 --- a/fs/xfs/xfs_dir2_trace.c +++ b/fs/xfs/xfs_dir2_trace.c @@ -211,7 +211,7 @@ xfs_dir2_trace_args_s( (void *)((unsigned long)(args->inumber >> 32)), (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)args->justcheck, (void *)(long)s, 0); + (void *)(unsigned long)args->justcheck, (void *)(long)s, NULL); } void diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 1ed650e902d258..3b0c8494d45e03 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -76,6 +76,7 @@ struct fsxattr { #define XFS_XFLAG_SYNC 0x00000020 /* all writes synchronous */ #define XFS_XFLAG_NOATIME 0x00000040 /* do not update access time */ #define XFS_XFLAG_NODUMP 0x00000080 /* do not include in backups */ +#define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* @@ -164,7 +165,7 @@ typedef struct xfs_flock64 { __s64 l_start; __s64 l_len; /* len == 0 means until end of file */ __s32 l_sysid; - pid_t l_pid; + __u32 l_pid; __s32 l_pad[4]; /* reserve area */ } xfs_flock64_t; @@ -313,10 +314,10 @@ typedef struct xfs_bstat { * The user-level BulkStat Request interface structure. */ typedef struct xfs_fsop_bulkreq { - __u64 *lastip; /* last inode # pointer */ + __u64 __user *lastip; /* last inode # pointer */ __s32 icount; /* count of entries in buffer */ - void *ubuffer; /* user buffer for inode desc. */ - __s32 *ocount; /* output count pointer */ + void __user *ubuffer;/* user buffer for inode desc. */ + __s32 __user *ocount; /* output count pointer */ } xfs_fsop_bulkreq_t; @@ -344,12 +345,12 @@ typedef struct xfs_error_injection { */ typedef struct xfs_fsop_handlereq { __u32 fd; /* fd for FD_TO_HANDLE */ - void *path; /* user pathname */ + void __user *path; /* user pathname */ __u32 oflags; /* open flags */ - void *ihandle; /* user supplied handle */ + void __user *ihandle;/* user supplied handle */ __u32 ihandlen; /* user supplied length */ - void *ohandle; /* user buffer for handle */ - __u32 *ohandlen; /* user buffer length */ + void __user *ohandle;/* user buffer for handle */ + __u32 __user *ohandlen;/* user buffer length */ } xfs_fsop_handlereq_t; /* @@ -360,35 +361,35 @@ typedef struct xfs_fsop_handlereq { */ typedef struct xfs_fsop_setdm_handlereq { - struct xfs_fsop_handlereq hreq; /* handle interface structure */ - struct fsdmidata *data; /* DMAPI data to set */ + struct xfs_fsop_handlereq hreq; /* handle information */ + struct fsdmidata __user *data; /* DMAPI data */ } xfs_fsop_setdm_handlereq_t; typedef struct xfs_attrlist_cursor { - __u32 opaque[4]; + __u32 opaque[4]; } xfs_attrlist_cursor_t; typedef struct xfs_fsop_attrlist_handlereq { - struct xfs_fsop_handlereq hreq; /* handle interface structure */ - struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */ - __u32 flags; /* flags, use ROOT/USER names */ - __u32 buflen; /* length of buffer supplied */ - void *buffer; /* attrlist data to return */ + struct xfs_fsop_handlereq hreq; /* handle interface structure */ + struct xfs_attrlist_cursor pos; /* opaque cookie, list offset */ + __u32 flags; /* which namespace to use */ + __u32 buflen; /* length of buffer supplied */ + void __user *buffer; /* returned names */ } xfs_fsop_attrlist_handlereq_t; typedef struct xfs_attr_multiop { - __u32 am_opcode; - __s32 am_error; - void *am_attrname; - void *am_attrvalue; - __u32 am_length; - __u32 am_flags; + __u32 am_opcode; + __s32 am_error; + void __user *am_attrname; + void __user *am_attrvalue; + __u32 am_length; + __u32 am_flags; } xfs_attr_multiop_t; typedef struct xfs_fsop_attrmulti_handlereq { - struct xfs_fsop_handlereq hreq; /* handle interface structure */ - __u32 opcount; /* count of following multiop */ - struct xfs_attr_multiop *ops; /* attr_multi data to get/set */ + struct xfs_fsop_handlereq hreq; /* handle interface structure */ + __u32 opcount;/* count of following multiop */ + struct xfs_attr_multiop __user *ops; /* attr_multi data */ } xfs_fsop_attrmulti_handlereq_t; /* @@ -445,6 +446,13 @@ typedef struct xfs_handle { #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ /* + * ioctl commands that are used by Linux filesystems + */ +#define XFS_IOC_GETXFLAGS _IOR('f', 1, long) +#define XFS_IOC_SETXFLAGS _IOW('f', 2, long) +#define XFS_IOC_GETVERSION _IOR('v', 1, long) + +/* * ioctl commands that replace IRIX fcntl()'s * For 'documentation' purposed more than anything else, * the "cmd #" field reflects the IRIX fcntl number. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 36bb461b626c36..4736fc4eaeed7a 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -507,9 +507,9 @@ xfs_reserve_blocks( __uint64_t *inval, xfs_fsop_resblks_t *outval) { - __uint64_t lcounter, delta; - __uint64_t request; - unsigned long s; + __int64_t lcounter, delta; + __uint64_t request; + unsigned long s; /* If inval is null, report current values and return */ @@ -536,8 +536,7 @@ xfs_reserve_blocks( mp->m_resblks = request; } else { delta = request - mp->m_resblks; - lcounter = mp->m_sb.sb_fdblocks; - lcounter -= delta; + lcounter = mp->m_sb.sb_fdblocks - delta; if (lcounter < 0) { /* We can't satisfy the request, just get what we can */ mp->m_resblks += mp->m_sb.sb_fdblocks; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8a821fed5a8c7a..ba160a993de099 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -860,25 +860,28 @@ xfs_dic2xflags( xfs_arch_t arch) { __uint16_t di_flags; - uint flags = 0; + uint flags; di_flags = INT_GET(dic->di_flags, arch); - if (di_flags & XFS_DIFLAG_REALTIME) - flags |= XFS_XFLAG_REALTIME; - if (di_flags & XFS_DIFLAG_PREALLOC) - flags |= XFS_XFLAG_PREALLOC; - if (di_flags & XFS_DIFLAG_IMMUTABLE) - flags |= XFS_XFLAG_IMMUTABLE; - if (di_flags & XFS_DIFLAG_APPEND) - flags |= XFS_XFLAG_APPEND; - if (di_flags & XFS_DIFLAG_SYNC) - flags |= XFS_XFLAG_SYNC; - if (di_flags & XFS_DIFLAG_NOATIME) - flags |= XFS_XFLAG_NOATIME; - if (di_flags & XFS_DIFLAG_NODUMP) - flags |= XFS_XFLAG_NODUMP; - if (XFS_CFORK_Q_ARCH(dic, arch)) - flags |= XFS_XFLAG_HASATTR; + flags = XFS_CFORK_Q_ARCH(dic, arch) ? XFS_XFLAG_HASATTR : 0; + if (di_flags & XFS_DIFLAG_ANY) { + if (di_flags & XFS_DIFLAG_REALTIME) + flags |= XFS_XFLAG_REALTIME; + if (di_flags & XFS_DIFLAG_PREALLOC) + flags |= XFS_XFLAG_PREALLOC; + if (di_flags & XFS_DIFLAG_IMMUTABLE) + flags |= XFS_XFLAG_IMMUTABLE; + if (di_flags & XFS_DIFLAG_APPEND) + flags |= XFS_XFLAG_APPEND; + if (di_flags & XFS_DIFLAG_SYNC) + flags |= XFS_XFLAG_SYNC; + if (di_flags & XFS_DIFLAG_NOATIME) + flags |= XFS_XFLAG_NOATIME; + if (di_flags & XFS_DIFLAG_NODUMP) + flags |= XFS_XFLAG_NODUMP; + if (di_flags & XFS_DIFLAG_RTINHERIT) + flags |= XFS_XFLAG_RTINHERIT; + } return flags; } @@ -1236,8 +1239,15 @@ xfs_ialloc( break; case S_IFREG: case S_IFDIR: - if (pip->i_d.di_flags & - (XFS_DIFLAG_NOATIME|XFS_DIFLAG_NODUMP|XFS_DIFLAG_SYNC)) { + if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { + if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { + if ((mode & S_IFMT) == S_IFDIR) { + ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; + } else { + ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; + ip->i_iocore.io_flags |= XFS_IOCORE_RT; + } + } if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && xfs_inherit_noatime) ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; @@ -1248,6 +1258,7 @@ xfs_ialloc( xfs_inherit_sync) ip->i_d.di_flags |= XFS_DIFLAG_SYNC; } + /* FALLTHROUGH */ case S_IFLNK: ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_df.if_flags = XFS_IFEXTENTS; @@ -3579,6 +3590,7 @@ corrupt_out: return XFS_ERROR(EFSCORRUPTED); } + /* * Flush all inactive inodes in mp. Return true if no user references * were found, false otherwise. @@ -3634,7 +3646,6 @@ xfs_iflush_all( continue; } if (!(flag & XFS_FLUSH_ALL)) { - ASSERT(0); busy = 1; done = 1; break; @@ -3851,6 +3862,6 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) (void *)ra, /* caller of ilock */ (void *)(unsigned long)current_cpu(), (void *)(unsigned long)current_pid(), - 0,0,0,0,0,0,0,0,0,0); + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } #endif diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7e1c1290a515bd..3826e8f0e28a6d 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -165,20 +165,24 @@ xfs_imap_to_bmap( nisize = io->io_new_size; for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { - iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ? - mp->m_rtdev_targp : mp->m_ddev_targp; iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); iomapp->iomap_delta = offset - iomapp->iomap_offset; iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); iomapp->iomap_flags = flags; + if (io->io_flags & XFS_IOCORE_RT) { + iomapp->iomap_flags |= IOMAP_REALTIME; + iomapp->iomap_target = mp->m_rtdev_targp; + } else { + iomapp->iomap_target = mp->m_ddev_targp; + } start_block = imap->br_startblock; if (start_block == HOLESTARTBLOCK) { iomapp->iomap_bn = IOMAP_DADDR_NULL; - iomapp->iomap_flags = IOMAP_HOLE; + iomapp->iomap_flags |= IOMAP_HOLE; } else if (start_block == DELAYSTARTBLOCK) { iomapp->iomap_bn = IOMAP_DADDR_NULL; - iomapp->iomap_flags = IOMAP_DELAY; + iomapp->iomap_flags |= IOMAP_DELAY; } else { iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block); if (ISUNWRITTEN(imap)) @@ -512,6 +516,15 @@ xfs_iomap_write_direct( *ret_imap = imap[0]; *nmaps = 1; + if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { + cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " + "start_block : %llx start_off : %llx blkcnt : %llx " + "extent-state : %x \n", + (ip->i_mount)->m_fsname, + (long long)ip->i_ino, + ret_imap->br_startblock, ret_imap->br_startoff, + ret_imap->br_blockcount,ret_imap->br_state); + } return 0; error0: /* Cancel bmap, unlock inode, and cancel trans */ @@ -572,8 +585,10 @@ retry: * out to the file system's write iosize. We clean up any extra * space left over when the file is closed in xfs_inactive(). * - * We don't bother with this for sync writes, because we need - * to minimize the amount we write for good performance. + * For sync writes, we are flushing delayed allocate space to + * try to make additional space available for allocation near + * the filesystem full boundary - preallocation hurts in that + * situation, of course. */ if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) { xfs_off_t aligned_offset; @@ -598,6 +613,20 @@ retry: return error; } for (n = 0; n < nimaps; n++) { + if ( !(io->io_flags & XFS_IOCORE_RT) && + !imap[n].br_startblock) { + cmn_err(CE_PANIC,"Access to block " + "zero: fs <%s> inode: %lld " + "start_block : %llx start_off " + ": %llx blkcnt : %llx " + "extent-state : %x \n", + (ip->i_mount)->m_fsname, + (long long)ip->i_ino, + imap[n].br_startblock, + imap[n].br_startoff, + imap[n].br_blockcount, + imap[n].br_state); + } if ((imap[n].br_startblock != HOLESTARTBLOCK) && (imap[n].br_startblock != DELAYSTARTBLOCK)) { goto write_map; @@ -621,7 +650,8 @@ write_map: * request to a stripe width boundary if the file size is >= * stripe width and we are allocating past the allocation eof. */ - if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC) + if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_swidth + && (mp->m_flags & XFS_MOUNT_SWALLOC) && (isize >= XFS_FSB_TO_B(mp, mp->m_swidth)) && aeof) { int eof; xfs_fileoff_t new_last_fsb; @@ -639,8 +669,8 @@ write_map: * if the file size is >= stripe unit size, and we are allocating past * the allocation eof. */ - } else if (mp->m_dalign && (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)) - && aeof) { + } else if (!(io->io_flags & XFS_IOCORE_RT) && mp->m_dalign && + (isize >= XFS_FSB_TO_B(mp, mp->m_dalign)) && aeof) { int eof; xfs_fileoff_t new_last_fsb; new_last_fsb = roundup_64(last_fsb, mp->m_dalign); @@ -651,8 +681,22 @@ write_map: if (eof) { last_fsb = new_last_fsb; } - } + /* + * Round up the allocation request to a real-time extent boundary + * if the file is on the real-time subvolume. + */ + } else if (io->io_flags & XFS_IOCORE_RT && aeof) { + int eof; + xfs_fileoff_t new_last_fsb; + new_last_fsb = roundup_64(last_fsb, mp->m_sb.sb_rextsize); + error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof); + if (error) { + return error; + } + if (eof) + last_fsb = new_last_fsb; + } error = xfs_bmapi(NULL, ip, offset_fsb, (xfs_filblks_t)(last_fsb - offset_fsb), XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | @@ -680,6 +724,15 @@ write_map: *ret_imap = imap[0]; *nmaps = 1; + if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { + cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " + "start_block : %llx start_off : %llx blkcnt : %llx " + "extent-state : %x \n", + (ip->i_mount)->m_fsname, + (long long)ip->i_ino, + ret_imap->br_startblock, ret_imap->br_startoff, + ret_imap->br_blockcount,ret_imap->br_state); + } return 0; } @@ -697,6 +750,7 @@ xfs_iomap_write_allocate( int *retmap) { xfs_mount_t *mp = ip->i_mount; + xfs_iocore_t *io = &ip->i_iocore; xfs_fileoff_t offset_fsb, last_block; xfs_fileoff_t end_fsb, map_start_fsb; xfs_fsblock_t first_block; @@ -802,6 +856,18 @@ xfs_iomap_write_allocate( */ for (i = 0; i < nimaps; i++) { + if ( !(io->io_flags & XFS_IOCORE_RT) && + !imap[i].br_startblock) { + cmn_err(CE_PANIC,"Access to block zero: " + "fs <%s> inode: %lld " + "start_block : %llx start_off : %llx " + "blkcnt : %llx extent-state : %x \n", + (ip->i_mount)->m_fsname, + (long long)ip->i_ino, + imap[i].br_startblock, + imap[i].br_startoff, + imap[i].br_blockcount,imap[i].br_state); + } if ((map->br_startoff >= imap[i].br_startoff) && (map->br_startoff < (imap[i].br_startoff + imap[i].br_blockcount))) { @@ -837,6 +903,7 @@ xfs_iomap_write_unwritten( size_t count) { xfs_mount_t *mp = ip->i_mount; + xfs_iocore_t *io = &ip->i_iocore; xfs_trans_t *tp; xfs_fileoff_t offset_fsb; xfs_filblks_t count_fsb; @@ -853,7 +920,8 @@ xfs_iomap_write_unwritten( &ip->i_iocore, offset, count); offset_fsb = XFS_B_TO_FSBT(mp, offset); - count_fsb = XFS_B_TO_FSB(mp, count); + count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); + count_fsb = (xfs_filblks_t)(count_fsb - offset_fsb); do { nres = XFS_DIOSTRAT_SPACE_RES(mp, 0); @@ -898,6 +966,16 @@ xfs_iomap_write_unwritten( xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) goto error0; + + if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) { + cmn_err(CE_PANIC,"Access to block zero: fs <%s> " + "inode: %lld start_block : %llx start_off : " + "%llx blkcnt : %llx extent-state : %x \n", + (ip->i_mount)->m_fsname, + (long long)ip->i_ino, + imap.br_startblock,imap.br_startoff, + imap.br_blockcount,imap.br_state); + } if ((numblks_fsb = imap.br_blockcount) == 0) { /* diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 673410c564b891..31c91087cb3343 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2003,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 @@ -42,6 +42,7 @@ typedef enum { /* iomap_flags values */ IOMAP_EOF = 0x01, /* mapping contains EOF */ IOMAP_HOLE = 0x02, /* mapping covers a hole */ IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ + IOMAP_REALTIME = 0x10, /* mapping on the realtime device */ IOMAP_UNWRITTEN = 0x20, /* mapping covers allocated */ /* but uninitialized file data */ IOMAP_NEW = 0x40 /* just allocate */ @@ -57,7 +58,7 @@ typedef enum { BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ - BMAPI_SYNC = (1 << 7), /* sync write */ + BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ BMAPI_DEVICE = (1 << 9), /* we only want to know the device */ } bmapi_flags_t; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 01fae1abb2ea24..36dc09c8c1aa12 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -68,7 +68,7 @@ int /* error status */ xfs_bulkstat_one( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode number to get data for */ - void *buffer, /* buffer to place output in */ + void __user *buffer, /* buffer to place output in */ int ubsize, /* size of buffer */ void *private_data, /* my private data */ xfs_daddr_t bno, /* starting bno of inode cluster */ @@ -231,7 +231,7 @@ xfs_bulkstat( bulkstat_one_pf formatter, /* func that'd fill a single buf */ void *private_data,/* private data for formatter */ size_t statstruct_size, /* sizeof struct filling */ - xfs_caddr_t ubuffer, /* buffer with inode stats */ + char __user *ubuffer, /* buffer with inode stats */ int flags, /* defined in xfs_itable.h */ int *done) /* 1 if there're more stats to get */ { @@ -265,7 +265,7 @@ xfs_bulkstat( int tmp; /* result value from btree calls */ int ubcount; /* size of user's buffer */ int ubleft; /* bytes left in user's buffer */ - xfs_caddr_t ubufp; /* current pointer into user's buffer */ + char __user *ubufp; /* pointer into user's buffer */ int ubelem; /* spaces used in user's buffer */ int ubused; /* bytes used by formatter */ xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ @@ -633,7 +633,7 @@ int /* error status */ xfs_bulkstat_single( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastinop, /* inode to return */ - xfs_caddr_t buffer, /* buffer with inode stats */ + char __user *buffer, /* buffer with inode stats */ int *done) /* 1 if there're more stats to get */ { int count; /* count value for bulkstat call */ @@ -682,7 +682,7 @@ xfs_inumbers( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastino, /* last inode returned */ int *count, /* size of buffer/count returned */ - xfs_caddr_t ubuffer) /* buffer with inode descriptions */ + xfs_inogrp_t __user *ubuffer)/* buffer with inode descriptions */ { xfs_buf_t *agbp; xfs_agino_t agino; @@ -766,7 +766,7 @@ xfs_inumbers( error = XFS_ERROR(EFAULT); break; } - ubuffer += bufidx * sizeof(*buffer); + ubuffer += bufidx; *count += bufidx; bufidx = 0; } diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index 476e531a9a9ba9..2be9d1805ab237 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h @@ -40,7 +40,7 @@ */ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, xfs_ino_t ino, - void *buffer, + void __user *buffer, int ubsize, void *private_data, xfs_daddr_t bno, @@ -73,7 +73,7 @@ xfs_bulkstat( bulkstat_one_pf formatter, /* func that'd fill a single buf */ void *private_data, /* private data for formatter */ size_t statstruct_size,/* sizeof struct that we're filling */ - xfs_caddr_t ubuffer, /* buffer with inode stats */ + char __user *ubuffer,/* buffer with inode stats */ int flags, /* flag to control access method */ int *done); /* 1 if there're more stats to get */ @@ -81,14 +81,14 @@ int xfs_bulkstat_single( xfs_mount_t *mp, xfs_ino_t *lastinop, - xfs_caddr_t buffer, + char __user *buffer, int *done); int xfs_bulkstat_one( xfs_mount_t *mp, xfs_ino_t ino, - void *buffer, + void __user *buffer, int ubsize, void *private_data, xfs_daddr_t bno, @@ -101,6 +101,6 @@ xfs_inumbers( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *last, /* last inode returned */ int *count, /* size of buffer/count returned */ - xfs_caddr_t buffer);/* buffer with inode descriptions */ + xfs_inogrp_t __user *buffer);/* buffer with inode info */ #endif /* __XFS_ITABLE_H__ */ diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 212d4e837a3a57..10d823bd214740 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -122,7 +122,6 @@ STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket); /* local debug functions */ #if defined(DEBUG) && !defined(XLOG_NOLOG) STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); -STATIC void xlog_verify_disk_cycle_no(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_verify_grant_head(xlog_t *log, int equals); STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, int count, boolean_t syncing); @@ -130,7 +129,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, xfs_lsn_t tail_lsn); #else #define xlog_verify_dest_ptr(a,b) -#define xlog_verify_disk_cycle_no(a,b) #define xlog_verify_grant_head(a,b) #define xlog_verify_iclog(a,b,c,d) #define xlog_verify_tail_lsn(a,b,c) @@ -356,13 +354,13 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ if (!xlog_debug && xlog_target == log->l_targ) return 0; #endif - cb->cb_next = 0; + cb->cb_next = NULL; spl = LOG_LOCK(log); abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); if (!abortflg) { ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) || (iclog->ic_state == XLOG_STATE_WANT_SYNC)); - cb->cb_next = 0; + cb->cb_next = NULL; *(iclog->ic_callback_tail) = cb; iclog->ic_callback_tail = &(cb->cb_next); } @@ -564,7 +562,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) xlog_in_core_t *first_iclog; #endif xfs_log_iovec_t reg[1]; - xfs_log_ticket_t tic = 0; + xfs_log_ticket_t tic = NULL; xfs_lsn_t lsn; int error; SPLDECL(s); @@ -1277,7 +1275,7 @@ xlog_commit_record(xfs_mount_t *mp, int error; xfs_log_iovec_t reg[1]; - reg[0].i_addr = 0; + reg[0].i_addr = NULL; reg[0].i_len = 0; ASSERT_ALWAYS(iclog); @@ -1857,7 +1855,7 @@ xlog_state_clean_log(xlog_t *log) if (iclog->ic_state == XLOG_STATE_DIRTY) { iclog->ic_state = XLOG_STATE_ACTIVE; iclog->ic_offset = 0; - iclog->ic_callback = 0; /* don't need to free */ + iclog->ic_callback = NULL; /* don't need to free */ /* * If the number of ops in this iclog indicate it just * contains the dummy transaction, we can @@ -2080,7 +2078,7 @@ xlog_state_do_callback( while (cb != 0) { iclog->ic_callback_tail = &(iclog->ic_callback); - iclog->ic_callback = 0; + iclog->ic_callback = NULL; LOG_UNLOCK(log, s); /* perform callbacks in the order given */ @@ -3098,7 +3096,7 @@ xlog_state_ticket_alloc(xlog_t *log) log->l_ticket_cnt++; log->l_ticket_tcnt++; } - t_list->t_next = 0; + t_list->t_next = NULL; log->l_tail = t_list; LOG_UNLOCK(log, s); } /* xlog_state_ticket_alloc */ @@ -3126,7 +3124,7 @@ xlog_ticket_put(xlog_t *log, /* no need to clear fields */ #else /* When we debug, it is easier if tickets are cycled */ - ticket->t_next = 0; + ticket->t_next = NULL; if (log->l_tail != 0) { log->l_tail->t_next = ticket; } else { @@ -3242,33 +3240,6 @@ xlog_verify_dest_ptr(xlog_t *log, xlog_panic("xlog_verify_dest_ptr: invalid ptr"); } /* xlog_verify_dest_ptr */ - -#ifdef DEBUG -/* check split LR write */ -STATIC void -xlog_verify_disk_cycle_no(xlog_t *log, - xlog_in_core_t *iclog) -{ - xfs_buf_t *bp; - uint cycle_no; - xfs_caddr_t ptr; - xfs_daddr_t i; - - if (BLOCK_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT) < 10) { - cycle_no = CYCLE_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT); - bp = xlog_get_bp(log, 1); - ASSERT(bp); - for (i = 0; i < BLOCK_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT); i++) { - xlog_bread(log, i, 1, bp); - ptr = xlog_align(log, i, 1, bp); - if (GET_CYCLE(ptr, ARCH_CONVERT) != cycle_no) - xlog_warn("XFS: xlog_verify_disk_cycle_no: bad cycle no"); - } - xlog_put_bp(bp); - } -} /* xlog_verify_disk_cycle_no */ -#endif - STATIC void xlog_verify_grant_head(xlog_t *log, int equals) { diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 2e5ab6af878ea4..65dbbb638ec17d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2319,7 +2319,7 @@ xlog_recover_do_inode_trans( * invalidate the buffer when we write it out below. */ imap.im_blkno = 0; - xfs_imap(log->l_mp, 0, ino, &imap, 0); + xfs_imap(log->l_mp, NULL, ino, &imap, 0); } /* diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 93c544ee5c11c1..6bbcd7bd68b8c5 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -278,17 +278,22 @@ xfs_mount_validate_sb( return XFS_ERROR(EFSCORRUPTED); } -#if !XFS_BIG_BLKNOS + ASSERT(PAGE_SHIFT >= sbp->sb_blocklog); + ASSERT(sbp->sb_blocklog >= BBSHIFT); + +#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ + if (unlikely( + (sbp->sb_dblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX || + (sbp->sb_rblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX)) { +#else /* Limited by UINT_MAX of sectors */ if (unlikely( - (sbp->sb_dblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT)) - > UINT_MAX || - (sbp->sb_rblocks << (__uint64_t)(sbp->sb_blocklog - BBSHIFT)) - > UINT_MAX)) { + (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX || + (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) { +#endif cmn_err(CE_WARN, "XFS: File system is too large to be mounted on this system."); return XFS_ERROR(E2BIG); } -#endif if (unlikely(sbp->sb_inprogress)) { cmn_err(CE_WARN, "XFS: file system busy"); @@ -633,9 +638,8 @@ xfs_mountfs( xfs_buf_t *bp; xfs_sb_t *sbp = &(mp->m_sb); xfs_inode_t *rip; - vnode_t *rvp = 0; + vnode_t *rvp = NULL; int readio_log, writeio_log; - vmap_t vmap; xfs_daddr_t d; __uint64_t ret64; __int64_t update_flags; @@ -979,7 +983,6 @@ xfs_mountfs( ASSERT(rip != NULL); rvp = XFS_ITOV(rip); - VMAP(rvp, vmap); if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { cmn_err(CE_WARN, "XFS: corrupted root inode"); @@ -1043,7 +1046,6 @@ xfs_mountfs( * Free up the root inode. */ VN_RELE(rvp); - vn_purge(rvp, &vmap); error3: xfs_log_unmount_dealloc(mp); error2: diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 8cddc16397de2c..703ec4efcb4115 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -309,23 +309,27 @@ typedef struct xfs_dqtrxops { } xfs_dqtrxops_t; #define XFS_DQTRXOP(mp, tp, op, args...) \ - ((mp)->m_qm_ops.xfs_dqtrxops ? \ - ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) + ((mp)->m_qm_ops.xfs_dqtrxops ? \ + ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) + +#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ + ((mp)->m_qm_ops.xfs_dqtrxops ? \ + ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) #define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ - XFS_DQTRXOP(mp, otp, qo_dup_dqinfo, ntp) + XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) #define XFS_TRANS_FREE_DQINFO(mp, tp) \ - XFS_DQTRXOP(mp, tp, qo_free_dqinfo) + XFS_DQTRXOP_VOID(mp, tp, qo_free_dqinfo) #define XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, field, delta) \ - XFS_DQTRXOP(mp, tp, qo_mod_dquot_byino, ip, field, delta) + XFS_DQTRXOP_VOID(mp, tp, qo_mod_dquot_byino, ip, field, delta) #define XFS_TRANS_APPLY_DQUOT_DELTAS(mp, tp) \ - XFS_DQTRXOP(mp, tp, qo_apply_dquot_deltas) + XFS_DQTRXOP_VOID(mp, tp, qo_apply_dquot_deltas) #define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, fl) \ XFS_DQTRXOP(mp, tp, qo_reserve_quota_nblks, mp, ip, nblks, ninos, fl) #define XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, fl) \ XFS_DQTRXOP(mp, tp, qo_reserve_quota_bydquots, mp, ud, gd, nb, ni, fl) #define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ - XFS_DQTRXOP(mp, tp, qo_unreserve_and_mod_dquots) + XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) #define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \ XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index c130d4259fece5..acc87d134dd148 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -2353,13 +2353,7 @@ xfs_rtmount_inodes( ASSERT(sbp->sb_rsumino != NULLFSINO); error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, &mp->m_rsumip, 0); if (error) { - vnode_t *rbmvp; /* vnode for bitmap file */ - vmap_t vmap; /* vmap to delete vnode */ - - rbmvp = XFS_ITOV(mp->m_rbmip); - VMAP(rbmvp, vmap); - VN_RELE(rbmvp); - vn_purge(rbmvp, &vmap); + VN_RELE(XFS_ITOV(mp->m_rbmip)); return error; } ASSERT(mp->m_rsumip != NULL); diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index 9e0adf4c48a767..ad090a834ced69 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h @@ -250,9 +250,9 @@ 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_MOREBITSBIT) && \ - ((sbp)->sb_features2 & ~XFS_SB_VERSION2_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) \ diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 81885773918182..c2bbc9a2c8b8fa 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -491,6 +491,9 @@ xfs_trans_apply_sb_deltas( if (tp->t_frextents_delta != 0) { INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta); } + if (tp->t_res_frextents_delta != 0) { + INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta); + } if (tp->t_dblocks_delta != 0) { INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta); whole = 1; diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c index 767af4810775df..1b8a756d80ed00 100644 --- a/fs/xfs/xfs_trans_item.c +++ b/fs/xfs/xfs_trans_item.c @@ -290,7 +290,7 @@ xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp) } ASSERT(0); /* NOTREACHED */ - return 0; /* keep gcc quite */ + return NULL; /* keep gcc quite */ } /* diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 8d6aac75047cc4..04609d27ea519d 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -58,7 +58,7 @@ typedef enum { B_FALSE,B_TRUE } boolean_t; typedef __int64_t prid_t; /* project ID */ typedef __uint32_t inst_t; /* an instruction */ -typedef __u64 xfs_off_t; +typedef __s64 xfs_off_t; /* <file offset> type */ typedef __u64 xfs_ino_t; /* <inode> type */ typedef __s64 xfs_daddr_t; /* <disk address> type */ typedef char * xfs_caddr_t; /* <core address> type */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 114c53a766a20e..3b4addb11db9eb 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -431,6 +431,16 @@ xfs_mount( logdev = rtdev = NULL; /* + * Setup xfs_mount function vectors from available behaviors + */ + p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); + mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; + p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); + mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; + p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); + mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; + + /* * Open real time and log devices - order is important. */ if (args->logname[0]) { @@ -455,68 +465,73 @@ xfs_mount( } /* - * Setup xfs_mount function vectors from available behaviors - */ - p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); - mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; - p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); - mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; - p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); - mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; - - /* * Setup xfs_mount buffer target pointers */ + error = ENOMEM; mp->m_ddev_targp = xfs_alloc_buftarg(ddev); - if (rtdev) + if (!mp->m_ddev_targp) { + xfs_blkdev_put(logdev); + xfs_blkdev_put(rtdev); + return error; + } + if (rtdev) { mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev); + if (!mp->m_rtdev_targp) + goto error0; + } mp->m_logdev_targp = (logdev && logdev != ddev) ? xfs_alloc_buftarg(logdev) : mp->m_ddev_targp; + if (!mp->m_logdev_targp) + goto error0; /* * Setup flags based on mount(2) options and then the superblock */ error = xfs_start_flags(vfsp, args, mp); if (error) - goto error; + goto error1; error = xfs_readsb(mp); if (error) - goto error; + goto error1; error = xfs_finish_flags(vfsp, args, mp); - if (error) { - xfs_freesb(mp); - goto error; - } + if (error) + goto error2; /* * Setup xfs_mount buffer target pointers based on superblock */ - xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, - mp->m_sb.sb_sectsize); - if (logdev && logdev != ddev) { + error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, + mp->m_sb.sb_sectsize); + if (!error && logdev && logdev != ddev) { unsigned int log_sector_size = BBSIZE; if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) log_sector_size = mp->m_sb.sb_logsectsize; - xfs_setsize_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, - log_sector_size); + error = xfs_setsize_buftarg(mp->m_logdev_targp, + mp->m_sb.sb_blocksize, + log_sector_size); } - if (rtdev) - xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize, - mp->m_sb.sb_blocksize); + if (!error && rtdev) + error = xfs_setsize_buftarg(mp->m_rtdev_targp, + mp->m_sb.sb_blocksize, + mp->m_sb.sb_sectsize); + if (error) + goto error2; - if (!(error = XFS_IOINIT(vfsp, args, flags))) + error = XFS_IOINIT(vfsp, args, flags); + if (!error) return 0; - - error: +error2: + if (mp->m_sb_bp) + xfs_freesb(mp); +error1: xfs_binval(mp->m_ddev_targp); - if (logdev != NULL && logdev != ddev) { + if (logdev && logdev != ddev) xfs_binval(mp->m_logdev_targp); - } - if (rtdev != NULL) { + if (rtdev) xfs_binval(mp->m_rtdev_targp); - } - xfs_unmountfs_close(mp, NULL); +error0: + xfs_unmountfs_close(mp, credp); return error; } diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 72a04a11cec4de..b7ecbce3e8b990 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -823,10 +823,15 @@ xfs_setattr( mp->m_sb.sb_blocklog; } if (mask & XFS_AT_XFLAGS) { - ip->i_d.di_flags = 0; - if (vap->va_xflags & XFS_XFLAG_REALTIME) { + /* can't set PREALLOC this way, just preserve it */ + ip->i_d.di_flags = + (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); + if (vap->va_xflags & XFS_XFLAG_REALTIME && + (ip->i_d.di_mode & S_IFMT) == S_IFREG) { ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; ip->i_iocore.io_flags |= XFS_IOCORE_RT; + } else { + ip->i_iocore.io_flags &= ~XFS_IOCORE_RT; } if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE; @@ -838,7 +843,9 @@ xfs_setattr( ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; if (vap->va_xflags & XFS_XFLAG_NODUMP) ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; - /* can't set PREALLOC this way, just ignore it */ + if ((vap->va_xflags & XFS_XFLAG_RTINHERIT) && + (ip->i_d.di_mode & S_IFMT) == S_IFDIR) + ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; } xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); timeflags |= XFS_ICHGTIME_CHG; @@ -1822,8 +1829,6 @@ xfs_lookup( } -#define XFS_CREATE_NEW_MAXTRIES 10000 - /* * xfs_create (create a new file). */ @@ -4337,8 +4342,10 @@ xfs_free_file_space( nimap = 1; error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, &imap, &nimap, NULL); - if (error) + if (error) { + xfs_iunlock(ip, XFS_IOLOCK_EXCL); return error; + } ASSERT(nimap == 0 || nimap == 1); if (nimap && imap.br_startblock != HOLESTARTBLOCK) { xfs_daddr_t block; @@ -4352,8 +4359,10 @@ xfs_free_file_space( nimap = 1; error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, &imap, &nimap, NULL); - if (error) + if (error) { + xfs_iunlock(ip, XFS_IOLOCK_EXCL); return error; + } ASSERT(nimap == 0 || nimap == 1); if (nimap && imap.br_startblock != HOLESTARTBLOCK) { ASSERT(imap.br_startblock != DELAYSTARTBLOCK); |